25
25
//! In particular, it might be enough to say (A,B) are bivariant for
26
26
//! all (A,B).
27
27
28
- use middle:: ty:: BuiltinBounds ;
28
+ use super :: combine:: { self , CombineFields } ;
29
+ use super :: type_variable:: { BiTo } ;
30
+
29
31
use middle:: ty:: { self , Ty } ;
30
32
use 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 } ;
35
35
36
- pub struct Bivariate < ' f , ' tcx : ' f > {
37
- fields : CombineFields < ' f , ' tcx >
36
+ pub struct Bivariate < ' a , ' tcx : ' a > {
37
+ fields : CombineFields < ' a , ' tcx >
38
38
}
39
39
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
+ }
43
44
}
44
45
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" }
48
48
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 ( ) }
59
50
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 }
70
52
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 >
79
58
{
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) ,
84
72
}
85
73
}
86
74
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 > > {
88
76
debug ! ( "{}.tys({}, {})" , self . tag( ) ,
89
77
a. repr( self . fields. infcx. tcx) , b. repr( self . fields. infcx. tcx) ) ;
90
78
if a == b { return Ok ( a) ; }
@@ -109,17 +97,22 @@ impl<'f, 'tcx> Combine<'tcx> for Bivariate<'f, 'tcx> {
109
97
}
110
98
111
99
_ => {
112
- super_tys ( self , a, b)
100
+ combine :: super_combine_tys ( self . fields . infcx , self , a, b)
113
101
}
114
102
}
115
103
}
116
104
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 >
119
112
{
120
113
let a1 = ty:: erase_late_bound_regions ( self . tcx ( ) , a) ;
121
114
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) ) ;
123
116
Ok ( ty:: Binder ( c) )
124
117
}
125
118
}
0 commit comments