From 248f5a4046ab5a90189f37c305c759b7cde8acb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 12 Feb 2020 16:50:28 -0800 Subject: [PATCH] Add trait `Self` filtering to `rustc_on_unimplemented` --- src/libcore/marker.rs | 5 +- .../error_reporting/on_unimplemented.rs | 10 ++++ .../expected-boxed-future-isnt-pinned.rs | 26 +++++----- .../expected-boxed-future-isnt-pinned.stderr | 52 +------------------ 4 files changed, 27 insertions(+), 66 deletions(-) diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 5c35041249f36..2800f11cc01b1 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -728,10 +728,7 @@ unsafe impl Freeze for &mut T {} /// [`pin module`]: ../../std/pin/index.html #[stable(feature = "pin", since = "1.33.0")] #[rustc_on_unimplemented( - on( - _Self = "dyn std::future::Future + std::marker::Send", - note = "consider using `Box::pin`", - ), + on(_Self = "std::future::Future", note = "consider using `Box::pin`",), message = "`{Self}` cannot be unpinned" )] #[lang = "unpin"] diff --git a/src/librustc/traits/error_reporting/on_unimplemented.rs b/src/librustc/traits/error_reporting/on_unimplemented.rs index 2ba12baaf6d6e..ab2d74b1c8deb 100644 --- a/src/librustc/traits/error_reporting/on_unimplemented.rs +++ b/src/librustc/traits/error_reporting/on_unimplemented.rs @@ -201,6 +201,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } } + if let ty::Dynamic(traits, _) = self_ty.kind { + for t in *traits.skip_binder() { + match t { + ty::ExistentialPredicate::Trait(trait_ref) => { + flags.push((sym::_Self, Some(self.tcx.def_path_str(trait_ref.def_id)))) + } + _ => {} + } + } + } if let Ok(Some(command)) = OnUnimplementedDirective::of_item(self.tcx, trait_ref.def_id, def_id) diff --git a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.rs b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.rs index eda579f7fb49e..0a1686eac9d34 100644 --- a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.rs +++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.rs @@ -11,17 +11,19 @@ fn foo + Send + 'static>(x: F) -> BoxFuture<'static, i32> x //~ ERROR mismatched types } -fn bar + Send + 'static>(x: F) -> BoxFuture<'static, i32> { - Box::new(x) //~ ERROR mismatched types -} - -fn baz + Send + 'static>(x: F) -> BoxFuture<'static, i32> { - Pin::new(x) //~ ERROR mismatched types - //~^ ERROR E0277 -} - -fn qux + Send + 'static>(x: F) -> BoxFuture<'static, i32> { - Pin::new(Box::new(x)) //~ ERROR E0277 -} +// FIXME: uncomment these once this commit is in Beta and we can rely on `rustc_on_unimplemented` +// having filtering for `Self` being a trait. +// +// fn bar + Send + 'static>(x: F) -> BoxFuture<'static, i32> { +// Box::new(x) +// } +// +// fn baz + Send + 'static>(x: F) -> BoxFuture<'static, i32> { +// Pin::new(x) +// } +// +// fn qux + Send + 'static>(x: F) -> BoxFuture<'static, i32> { +// Pin::new(Box::new(x)) +// } fn main() {} diff --git a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr index 783b118d2f9a2..48d941283b62d 100644 --- a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr +++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr @@ -15,54 +15,6 @@ LL | x = help: type parameters must be constrained to match other types = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters -error[E0308]: mismatched types - --> $DIR/expected-boxed-future-isnt-pinned.rs:15:5 - | -LL | fn bar + Send + 'static>(x: F) -> BoxFuture<'static, i32> { - | ----------------------- expected `std::pin::Pin + std::marker::Send + 'static)>>` because of return type -LL | Box::new(x) - | ^^^^^^^^^^^ expected struct `std::pin::Pin`, found struct `std::boxed::Box` - | - = note: expected struct `std::pin::Pin + std::marker::Send + 'static)>>` - found struct `std::boxed::Box` - = help: use `Box::pin` - -error[E0308]: mismatched types - --> $DIR/expected-boxed-future-isnt-pinned.rs:19:14 - | -LL | fn baz + Send + 'static>(x: F) -> BoxFuture<'static, i32> { - | - this type parameter -LL | Pin::new(x) - | ^ - | | - | expected struct `std::boxed::Box`, found type parameter `F` - | help: store this in the heap by calling `Box::new`: `Box::new(x)` - | - = note: expected struct `std::boxed::Box + std::marker::Send>` - found type parameter `F` - = help: type parameters must be constrained to match other types - = 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 - -error[E0277]: `dyn std::future::Future + std::marker::Send` cannot be unpinned - --> $DIR/expected-boxed-future-isnt-pinned.rs:19:5 - | -LL | Pin::new(x) - | ^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `dyn std::future::Future + std::marker::Send` - | - = note: consider using `Box::pin` - = note: required by `std::pin::Pin::

::new` - -error[E0277]: `dyn std::future::Future + std::marker::Send` cannot be unpinned - --> $DIR/expected-boxed-future-isnt-pinned.rs:24:5 - | -LL | Pin::new(Box::new(x)) - | ^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `dyn std::future::Future + std::marker::Send` - | - = note: consider using `Box::pin` - = note: required by `std::pin::Pin::

::new` - -error: aborting due to 5 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0308`.