Skip to content

Commit 796814d

Browse files
committed
Account for expected dyn Trait found impl Trait
1 parent d992d9c commit 796814d

File tree

3 files changed

+81
-0
lines changed

3 files changed

+81
-0
lines changed

compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,26 @@ impl<T> Trait<T> for X {
294294
);
295295
}
296296
}
297+
(ty::Dynamic(t, _, ty::DynKind::Dyn), ty::Alias(ty::Opaque, alias))
298+
if let Some(def_id) = t.principal_def_id()
299+
&& tcx.explicit_item_bounds(alias.def_id).skip_binder().iter().any(
300+
|(pred, _span)| match pred.kind().skip_binder() {
301+
ty::ClauseKind::Trait(trait_predicate)
302+
if trait_predicate.polarity
303+
== ty::ImplPolarity::Positive =>
304+
{
305+
trait_predicate.def_id() == def_id
306+
}
307+
_ => false,
308+
},
309+
) =>
310+
{
311+
diag.help(format!(
312+
"you can box the `{}` to coerce it to `Box<{}>`, but you'll have to \
313+
change the expected type as well",
314+
values.found, values.expected,
315+
));
316+
}
297317
(ty::Dynamic(t, _, ty::DynKind::Dyn), _)
298318
if let Some(def_id) = t.principal_def_id() =>
299319
{
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
trait Trait {}
2+
struct Struct;
3+
impl Trait for Struct {}
4+
fn foo() -> impl Trait {
5+
Struct
6+
}
7+
fn main() {
8+
let a: Box<dyn Trait> = if true {
9+
Box::new(Struct)
10+
} else {
11+
foo() //~ ERROR E0308
12+
};
13+
let a: dyn Trait = if true {
14+
Struct //~ ERROR E0308
15+
} else {
16+
foo() //~ ERROR E0308
17+
};
18+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/dyn-impl-type-mismatch.rs:11:9
3+
|
4+
LL | fn foo() -> impl Trait {
5+
| ---------- the found opaque type
6+
...
7+
LL | foo()
8+
| ^^^^^ expected `Box<dyn Trait>`, found opaque type
9+
|
10+
= note: expected struct `Box<dyn Trait>`
11+
found opaque type `impl Trait`
12+
= 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
13+
help: store this in the heap by calling `Box::new`
14+
|
15+
LL | Box::new(foo())
16+
| +++++++++ +
17+
18+
error[E0308]: mismatched types
19+
--> $DIR/dyn-impl-type-mismatch.rs:14:9
20+
|
21+
LL | Struct
22+
| ^^^^^^ expected `dyn Trait`, found `Struct`
23+
|
24+
= note: expected trait object `dyn Trait`
25+
found struct `Struct`
26+
= help: `Struct` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
27+
28+
error[E0308]: mismatched types
29+
--> $DIR/dyn-impl-type-mismatch.rs:16:9
30+
|
31+
LL | fn foo() -> impl Trait {
32+
| ---------- the found opaque type
33+
...
34+
LL | foo()
35+
| ^^^^^ expected `dyn Trait`, found opaque type
36+
|
37+
= note: expected trait object `dyn Trait`
38+
found opaque type `impl Trait`
39+
= help: you can box the `impl Trait` to coerce it to `Box<dyn Trait>`, but you'll have to change the expected type as well
40+
41+
error: aborting due to 3 previous errors
42+
43+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)