Account for Pin::new(_) and Pin::new(Box::new(_)) when Box::pin(_) would be applicable

This commit is contained in:
Esteban Küber 2020-02-12 11:51:07 -08:00
parent 80cdb0af7d
commit c376fc0017
5 changed files with 22 additions and 12 deletions

View File

@ -727,6 +727,13 @@ unsafe impl<T: ?Sized> Freeze for &mut T {}
/// [`Pin<P>`]: ../pin/struct.Pin.html /// [`Pin<P>`]: ../pin/struct.Pin.html
/// [`pin module`]: ../../std/pin/index.html /// [`pin module`]: ../../std/pin/index.html
#[stable(feature = "pin", since = "1.33.0")] #[stable(feature = "pin", since = "1.33.0")]
#[rustc_on_unimplemented(
on(
_Self = "dyn std::future::Future<Output = i32> + std::marker::Send",
note = "consider using `Box::pin`",
),
message = "`{Self}` cannot be unpinned"
)]
#[lang = "unpin"] #[lang = "unpin"]
pub auto trait Unpin {} pub auto trait Unpin {}

View File

@ -11,5 +11,5 @@ fn main() {
let mut generator = static || { let mut generator = static || {
yield; yield;
}; };
assert_unpin(generator); //~ ERROR std::marker::Unpin` is not satisfied assert_unpin(generator); //~ ERROR E0277
} }

View File

@ -1,4 +1,4 @@
error[E0277]: the trait bound `[static generator@$DIR/static-not-unpin.rs:11:25: 13:6 _]: std::marker::Unpin` is not satisfied error[E0277]: `[static generator@$DIR/static-not-unpin.rs:11:25: 13:6 _]` cannot be unpinned
--> $DIR/static-not-unpin.rs:14:18 --> $DIR/static-not-unpin.rs:14:18
| |
LL | fn assert_unpin<T: Unpin>(_: T) { LL | fn assert_unpin<T: Unpin>(_: T) {

View File

@ -10,17 +10,18 @@ fn foo<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32>
// We could instead use an `async` block, but this way we have no std spans. // We could instead use an `async` block, but this way we have no std spans.
x //~ ERROR mismatched types x //~ ERROR mismatched types
} }
fn bar<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> { fn bar<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
Box::new(x) //~ ERROR mismatched types Box::new(x) //~ ERROR mismatched types
//~^ HELP use `Box::pin`
} }
fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> { fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
Pin::new(x) //~ ERROR mismatched types Pin::new(x) //~ ERROR mismatched types
//~^ ERROR the trait bound //~^ ERROR E0277
} }
fn qux<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> { fn qux<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
Pin::new(Box::new(x)) //~ ERROR mismatched types Pin::new(Box::new(x)) //~ ERROR E0277
//~^ ERROR the trait bound
} }
fn main() {} fn main() {}

View File

@ -16,7 +16,7 @@ LL | x
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/expected-boxed-future-isnt-pinned.rs:14:5 --> $DIR/expected-boxed-future-isnt-pinned.rs:15:5
| |
LL | fn bar<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> { LL | fn bar<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
| ----------------------- expected `std::pin::Pin<std::boxed::Box<(dyn std::future::Future<Output = i32> + std::marker::Send + 'static)>>` because of return type | ----------------------- expected `std::pin::Pin<std::boxed::Box<(dyn std::future::Future<Output = i32> + std::marker::Send + 'static)>>` because of return type
@ -28,7 +28,7 @@ LL | Box::new(x)
= help: use `Box::pin` = help: use `Box::pin`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/expected-boxed-future-isnt-pinned.rs:18:14 --> $DIR/expected-boxed-future-isnt-pinned.rs:19:14
| |
LL | fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> { LL | fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
| - this type parameter | - this type parameter
@ -44,20 +44,22 @@ LL | Pin::new(x)
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
error[E0277]: the trait bound `dyn std::future::Future<Output = i32> + std::marker::Send: std::marker::Unpin` is not satisfied error[E0277]: `dyn std::future::Future<Output = i32> + std::marker::Send` cannot be unpinned
--> $DIR/expected-boxed-future-isnt-pinned.rs:18:5 --> $DIR/expected-boxed-future-isnt-pinned.rs:19:5
| |
LL | Pin::new(x) LL | Pin::new(x)
| ^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `dyn std::future::Future<Output = i32> + std::marker::Send` | ^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `dyn std::future::Future<Output = i32> + std::marker::Send`
| |
= note: consider using `Box::pin`
= note: required by `std::pin::Pin::<P>::new` = note: required by `std::pin::Pin::<P>::new`
error[E0277]: the trait bound `dyn std::future::Future<Output = i32> + std::marker::Send: std::marker::Unpin` is not satisfied error[E0277]: `dyn std::future::Future<Output = i32> + std::marker::Send` cannot be unpinned
--> $DIR/expected-boxed-future-isnt-pinned.rs:22:5 --> $DIR/expected-boxed-future-isnt-pinned.rs:24:5
| |
LL | Pin::new(Box::new(x)) LL | Pin::new(Box::new(x))
| ^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `dyn std::future::Future<Output = i32> + std::marker::Send` | ^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `dyn std::future::Future<Output = i32> + std::marker::Send`
| |
= note: consider using `Box::pin`
= note: required by `std::pin::Pin::<P>::new` = note: required by `std::pin::Pin::<P>::new`
error: aborting due to 5 previous errors error: aborting due to 5 previous errors