Skip to content

Commit fad2242

Browse files
committed
Add variance-related information to lifetime error messages
1 parent 86b0baf commit fad2242

33 files changed

+397
-144
lines changed

compiler/rustc_infer/src/infer/canonical/query_response.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,12 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
660660
)
661661
}
662662

663-
fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>) {
663+
fn push_outlives(
664+
&mut self,
665+
sup: ty::Region<'tcx>,
666+
sub: ty::Region<'tcx>,
667+
_info: ty::VarianceDiagInfo<'tcx>,
668+
) {
664669
self.obligations.push(Obligation {
665670
cause: self.cause.clone(),
666671
param_env: self.param_env,

compiler/rustc_infer/src/infer/combine.rs

+20-5
Original file line numberDiff line numberDiff line change
@@ -371,9 +371,12 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
371371
match dir {
372372
EqTo => self.equate(a_is_expected).relate(a_ty, b_ty),
373373
SubtypeOf => self.sub(a_is_expected).relate(a_ty, b_ty),
374-
SupertypeOf => {
375-
self.sub(a_is_expected).relate_with_variance(ty::Contravariant, a_ty, b_ty)
376-
}
374+
SupertypeOf => self.sub(a_is_expected).relate_with_variance(
375+
ty::Contravariant,
376+
ty::VarianceDiagInfo::default(),
377+
a_ty,
378+
b_ty,
379+
),
377380
}?;
378381

379382
Ok(())
@@ -574,6 +577,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
574577
fn relate_with_variance<T: Relate<'tcx>>(
575578
&mut self,
576579
variance: ty::Variance,
580+
_info: ty::VarianceDiagInfo<'tcx>,
577581
a: T,
578582
b: T,
579583
) -> RelateResult<'tcx, T> {
@@ -737,7 +741,12 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
737741
if self.tcx().lazy_normalization() =>
738742
{
739743
assert_eq!(promoted, None);
740-
let substs = self.relate_with_variance(ty::Variance::Invariant, substs, substs)?;
744+
let substs = self.relate_with_variance(
745+
ty::Variance::Invariant,
746+
ty::VarianceDiagInfo::default(),
747+
substs,
748+
substs,
749+
)?;
741750
Ok(self.tcx().mk_const(ty::Const {
742751
ty: c.ty,
743752
val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }),
@@ -831,6 +840,7 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
831840
fn relate_with_variance<T: Relate<'tcx>>(
832841
&mut self,
833842
_variance: ty::Variance,
843+
_info: ty::VarianceDiagInfo<'tcx>,
834844
a: T,
835845
b: T,
836846
) -> RelateResult<'tcx, T> {
@@ -965,7 +975,12 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
965975
if self.tcx().lazy_normalization() =>
966976
{
967977
assert_eq!(promoted, None);
968-
let substs = self.relate_with_variance(ty::Variance::Invariant, substs, substs)?;
978+
let substs = self.relate_with_variance(
979+
ty::Variance::Invariant,
980+
ty::VarianceDiagInfo::default(),
981+
substs,
982+
substs,
983+
)?;
969984
Ok(self.tcx().mk_const(ty::Const {
970985
ty: c.ty,
971986
val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }),

compiler/rustc_infer/src/infer/equate.rs

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> {
5959
fn relate_with_variance<T: Relate<'tcx>>(
6060
&mut self,
6161
_: ty::Variance,
62+
_info: ty::VarianceDiagInfo<'tcx>,
6263
a: T,
6364
b: T,
6465
) -> RelateResult<'tcx, T> {

compiler/rustc_infer/src/infer/glb.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> {
4343
fn relate_with_variance<T: Relate<'tcx>>(
4444
&mut self,
4545
variance: ty::Variance,
46+
_info: ty::VarianceDiagInfo<'tcx>,
4647
a: T,
4748
b: T,
4849
) -> RelateResult<'tcx, T> {
@@ -96,7 +97,7 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> {
9697
// When higher-ranked types are involved, computing the LUB is
9798
// very challenging, switch to invariance. This is obviously
9899
// overly conservative but works ok in practice.
99-
self.relate_with_variance(ty::Variance::Invariant, a, b)?;
100+
self.relate_with_variance(ty::Variance::Invariant, ty::VarianceDiagInfo::default(), a, b)?;
100101
Ok(a)
101102
}
102103
}

compiler/rustc_infer/src/infer/lub.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> {
4343
fn relate_with_variance<T: Relate<'tcx>>(
4444
&mut self,
4545
variance: ty::Variance,
46+
_info: ty::VarianceDiagInfo<'tcx>,
4647
a: T,
4748
b: T,
4849
) -> RelateResult<'tcx, T> {
@@ -96,7 +97,7 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> {
9697
// When higher-ranked types are involved, computing the LUB is
9798
// very challenging, switch to invariance. This is obviously
9899
// overly conservative but works ok in practice.
99-
self.relate_with_variance(ty::Variance::Invariant, a, b)?;
100+
self.relate_with_variance(ty::Variance::Invariant, ty::VarianceDiagInfo::default(), a, b)?;
100101
Ok(a)
101102
}
102103
}

compiler/rustc_infer/src/infer/nll_relate/mod.rs

+28-6
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ where
5555
/// - Bivariant means that it doesn't matter.
5656
ambient_variance: ty::Variance,
5757

58+
ambient_variance_info: ty::VarianceDiagInfo<'tcx>,
59+
5860
/// When we pass through a set of binders (e.g., when looking into
5961
/// a `fn` type), we push a new bound region scope onto here. This
6062
/// will contain the instantiated region for each region in those
@@ -78,7 +80,12 @@ pub trait TypeRelatingDelegate<'tcx> {
7880
/// satisfied for the two types to be related. `sub` and `sup` may
7981
/// be regions from the type or new variables created through the
8082
/// delegate.
81-
fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>);
83+
fn push_outlives(
84+
&mut self,
85+
sup: ty::Region<'tcx>,
86+
sub: ty::Region<'tcx>,
87+
info: ty::VarianceDiagInfo<'tcx>,
88+
);
8289

8390
fn const_equate(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>);
8491

@@ -138,7 +145,14 @@ where
138145
delegate: D,
139146
ambient_variance: ty::Variance,
140147
) -> Self {
141-
Self { infcx, delegate, ambient_variance, a_scopes: vec![], b_scopes: vec![] }
148+
Self {
149+
infcx,
150+
delegate,
151+
ambient_variance,
152+
ambient_variance_info: ty::VarianceDiagInfo::default(),
153+
a_scopes: vec![],
154+
b_scopes: vec![],
155+
}
142156
}
143157

144158
fn ambient_covariance(&self) -> bool {
@@ -239,10 +253,15 @@ where
239253

240254
/// Push a new outlives requirement into our output set of
241255
/// constraints.
242-
fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>) {
256+
fn push_outlives(
257+
&mut self,
258+
sup: ty::Region<'tcx>,
259+
sub: ty::Region<'tcx>,
260+
info: ty::VarianceDiagInfo<'tcx>,
261+
) {
243262
debug!("push_outlives({:?}: {:?})", sup, sub);
244263

245-
self.delegate.push_outlives(sup, sub);
264+
self.delegate.push_outlives(sup, sub, info);
246265
}
247266

248267
/// Relate a projection type and some value type lazily. This will always
@@ -490,13 +509,15 @@ where
490509
fn relate_with_variance<T: Relate<'tcx>>(
491510
&mut self,
492511
variance: ty::Variance,
512+
info: ty::VarianceDiagInfo<'tcx>,
493513
a: T,
494514
b: T,
495515
) -> RelateResult<'tcx, T> {
496516
debug!("relate_with_variance(variance={:?}, a={:?}, b={:?})", variance, a, b);
497517

498518
let old_ambient_variance = self.ambient_variance;
499519
self.ambient_variance = self.ambient_variance.xform(variance);
520+
self.ambient_variance_info = self.ambient_variance_info.clone().xform(info);
500521

501522
debug!("relate_with_variance: ambient_variance = {:?}", self.ambient_variance);
502523

@@ -574,12 +595,12 @@ where
574595

575596
if self.ambient_covariance() {
576597
// Covariance: a <= b. Hence, `b: a`.
577-
self.push_outlives(v_b, v_a);
598+
self.push_outlives(v_b, v_a, self.ambient_variance_info.clone());
578599
}
579600

580601
if self.ambient_contravariance() {
581602
// Contravariant: b <= a. Hence, `a: b`.
582-
self.push_outlives(v_a, v_b);
603+
self.push_outlives(v_a, v_b, self.ambient_variance_info.clone());
583604
}
584605

585606
Ok(a)
@@ -835,6 +856,7 @@ where
835856
fn relate_with_variance<T: Relate<'tcx>>(
836857
&mut self,
837858
variance: ty::Variance,
859+
_info: ty::VarianceDiagInfo<'tcx>,
838860
a: T,
839861
b: T,
840862
) -> RelateResult<'tcx, T> {

compiler/rustc_infer/src/infer/sub.rs

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> {
6262
fn relate_with_variance<T: Relate<'tcx>>(
6363
&mut self,
6464
variance: ty::Variance,
65+
_info: ty::VarianceDiagInfo<'tcx>,
6566
a: T,
6667
b: T,
6768
) -> RelateResult<'tcx, T> {

compiler/rustc_middle/src/ty/_match.rs

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ impl TypeRelation<'tcx> for Match<'tcx> {
4646
fn relate_with_variance<T: Relate<'tcx>>(
4747
&mut self,
4848
_: ty::Variance,
49+
_: ty::VarianceDiagInfo<'tcx>,
4950
a: T,
5051
b: T,
5152
) -> RelateResult<'tcx, T> {

compiler/rustc_middle/src/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ pub use self::sty::{
7171
ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FnSig, FreeRegion, GenSig,
7272
GeneratorSubsts, GeneratorSubstsParts, ParamConst, ParamTy, PolyExistentialProjection,
7373
PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef, ProjectionTy, Region, RegionKind,
74-
RegionVid, TraitRef, TyKind, TypeAndMut, UpvarSubsts,
74+
RegionVid, TraitRef, TyKind, TypeAndMut, UpvarSubsts, VarianceDiagInfo, VarianceDiagMutKind,
7575
};
7676
pub use self::trait_def::TraitDef;
7777

compiler/rustc_middle/src/ty/relate.rs

+57-28
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ pub trait TypeRelation<'tcx>: Sized {
6767
fn relate_with_variance<T: Relate<'tcx>>(
6868
&mut self,
6969
variance: ty::Variance,
70+
info: ty::VarianceDiagInfo<'tcx>,
7071
a: T,
7172
b: T,
7273
) -> RelateResult<'tcx, T>;
@@ -111,24 +112,23 @@ pub trait Relate<'tcx>: TypeFoldable<'tcx> + Copy {
111112
///////////////////////////////////////////////////////////////////////////
112113
// Relate impls
113114

114-
impl<'tcx> Relate<'tcx> for ty::TypeAndMut<'tcx> {
115-
fn relate<R: TypeRelation<'tcx>>(
116-
relation: &mut R,
117-
a: ty::TypeAndMut<'tcx>,
118-
b: ty::TypeAndMut<'tcx>,
119-
) -> RelateResult<'tcx, ty::TypeAndMut<'tcx>> {
120-
debug!("{}.mts({:?}, {:?})", relation.tag(), a, b);
121-
if a.mutbl != b.mutbl {
122-
Err(TypeError::Mutability)
123-
} else {
124-
let mutbl = a.mutbl;
125-
let variance = match mutbl {
126-
ast::Mutability::Not => ty::Covariant,
127-
ast::Mutability::Mut => ty::Invariant,
128-
};
129-
let ty = relation.relate_with_variance(variance, a.ty, b.ty)?;
130-
Ok(ty::TypeAndMut { ty, mutbl })
131-
}
115+
fn relate_type_and_mut<'tcx, R: TypeRelation<'tcx>>(
116+
relation: &mut R,
117+
a: ty::TypeAndMut<'tcx>,
118+
b: ty::TypeAndMut<'tcx>,
119+
kind: ty::VarianceDiagMutKind,
120+
) -> RelateResult<'tcx, ty::TypeAndMut<'tcx>> {
121+
debug!("{}.mts({:?}, {:?})", relation.tag(), a, b);
122+
if a.mutbl != b.mutbl {
123+
Err(TypeError::Mutability)
124+
} else {
125+
let mutbl = a.mutbl;
126+
let (variance, info) = match mutbl {
127+
ast::Mutability::Not => (ty::Covariant, ty::VarianceDiagInfo::None),
128+
ast::Mutability::Mut => (ty::Invariant, ty::VarianceDiagInfo::Mut { kind, ty: a.ty }),
129+
};
130+
let ty = relation.relate_with_variance(variance, info, a.ty, b.ty)?;
131+
Ok(ty::TypeAndMut { ty, mutbl })
132132
}
133133
}
134134

@@ -142,7 +142,7 @@ pub fn relate_substs<R: TypeRelation<'tcx>>(
142142

143143
let params = iter::zip(a_subst, b_subst).enumerate().map(|(i, (a, b))| {
144144
let variance = variances.map_or(ty::Invariant, |v| v[i]);
145-
relation.relate_with_variance(variance, a, b)
145+
relation.relate_with_variance(variance, ty::VarianceDiagInfo::default(), a, b)
146146
});
147147

148148
tcx.mk_substs(params)
@@ -177,7 +177,12 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
177177
if is_output {
178178
relation.relate(a, b)
179179
} else {
180-
relation.relate_with_variance(ty::Contravariant, a, b)
180+
relation.relate_with_variance(
181+
ty::Contravariant,
182+
ty::VarianceDiagInfo::default(),
183+
a,
184+
b,
185+
)
181186
}
182187
})
183188
.enumerate()
@@ -251,8 +256,18 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> {
251256
b.item_def_id,
252257
)))
253258
} else {
254-
let ty = relation.relate_with_variance(ty::Invariant, a.ty, b.ty)?;
255-
let substs = relation.relate_with_variance(ty::Invariant, a.substs, b.substs)?;
259+
let ty = relation.relate_with_variance(
260+
ty::Invariant,
261+
ty::VarianceDiagInfo::default(),
262+
a.ty,
263+
b.ty,
264+
)?;
265+
let substs = relation.relate_with_variance(
266+
ty::Invariant,
267+
ty::VarianceDiagInfo::default(),
268+
a.substs,
269+
b.substs,
270+
)?;
256271
Ok(ty::ExistentialProjection { item_def_id: a.item_def_id, substs, ty })
257272
}
258273
}
@@ -364,7 +379,12 @@ pub fn super_relate_tys<R: TypeRelation<'tcx>>(
364379

