1
Fork 0

address review feedback

This commit is contained in:
Lukas Markeffsky 2024-03-04 21:06:16 +01:00
parent aa55f6daa2
commit 6bd970d585
4 changed files with 101 additions and 31 deletions

View file

@ -1382,6 +1382,41 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
#[extension(pub(super) trait InferCtxtPrivExt<'tcx>)]
impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn can_match_trait(
&self,
goal: ty::TraitPredicate<'tcx>,
assumption: ty::PolyTraitPredicate<'tcx>,
) -> bool {
if goal.polarity != assumption.polarity() {
return false;
}
let trait_goal = goal.trait_ref;
let trait_assumption = self.instantiate_binder_with_fresh_vars(
DUMMY_SP,
infer::BoundRegionConversionTime::HigherRankedType,
assumption.to_poly_trait_ref(),
);
self.can_eq(ty::ParamEnv::empty(), trait_goal, trait_assumption)
}
fn can_match_projection(
&self,
goal: ty::ProjectionPredicate<'tcx>,
assumption: ty::PolyProjectionPredicate<'tcx>,
) -> bool {
let assumption = self.instantiate_binder_with_fresh_vars(
DUMMY_SP,
infer::BoundRegionConversionTime::HigherRankedType,
assumption,
);
let param_env = ty::ParamEnv::empty();
self.can_eq(param_env, goal.projection_ty, assumption.projection_ty)
&& self.can_eq(param_env, goal.term, assumption.term)
}
// returns if `cond` not occurring implies that `error` does not occur - i.e., that
// `error` occurring implies that `cond` occurs.
fn error_implies(&self, cond: ty::Predicate<'tcx>, error: ty::Predicate<'tcx>) -> bool {
@ -1390,39 +1425,27 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
if let Some(error) = error.to_opt_poly_trait_pred() {
elaborate(self.tcx, std::iter::once(cond))
.filter_map(|implied| implied.to_opt_poly_trait_pred())
.any(|implied| {
if error.polarity() != implied.polarity() {
return false;
}
let error = error.to_poly_trait_ref();
let implied = implied.to_poly_trait_ref();
// FIXME: I'm just not taking associated types at all here.
// Eventually I'll need to implement param-env-aware
// `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic.
let param_env = ty::ParamEnv::empty();
let is_implied = self.can_sub(param_env, error, implied);
if is_implied {
debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implied);
}
is_implied
})
self.enter_forall(error, |error| {
elaborate(self.tcx, std::iter::once(cond))
.filter_map(|implied| implied.to_opt_poly_trait_pred())
.any(|implied| {
let is_implied = self.can_match_trait(error, implied);
if is_implied {
debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implied);
}
is_implied
})
})
} else if let Some(error) = error.to_opt_poly_projection_pred() {
self.enter_forall(error, |error| {
elaborate(self.tcx, std::iter::once(cond))
.filter_map(|implied| implied.to_opt_poly_projection_pred())
.any(|implied| {
self.enter_forall(implied, |implied| {
let param_env = ty::ParamEnv::empty();
let is_implied =
self.can_eq(param_env, error.projection_ty, implied.projection_ty)
&& self.can_eq(param_env, error.term, implied.term);
if is_implied {
debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implied);
}
is_implied
})
let is_implied = self.can_match_projection(error, implied);
if is_implied {
debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implied);
}
is_implied
})
})
} else {

View file

@ -235,8 +235,8 @@ enum Elaborate {
///
/// And a super predicate of `TargetTrait` that has any of the following forms:
///
/// 1. `<OtherType as OtherTrait>::Assoc = <TargetType as TargetTrait>::Assoc`
/// 2. `<<TargetType as TargetTrait>::Assoc as OtherTrait>::Assoc = OtherType`
/// 1. `<OtherType as OtherTrait>::Assoc == <TargetType as TargetTrait>::Assoc`
/// 2. `<<TargetType as TargetTrait>::Assoc as OtherTrait>::Assoc == OtherType`
/// 3. `<TargetType as TargetTrait>::Assoc: OtherTrait`
///
/// Replace the span of the cause with the span of the associated item:
@ -292,6 +292,9 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
}
// Form 2: A projection obligation for an associated item failed to be met.
// We overwrite the span from above to ensure that a bound like
// `Self::Assoc1: Trait<OtherAssoc = Self::Assoc2>` gets the same
// span for both obligations that it is lowered to.
if let Some(impl_item_span) = ty_to_impl_span(proj.self_ty()) {
cause.span = impl_item_span;
}