@@ -44,6 +44,10 @@ pub trait LatticeDir<'f, 'gcx: 'f+'tcx, 'tcx: 'f> : TypeRelation<'f, 'gcx, 'tcx>
4444
4545 // Relates the type `v` to `a` and `b` such that `v` represents
4646 // 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.
4751 fn relate_bound ( & mut self , v : Ty < ' tcx > , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> RelateResult < ' tcx , ( ) > ;
4852}
4953
@@ -74,7 +78,29 @@ pub fn super_lattice_tys<'a, 'gcx, 'tcx, L>(this: &mut L,
7478 Ok ( v)
7579 }
7680
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+ }
78104 ( _, & ty:: TyInfer ( TyVar ( ..) ) ) => {
79105 let v = infcx. next_ty_var ( TypeVariableOrigin :: LatticeVariable ( this. cause ( ) . span ) ) ;
80106 this. relate_bound ( v, a, b) ?;
0 commit comments