On E0308 involving dyn Trait, mention trait objects

When encountering a type mismatch error involving `dyn Trait`, mention
the existence of boxed trait objects if the other type involved
implements `Trait`.

Partially addresses #102629.
This commit is contained in:
Esteban Küber 2024-01-24 16:30:37 +00:00
parent 0b7730105f
commit d992d9cd56
7 changed files with 56 additions and 0 deletions

View File

@ -294,6 +294,55 @@ fn foo(&self, x: T) -> T { x }
); );
} }
} }
(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))
| (ty::Alias(ty::Opaque, opaque_ty), _) => { | (ty::Alias(ty::Opaque, opaque_ty), _) => {
if opaque_ty.def_id.is_local() if opaque_ty.def_id.is_local()

View File

@ -8,6 +8,7 @@ LL | f5.2 = Bar1 {f: 36};
| |
= note: expected trait object `dyn ToBar` = note: expected trait object `dyn ToBar`
found struct `Bar1` 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 error[E0277]: the size for values of type `dyn ToBar` cannot be known at compilation time
--> $DIR/dst-bad-assign-3.rs:33:5 --> $DIR/dst-bad-assign-3.rs:33:5

View File

@ -8,6 +8,7 @@ LL | f5.ptr = Bar1 {f: 36};
| |
= note: expected trait object `dyn ToBar` = note: expected trait object `dyn ToBar`
found struct `Bar1` 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 error[E0277]: the size for values of type `dyn ToBar` cannot be known at compilation time
--> $DIR/dst-bad-assign.rs:35:5 --> $DIR/dst-bad-assign.rs:35:5

View File

@ -8,6 +8,7 @@ LL | dyn_star_foreign::require_dyn_star_display(1usize);
| |
= note: expected trait object `(dyn* std::fmt::Display + 'static)` = note: expected trait object `(dyn* std::fmt::Display + 'static)`
found type `usize` found type `usize`
= help: `usize` implements `Display`, `#[feature(dyn_star)]` is likely not enabled; that feature it is currently incomplete
note: function defined here note: function defined here
--> $DIR/auxiliary/dyn-star-foreign.rs:6:8 --> $DIR/auxiliary/dyn-star-foreign.rs:6:8
| |

View File

@ -27,6 +27,7 @@ LL | type VRefCont<'a> = &'a V where Self: 'a;
| ^^^^^ | ^^^^^
= note: expected trait object `(dyn RefCont<'_, u8> + 'static)` = note: expected trait object `(dyn RefCont<'_, u8> + 'static)`
found reference `&u8` 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)>>` = 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 error: aborting due to 2 previous errors

View File

@ -6,6 +6,7 @@ LL | fn fuz() -> (usize, Trait) { (42, Struct) }
| |
= note: expected trait object `(dyn Trait + 'static)` = note: expected trait object `(dyn Trait + 'static)`
found struct `Struct` 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 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 --> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:13
@ -27,6 +28,7 @@ LL | fn bar() -> (usize, dyn Trait) { (42, Struct) }
| |
= note: expected trait object `(dyn Trait + 'static)` = note: expected trait object `(dyn Trait + 'static)`
found struct `Struct` 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 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 --> $DIR/dyn-trait-return-should-be-impl-trait.rs:10:13

View File

@ -27,6 +27,7 @@ LL | 1.query::<dyn ToString>("")
| |
= note: expected trait object `dyn ToString` = note: expected trait object `dyn ToString`
found reference `&'static str` 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 note: method defined here
--> $DIR/issue-61525.rs:2:8 --> $DIR/issue-61525.rs:2:8
| |