@@ -25,13 +25,11 @@ use rustc_data_structures::fx::FxHashMap;
2525use rustc_middle:: traits:: ObligationCause ;
2626use rustc_middle:: ty:: fold:: FnMutDelegate ;
2727use rustc_middle:: ty:: relate:: { Relate , RelateResult , TypeRelation } ;
28- use rustc_middle:: ty:: visit :: TypeVisitableExt ;
28+ use rustc_middle:: ty:: TypeVisitableExt ;
2929use rustc_middle:: ty:: { self , InferConst , Ty , TyCtxt } ;
3030use rustc_span:: { Span , Symbol } ;
31- use std:: fmt:: Debug ;
3231
3332use super :: combine:: ObligationEmittingRelation ;
34- use super :: generalize:: { self , Generalization } ;
3533use crate :: infer:: InferCtxt ;
3634use crate :: infer:: { TypeVariableOrigin , TypeVariableOriginKind } ;
3735use crate :: traits:: { Obligation , PredicateObligations } ;
@@ -99,15 +97,6 @@ pub trait TypeRelatingDelegate<'tcx> {
9997 /// placeholder region.
10098 fn next_placeholder_region ( & mut self , placeholder : ty:: PlaceholderRegion ) -> ty:: Region < ' tcx > ;
10199
102- /// Creates a new existential region in the given universe. This
103- /// is used when handling subtyping and type variables -- if we
104- /// have that `?X <: Foo<'a>`, for example, we would instantiate
105- /// `?X` with a type like `Foo<'?0>` where `'?0` is a fresh
106- /// existential variable created by this function. We would then
107- /// relate `Foo<'?0>` with `Foo<'a>` (and probably add an outlives
108- /// relation stating that `'?0: 'a`).
109- fn generalize_existential ( & mut self , universe : ty:: UniverseIndex ) -> ty:: Region < ' tcx > ;
110-
111100 /// Enables some optimizations if we do not expect inference variables
112101 /// in the RHS of the relation.
113102 fn forbid_inference_vars ( ) -> bool ;
@@ -153,113 +142,44 @@ where
153142 self . delegate . push_outlives ( sup, sub, info) ;
154143 }
155144
156- /// Relate a type inference variable with a value type. This works
157- /// by creating a "generalization" G of the value where all the
158- /// lifetimes are replaced with fresh inference values. This
159- /// generalization G becomes the value of the inference variable,
160- /// and is then related in turn to the value. So e.g. if you had
161- /// `vid = ?0` and `value = &'a u32`, we might first instantiate
162- /// `?0` to a type like `&'0 u32` where `'0` is a fresh variable,
163- /// and then relate `&'0 u32` with `&'a u32` (resulting in
164- /// relations between `'0` and `'a`).
165- ///
166- /// The variable `pair` can be either a `(vid, ty)` or `(ty, vid)`
167- /// -- in other words, it is always an (unresolved) inference
168- /// variable `vid` and a type `ty` that are being related, but the
169- /// vid may appear either as the "a" type or the "b" type,
170- /// depending on where it appears in the tuple. The trait
171- /// `VidValuePair` lets us work with the vid/type while preserving
172- /// the "sidedness" when necessary -- the sidedness is relevant in
173- /// particular for the variance and set of in-scope things.
174- fn relate_ty_var < PAIR : VidValuePair < ' tcx > > (
175- & mut self ,
176- pair : PAIR ,
177- ) -> RelateResult < ' tcx , Ty < ' tcx > > {
178- debug ! ( "relate_ty_var({:?})" , pair) ;
179-
180- let vid = pair. vid ( ) ;
181- let value_ty = pair. value_ty ( ) ;
182-
183- // FIXME(invariance) -- this logic assumes invariance, but that is wrong.
184- // This only presently applies to chalk integration, as NLL
185- // doesn't permit type variables to appear on both sides (and
186- // doesn't use lazy norm).
187- match * value_ty. kind ( ) {
188- ty:: Infer ( ty:: TyVar ( value_vid) ) => {
189- // Two type variables: just equate them.
190- self . infcx . inner . borrow_mut ( ) . type_variables ( ) . equate ( vid, value_vid) ;
191- return Ok ( value_ty) ;
192- }
193-
194- _ => ( ) ,
195- }
196-
197- let generalized_ty = self . generalize ( value_ty, vid) ?;
198- debug ! ( "relate_ty_var: generalized_ty = {:?}" , generalized_ty) ;
199-
200- if D :: forbid_inference_vars ( ) {
201- // In NLL, we don't have type inference variables
202- // floating around, so we can do this rather imprecise
203- // variant of the occurs-check.
204- assert ! ( !generalized_ty. has_non_region_infer( ) ) ;
205- }
206-
207- self . infcx . inner . borrow_mut ( ) . type_variables ( ) . instantiate ( vid, generalized_ty) ;
208-
209- // Relate the generalized kind to the original one.
210- let result = pair. relate_generalized_ty ( self , generalized_ty) ;
211-
212- debug ! ( "relate_ty_var: complete, result = {:?}" , result) ;
213- result
214- }
215-
216- fn generalize ( & mut self , ty : Ty < ' tcx > , for_vid : ty:: TyVid ) -> RelateResult < ' tcx , Ty < ' tcx > > {
217- let Generalization { value_may_be_infer : ty, has_unconstrained_ty_var : _ } =
218- generalize:: generalize (
219- self . infcx ,
220- & mut self . delegate ,
221- ty,
222- for_vid,
223- self . ambient_variance ,
224- ) ?;
225-
226- if ty. is_ty_var ( ) {
227- span_bug ! ( self . delegate. span( ) , "occurs check failure in MIR typeck" ) ;
228- }
229- Ok ( ty)
230- }
231-
232- fn relate_opaques ( & mut self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> RelateResult < ' tcx , Ty < ' tcx > > {
145+ fn relate_opaques ( & mut self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> RelateResult < ' tcx , ( ) > {
146+ let infcx = self . infcx ;
147+ debug_assert ! ( !infcx. next_trait_solver( ) ) ;
233148 let ( a, b) = if self . a_is_expected ( ) { ( a, b) } else { ( b, a) } ;
234- let mut generalize = |ty, ty_is_expected| {
235- let var = self . infcx . next_ty_var_id_in_universe (
149+ // `handle_opaque_type` cannot handle subtyping, so to support subtyping
150+ // we instead eagerly generalize here. This is a bit of a mess but will go
151+ // away once we're using the new solver.
152+ let mut enable_subtyping = |ty, ty_is_expected| {
153+ let ty_vid = infcx. next_ty_var_id_in_universe (
236154 TypeVariableOrigin {
237155 kind : TypeVariableOriginKind :: MiscVariable ,
238156 span : self . delegate . span ( ) ,
239157 } ,
240158 ty:: UniverseIndex :: ROOT ,
241159 ) ;
242- if ty_is_expected {
243- self . relate_ty_var ( ( ty, var) )
160+
161+ let variance = if ty_is_expected {
162+ self . ambient_variance
244163 } else {
245- self . relate_ty_var ( ( var, ty) )
246- }
164+ self . ambient_variance . xform ( ty:: Contravariant )
165+ } ;
166+
167+ self . infcx . instantiate_ty_var ( self , ty_is_expected, ty_vid, variance, ty) ?;
168+ Ok ( infcx. resolve_vars_if_possible ( Ty :: new_infer ( infcx. tcx , ty:: TyVar ( ty_vid) ) ) )
247169 } ;
170+
248171 let ( a, b) = match ( a. kind ( ) , b. kind ( ) ) {
249- ( & ty:: Alias ( ty:: Opaque , ..) , _) => ( a, generalize ( b, false ) ?) ,
250- ( _, & ty:: Alias ( ty:: Opaque , ..) ) => ( generalize ( a, true ) ?, b) ,
172+ ( & ty:: Alias ( ty:: Opaque , ..) , _) => ( a, enable_subtyping ( b, false ) ?) ,
173+ ( _, & ty:: Alias ( ty:: Opaque , ..) ) => ( enable_subtyping ( a, true ) ?, b) ,
251174 _ => unreachable ! (
252175 "expected at least one opaque type in `relate_opaques`, got {a} and {b}."
253176 ) ,
254177 } ;
255178 let cause = ObligationCause :: dummy_with_span ( self . delegate . span ( ) ) ;
256- let obligations = self
257- . infcx
258- . handle_opaque_type ( a, b, true , & cause, self . delegate . param_env ( ) ) ?
259- . obligations ;
179+ let obligations =
180+ infcx. handle_opaque_type ( a, b, true , & cause, self . delegate . param_env ( ) ) ?. obligations ;
260181 self . delegate . register_obligations ( obligations) ;
261- trace ! ( a = ?a. kind( ) , b = ?b. kind( ) , "opaque type instantiated" ) ;
262- Ok ( a)
182+ Ok ( ( ) )
263183 }
264184
265185 fn enter_forall < T , U > (
@@ -357,76 +277,6 @@ where
357277 }
358278}
359279
360- /// When we instantiate an inference variable with a value in
361- /// `relate_ty_var`, we always have the pair of a `TyVid` and a `Ty`,
362- /// but the ordering may vary (depending on whether the inference
363- /// variable was found on the `a` or `b` sides). Therefore, this trait
364- /// allows us to factor out common code, while preserving the order
365- /// when needed.
366- trait VidValuePair < ' tcx > : Debug {
367- /// Extract the inference variable (which could be either the
368- /// first or second part of the tuple).
369- fn vid ( & self ) -> ty:: TyVid ;
370-
371- /// Extract the value it is being related to (which will be the
372- /// opposite part of the tuple from the vid).
373- fn value_ty ( & self ) -> Ty < ' tcx > ;
374-
375- /// Given a generalized type G that should replace the vid, relate
376- /// G to the value, putting G on whichever side the vid would have
377- /// appeared.
378- fn relate_generalized_ty < D > (
379- & self ,
380- relate : & mut TypeRelating < ' _ , ' tcx , D > ,
381- generalized_ty : Ty < ' tcx > ,
382- ) -> RelateResult < ' tcx , Ty < ' tcx > >
383- where
384- D : TypeRelatingDelegate < ' tcx > ;
385- }
386-
387- impl < ' tcx > VidValuePair < ' tcx > for ( ty:: TyVid , Ty < ' tcx > ) {
388- fn vid ( & self ) -> ty:: TyVid {
389- self . 0
390- }
391-
392- fn value_ty ( & self ) -> Ty < ' tcx > {
393- self . 1
394- }
395-
396- fn relate_generalized_ty < D > (
397- & self ,
398- relate : & mut TypeRelating < ' _ , ' tcx , D > ,
399- generalized_ty : Ty < ' tcx > ,
400- ) -> RelateResult < ' tcx , Ty < ' tcx > >
401- where
402- D : TypeRelatingDelegate < ' tcx > ,
403- {
404- relate. relate ( generalized_ty, self . value_ty ( ) )
405- }
406- }
407-
408- // In this case, the "vid" is the "b" type.
409- impl < ' tcx > VidValuePair < ' tcx > for ( Ty < ' tcx > , ty:: TyVid ) {
410- fn vid ( & self ) -> ty:: TyVid {
411- self . 1
412- }
413-
414- fn value_ty ( & self ) -> Ty < ' tcx > {
415- self . 0
416- }
417-
418- fn relate_generalized_ty < D > (
419- & self ,
420- relate : & mut TypeRelating < ' _ , ' tcx , D > ,
421- generalized_ty : Ty < ' tcx > ,
422- ) -> RelateResult < ' tcx , Ty < ' tcx > >
423- where
424- D : TypeRelatingDelegate < ' tcx > ,
425- {
426- relate. relate ( self . value_ty ( ) , generalized_ty)
427- }
428- }
429-
430280impl < ' tcx , D > TypeRelation < ' tcx > for TypeRelating < ' _ , ' tcx , D >
431281where
432282 D : TypeRelatingDelegate < ' tcx > ,
@@ -473,29 +323,39 @@ where
473323
474324 if !D :: forbid_inference_vars ( ) {
475325 b = self . infcx . shallow_resolve ( b) ;
326+ } else {
327+ assert ! ( !b. has_non_region_infer( ) , "unexpected inference var {:?}" , b) ;
476328 }
477329
478330 if a == b {
479331 return Ok ( a) ;
480332 }
481333
482334 match ( a. kind ( ) , b. kind ( ) ) {
483- ( _, & ty:: Infer ( ty:: TyVar ( vid) ) ) => {
484- if D :: forbid_inference_vars ( ) {
485- // Forbid inference variables in the RHS.
486- bug ! ( "unexpected inference var {:?}" , b)
487- } else {
488- self . relate_ty_var ( ( a, vid) )
335+ ( & ty:: Infer ( ty:: TyVar ( a_vid) ) , & ty:: Infer ( ty:: TyVar ( b_vid) ) ) => {
336+ match self . ambient_variance {
337+ ty:: Invariant => infcx. inner . borrow_mut ( ) . type_variables ( ) . equate ( a_vid, b_vid) ,
338+ _ => unimplemented ! ( ) ,
489339 }
490340 }
491341
492- ( & ty:: Infer ( ty:: TyVar ( vid) ) , _) => self . relate_ty_var ( ( vid, b) ) ,
342+ ( & ty:: Infer ( ty:: TyVar ( a_vid) ) , _) => {
343+ infcx. instantiate_ty_var ( self , true , a_vid, self . ambient_variance , b) ?
344+ }
345+
346+ ( _, & ty:: Infer ( ty:: TyVar ( b_vid) ) ) => infcx. instantiate_ty_var (
347+ self ,
348+ false ,
349+ b_vid,
350+ self . ambient_variance . xform ( ty:: Contravariant ) ,
351+ a,
352+ ) ?,
493353
494354 (
495355 & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id : a_def_id, .. } ) ,
496356 & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id : b_def_id, .. } ) ,
497357 ) if a_def_id == b_def_id || infcx. next_trait_solver ( ) => {
498- infcx. super_combine_tys ( self , a, b) . or_else ( |err| {
358+ infcx. super_combine_tys ( self , a, b) . map ( |_| ( ) ) . or_else ( |err| {
499359 // This behavior is only there for the old solver, the new solver
500360 // shouldn't ever fail. Instead, it unconditionally emits an
501361 // alias-relate goal.
@@ -505,22 +365,24 @@ where
505365 "failure to relate an opaque to itself should result in an error later on" ,
506366 ) ;
507367 if a_def_id. is_local ( ) { self . relate_opaques ( a, b) } else { Err ( err) }
508- } )
368+ } ) ? ;
509369 }
510370 ( & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, .. } ) , _)
511371 | ( _, & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, .. } ) )
512372 if def_id. is_local ( ) && !self . infcx . next_trait_solver ( ) =>
513373 {
514- self . relate_opaques ( a, b)
374+ self . relate_opaques ( a, b) ? ;
515375 }
516376
517377 _ => {
518378 debug ! ( ?a, ?b, ?self . ambient_variance) ;
519379
520380 // Will also handle unification of `IntVar` and `FloatVar`.
521- self . infcx . super_combine_tys ( self , a, b)
381+ self . infcx . super_combine_tys ( self , a, b) ? ;
522382 }
523383 }
384+
385+ Ok ( a)
524386 }
525387
526388 #[ instrument( skip( self ) , level = "trace" ) ]
0 commit comments