7次发布
0.1.6 | 2024年5月8日 |
---|---|
0.1.5 | 2023年8月25日 |
0.1.4 | 2022年2月6日 |
0.1.3 | 2021年4月6日 |
0.1.0 | 2020年11月9日 |
#104 in 测试
38KB
519 行
assert-unmoved
一个类型,断言在经过固定和可变访问后,其底层类型未被移动。
这是对futures-test的AssertUnmoved
的重新编写,以便在更多用例中使用。它还支持除了futures之外的其他特性和类型。
在此项目中进行的许多更改也已反映在上游:rust-lang/futures-rs#2148,rust-lang/futures-rs#2208
使用方法
将此添加到您的Cargo.toml
[dependencies]
assert-unmoved = "0.1"
示例
检测不正确的Pin::new_unchecked
使用(应崩溃)的示例
use std::pin::Pin;
use assert_unmoved::AssertUnmoved;
use futures::{
future::{self, Future},
task::{noop_waker, Context},
};
let waker = noop_waker();
let mut cx = Context::from_waker(&waker);
// First we allocate the future on the stack and poll it.
let mut future = AssertUnmoved::new(future::pending::<()>());
let pinned_future = unsafe { Pin::new_unchecked(&mut future) };
assert!(pinned_future.poll(&mut cx).is_pending());
// Next we move it back to the heap and poll it again. This second call
// should panic (as the future is moved).
let mut boxed_future = Box::new(future);
let pinned_boxed_future = unsafe { Pin::new_unchecked(&mut *boxed_future) };
let _ = pinned_boxed_future.poll(&mut cx).is_pending();
检测不正确的StreamExt::next
实现(应崩溃)的示例
use std::pin::Pin;
use assert_unmoved::AssertUnmoved;
use futures::{
future::Future,
stream::{self, Stream},
task::{noop_waker, Context, Poll},
};
struct Next<'a, S: Stream>(&'a mut S);
impl<S: Stream> Future for Next<'_, S> {
type Output = Option<S::Item>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
// This is `Pin<&mut Type>` to `Pin<Field>` projection and is unsound
// if `S` is not `Unpin` (you can move `S` after `Next` dropped).
//
// The correct projection is `Pin<&mut Type>` to `Pin<&mut Field>`.
// In `Next`, it is `Pin<&mut Next<'_, S>>` to `Pin<&mut &mut S>`,
// and it needs to add `S: Unpin` bounds to convert `Pin<&mut &mut S>`
// to `Pin<&mut S>`.
let stream: Pin<&mut S> = unsafe { self.map_unchecked_mut(|f| f.0) };
stream.poll_next(cx)
}
}
let waker = noop_waker();
let mut cx = Context::from_waker(&waker);
let mut stream = AssertUnmoved::new(stream::pending::<()>());
{
let next = Next(&mut stream);
let mut pinned_next = Box::pin(next);
assert!(pinned_next.as_mut().poll(&mut cx).is_pending());
}
// Move stream to the heap.
let mut boxed_stream = Box::pin(stream);
let next = Next(&mut boxed_stream);
let mut pinned_next = Box::pin(next);
// This should panic (as the future is moved).
let _ = pinned_next.as_mut().poll(&mut cx).is_pending();
可选特性
futures03
— 为assert-unmoved类型实现futures v0.3特性和类型。tokio1
— 为assert-unmoved类型实现tokio v1特性和类型。tokio03
— 为assert-unmoved类型实现tokio v0.3特性和类型。tokio02
— 为assert-unmoved类型实现tokio v0.2特性和类型。
注意:启用这些特性时的MSRV取决于这些Crate的MSRV。
许可证
许可根据您的选择,在Apache License, Version 2.0或MIT许可证下。
除非您明确声明,否则根据Apache-2.0许可证定义,您有意提交以包含在作品中的任何贡献,将采用上述双重许可,无需任何附加条款或条件。
依赖关系
~0–1.4MB
~23K SLoC