Skip to content

Commit 6ee91e2

Browse files
committed
make super_relate_consts use trait objects
1 parent a9cd294 commit 6ee91e2

File tree

3 files changed

+113
-32
lines changed

3 files changed

+113
-32
lines changed

compiler/rustc_infer/src/infer/combine.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -564,10 +564,10 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
564564
// Avoid fetching the variance if we are in an invariant
565565
// context; no need, and it can induce dependency cycles
566566
// (e.g., #41849).
567-
relate::relate_substs(self, None, a_subst, b_subst)
567+
self.relate_substs(None, a_subst, b_subst)
568568
} else {
569569
let opt_variances = self.tcx().variances_of(item_def_id);
570-
relate::relate_substs(self, Some(&opt_variances), a_subst, b_subst)
570+
self.relate_substs(Some(&opt_variances), a_subst, b_subst)
571571
}
572572
}
573573

compiler/rustc_infer/src/infer/equate.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> {
5252
// variance requires computing types which can require
5353
// performing trait matching (which then performs equality
5454
// unification).
55-
56-
relate::relate_substs(self, None, a_subst, b_subst)
55+
self.relate_substs(None, a_subst, b_subst)
5756
}
5857

5958
fn relate_with_variance<T: Relate<'tcx>>(

compiler/rustc_middle/src/ty/relate.rs

+110-28
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,87 @@ pub enum Cause {
2121
ExistentialRegionBound, // relating an existential region bound
2222
}
2323

24+
pub trait DynTypeRelation<'tcx> {
25+
fn tcx(&self) -> TyCtxt<'tcx>;
26+
27+
fn param_env(&self) -> ty::ParamEnv<'tcx>;
28+
29+
fn tag(&self) -> &'static str;
30+
31+
fn a_is_expected(&self) -> bool;
32+
33+
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>>;
34+
35+
fn regions(
36+
&mut self,
37+
a: ty::Region<'tcx>,
38+
b: ty::Region<'tcx>,
39+
) -> RelateResult<'tcx, ty::Region<'tcx>>;
40+
41+
fn consts(
42+
&mut self,
43+
a: &'tcx ty::Const<'tcx>,
44+
b: &'tcx ty::Const<'tcx>,
45+
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>;
46+
47+
fn relate_substs(
48+
&mut self,
49+
variances: Option<&[ty::Variance]>,
50+
a_subst: SubstsRef<'tcx>,
51+
b_subst: SubstsRef<'tcx>,
52+
) -> RelateResult<'tcx, SubstsRef<'tcx>>;
53+
}
54+
55+
impl<'tcx, T: TypeRelation<'tcx>> DynTypeRelation<'tcx> for T {
56+
fn tcx(&self) -> TyCtxt<'tcx> {
57+
TypeRelation::tcx(self)
58+
}
59+
60+
fn param_env(&self) -> ty::ParamEnv<'tcx> {
61+
TypeRelation::param_env(self)
62+
}
63+
64+
/// Returns a static string we can use for printouts.
65+
fn tag(&self) -> &'static str {
66+
TypeRelation::tag(self)
67+
}
68+
69+
/// Returns `true` if the value `a` is the "expected" type in the
70+
/// relation. Just affects error messages.
71+
fn a_is_expected(&self) -> bool {
72+
TypeRelation::a_is_expected(self)
73+
}
74+
75+
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
76+
TypeRelation::tys(self, a, b)
77+
}
78+
79+
fn regions(
80+
&mut self,
81+
a: ty::Region<'tcx>,
82+
b: ty::Region<'tcx>,
83+
) -> RelateResult<'tcx, ty::Region<'tcx>> {
84+
TypeRelation::regions(self, a, b)
85+
}
86+
87+
fn consts(
88+
&mut self,
89+
a: &'tcx ty::Const<'tcx>,
90+
b: &'tcx ty::Const<'tcx>,
91+
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
92+
TypeRelation::consts(self, a, b)
93+
}
94+
95+
fn relate_substs(
96+
&mut self,
97+
variances: Option<&[ty::Variance]>,
98+
a_subst: SubstsRef<'tcx>,
99+
b_subst: SubstsRef<'tcx>,
100+
) -> RelateResult<'tcx, SubstsRef<'tcx>> {
101+
TypeRelation::relate_substs(self, variances, a_subst, b_subst)
102+
}
103+
}
104+
24105
pub trait TypeRelation<'tcx>: Sized {
25106
fn tcx(&self) -> TyCtxt<'tcx>;
26107

