about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/marker.rs5
-rw-r--r--src/librustc/traits/error_reporting/on_unimplemented.rs10
-rw-r--r--src/test/ui/suggestions/expected-boxed-future-isnt-pinned.rs26
-rw-r--r--src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr52
4 files changed, 27 insertions, 66 deletions
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 5c35041249f..2800f11cc01 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -728,10 +728,7 @@ unsafe impl<T: ?Sized> 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<Output = i32> + 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 2ba12baaf6d..ab2d74b1c8d 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 eda579f7fb4..0a1686eac9d 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<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32>
     x //~ ERROR mismatched types
 }
 
-fn bar<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
-    Box::new(x) //~ ERROR mismatched types
-}
-
-fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
-    Pin::new(x) //~ ERROR mismatched types
-    //~^ ERROR E0277
-}
-
-fn qux<F: Future<Output=i32> + 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<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
+//     Box::new(x)
+// }
+//
+// fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
+//     Pin::new(x)
+// }
+//
+// fn qux<F: Future<Output=i32> + 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 783b118d2f9..48d941283b6 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<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
-LL |     Box::new(x)
-   |     ^^^^^^^^^^^ expected struct `std::pin::Pin`, found struct `std::boxed::Box`
-   |
-   = note: expected struct `std::pin::Pin<std::boxed::Box<(dyn std::future::Future<Output = i32> + std::marker::Send + 'static)>>`
-              found struct `std::boxed::Box<F>`
-   = help: use `Box::pin`
-
-error[E0308]: mismatched types
-  --> $DIR/expected-boxed-future-isnt-pinned.rs:19:14
-   |
-LL | fn baz<F: Future<Output=i32> + 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<dyn std::future::Future<Output = i32> + 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<Output = i32> + 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<Output = i32> + std::marker::Send`
-   |
-   = note: consider using `Box::pin`
-   = note: required by `std::pin::Pin::<P>::new`
-
-error[E0277]: `dyn std::future::Future<Output = i32> + 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<Output = i32> + std::marker::Send`
-   |
-   = note: consider using `Box::pin`
-   = note: required by `std::pin::Pin::<P>::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`.