Add variance-related information to lifetime error messages
This commit is contained in:
parent
86b0bafbf1
commit
fad2242ff7
33 changed files with 397 additions and 144 deletions
|
@ -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,
|
||||
|
|
|
@ -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 }),
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue