@@ -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+
24105pub 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-
151232impl < ' 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
757839pub fn expected_found < R , T > ( relation : & mut R , a : T , b : T ) -> ExpectedFound < T >
758840where
759- R : TypeRelation < ' tcx > ,
841+ R : ? Sized + DynTypeRelation < ' tcx > ,
760842{
761843 expected_found_bool ( relation. a_is_expected ( ) , a, b)
762844}
0 commit comments