@@ -45,6 +126,22 @@ pub trait TypeRelation<'tcx>: Sized {
45126
Relate::relate(self, a, b)
46127
}
47128

129+
fn relate_substs(
130+
&mut self,
131+
variances: Option<&[ty::Variance]>,
132+
a_subst: SubstsRef<'tcx>,
133+
b_subst: SubstsRef<'tcx>,
134+
) -> RelateResult<'tcx, SubstsRef<'tcx>> {
135+
let tcx = self.tcx();
136+
137+
let params = a_subst.iter().zip(b_subst).enumerate().map(|(i, (a, b))| {
138+
let variance = variances.map_or(ty::Invariant, |v| v[i]);
139+
self.relate_with_variance(variance, a, b)
140+
});
141+
142+
Ok(tcx.mk_substs(params)?)
143+
}
144+
48145
/// Relate the two substitutions for the given item. The default
49146
/// is to look up the variance for the item and proceed
50147
/// accordingly.
@@ -60,7 +157,7 @@ pub trait TypeRelation<'tcx>: Sized {
60157
);
61158

62159
let opt_variances = self.tcx().variances_of(item_def_id);
63-
relate_substs(self, Some(opt_variances), a_subst, b_subst)
160+
self.relate_substs(Some(opt_variances), a_subst, b_subst)
64161
}
65162

66163
/// Switch variance for the purpose of relating `a` and `b`.
@@ -132,22 +229,6 @@ impl<'tcx> Relate<'tcx> for ty::TypeAndMut<'tcx> {
132229
}
133230
}
134231

135-
pub fn relate_substs<R: TypeRelation<'tcx>>(
136-
relation: &mut R,
137-
variances: Option<&[ty::Variance]>,
138-
a_subst: SubstsRef<'tcx>,
139-
b_subst: SubstsRef<'tcx>,
140-
) -> RelateResult<'tcx, SubstsRef<'tcx>> {
141-
let tcx = relation.tcx();
142-
143-
let params = a_subst.iter().zip(b_subst).enumerate().map(|(i, (a, b))| {
144-
let variance = variances.map_or(ty::Invariant, |v| v[i]);
145-
relation.relate_with_variance(variance, a, b)
146-
});
147-
148-
Ok(tcx.mk_substs(params)?)
149-
}
150-
151232
impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
152233
fn relate<R: TypeRelation<'tcx>>(
153234
relation: &mut R,
@@ -266,7 +347,7 @@ impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> {
266347
if a.def_id != b.def_id {
267348
Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id)))
268349
} else {
269-
let substs = relate_substs(relation, None, a.substs, b.substs)?;
350+
let substs = relation.relate_substs(None, a.substs, b.substs)?;
270351
Ok(ty::TraitRef { def_id: a.def_id, substs })
271352
}
272353
}
@@ -282,7 +363,7 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
282363
if a.def_id != b.def_id {
283364
Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id)))
284365
} else {
285-
let substs = relate_substs(relation, None, a.substs, b.substs)?;
366+
let substs = relation.relate_substs(None, a.substs, b.substs)?;
286367
Ok(ty::ExistentialTraitRef { def_id: a.def_id, substs })
287368
}
288369
}
@@ -468,7 +549,7 @@ pub fn super_relate_tys<R: TypeRelation<'tcx>>(
468549
(&ty::Opaque(a_def_id, a_substs), &ty::Opaque(b_def_id, b_substs))
469550
if a_def_id == b_def_id =>
470551
{
471-
let substs = relate_substs(relation, None, a_substs, b_substs)?;
552+
let substs = relation.relate_substs(None, a_substs, b_substs)?;
472553
Ok(tcx.mk_opaque(a_def_id, substs))
473554
}
474555

@@ -479,8 +560,8 @@ pub fn super_relate_tys<R: TypeRelation<'tcx>>(
479560
/// The main "const relation" routine. Note that this does not handle
480561
/// inference artifacts, so you should filter those out before calling
481562
/// it.
482-
pub fn super_relate_consts<R: TypeRelation<'tcx>>(
483-
relation: &mut R,
563+
pub fn super_relate_consts<'tcx>(
564+
relation: &mut dyn DynTypeRelation<'tcx>,
484565
a: &'tcx ty::Const<'tcx>,
485566
b: &'tcx ty::Const<'tcx>,
486567
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
@@ -594,8 +675,9 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
594675
ty::ConstKind::Unevaluated(a_def, a_substs, a_promoted),
595676
ty::ConstKind::Unevaluated(b_def, b_substs, b_promoted),
596677
) if a_def == b_def && a_promoted == b_promoted => {
597-
let substs =
598-
relation.relate_with_variance(ty::Variance::Invariant, a_substs, b_substs)?;
678+
// Relate substs uses `ty::Inveriant` if it no variances are supplied,
679+
// which is what we want here.
680+
let substs = relation.relate_substs(None, a_substs, b_substs)?;
599681
Ok(ty::ConstKind::Unevaluated(a_def, substs, a_promoted))
600682
}
601683
_ => Err(TypeError::ConstMismatch(expected_found(relation, a, b))),
@@ -643,7 +725,7 @@ impl<'tcx> Relate<'tcx> for ty::ClosureSubsts<'tcx> {
643725
a: ty::ClosureSubsts<'tcx>,
644726
b: ty::ClosureSubsts<'tcx>,
645727
) -> RelateResult<'tcx, ty::ClosureSubsts<'tcx>> {
646-
let substs = relate_substs(relation, None, a.substs, b.substs)?;
728+
let substs = relation.relate_substs(None, a.substs, b.substs)?;
647729
Ok(ty::ClosureSubsts { substs })
648730
}
649731
}
@@ -654,7 +736,7 @@ impl<'tcx> Relate<'tcx> for ty::GeneratorSubsts<'tcx> {
654736
a: ty::GeneratorSubsts<'tcx>,
655737
b: ty::GeneratorSubsts<'tcx>,
656738
) -> RelateResult<'tcx, ty::GeneratorSubsts<'tcx>> {
657-
let substs = relate_substs(relation, None, a.substs, b.substs)?;
739+
let substs = relation.relate_substs(None, a.substs, b.substs)?;
658740
Ok(ty::GeneratorSubsts { substs })
659741
}
660742
}
@@ -665,7 +747,7 @@ impl<'tcx> Relate<'tcx> for SubstsRef<'tcx> {
665747
a: SubstsRef<'tcx>,
666748
b: SubstsRef<'tcx>,
667749
) -> RelateResult<'tcx, SubstsRef<'tcx>> {
668-
relate_substs(relation, None, a, b)
750+
relation.relate_substs(None, a, b)
669751
}
670752
}
671753

@@ -756,7 +838,7 @@ impl<'tcx> Relate<'tcx> for ty::ProjectionPredicate<'tcx> {
756838

757839
pub fn expected_found<R, T>(relation: &mut R, a: T, b: T) -> ExpectedFound<T>
758840
where
759-
R: TypeRelation<'tcx>,
841+
R: ?Sized + DynTypeRelation<'tcx>,
760842
{
761843
expected_found_bool(relation.a_is_expected(), a, b)
762844
}

0 commit comments

Comments
 (0)