@@ -28,16 +28,13 @@ use super::lub::Lub;
2828use super :: sub:: Sub ;
2929use super :: type_variable:: TypeVariableValue ;
3030use super :: { DefineOpaqueTypes , InferCtxt , MiscVariable , TypeTrace } ;
31+ use crate :: infer:: generalize:: { Generalization , Generalizer } ;
3132use crate :: traits:: { Obligation , PredicateObligations } ;
32- use rustc_data_structures:: sso:: SsoHashMap ;
33- use rustc_hir:: def_id:: DefId ;
3433use rustc_middle:: infer:: canonical:: OriginalQueryValues ;
3534use rustc_middle:: infer:: unify_key:: { ConstVarValue , ConstVariableValue } ;
3635use rustc_middle:: infer:: unify_key:: { ConstVariableOrigin , ConstVariableOriginKind } ;
37- use rustc_middle:: traits:: ObligationCause ;
3836use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
39- use rustc_middle:: ty:: relate:: { self , Relate , RelateResult , TypeRelation } ;
40- use rustc_middle:: ty:: subst:: SubstsRef ;
37+ use rustc_middle:: ty:: relate:: { RelateResult , TypeRelation } ;
4138use rustc_middle:: ty:: {
4239 self , AliasKind , FallibleTypeFolder , InferConst , ToPredicate , Ty , TyCtxt , TypeFoldable ,
4340 TypeSuperFoldable , TypeVisitableExt ,
@@ -412,7 +409,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
412409 // `'?2` and `?3` are fresh region/type inference
413410 // variables. (Down below, we will relate `a_ty <: b_ty`,
414411 // adding constraints like `'x: '?2` and `?1 <: ?3`.)
415- let Generalization { ty : b_ty, needs_wf } = self . generalize ( a_ty, b_vid, dir) ?;
412+ let Generalization { value : b_ty, needs_wf } = self . generalize ( a_ty, b_vid, dir) ?;
416413 debug ! ( ?b_ty) ;
417414 self . infcx . inner . borrow_mut ( ) . type_variables ( ) . instantiate ( b_vid, b_ty) ;
418415
@@ -456,11 +453,11 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
456453 /// - `for_vid` is a "root vid"
457454 #[ instrument( skip( self ) , level = "trace" , ret) ]
458455 fn generalize (
459- & self ,
456+ & mut self ,
460457 ty : Ty < ' tcx > ,
461458 for_vid : ty:: TyVid ,
462459 dir : RelationDir ,
463- ) -> RelateResult < ' tcx , Generalization < ' tcx > > {
460+ ) -> RelateResult < ' tcx , Generalization < Ty < ' tcx > > > {
464461 // Determine the ambient variance within which `ty` appears.
465462 // The surrounding equation is:
466463 //
@@ -476,31 +473,23 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
476473
477474 trace ! ( ?ambient_variance) ;
478475
479- let for_universe = match self . infcx . inner . borrow_mut ( ) . type_variables ( ) . probe ( for_vid) {
480- v @ TypeVariableValue :: Known { .. } => {
481- bug ! ( "instantiating {:?} which has a known value {:?}" , for_vid, v, )
482- }
483- TypeVariableValue :: Unknown { universe } => universe,
484- } ;
476+ let for_universe = self . infcx . probe_ty_var ( for_vid) . unwrap_err ( ) ;
477+ let for_vid_sub_root = self . infcx . inner . borrow_mut ( ) . type_variables ( ) . sub_root_var ( for_vid) ;
485478
486479 trace ! ( ?for_universe) ;
487480 trace ! ( ?self . trace) ;
488481
489- let mut generalize = Generalizer {
482+ Generalizer {
490483 infcx : self . infcx ,
491- cause : & self . trace . cause ,
492- for_vid_sub_root : self . infcx . inner . borrow_mut ( ) . type_variables ( ) . sub_root_var ( for_vid) ,
493- for_universe,
484+ delegate : self ,
494485 ambient_variance,
495- needs_wf : false ,
486+ for_universe,
487+ for_vid_sub_root,
496488 root_ty : ty,
497- param_env : self . param_env ,
498- cache : SsoHashMap :: new ( ) ,
499- } ;
500-
501- let ty = generalize. relate ( ty, ty) ?;
502- let needs_wf = generalize. needs_wf ;
503- Ok ( Generalization { ty, needs_wf } )
489+ cache : Default :: default ( ) ,
490+ needs_wf : false ,
491+ }
492+ . generalize ( ty)
504493 }
505494
506495 pub fn register_obligations ( & mut self , obligations : PredicateObligations < ' tcx > ) {
@@ -514,313 +503,6 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
514503 }
515504}
516505
517- struct Generalizer < ' cx , ' tcx > {
518- infcx : & ' cx InferCtxt < ' tcx > ,
519-
520- /// The span, used when creating new type variables and things.
521- cause : & ' cx ObligationCause < ' tcx > ,
522-
523- /// The vid of the type variable that is in the process of being
524- /// instantiated; if we find this within the type we are folding,
525- /// that means we would have created a cyclic type.
526- for_vid_sub_root : ty:: TyVid ,
527-
528- /// The universe of the type variable that is in the process of
529- /// being instantiated. Any fresh variables that we create in this
530- /// process should be in that same universe.
531- for_universe : ty:: UniverseIndex ,
532-
533- /// Track the variance as we descend into the type.
534- ambient_variance : ty:: Variance ,
535-
536- /// See the field `needs_wf` in `Generalization`.
537- needs_wf : bool ,
538-
539- /// The root type that we are generalizing. Used when reporting cycles.
540- root_ty : Ty < ' tcx > ,
541-
542- param_env : ty:: ParamEnv < ' tcx > ,
543-
544- cache : SsoHashMap < Ty < ' tcx > , Ty < ' tcx > > ,
545- }
546-
547- /// Result from a generalization operation. This includes
548- /// not only the generalized type, but also a bool flag
549- /// indicating whether further WF checks are needed.
550- #[ derive( Debug ) ]
551- struct Generalization < ' tcx > {
552- ty : Ty < ' tcx > ,
553-
554- /// If true, then the generalized type may not be well-formed,
555- /// even if the source type is well-formed, so we should add an
556- /// additional check to enforce that it is. This arises in
557- /// particular around 'bivariant' type parameters that are only
558- /// constrained by a where-clause. As an example, imagine a type:
559- ///
560- /// struct Foo<A, B> where A: Iterator<Item = B> {
561- /// data: A
562- /// }
563- ///
564- /// here, `A` will be covariant, but `B` is
565- /// unconstrained. However, whatever it is, for `Foo` to be WF, it
566- /// must be equal to `A::Item`. If we have an input `Foo<?A, ?B>`,
567- /// then after generalization we will wind up with a type like
568- /// `Foo<?C, ?D>`. When we enforce that `Foo<?A, ?B> <: Foo<?C,
569- /// ?D>` (or `>:`), we will wind up with the requirement that `?A
570- /// <: ?C`, but no particular relationship between `?B` and `?D`
571- /// (after all, we do not know the variance of the normalized form
572- /// of `A::Item` with respect to `A`). If we do nothing else, this
573- /// may mean that `?D` goes unconstrained (as in #41677). So, in
574- /// this scenario where we create a new type variable in a
575- /// bivariant context, we set the `needs_wf` flag to true. This
576- /// will force the calling code to check that `WF(Foo<?C, ?D>)`
577- /// holds, which in turn implies that `?C::Item == ?D`. So once
578- /// `?C` is constrained, that should suffice to restrict `?D`.
579- needs_wf : bool ,
580- }
581-
582- impl < ' tcx > TypeRelation < ' tcx > for Generalizer < ' _ , ' tcx > {
583- fn tcx ( & self ) -> TyCtxt < ' tcx > {
584- self . infcx . tcx
585- }
586-
587- fn param_env ( & self ) -> ty:: ParamEnv < ' tcx > {
588- self . param_env
589- }
590-
591- fn tag ( & self ) -> & ' static str {
592- "Generalizer"
593- }
594-
595- fn a_is_expected ( & self ) -> bool {
596- true
597- }
598-
599- fn binders < T > (
600- & mut self ,
601- a : ty:: Binder < ' tcx , T > ,
602- b : ty:: Binder < ' tcx , T > ,
603- ) -> RelateResult < ' tcx , ty:: Binder < ' tcx , T > >
604- where
605- T : Relate < ' tcx > ,
606- {
607- Ok ( a. rebind ( self . relate ( a. skip_binder ( ) , b. skip_binder ( ) ) ?) )
608- }
609-
610- fn relate_item_substs (
611- & mut self ,
612- item_def_id : DefId ,
613- a_subst : SubstsRef < ' tcx > ,
614- b_subst : SubstsRef < ' tcx > ,
615- ) -> RelateResult < ' tcx , SubstsRef < ' tcx > > {
616- if self . ambient_variance == ty:: Variance :: Invariant {
617- // Avoid fetching the variance if we are in an invariant
618- // context; no need, and it can induce dependency cycles
619- // (e.g., #41849).
620- relate:: relate_substs ( self , a_subst, b_subst)
621- } else {
622- let tcx = self . tcx ( ) ;
623- let opt_variances = tcx. variances_of ( item_def_id) ;
624- relate:: relate_substs_with_variances (
625- self ,
626- item_def_id,
627- & opt_variances,
628- a_subst,
629- b_subst,
630- true ,
631- )
632- }
633- }
634-
635- fn relate_with_variance < T : Relate < ' tcx > > (
636- & mut self ,
637- variance : ty:: Variance ,
638- _info : ty:: VarianceDiagInfo < ' tcx > ,
639- a : T ,
640- b : T ,
641- ) -> RelateResult < ' tcx , T > {
642- let old_ambient_variance = self . ambient_variance ;
643- self . ambient_variance = self . ambient_variance . xform ( variance) ;
644-
645- let result = self . relate ( a, b) ;
646- self . ambient_variance = old_ambient_variance;
647- result
648- }
649-
650- fn tys ( & mut self , t : Ty < ' tcx > , t2 : Ty < ' tcx > ) -> RelateResult < ' tcx , Ty < ' tcx > > {
651- assert_eq ! ( t, t2) ; // we are abusing TypeRelation here; both LHS and RHS ought to be ==
652-
653- if let Some ( & result) = self . cache . get ( & t) {
654- return Ok ( result) ;
655- }
656- debug ! ( "generalize: t={:?}" , t) ;
657-
658- // Check to see whether the type we are generalizing references
659- // any other type variable related to `vid` via
660- // subtyping. This is basically our "occurs check", preventing
661- // us from creating infinitely sized types.
662- let result = match * t. kind ( ) {
663- ty:: Infer ( ty:: TyVar ( vid) ) => {
664- let vid = self . infcx . inner . borrow_mut ( ) . type_variables ( ) . root_var ( vid) ;
665- let sub_vid = self . infcx . inner . borrow_mut ( ) . type_variables ( ) . sub_root_var ( vid) ;
666- if sub_vid == self . for_vid_sub_root {
667- // If sub-roots are equal, then `for_vid` and
668- // `vid` are related via subtyping.
669- Err ( TypeError :: CyclicTy ( self . root_ty ) )
670- } else {
671- let probe = self . infcx . inner . borrow_mut ( ) . type_variables ( ) . probe ( vid) ;
672- match probe {
673- TypeVariableValue :: Known { value : u } => {
674- debug ! ( "generalize: known value {:?}" , u) ;
675- self . relate ( u, u)
676- }
677- TypeVariableValue :: Unknown { universe } => {
678- match self . ambient_variance {
679- // Invariant: no need to make a fresh type variable.
680- ty:: Invariant => {
681- if self . for_universe . can_name ( universe) {
682- return Ok ( t) ;
683- }
684- }
685-
686- // Bivariant: make a fresh var, but we
687- // may need a WF predicate. See
688- // comment on `needs_wf` field for
689- // more info.
690- ty:: Bivariant => self . needs_wf = true ,
691-
692- // Co/contravariant: this will be
693- // sufficiently constrained later on.
694- ty:: Covariant | ty:: Contravariant => ( ) ,
695- }
696-
697- let origin =
698- * self . infcx . inner . borrow_mut ( ) . type_variables ( ) . var_origin ( vid) ;
699- let new_var_id = self
700- . infcx
701- . inner
702- . borrow_mut ( )
703- . type_variables ( )
704- . new_var ( self . for_universe , origin) ;
705- let u = self . tcx ( ) . mk_ty_var ( new_var_id) ;
706-
707- // Record that we replaced `vid` with `new_var_id` as part of a generalization
708- // operation. This is needed to detect cyclic types. To see why, see the
709- // docs in the `type_variables` module.
710- self . infcx . inner . borrow_mut ( ) . type_variables ( ) . sub ( vid, new_var_id) ;
711- debug ! ( "generalize: replacing original vid={:?} with new={:?}" , vid, u) ;
712- Ok ( u)
713- }
714- }
715- }
716- }
717- ty:: Infer ( ty:: IntVar ( _) | ty:: FloatVar ( _) ) => {
718- // No matter what mode we are in,
719- // integer/floating-point types must be equal to be
720- // relatable.
721- Ok ( t)
722- }
723- ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, substs, .. } ) => {
724- let s = self . relate ( substs, substs) ?;
725- Ok ( if s == substs { t } else { self . infcx . tcx . mk_opaque ( def_id, s) } )
726- }
727- _ => relate:: super_relate_tys ( self , t, t) ,
728- } ?;
729-
730- self . cache . insert ( t, result) ;
731- Ok ( result)
732- }
733-
734- fn regions (
735- & mut self ,
736- r : ty:: Region < ' tcx > ,
737- r2 : ty:: Region < ' tcx > ,
738- ) -> RelateResult < ' tcx , ty:: Region < ' tcx > > {
739- assert_eq ! ( r, r2) ; // we are abusing TypeRelation here; both LHS and RHS ought to be ==
740-
741- debug ! ( "generalize: regions r={:?}" , r) ;
742-
743- match * r {
744- // Never make variables for regions bound within the type itself,
745- // nor for erased regions.
746- ty:: ReLateBound ( ..) | ty:: ReErased => {
747- return Ok ( r) ;
748- }
749-
750- ty:: ReError ( _) => {
751- return Ok ( r) ;
752- }
753-
754- ty:: RePlaceholder ( ..)
755- | ty:: ReVar ( ..)
756- | ty:: ReStatic
757- | ty:: ReEarlyBound ( ..)
758- | ty:: ReFree ( ..) => {
759- // see common code below
760- }
761- }
762-
763- // If we are in an invariant context, we can re-use the region
764- // as is, unless it happens to be in some universe that we
765- // can't name. (In the case of a region *variable*, we could
766- // use it if we promoted it into our universe, but we don't
767- // bother.)
768- if let ty:: Invariant = self . ambient_variance {
769- let r_universe = self . infcx . universe_of_region ( r) ;
770- if self . for_universe . can_name ( r_universe) {
771- return Ok ( r) ;
772- }
773- }
774-
775- // FIXME: This is non-ideal because we don't give a
776- // very descriptive origin for this region variable.
777- Ok ( self . infcx . next_region_var_in_universe ( MiscVariable ( self . cause . span ) , self . for_universe ) )
778- }
779-
780- fn consts (
781- & mut self ,
782- c : ty:: Const < ' tcx > ,
783- c2 : ty:: Const < ' tcx > ,
784- ) -> RelateResult < ' tcx , ty:: Const < ' tcx > > {
785- assert_eq ! ( c, c2) ; // we are abusing TypeRelation here; both LHS and RHS ought to be ==
786-
787- match c. kind ( ) {
788- ty:: ConstKind :: Infer ( InferConst :: Var ( vid) ) => {
789- let mut inner = self . infcx . inner . borrow_mut ( ) ;
790- let variable_table = & mut inner. const_unification_table ( ) ;
791- let var_value = variable_table. probe_value ( vid) ;
792- match var_value. val {
793- ConstVariableValue :: Known { value : u } => {
794- drop ( inner) ;
795- self . relate ( u, u)
796- }
797- ConstVariableValue :: Unknown { universe } => {
798- if self . for_universe . can_name ( universe) {
799- Ok ( c)
800- } else {
801- let new_var_id = variable_table. new_key ( ConstVarValue {
802- origin : var_value. origin ,
803- val : ConstVariableValue :: Unknown { universe : self . for_universe } ,
804- } ) ;
805- Ok ( self . tcx ( ) . mk_const ( new_var_id, c. ty ( ) ) )
806- }
807- }
808- }
809- }
810- ty:: ConstKind :: Unevaluated ( ty:: UnevaluatedConst { def, substs } ) => {
811- let substs = self . relate_with_variance (
812- ty:: Variance :: Invariant ,
813- ty:: VarianceDiagInfo :: default ( ) ,
814- substs,
815- substs,
816- ) ?;
817- Ok ( self . tcx ( ) . mk_const ( ty:: UnevaluatedConst { def, substs } , c. ty ( ) ) )
818- }
819- _ => relate:: super_relate_consts ( self , c, c) ,
820- }
821- }
822- }
823-
824506pub trait ObligationEmittingRelation < ' tcx > : TypeRelation < ' tcx > {
825507 /// Register obligations that must hold in order for this relation to hold
826508 fn register_obligations ( & mut self , obligations : PredicateObligations < ' tcx > ) ;
0 commit comments