2525//! In particular, it might be enough to say (A,B) are bivariant for
2626//! all (A,B).
2727
28- use middle:: ty:: BuiltinBounds ;
28+ use super :: combine:: { self , CombineFields } ;
29+ use super :: type_variable:: { BiTo } ;
30+
2931use middle:: ty:: { self , Ty } ;
3032use middle:: ty:: TyVar ;
31- use middle:: infer:: combine:: * ;
32- use middle:: infer:: CombineResult ;
33- use middle:: infer:: type_variable:: BiTo ;
34- use util:: ppaux:: Repr ;
33+ use middle:: ty_relate:: { Relate , RelateResult , TypeRelation } ;
34+ use util:: ppaux:: { Repr } ;
3535
36- pub struct Bivariate < ' f , ' tcx : ' f > {
37- fields : CombineFields < ' f , ' tcx >
36+ pub struct Bivariate < ' a , ' tcx : ' a > {
37+ fields : CombineFields < ' a , ' tcx >
3838}
3939
40- #[ allow( non_snake_case) ]
41- pub fn Bivariate < ' f , ' tcx > ( cf : CombineFields < ' f , ' tcx > ) -> Bivariate < ' f , ' tcx > {
42- Bivariate { fields : cf }
40+ impl < ' a , ' tcx > Bivariate < ' a , ' tcx > {
41+ pub fn new ( fields : CombineFields < ' a , ' tcx > ) -> Bivariate < ' a , ' tcx > {
42+ Bivariate { fields : fields }
43+ }
4344}
4445
45- impl < ' f , ' tcx > Combine < ' tcx > for Bivariate < ' f , ' tcx > {
46- fn tag ( & self ) -> String { "Bivariate" . to_string ( ) }
47- fn fields < ' a > ( & ' a self ) -> & ' a CombineFields < ' a , ' tcx > { & self . fields }
46+ impl < ' a , ' tcx > TypeRelation < ' a , ' tcx > for Bivariate < ' a , ' tcx > {
47+ fn tag ( & self ) -> & ' static str { "Bivariate" }
4848
49- fn tys_with_variance ( & self , v : ty:: Variance , a : Ty < ' tcx > , b : Ty < ' tcx > )
50- -> CombineResult < ' tcx , Ty < ' tcx > >
51- {
52- match v {
53- ty:: Invariant => self . equate ( ) . tys ( a, b) ,
54- ty:: Covariant => self . tys ( a, b) ,
55- ty:: Contravariant => self . tys ( a, b) ,
56- ty:: Bivariant => self . tys ( a, b) ,
57- }
58- }
49+ fn tcx ( & self ) -> & ' a ty:: ctxt < ' tcx > { self . fields . tcx ( ) }
5950
60- fn regions_with_variance ( & self , v : ty:: Variance , a : ty:: Region , b : ty:: Region )
61- -> CombineResult < ' tcx , ty:: Region >
62- {
63- match v {
64- ty:: Invariant => self . equate ( ) . regions ( a, b) ,
65- ty:: Covariant => self . regions ( a, b) ,
66- ty:: Contravariant => self . regions ( a, b) ,
67- ty:: Bivariant => self . regions ( a, b) ,
68- }
69- }
51+ fn a_is_expected ( & self ) -> bool { self . fields . a_is_expected }
7052
71- fn regions ( & self , a : ty:: Region , _: ty:: Region ) -> CombineResult < ' tcx , ty:: Region > {
72- Ok ( a)
73- }
74-
75- fn builtin_bounds ( & self ,
76- a : BuiltinBounds ,
77- b : BuiltinBounds )
78- -> CombineResult < ' tcx , BuiltinBounds >
53+ fn relate_with_variance < T : Relate < ' a , ' tcx > > ( & mut self ,
54+ variance : ty:: Variance ,
55+ a : & T ,
56+ b : & T )
57+ -> RelateResult < ' tcx , T >
7958 {
80- if a != b {
81- Err ( ty:: terr_builtin_bounds ( expected_found ( self , a, b) ) )
82- } else {
83- Ok ( a)
59+ match variance {
60+ // If we have Foo<A> and Foo is invariant w/r/t A,
61+ // and we want to assert that
62+ //
63+ // Foo<A> <: Foo<B> ||
64+ // Foo<B> <: Foo<A>
65+ //
66+ // then still A must equal B.
67+ ty:: Invariant => self . relate ( a, b) ,
68+
69+ ty:: Covariant => self . relate ( a, b) ,
70+ ty:: Bivariant => self . relate ( a, b) ,
71+ ty:: Contravariant => self . relate ( a, b) ,
8472 }
8573 }
8674
87- fn tys ( & self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> CombineResult < ' tcx , Ty < ' tcx > > {
75+ fn tys ( & mut self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> RelateResult < ' tcx , Ty < ' tcx > > {
8876 debug ! ( "{}.tys({}, {})" , self . tag( ) ,
8977 a. repr( self . fields. infcx. tcx) , b. repr( self . fields. infcx. tcx) ) ;
9078 if a == b { return Ok ( a) ; }
@@ -109,17 +97,22 @@ impl<'f, 'tcx> Combine<'tcx> for Bivariate<'f, 'tcx> {
10997 }
11098
11199 _ => {
112- super_tys ( self , a, b)
100+ combine :: super_combine_tys ( self . fields . infcx , self , a, b)
113101 }
114102 }
115103 }
116104
117- fn binders < T > ( & self , a : & ty:: Binder < T > , b : & ty:: Binder < T > ) -> CombineResult < ' tcx , ty:: Binder < T > >
118- where T : Combineable < ' tcx >
105+ fn regions ( & mut self , a : ty:: Region , _: ty:: Region ) -> RelateResult < ' tcx , ty:: Region > {
106+ Ok ( a)
107+ }
108+
109+ fn binders < T > ( & mut self , a : & ty:: Binder < T > , b : & ty:: Binder < T > )
110+ -> RelateResult < ' tcx , ty:: Binder < T > >
111+ where T : Relate < ' a , ' tcx >
119112 {
120113 let a1 = ty:: erase_late_bound_regions ( self . tcx ( ) , a) ;
121114 let b1 = ty:: erase_late_bound_regions ( self . tcx ( ) , b) ;
122- let c = try!( Combineable :: combine ( self , & a1, & b1) ) ;
115+ let c = try!( self . relate ( & a1, & b1) ) ;
123116 Ok ( ty:: Binder ( c) )
124117 }
125118}
0 commit comments