@@ -44,6 +44,10 @@ pub trait LatticeDir<'f, 'gcx: 'f+'tcx, 'tcx: 'f> : TypeRelation<'f, 'gcx, 'tcx>
44
44
45
45
// Relates the type `v` to `a` and `b` such that `v` represents
46
46
// the LUB/GLB of `a` and `b` as appropriate.
47
+ //
48
+ // Subtle hack: ordering *may* be significant here. This method
49
+ // relates `v` to `a` first, which may help us to avoid unecessary
50
+ // type variable obligations. See caller for details.
47
51
fn relate_bound ( & mut self , v : Ty < ' tcx > , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> RelateResult < ' tcx , ( ) > ;
48
52
}
49
53
@@ -74,7 +78,29 @@ pub fn super_lattice_tys<'a, 'gcx, 'tcx, L>(this: &mut L,
74
78
Ok ( v)
75
79
}
76
80
77
- ( & ty:: TyInfer ( TyVar ( ..) ) , _) |
81
+ // If one side is known to be a variable and one is not,
82
+ // create a variable (`v`) to represent the LUB. Make sure to
83
+ // relate `v` to the non-type-variable first (by passing it
84
+ // first to `relate_bound`). Otherwise, we would produce a
85
+ // subtype obligation that must then be processed.
86
+ //
87
+ // Example: if the LHS is a type variable, and RHS is
88
+ // `Box<i32>`, then we current compare `v` to the RHS first,
89
+ // which will instantiate `v` with `Box<i32>`. Then when `v`
90
+ // is compared to the LHS, we instantiate LHS with `Box<i32>`.
91
+ // But if we did in reverse order, we would create a `v <:
92
+ // LHS` (or vice versa) constraint and then instantiate
93
+ // `v`. This would require further processing to achieve same
94
+ // end-result; in partiular, this screws up some of the logic
95
+ // in coercion, which expects LUB to figure out that the LHS
96
+ // is (e.g.) `Box<i32>`. A more obvious solution might be to
97
+ // iterate on the subtype obligations that are returned, but I
98
+ // think this suffices. -nmatsakis
99
+ ( & ty:: TyInfer ( TyVar ( ..) ) , _) => {
100
+ let v = infcx. next_ty_var ( TypeVariableOrigin :: LatticeVariable ( this. cause ( ) . span ) ) ;
101
+ this. relate_bound ( v, b, a) ?;
102
+ Ok ( v)
103
+ }
78
104
( _, & ty:: TyInfer ( TyVar ( ..) ) ) => {
79
105
let v = infcx. next_ty_var ( TypeVariableOrigin :: LatticeVariable ( this. cause ( ) . span ) ) ;
80
106
this. relate_bound ( v, a, b) ?;
0 commit comments