address review feedback
This commit is contained in:
parent
aa55f6daa2
commit
6bd970d585
4 changed files with 101 additions and 31 deletions
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue