@@ -21,6 +21,87 @@ pub enum Cause {
21
21
ExistentialRegionBound , // relating an existential region bound
22
22
}
23
23
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
+
24
105
pub trait TypeRelation < ' tcx > : Sized {
25
106
fn tcx ( & self ) -> TyCtxt < ' tcx > ;
26
107
@@ -45,6 +126,22 @@ pub trait TypeRelation<'tcx>: Sized {
45
126
Relate :: relate ( self , a, b)
46
127
}
47
128
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
+
48
145
/// Relate the two substitutions for the given item. The default
49
146
/// is to look up the variance for the item and proceed
50
147
/// accordingly.
@@ -60,7 +157,7 @@ pub trait TypeRelation<'tcx>: Sized {
60
157
) ;
61
158
62
159
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)
64
161
}
65
162
66
163
/// Switch variance for the purpose of relating `a` and `b`.
@@ -132,22 +229,6 @@ impl<'tcx> Relate<'tcx> for ty::TypeAndMut<'tcx> {
132
229
}
133
230
}
134
231
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
-
151
232
impl < ' tcx > Relate < ' tcx > for ty:: FnSig < ' tcx > {
152
233
fn relate < R : TypeRelation < ' tcx > > (
153
234
relation : & mut R ,
@@ -266,7 +347,7 @@ impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> {
266
347
if a. def_id != b. def_id {
267
348
Err ( TypeError :: Traits ( expected_found ( relation, a. def_id , b. def_id ) ) )
268
349
} else {
269
- let substs = relate_substs ( relation , None , a. substs , b. substs ) ?;
350
+ let substs = relation . relate_substs ( None , a. substs , b. substs ) ?;
270
351
Ok ( ty:: TraitRef { def_id : a. def_id , substs } )
271
352
}
272
353
}
@@ -282,7 +363,7 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
282
363
if a. def_id != b. def_id {
283
364
Err ( TypeError :: Traits ( expected_found ( relation, a. def_id , b. def_id ) ) )
284
365
} else {
285
- let substs = relate_substs ( relation , None , a. substs , b. substs ) ?;
366
+ let substs = relation . relate_substs ( None , a. substs , b. substs ) ?;
286
367
Ok ( ty:: ExistentialTraitRef { def_id : a. def_id , substs } )
287
368
}
288
369
}
@@ -468,7 +549,7 @@ pub fn super_relate_tys<R: TypeRelation<'tcx>>(
468
549
( & ty:: Opaque ( a_def_id, a_substs) , & ty:: Opaque ( b_def_id, b_substs) )
469
550
if a_def_id == b_def_id =>
470
551
{
471
- let substs = relate_substs ( relation , None , a_substs, b_substs) ?;
552
+ let substs = relation . relate_substs ( None , a_substs, b_substs) ?;
472
553
Ok ( tcx. mk_opaque ( a_def_id, substs) )
473
554
}
474
555
@@ -479,8 +560,8 @@ pub fn super_relate_tys<R: TypeRelation<'tcx>>(
479
560
/// The main "const relation" routine. Note that this does not handle
480
561
/// inference artifacts, so you should filter those out before calling
481
562
/// 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 > ,
484
565
a : & ' tcx ty:: Const < ' tcx > ,
485
566
b : & ' tcx ty:: Const < ' tcx > ,
486
567
) -> RelateResult < ' tcx , & ' tcx ty:: Const < ' tcx > > {
@@ -594,8 +675,9 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
594
675
ty:: ConstKind :: Unevaluated ( a_def, a_substs, a_promoted) ,
595
676
ty:: ConstKind :: Unevaluated ( b_def, b_substs, b_promoted) ,
596
677
) 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) ?;
599
681
Ok ( ty:: ConstKind :: Unevaluated ( a_def, substs, a_promoted) )
600
682
}
601
683
_ => Err ( TypeError :: ConstMismatch ( expected_found ( relation, a, b) ) ) ,
@@ -643,7 +725,7 @@ impl<'tcx> Relate<'tcx> for ty::ClosureSubsts<'tcx> {
643
725
a : ty:: ClosureSubsts < ' tcx > ,
644
726
b : ty:: ClosureSubsts < ' tcx > ,
645
727
) -> 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 ) ?;
647
729
Ok ( ty:: ClosureSubsts { substs } )
648
730
}
649
731
}
@@ -654,7 +736,7 @@ impl<'tcx> Relate<'tcx> for ty::GeneratorSubsts<'tcx> {
654
736
a : ty:: GeneratorSubsts < ' tcx > ,
655
737
b : ty:: GeneratorSubsts < ' tcx > ,
656
738
) -> 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 ) ?;
658
740
Ok ( ty:: GeneratorSubsts { substs } )
659
741
}
660
742
}
@@ -665,7 +747,7 @@ impl<'tcx> Relate<'tcx> for SubstsRef<'tcx> {
665
747
a : SubstsRef < ' tcx > ,
666
748
b : SubstsRef < ' tcx > ,
667
749
) -> RelateResult < ' tcx , SubstsRef < ' tcx > > {
668
- relate_substs ( relation , None , a, b)
750
+ relation . relate_substs ( None , a, b)
669
751
}
670
752
}
671
753
@@ -756,7 +838,7 @@ impl<'tcx> Relate<'tcx> for ty::ProjectionPredicate<'tcx> {
756
838
757
839
pub fn expected_found < R , T > ( relation : & mut R , a : T , b : T ) -> ExpectedFound < T >
758
840
where
759
- R : TypeRelation < ' tcx > ,
841
+ R : ? Sized + DynTypeRelation < ' tcx > ,
760
842
{
761
843
expected_found_bool ( relation. a_is_expected ( ) , a, b)
762
844
}
0 commit comments