Skip to content

Commit 248f5a4

Browse files
committed
Add trait Self filtering to rustc_on_unimplemented
1 parent c376fc0 commit 248f5a4

File tree

4 files changed

+27
-66
lines changed

4 files changed

+27
-66
lines changed

src/libcore/marker.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -728,10 +728,7 @@ unsafe impl<T: ?Sized> Freeze for &mut T {}
728728
/// [`pin module`]: ../../std/pin/index.html
729729
#[stable(feature = "pin", since = "1.33.0")]
730730
#[rustc_on_unimplemented(
731-
on(
732-
_Self = "dyn std::future::Future<Output = i32> + std::marker::Send",
733-
note = "consider using `Box::pin`",
734-
),
731+
on(_Self = "std::future::Future", note = "consider using `Box::pin`",),
735732
message = "`{Self}` cannot be unpinned"
736733
)]
737734
#[lang = "unpin"]

src/librustc/traits/error_reporting/on_unimplemented.rs

+10
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
201201
}
202202
}
203203
}
204+
if let ty::Dynamic(traits, _) = self_ty.kind {
205+
for t in *traits.skip_binder() {
206+
match t {
207+
ty::ExistentialPredicate::Trait(trait_ref) => {
208+
flags.push((sym::_Self, Some(self.tcx.def_path_str(trait_ref.def_id))))
209+
}
210+
_ => {}
211+
}
212+
}
213+
}
204214

205215
if let Ok(Some(command)) =
206216
OnUnimplementedDirective::of_item(self.tcx, trait_ref.def_id, def_id)

src/test/ui/suggestions/expected-boxed-future-isnt-pinned.rs

+14-12
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,19 @@ fn foo<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32>
1111
x //~ ERROR mismatched types
1212
}
1313

14-
fn bar<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
15-
Box::new(x) //~ ERROR mismatched types
16-
}
17-
18-
fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
19-
Pin::new(x) //~ ERROR mismatched types
20-
//~^ ERROR E0277
21-
}
22-
23-
fn qux<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
24-
Pin::new(Box::new(x)) //~ ERROR E0277
25-
}
14+
// FIXME: uncomment these once this commit is in Beta and we can rely on `rustc_on_unimplemented`
15+
// having filtering for `Self` being a trait.
16+
//
17+
// fn bar<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
18+
// Box::new(x)
19+
// }
20+
//
21+
// fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
22+
// Pin::new(x)
23+
// }
24+
//
25+
// fn qux<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
26+
// Pin::new(Box::new(x))
27+
// }
2628

2729
fn main() {}

src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr

+2-50
Original file line numberDiff line numberDiff line change
@@ -15,54 +15,6 @@ LL | x
1515
= help: type parameters must be constrained to match other types
1616
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
1717

18-
error[E0308]: mismatched types
19-
--> $DIR/expected-boxed-future-isnt-pinned.rs:15:5
20-
|
21-
LL | fn bar<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
22-
| ----------------------- expected `std::pin::Pin<std::boxed::Box<(dyn std::future::Future<Output = i32> + std::marker::Send + 'static)>>` because of return type
23-
LL | Box::new(x)
24-
| ^^^^^^^^^^^ expected struct `std::pin::Pin`, found struct `std::boxed::Box`
25-
|
26-
= note: expected struct `std::pin::Pin<std::boxed::Box<(dyn std::future::Future<Output = i32> + std::marker::Send + 'static)>>`
27-
found struct `std::boxed::Box<F>`
28-
= help: use `Box::pin`
29-
30-
error[E0308]: mismatched types
31-
--> $DIR/expected-boxed-future-isnt-pinned.rs:19:14
32-
|
33-
LL | fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
34-
| - this type parameter
35-
LL | Pin::new(x)
36-
| ^
37-
| |
38-
| expected struct `std::boxed::Box`, found type parameter `F`
39-
| help: store this in the heap by calling `Box::new`: `Box::new(x)`
40-
|
41-
= note: expected struct `std::boxed::Box<dyn std::future::Future<Output = i32> + std::marker::Send>`
42-
found type parameter `F`
43-
= help: type parameters must be constrained to match other types
44-
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
45-
= 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
46-
47-
error[E0277]: `dyn std::future::Future<Output = i32> + std::marker::Send` cannot be unpinned
48-
--> $DIR/expected-boxed-future-isnt-pinned.rs:19:5
49-
|
50-
LL | Pin::new(x)
51-
| ^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `dyn std::future::Future<Output = i32> + std::marker::Send`
52-
|
53-
= note: consider using `Box::pin`
54-
= note: required by `std::pin::Pin::<P>::new`
55-
56-
error[E0277]: `dyn std::future::Future<Output = i32> + std::marker::Send` cannot be unpinned
57-
--> $DIR/expected-boxed-future-isnt-pinned.rs:24:5
58-
|
59-
LL | Pin::new(Box::new(x))
60-
| ^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `dyn std::future::Future<Output = i32> + std::marker::Send`
61-
|
62-
= note: consider using `Box::pin`
63-
= note: required by `std::pin::Pin::<P>::new`
64-
65-
error: aborting due to 5 previous errors
18+
error: aborting due to previous error
6619

67-
Some errors have detailed explanations: E0277, E0308.
68-
For more information about an error, try `rustc --explain E0277`.
20+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)