diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-01-25 08:39:44 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-25 08:39:44 +0100 |
| commit | 0cbef470d5e0cd8590236b7a9cbf1b0c3c7fc954 (patch) | |
| tree | f22cfe9aa5dd3879f8e122c7714298c19638285d /compiler | |
| parent | 72b70ec4746b6e1eb3ee8eabd84f31c61ad17ccf (diff) | |
| parent | 796814d91627203444769a680c53ff59a7ff4696 (diff) | |
| download | rust-0cbef470d5e0cd8590236b7a9cbf1b0c3c7fc954.tar.gz rust-0cbef470d5e0cd8590236b7a9cbf1b0c3c7fc954.zip | |
Rollup merge of #120315 - estebank:issue-102629-2, r=wesleywiser
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`. Fix #102629.
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index 01cd3c57925..21ea48c6c83 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -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() |
