Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

On E0308 involving dyn Trait, mention trait objects #120315

Merged
merged 2 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,75 @@ impl<T> Trait<T> for X {
);
}
}
(ty::Dynamic(t, _, ty::DynKind::Dyn), ty::Alias(ty::Opaque, alias))
if let Some(def_id) = t.principal_def_id()
&& tcx.explicit_item_bounds(alias.def_id).skip_binder().iter().any(
|(pred, _span)| match pred.kind().skip_binder() {
ty::ClauseKind::Trait(trait_predicate)
if trait_predicate.polarity
== ty::ImplPolarity::Positive =>
{
trait_predicate.def_id() == def_id
}
_ => false,
},
) =>
{
diag.help(format!(
"you can box the `{}` to coerce it to `Box<{}>`, but you'll have to \
change the expected type as well",
values.found, values.expected,
));
}
(ty::Dynamic(t, _, ty::DynKind::Dyn), _)
if let Some(def_id) = t.principal_def_id() =>
{
let mut impl_def_ids = vec![];
tcx.for_each_relevant_impl(def_id, values.found, |did| {
impl_def_ids.push(did)
});
if let [_] = &impl_def_ids[..] {
let trait_name = tcx.item_name(def_id);
diag.help(format!(
"`{}` implements `{trait_name}` so you could box the found value \
and coerce it to the trait object `Box<dyn {trait_name}>`, you \
will have to change the expected type as well",
values.found,
));
}
}
(_, ty::Dynamic(t, _, ty::DynKind::Dyn))
if let Some(def_id) = t.principal_def_id() =>
{
let mut impl_def_ids = vec![];
tcx.for_each_relevant_impl(def_id, values.expected, |did| {
impl_def_ids.push(did)
});
if let [_] = &impl_def_ids[..] {
let trait_name = tcx.item_name(def_id);
diag.help(format!(
"`{}` implements `{trait_name}` so you could change the expected \
type to `Box<dyn {trait_name}>`",
values.expected,
));
}
}
(ty::Dynamic(t, _, ty::DynKind::DynStar), _)
if let Some(def_id) = t.principal_def_id() =>
{
let mut impl_def_ids = vec![];
tcx.for_each_relevant_impl(def_id, values.found, |did| {
impl_def_ids.push(did)
});
if let [_] = &impl_def_ids[..] {
let trait_name = tcx.item_name(def_id);
diag.help(format!(
"`{}` implements `{trait_name}`, `#[feature(dyn_star)]` is likely \
not enabled; that feature it is currently incomplete",
values.found,
));
}
}
(_, ty::Alias(ty::Opaque, opaque_ty))
| (ty::Alias(ty::Opaque, opaque_ty), _) => {
if opaque_ty.def_id.is_local()
Expand Down
1 change: 1 addition & 0 deletions tests/ui/dst/dst-bad-assign-3.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ LL | f5.2 = Bar1 {f: 36};
|
= note: expected trait object `dyn ToBar`
found struct `Bar1`
= help: `Bar1` implements `ToBar` so you could box the found value and coerce it to the trait object `Box<dyn ToBar>`, you will have to change the expected type as well

error[E0277]: the size for values of type `dyn ToBar` cannot be known at compilation time
--> $DIR/dst-bad-assign-3.rs:33:5
Expand Down
1 change: 1 addition & 0 deletions tests/ui/dst/dst-bad-assign.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ LL | f5.ptr = Bar1 {f: 36};
|
= note: expected trait object `dyn ToBar`
found struct `Bar1`
= help: `Bar1` implements `ToBar` so you could box the found value and coerce it to the trait object `Box<dyn ToBar>`, you will have to change the expected type as well

error[E0277]: the size for values of type `dyn ToBar` cannot be known at compilation time
--> $DIR/dst-bad-assign.rs:35:5
Expand Down
1 change: 1 addition & 0 deletions tests/ui/dyn-star/no-implicit-dyn-star.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ LL | dyn_star_foreign::require_dyn_star_display(1usize);
|
= note: expected trait object `(dyn* std::fmt::Display + 'static)`
found type `usize`
= help: `usize` implements `Display`, `#[feature(dyn_star)]` is likely not enabled; that feature it is currently incomplete
note: function defined here
--> $DIR/auxiliary/dyn-star-foreign.rs:6:8
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ LL | type VRefCont<'a> = &'a V where Self: 'a;
| ^^^^^
= note: expected trait object `(dyn RefCont<'_, u8> + 'static)`
found reference `&u8`
= help: `&u8` implements `RefCont` so you could box the found value and coerce it to the trait object `Box<dyn RefCont>`, you will have to change the expected type as well
= note: required for the cast from `Box<BTreeMap<u8, u8>>` to `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>`

error: aborting due to 2 previous errors
Expand Down
18 changes: 18 additions & 0 deletions tests/ui/impl-trait/dyn-impl-type-mismatch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
trait Trait {}
struct Struct;
impl Trait for Struct {}
fn foo() -> impl Trait {
Struct
}
fn main() {
let a: Box<dyn Trait> = if true {
Box::new(Struct)
} else {
foo() //~ ERROR E0308
};
let a: dyn Trait = if true {
Struct //~ ERROR E0308
} else {
foo() //~ ERROR E0308
};
}
43 changes: 43 additions & 0 deletions tests/ui/impl-trait/dyn-impl-type-mismatch.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
error[E0308]: mismatched types
--> $DIR/dyn-impl-type-mismatch.rs:11:9
|
LL | fn foo() -> impl Trait {
| ---------- the found opaque type
...
LL | foo()
| ^^^^^ expected `Box<dyn Trait>`, found opaque type
|
= note: expected struct `Box<dyn Trait>`
found opaque type `impl Trait`
= 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
help: store this in the heap by calling `Box::new`
|
LL | Box::new(foo())
| +++++++++ +

error[E0308]: mismatched types
--> $DIR/dyn-impl-type-mismatch.rs:14:9
|
LL | Struct
| ^^^^^^ expected `dyn Trait`, found `Struct`
|
= note: expected trait object `dyn Trait`
found struct `Struct`
= 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

error[E0308]: mismatched types
--> $DIR/dyn-impl-type-mismatch.rs:16:9
|
LL | fn foo() -> impl Trait {
| ---------- the found opaque type
...
LL | foo()
| ^^^^^ expected `dyn Trait`, found opaque type
|
= note: expected trait object `dyn Trait`
found opaque type `impl Trait`
= 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

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0308`.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ LL | fn fuz() -> (usize, Trait) { (42, Struct) }
|
= note: expected trait object `(dyn Trait + 'static)`
found struct `Struct`
= 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

error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:13
Expand All @@ -27,6 +28,7 @@ LL | fn bar() -> (usize, dyn Trait) { (42, Struct) }
|
= note: expected trait object `(dyn Trait + 'static)`
found struct `Struct`
= 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

error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:10:13
Expand Down
1 change: 1 addition & 0 deletions tests/ui/methods/issues/issue-61525.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ LL | 1.query::<dyn ToString>("")
|
= note: expected trait object `dyn ToString`
found reference `&'static str`
= help: `&'static str` implements `ToString` so you could box the found value and coerce it to the trait object `Box<dyn ToString>`, you will have to change the expected type as well
note: method defined here
--> $DIR/issue-61525.rs:2:8
|
Expand Down
Loading