Add variance-related information to lifetime error messages

This commit is contained in:
Aaron Hill 2021-05-13 09:30:14 -04:00
parent 86b0bafbf1
commit fad2242ff7
No known key found for this signature in database
GPG key ID: B4087E510E98B164
33 changed files with 397 additions and 144 deletions

View file

@ -660,7 +660,12 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
)
}
fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>) {
fn push_outlives(
&mut self,
sup: ty::Region<'tcx>,
sub: ty::Region<'tcx>,
_info: ty::VarianceDiagInfo<'tcx>,
) {
self.obligations.push(Obligation {
cause: self.cause.clone(),
param_env: self.param_env,

View file

@ -371,9 +371,12 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
match dir {
EqTo => self.equate(a_is_expected).relate(a_ty, b_ty),
SubtypeOf => self.sub(a_is_expected).relate(a_ty, b_ty),
SupertypeOf => {
self.sub(a_is_expected).relate_with_variance(ty::Contravariant, a_ty, b_ty)
}
SupertypeOf => self.sub(a_is_expected).relate_with_variance(
ty::Contravariant,
ty::VarianceDiagInfo::default(),
a_ty,
b_ty,
),
}?;
Ok(())
@ -574,6 +577,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
fn relate_with_variance<T: Relate<'tcx>>(
&mut self,
variance: ty::Variance,
_info: ty::VarianceDiagInfo<'tcx>,
a: T,
b: T,
) -> RelateResult<'tcx, T> {
@ -737,7 +741,12 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
if self.tcx().lazy_normalization() =>
{
assert_eq!(promoted, None);
let substs = self.relate_with_variance(ty::Variance::Invariant, substs, substs)?;
let substs = self.relate_with_variance(
ty::Variance::Invariant,
ty::VarianceDiagInfo::default(),
substs,
substs,
)?;
Ok(self.tcx().mk_const(ty::Const {
ty: c.ty,
val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }),
@ -831,6 +840,7 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
fn relate_with_variance<T: Relate<'tcx>>(
&mut self,
_variance: ty::Variance,
_info: ty::VarianceDiagInfo<'tcx>,
a: T,
b: T,
) -> RelateResult<'tcx, T> {
@ -965,7 +975,12 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
if self.tcx().lazy_normalization() =>
{
assert_eq!(promoted, None);
let substs = self.relate_with_variance(ty::Variance::Invariant, substs, substs)?;
let substs = self.relate_with_variance(
ty::Variance::Invariant,
ty::VarianceDiagInfo::default(),
substs,
substs,
)?;
Ok(self.tcx().mk_const(ty::Const {
ty: c.ty,
val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }),

View file

@ -59,6 +59,7 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> {
fn relate_with_variance<T: Relate<'tcx>>(
&mut self,
_: ty::Variance,
_info: ty::VarianceDiagInfo<'tcx>,
a: T,
b: T,
) -> RelateResult<'tcx, T> {

View file

@ -43,6 +43,7 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> {
fn relate_with_variance<T: Relate<'tcx>>(
&mut self,
variance: ty::Variance,
_info: ty::VarianceDiagInfo<'tcx>,
a: T,
b: T,
) -> RelateResult<'tcx, T> {
@ -96,7 +97,7 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> {
// When higher-ranked types are involved, computing the LUB is
// very challenging, switch to invariance. This is obviously
// overly conservative but works ok in practice.
self.relate_with_variance(ty::Variance::Invariant, a, b)?;
self.relate_with_variance(ty::Variance::Invariant, ty::VarianceDiagInfo::default(), a, b)?;
Ok(a)
}
}

View file

@ -43,6 +43,7 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> {
fn relate_with_variance<T: Relate<'tcx>>(
&mut self,
variance: ty::Variance,
_info: ty::VarianceDiagInfo<'tcx>,
a: T,
b: T,
) -> RelateResult<'tcx, T> {
@ -96,7 +97,7 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> {
// When higher-ranked types are involved, computing the LUB is
// very challenging, switch to invariance. This is obviously
// overly conservative but works ok in practice.
self.relate_with_variance(ty::Variance::Invariant, a, b)?;
self.relate_with_variance(ty::Variance::Invariant, ty::VarianceDiagInfo::default(), a, b)?;
Ok(a)
}
}

View file

@ -55,6 +55,8 @@ where
/// - Bivariant means that it doesn't matter.
ambient_variance: ty::Variance,
ambient_variance_info: ty::VarianceDiagInfo<'tcx>,
/// When we pass through a set of binders (e.g., when looking into
/// a `fn` type), we push a new bound region scope onto here. This
/// will contain the instantiated region for each region in those
@ -78,7 +80,12 @@ pub trait TypeRelatingDelegate<'tcx> {
/// satisfied for the two types to be related. `sub` and `sup` may
/// be regions from the type or new variables created through the
/// delegate.
fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>);
fn push_outlives(
&mut self,
sup: ty::Region<'tcx>,
sub: ty::Region<'tcx>,
info: ty::VarianceDiagInfo<'tcx>,
);
fn const_equate(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>);
@ -138,7 +145,14 @@ where
delegate: D,
ambient_variance: ty::Variance,
) -> Self {
Self { infcx, delegate, ambient_variance, a_scopes: vec![], b_scopes: vec![] }
Self {
infcx,
delegate,
ambient_variance,
ambient_variance_info: ty::VarianceDiagInfo::default(),
a_scopes: vec![],
b_scopes: vec![],
}
}
fn ambient_covariance(&self) -> bool {
@ -239,10 +253,15 @@ where
/// Push a new outlives requirement into our output set of
/// constraints.
fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>) {
fn push_outlives(
&mut self,
sup: ty::Region<'tcx>,
sub: ty::Region<'tcx>,
info: ty::VarianceDiagInfo<'tcx>,
) {
debug!("push_outlives({:?}: {:?})", sup, sub);
self.delegate.push_outlives(sup, sub);
self.delegate.push_outlives(sup, sub, info);
}
/// Relate a projection type and some value type lazily. This will always
@ -490,6 +509,7 @@ where
fn relate_with_variance<T: Relate<'tcx>>(
&mut self,
variance: ty::Variance,
info: ty::VarianceDiagInfo<'tcx>,
a: T,
b: T,
) -> RelateResult<'tcx, T> {
@ -497,6 +517,7 @@ where
let old_ambient_variance = self.ambient_variance;
self.ambient_variance = self.ambient_variance.xform(variance);
self.ambient_variance_info = self.ambient_variance_info.clone().xform(info);
debug!("relate_with_variance: ambient_variance = {:?}", self.ambient_variance);
@ -574,12 +595,12 @@ where
if self.ambient_covariance() {
// Covariance: a <= b. Hence, `b: a`.
self.push_outlives(v_b, v_a);
self.push_outlives(v_b, v_a, self.ambient_variance_info.clone());
}
if self.ambient_contravariance() {
// Contravariant: b <= a. Hence, `a: b`.
self.push_outlives(v_a, v_b);
self.push_outlives(v_a, v_b, self.ambient_variance_info.clone());
}
Ok(a)
@ -835,6 +856,7 @@ where
fn relate_with_variance<T: Relate<'tcx>>(
&mut self,
variance: ty::Variance,
_info: ty::VarianceDiagInfo<'tcx>,
a: T,
b: T,
) -> RelateResult<'tcx, T> {

View file

@ -62,6 +62,7 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> {
fn relate_with_variance<T: Relate<'tcx>>(
&mut self,
variance: ty::Variance,
_info: ty::VarianceDiagInfo<'tcx>,
a: T,
b: T,
) -> RelateResult<'tcx, T> {