@@ -355,13 +355,46 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxUniverse {
355355 }
356356}
357357
358+ /// This state determines how generalization treats aliases.
359+ ///
360+ /// Based on which state we're in, we treat them either as rigid or normalizable,
361+ /// which might change depending on what types the generalization visitor encounters.
362+ /// See `handle_alias_ty` for the logic of how we change states.
358363#[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash ) ]
359364enum GeneralizerState {
360365 /// Treat aliases as potentially normalizable.
366+ ///
367+ /// This is the default state that generalization starts in, unless we're treating aliases as rigid.
368+ /// It also means we're not currently inside an alias, since then we change the state to
369+ /// `IncompletelyRelateAliasArgs`
361370 Default ,
362- IncompletelyRelateHigherRankedAlias ,
363- /// Only one layer
371+ /// We enter this state when we're generalizing the arguments of a potentially normalizeable alias.
372+ ///
373+ /// The behavior here is different between the old and the new solver:
374+ ///
375+ /// In the old solver, the difference between this and `Default` is needed to
376+ /// correctly handle `<T as Bar<<?0 as Foo>::Assoc>::Assoc == ?0`.
377+ /// That equality can hold by either normalizing the outer or the inner associated type.
378+ /// In the old solver, we always structurally relate aliases,
379+ /// however, when we encounter an occurs check failure, we propagate the failure to the outermost alias,
380+ /// for which we then emit a Projection goal.
381+ ///
382+ /// In the new solver, we rarely get into this state.
383+ /// When we encounter aliases we instead attempt to normalize them, and treat them as rigid using `ShallowStructurallyRelate`.
384+ /// Only when an alias is higher-ranked, we continue with similar logic to the old solver,
385+ /// except now we also explicitly relate the type and consts in the arguments of aliases while in this mode.
386+ ///
387+ /// FIXME: Because we relate the type and consts in the arguments of aliases while in this mode,
388+ /// this is "incomplete".
389+ IncompletelyRelateAliasArgs ,
390+ /// During generalization, when we encounter aliases,
391+ /// we will first attempt to normalize them when we're using the next trait solver.
392+ /// We can now treat the normalized alias as rigid, but only for "one layer", hence shallow.
393+ /// New aliases encountered inside the arguments of the outer alias should once again be related as normal.
364394 ShallowStructurallyRelateAliases ,
395+ /// Treat aliases as rigid when relating them.
396+ ///
397+ /// This corresponds to `relation.structurally_relate_aliases()`.
365398 StructurallyRelateAliases ,
366399}
367400
@@ -400,11 +433,10 @@ struct Generalizer<'me, 'tcx> {
400433 /// some other type. What will be the variance at this point?
401434 ambient_variance : ty:: Variance ,
402435
403- /// This is set once we're generalizing the arguments of an alias .
436+ /// This field keeps track of how we treat aliases during generalization .
404437 ///
405- /// This is necessary to correctly handle
406- /// `<T as Bar<<?0 as Foo>::Assoc>::Assoc == ?0`. This equality can
407- /// hold by either normalizing the outer or the inner associated type.
438+ /// Refer to [`GeneralizerState`]'s docs for more information about the
439+ /// all the possible values this can have, and when we use which.
408440 state : GeneralizerState ,
409441
410442 cache : SsoHashMap < ( Ty < ' tcx > , ty:: Variance , GeneralizerState ) , Ty < ' tcx > > ,
@@ -483,11 +515,11 @@ impl<'tcx> Generalizer<'_, 'tcx> {
483515
484516 return res;
485517 }
486- GeneralizerState :: Default | GeneralizerState :: IncompletelyRelateHigherRankedAlias => { }
518+ GeneralizerState :: Default | GeneralizerState :: IncompletelyRelateAliasArgs => { }
487519 }
488520
489521 let previous_state =
490- mem:: replace ( & mut self . state , GeneralizerState :: IncompletelyRelateHigherRankedAlias ) ;
522+ mem:: replace ( & mut self . state , GeneralizerState :: IncompletelyRelateAliasArgs ) ;
491523 let result = match self . relate ( alias, alias) {
492524 Ok ( alias) => Ok ( alias. to_ty ( self . cx ( ) ) ) ,
493525 Err ( e) => match previous_state {
@@ -504,7 +536,7 @@ impl<'tcx> Generalizer<'_, 'tcx> {
504536 debug ! ( "generalization failure in alias" ) ;
505537 Ok ( self . next_ty_var_for_alias ( ) )
506538 }
507- GeneralizerState :: IncompletelyRelateHigherRankedAlias => return Err ( e) ,
539+ GeneralizerState :: IncompletelyRelateAliasArgs => return Err ( e) ,
508540
509541 // Early return.
510542 GeneralizerState :: ShallowStructurallyRelateAliases
@@ -613,6 +645,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
613645 // of each other. This is currently only used for diagnostics.
614646 // To see why, see the docs in the `type_variables` module.
615647 inner. type_variables ( ) . sub_unify ( vid, new_var_id) ;
648+
616649 // If we're in the new solver and create a new inference
617650 // variable inside of an alias we eagerly constrain that
618651 // inference variable to prevent unexpected ambiguity errors.
@@ -632,13 +665,13 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
632665 && !matches ! ( self . infcx. typing_mode( ) , TypingMode :: Coherence )
633666 {
634667 match self . state {
635- GeneralizerState :: IncompletelyRelateHigherRankedAlias => {
668+ GeneralizerState :: IncompletelyRelateAliasArgs => {
636669 inner. type_variables ( ) . equate ( vid, new_var_id) ;
637670 }
671+ GeneralizerState :: Default
672+ | GeneralizerState :: ShallowStructurallyRelateAliases
673+ | GeneralizerState :: StructurallyRelateAliases => { }
638674 }
639- GeneralizerState :: Default
640- | GeneralizerState :: ShallowStructurallyRelateAliases
641- | GeneralizerState :: StructurallyRelateAliases => { }
642675 }
643676
644677 debug ! ( "replacing original vid={:?} with new={:?}" , vid, new_var_id) ;
@@ -765,13 +798,13 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
765798 && !matches ! ( self . infcx. typing_mode( ) , TypingMode :: Coherence )
766799 {
767800 match self . state {
768- GeneralizerState :: IncompletelyRelateHigherRankedAlias => {
801+ GeneralizerState :: IncompletelyRelateAliasArgs => {
769802 variable_table. union ( vid, new_var_id) ;
770803 }
804+ GeneralizerState :: Default
805+ | GeneralizerState :: ShallowStructurallyRelateAliases
806+ | GeneralizerState :: StructurallyRelateAliases => { }
771807 }
772- GeneralizerState :: Default
773- | GeneralizerState :: ShallowStructurallyRelateAliases
774- | GeneralizerState :: StructurallyRelateAliases => { }
775808 }
776809 Ok ( ty:: Const :: new_var ( self . cx ( ) , new_var_id) )
777810 }
0 commit comments