diagnostics: use DeepRejectCtxt
for check
This makes more things match, particularly applicable blankets.
This commit is contained in:
parent
3312f5d652
commit
c6fb0f344e
3 changed files with 32 additions and 9 deletions
|
@ -4,6 +4,7 @@ use rustc_hir as hir;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
|
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
|
||||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||||
|
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
||||||
use rustc_middle::ty::print::{FmtPrinter, Printer};
|
use rustc_middle::ty::print::{FmtPrinter, Printer};
|
||||||
use rustc_middle::ty::{self, suggest_constraining_type_param, Ty};
|
use rustc_middle::ty::{self, suggest_constraining_type_param, Ty};
|
||||||
use rustc_span::def_id::DefId;
|
use rustc_span::def_id::DefId;
|
||||||
|
@ -313,9 +314,15 @@ impl<T> Trait<T> for X {
|
||||||
(ty::Dynamic(t, _, ty::DynKind::Dyn), _)
|
(ty::Dynamic(t, _, ty::DynKind::Dyn), _)
|
||||||
if let Some(def_id) = t.principal_def_id() =>
|
if let Some(def_id) = t.principal_def_id() =>
|
||||||
{
|
{
|
||||||
let has_non_blanket_impl =
|
let mut has_matching_impl = false;
|
||||||
tcx.non_blanket_impls_for_ty(def_id, values.found).next().is_some();
|
tcx.for_each_relevant_impl(def_id, values.found, |did| {
|
||||||
if has_non_blanket_impl {
|
if DeepRejectCtxt::new(tcx, TreatParams::ForLookup)
|
||||||
|
.types_may_unify(values.found, tcx.type_of(did).skip_binder())
|
||||||
|
{
|
||||||
|
has_matching_impl = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if has_matching_impl {
|
||||||
let trait_name = tcx.item_name(def_id);
|
let trait_name = tcx.item_name(def_id);
|
||||||
diag.help(format!(
|
diag.help(format!(
|
||||||
"`{}` implements `{trait_name}` so you could box the found value \
|
"`{}` implements `{trait_name}` so you could box the found value \
|
||||||
|
@ -328,9 +335,15 @@ impl<T> Trait<T> for X {
|
||||||
(_, ty::Dynamic(t, _, ty::DynKind::Dyn))
|
(_, ty::Dynamic(t, _, ty::DynKind::Dyn))
|
||||||
if let Some(def_id) = t.principal_def_id() =>
|
if let Some(def_id) = t.principal_def_id() =>
|
||||||
{
|
{
|
||||||
let has_non_blanket_impl =
|
let mut has_matching_impl = false;
|
||||||
tcx.non_blanket_impls_for_ty(def_id, values.expected).next().is_some();
|
tcx.for_each_relevant_impl(def_id, values.expected, |did| {
|
||||||
if has_non_blanket_impl {
|
if DeepRejectCtxt::new(tcx, TreatParams::ForLookup)
|
||||||
|
.types_may_unify(values.expected, tcx.type_of(did).skip_binder())
|
||||||
|
{
|
||||||
|
has_matching_impl = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if has_matching_impl {
|
||||||
let trait_name = tcx.item_name(def_id);
|
let trait_name = tcx.item_name(def_id);
|
||||||
diag.help(format!(
|
diag.help(format!(
|
||||||
"`{}` implements `{trait_name}` so you could change the expected \
|
"`{}` implements `{trait_name}` so you could change the expected \
|
||||||
|
@ -342,9 +355,15 @@ impl<T> Trait<T> for X {
|
||||||
(ty::Dynamic(t, _, ty::DynKind::DynStar), _)
|
(ty::Dynamic(t, _, ty::DynKind::DynStar), _)
|
||||||
if let Some(def_id) = t.principal_def_id() =>
|
if let Some(def_id) = t.principal_def_id() =>
|
||||||
{
|
{
|
||||||
let has_non_blanket_impl =
|
let mut has_matching_impl = false;
|
||||||
tcx.non_blanket_impls_for_ty(def_id, values.found).next().is_some();
|
tcx.for_each_relevant_impl(def_id, values.found, |did| {
|
||||||
if has_non_blanket_impl {
|
if DeepRejectCtxt::new(tcx, TreatParams::ForLookup)
|
||||||
|
.types_may_unify(values.found, tcx.type_of(did).skip_binder())
|
||||||
|
{
|
||||||
|
has_matching_impl = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if has_matching_impl {
|
||||||
let trait_name = tcx.item_name(def_id);
|
let trait_name = tcx.item_name(def_id);
|
||||||
diag.help(format!(
|
diag.help(format!(
|
||||||
"`{}` implements `{trait_name}`, `#[feature(dyn_star)]` is likely \
|
"`{}` implements `{trait_name}`, `#[feature(dyn_star)]` is likely \
|
||||||
|
|
|
@ -14,6 +14,7 @@ LL | let y: *const dyn Trait<Y> = x as _;
|
||||||
|
|
|
|
||||||
= note: expected trait object `dyn Trait<X>`
|
= note: expected trait object `dyn Trait<X>`
|
||||||
found trait object `dyn Trait<Y>`
|
found trait object `dyn Trait<Y>`
|
||||||
|
= help: `dyn Trait<Y>` 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
|
error[E0308]: mismatched types
|
||||||
--> $DIR/ptr-to-trait-obj-different-args.rs:27:34
|
--> $DIR/ptr-to-trait-obj-different-args.rs:27:34
|
||||||
|
@ -25,6 +26,7 @@ LL | let _: *const dyn Trait<T> = x as _;
|
||||||
|
|
|
|
||||||
= note: expected trait object `dyn Trait<X>`
|
= note: expected trait object `dyn Trait<X>`
|
||||||
found trait object `dyn Trait<T>`
|
found trait object `dyn Trait<T>`
|
||||||
|
= help: `dyn Trait<T>` 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
|
error[E0308]: mismatched types
|
||||||
--> $DIR/ptr-to-trait-obj-different-args.rs:28:34
|
--> $DIR/ptr-to-trait-obj-different-args.rs:28:34
|
||||||
|
@ -37,6 +39,7 @@ LL | let _: *const dyn Trait<X> = t as _;
|
||||||
|
|
|
|
||||||
= note: expected trait object `dyn Trait<T>`
|
= note: expected trait object `dyn Trait<T>`
|
||||||
found trait object `dyn Trait<X>`
|
found trait object `dyn Trait<X>`
|
||||||
|
= help: `dyn Trait<X>` 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
|
error[E0308]: mismatched types
|
||||||
--> $DIR/ptr-to-trait-obj-different-args.rs:36:5
|
--> $DIR/ptr-to-trait-obj-different-args.rs:36:5
|
||||||
|
|
|
@ -6,6 +6,7 @@ LL | let p = p as *const dyn Trait<u8, u16>; // <- this is bad!
|
||||||
|
|
|
|
||||||
= note: expected trait object `dyn Trait<u8, u8>`
|
= note: expected trait object `dyn Trait<u8, u8>`
|
||||||
found trait object `dyn Trait<u8, u16>`
|
found trait object `dyn Trait<u8, u16>`
|
||||||
|
= help: `dyn Trait<u8, u16>` 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: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue