add suggested changes

This commit is contained in:
xonx 2026-01-11 18:42:52 +00:00
parent 5b1070b040
commit a873a3fe77
9 changed files with 48 additions and 25 deletions

View file

@ -72,12 +72,17 @@ use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Pos, Span, sym};
use tracing::{debug, instrument};
use crate::error_reporting::TypeErrCtxt;
use crate::error_reporting::traits::ambiguity::{
CandidateSource, compute_applicable_impls_for_diagnostics,
};
use crate::errors::{ObligationCauseFailureCode, TypeErrorAdditionalDiags};
use crate::infer;
use crate::infer::relate::{self, RelateResult, TypeRelation};
use crate::infer::{InferCtxt, InferCtxtExt as _, TypeTrace, ValuePairs};
use crate::solve::deeply_normalize_for_diagnostics;
use crate::traits::{MatchExpressionArmCause, ObligationCause, ObligationCauseCode};
use crate::traits::{
MatchExpressionArmCause, Obligation, ObligationCause, ObligationCauseCode, specialization_graph,
};
mod note_and_explain;
mod suggest;
@ -155,7 +160,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
err,
);
self.suggest_param_env_shadowing(&mut diag, expected, actual);
self.suggest_param_env_shadowing(&mut diag, expected, actual, param_env);
diag
}
@ -249,6 +254,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
diag: &mut Diag<'_>,
expected: Ty<'tcx>,
found: Ty<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) {
let (alias, concrete) = match (expected.kind(), found.kind()) {
(ty::Alias(ty::Projection, proj), _) => (proj, found),
@ -257,35 +263,39 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
};
let tcx = self.tcx;
let trait_def_id = alias.trait_def_id(tcx);
let impls = tcx.trait_impls_of(trait_def_id);
let all_impls =
impls.blanket_impls().iter().chain(impls.non_blanket_impls().values().flatten());
let trait_ref = alias.trait_ref(tcx);
let obligation =
Obligation::new(tcx, ObligationCause::dummy(), param_env, ty::Binder::dummy(trait_ref));
let applicable_impls = compute_applicable_impls_for_diagnostics(self.infcx, &obligation);
for candidate in applicable_impls {
let impl_def_id = match candidate {
CandidateSource::DefId(did) => did,
CandidateSource::ParamEnv(_) => continue,
};
for &impl_def_id in all_impls {
let is_shadowed = self.infcx.probe(|_| {
let impl_substs = self.infcx.fresh_args_for_item(DUMMY_SP, impl_def_id);
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_substs);
let expected_trait_ref = alias.trait_ref(tcx);
if self.infcx.can_eq(ty::ParamEnv::empty(), expected_trait_ref, impl_trait_ref) {
let name = tcx.item_name(alias.def_id);
let assoc_item = tcx
.associated_items(impl_def_id)
.filter_by_name_unhygienic(name)
.find(|item| matches!(item.kind, ty::AssocKind::Type { .. }));
if let Some(item) = assoc_item {
let impl_assoc_ty = tcx.type_of(item.def_id).instantiate(tcx, impl_substs);
if self.infcx.can_eq(ty::ParamEnv::empty(), impl_assoc_ty, concrete) {
return true;
}
}
if !self.infcx.can_eq(param_env, expected_trait_ref, impl_trait_ref) {
return false;
}
false
let leaf_def = match specialization_graph::assoc_def(tcx, impl_def_id, alias.def_id)
{
Ok(leaf) => leaf,
Err(_) => return false,
};
let impl_item_def_id = leaf_def.item.def_id;
let impl_assoc_ty = tcx.type_of(impl_item_def_id).instantiate(tcx, impl_substs);
self.infcx.can_eq(param_env, impl_assoc_ty, concrete)
});
if is_shadowed {

View file

@ -16,7 +16,7 @@ pub mod project;
pub mod query;
#[allow(hidden_glob_reexports)]
mod select;
mod specialize;
pub mod specialize;
mod structural_normalize;
#[allow(hidden_glob_reexports)]
mod util;