365380
(&ty::Dynamic(a_obj, a_region), &ty::Dynamic(b_obj, b_region)) => {
366381
let region_bound = relation.with_cause(Cause::ExistentialRegionBound, |relation| {
367-
relation.relate_with_variance(ty::Contravariant, a_region, b_region)
382+
relation.relate_with_variance(
383+
ty::Contravariant,
384+
ty::VarianceDiagInfo::default(),
385+
a_region,
386+
b_region,
387+
)
368388
})?;
369389
Ok(tcx.mk_dynamic(relation.relate(a_obj, b_obj)?, region_bound))
370390
}
@@ -398,15 +418,20 @@ pub fn super_relate_tys<R: TypeRelation<'tcx>>(
398418
}
399419

400420
(&ty::RawPtr(a_mt), &ty::RawPtr(b_mt)) => {
401-
let mt = relation.relate(a_mt, b_mt)?;
421+
let mt = relate_type_and_mut(relation, a_mt, b_mt, ty::VarianceDiagMutKind::RawPtr)?;
402422
Ok(tcx.mk_ptr(mt))
403423
}
404424

405425
(&ty::Ref(a_r, a_ty, a_mutbl), &ty::Ref(b_r, b_ty, b_mutbl)) => {
406-
let r = relation.relate_with_variance(ty::Contravariant, a_r, b_r)?;
426+
let r = relation.relate_with_variance(
427+
ty::Contravariant,
428+
ty::VarianceDiagInfo::default(),
429+
a_r,
430+
b_r,
431+
)?;
407432
let a_mt = ty::TypeAndMut { ty: a_ty, mutbl: a_mutbl };
408433
let b_mt = ty::TypeAndMut { ty: b_ty, mutbl: b_mutbl };
409-
let mt = relation.relate(a_mt, b_mt)?;
434+
let mt = relate_type_and_mut(relation, a_mt, b_mt, ty::VarianceDiagMutKind::Ref)?;
410435
Ok(tcx.mk_ref(r, mt))
411436
}
412437

@@ -536,8 +561,12 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
536561
(ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
537562
if au.def == bu.def && au.promoted == bu.promoted =>
538563
{
539-
let substs =
540-
relation.relate_with_variance(ty::Variance::Invariant, au.substs, bu.substs)?;
564+
let substs = relation.relate_with_variance(
565+
ty::Variance::Invariant,
566+
ty::VarianceDiagInfo::default(),
567+
au.substs,
568+
bu.substs,
569+
)?;
541570
return Ok(tcx.mk_const(ty::Const {
542571
val: ty::ConstKind::Unevaluated(ty::Unevaluated {
543572
def: au.def,

0 commit comments

Comments
 (0)