@@ -26,96 +26,6 @@ use tracing::{debug, instrument};
2626use super :: StructurallyRelateAliases ;
2727use super :: combine:: { CombineFields , PredicateEmittingRelation } ;
2828use crate :: infer:: { DefineOpaqueTypes , InferCtxt , SubregionOrigin } ;
29- use crate :: traits:: ObligationCause ;
30-
31- /// Trait for returning data about a lattice, and for abstracting
32- /// over the "direction" of the lattice operation (LUB/GLB).
33- ///
34- /// GLB moves "down" the lattice (to smaller values); LUB moves
35- /// "up" the lattice (to bigger values).
36- trait LatticeDir < ' f , ' tcx > : PredicateEmittingRelation < InferCtxt < ' tcx > > {
37- fn infcx ( & self ) -> & ' f InferCtxt < ' tcx > ;
38-
39- fn cause ( & self ) -> & ObligationCause < ' tcx > ;
40-
41- fn define_opaque_types ( & self ) -> DefineOpaqueTypes ;
42-
43- // Relates the type `v` to `a` and `b` such that `v` represents
44- // the LUB/GLB of `a` and `b` as appropriate.
45- //
46- // Subtle hack: ordering *may* be significant here. This method
47- // relates `v` to `a` first, which may help us to avoid unnecessary
48- // type variable obligations. See caller for details.
49- fn relate_bound ( & mut self , v : Ty < ' tcx > , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> RelateResult < ' tcx , ( ) > ;
50- }
51-
52- /// Relates two types using a given lattice.
53- #[ instrument( skip( this) , level = "debug" ) ]
54- fn super_lattice_tys < ' a , ' tcx : ' a , L > (
55- this : & mut L ,
56- a : Ty < ' tcx > ,
57- b : Ty < ' tcx > ,
58- ) -> RelateResult < ' tcx , Ty < ' tcx > >
59- where
60- L : LatticeDir < ' a , ' tcx > ,
61- {
62- if a == b {
63- return Ok ( a) ;
64- }
65-
66- let infcx = this. infcx ( ) ;
67-
68- let a = infcx. shallow_resolve ( a) ;
69- let b = infcx. shallow_resolve ( b) ;
70-
71- match ( a. kind ( ) , b. kind ( ) ) {
72- // If one side is known to be a variable and one is not,
73- // create a variable (`v`) to represent the LUB. Make sure to
74- // relate `v` to the non-type-variable first (by passing it
75- // first to `relate_bound`). Otherwise, we would produce a
76- // subtype obligation that must then be processed.
77- //
78- // Example: if the LHS is a type variable, and RHS is
79- // `Box<i32>`, then we current compare `v` to the RHS first,
80- // which will instantiate `v` with `Box<i32>`. Then when `v`
81- // is compared to the LHS, we instantiate LHS with `Box<i32>`.
82- // But if we did in reverse order, we would create a `v <:
83- // LHS` (or vice versa) constraint and then instantiate
84- // `v`. This would require further processing to achieve same
85- // end-result; in particular, this screws up some of the logic
86- // in coercion, which expects LUB to figure out that the LHS
87- // is (e.g.) `Box<i32>`. A more obvious solution might be to
88- // iterate on the subtype obligations that are returned, but I
89- // think this suffices. -nmatsakis
90- ( & ty:: Infer ( TyVar ( ..) ) , _) => {
91- let v = infcx. next_ty_var ( this. cause ( ) . span ) ;
92- this. relate_bound ( v, b, a) ?;
93- Ok ( v)
94- }
95- ( _, & ty:: Infer ( TyVar ( ..) ) ) => {
96- let v = infcx. next_ty_var ( this. cause ( ) . span ) ;
97- this. relate_bound ( v, a, b) ?;
98- Ok ( v)
99- }
100-
101- (
102- & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id : a_def_id, .. } ) ,
103- & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id : b_def_id, .. } ) ,
104- ) if a_def_id == b_def_id => infcx. super_combine_tys ( this, a, b) ,
105-
106- ( & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, .. } ) , _)
107- | ( _, & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, .. } ) )
108- if this. define_opaque_types ( ) == DefineOpaqueTypes :: Yes
109- && def_id. is_local ( )
110- && !this. infcx ( ) . next_trait_solver ( ) =>
111- {
112- this. register_goals ( infcx. handle_opaque_type ( a, b, this. span ( ) , this. param_env ( ) ) ?) ;
113- Ok ( a)
114- }
115-
116- _ => infcx. super_combine_tys ( this, a, b) ,
117- }
118- }
11929
12030#[ derive( Clone , Copy ) ]
12131pub ( crate ) enum LatticeOpKind {
@@ -173,9 +83,70 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, '_, 'tcx> {
17383 }
17484 }
17585
86+ /// Relates two types using a given lattice.
17687 #[ instrument( skip( self ) , level = "trace" ) ]
17788 fn tys ( & mut self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> RelateResult < ' tcx , Ty < ' tcx > > {
178- super_lattice_tys ( self , a, b)
89+ if a == b {
90+ return Ok ( a) ;
91+ }
92+
93+ let infcx = self . fields . infcx ;
94+
95+ let a = infcx. shallow_resolve ( a) ;
96+ let b = infcx. shallow_resolve ( b) ;
97+
98+ match ( a. kind ( ) , b. kind ( ) ) {
99+ // If one side is known to be a variable and one is not,
100+ // create a variable (`v`) to represent the LUB. Make sure to
101+ // relate `v` to the non-type-variable first (by passing it
102+ // first to `relate_bound`). Otherwise, we would produce a
103+ // subtype obligation that must then be processed.
104+ //
105+ // Example: if the LHS is a type variable, and RHS is
106+ // `Box<i32>`, then we current compare `v` to the RHS first,
107+ // which will instantiate `v` with `Box<i32>`. Then when `v`
108+ // is compared to the LHS, we instantiate LHS with `Box<i32>`.
109+ // But if we did in reverse order, we would create a `v <:
110+ // LHS` (or vice versa) constraint and then instantiate
111+ // `v`. This would require further processing to achieve same
112+ // end-result; in particular, this screws up some of the logic
113+ // in coercion, which expects LUB to figure out that the LHS
114+ // is (e.g.) `Box<i32>`. A more obvious solution might be to
115+ // iterate on the subtype obligations that are returned, but I
116+ // think this suffices. -nmatsakis
117+ ( & ty:: Infer ( TyVar ( ..) ) , _) => {
118+ let v = infcx. next_ty_var ( self . fields . trace . cause . span ) ;
119+ self . relate_bound ( v, b, a) ?;
120+ Ok ( v)
121+ }
122+ ( _, & ty:: Infer ( TyVar ( ..) ) ) => {
123+ let v = infcx. next_ty_var ( self . fields . trace . cause . span ) ;
124+ self . relate_bound ( v, a, b) ?;
125+ Ok ( v)
126+ }
127+
128+ (
129+ & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id : a_def_id, .. } ) ,
130+ & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id : b_def_id, .. } ) ,
131+ ) if a_def_id == b_def_id => infcx. super_combine_tys ( self , a, b) ,
132+
133+ ( & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, .. } ) , _)
134+ | ( _, & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, .. } ) )
135+ if self . fields . define_opaque_types == DefineOpaqueTypes :: Yes
136+ && def_id. is_local ( )
137+ && !infcx. next_trait_solver ( ) =>
138+ {
139+ self . register_goals ( infcx. handle_opaque_type (
140+ a,
141+ b,
142+ self . span ( ) ,
143+ self . param_env ( ) ,
144+ ) ?) ;
145+ Ok ( a)
146+ }
147+
148+ _ => infcx. super_combine_tys ( self , a, b) ,
149+ }
179150 }
180151
181152 #[ instrument( skip( self ) , level = "trace" ) ]
@@ -231,15 +202,13 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, '_, 'tcx> {
231202 }
232203}
233204
234- impl < ' combine , ' infcx , ' tcx > LatticeDir < ' infcx , ' tcx > for LatticeOp < ' combine , ' infcx , ' tcx > {
235- fn infcx ( & self ) -> & ' infcx InferCtxt < ' tcx > {
236- self . fields . infcx
237- }
238-
239- fn cause ( & self ) -> & ObligationCause < ' tcx > {
240- & self . fields . trace . cause
241- }
242-
205+ impl < ' combine , ' infcx , ' tcx > LatticeOp < ' combine , ' infcx , ' tcx > {
206+ // Relates the type `v` to `a` and `b` such that `v` represents
207+ // the LUB/GLB of `a` and `b` as appropriate.
208+ //
209+ // Subtle hack: ordering *may* be significant here. This method
210+ // relates `v` to `a` first, which may help us to avoid unnecessary
211+ // type variable obligations. See caller for details.
243212 fn relate_bound ( & mut self , v : Ty < ' tcx > , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> RelateResult < ' tcx , ( ) > {
244213 let mut sub = self . fields . sub ( ) ;
245214 match self . kind {
@@ -254,10 +223,6 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for LatticeOp<'combine, 'i
254223 }
255224 Ok ( ( ) )
256225 }
257-
258- fn define_opaque_types ( & self ) -> DefineOpaqueTypes {
259- self . fields . define_opaque_types
260- }
261226}
262227
263228impl < ' tcx > PredicateEmittingRelation < InferCtxt < ' tcx > > for LatticeOp < ' _ , ' _ , ' tcx > {
0 commit comments