@@ -548,7 +548,27 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
548548 goal : Goal < ' tcx , G > ,
549549 candidates : & mut Vec < Candidate < ' tcx > > ,
550550 ) {
551- let alias_ty = match goal. predicate . self_ty ( ) . kind ( ) {
551+ let ( ) = self . probe ( |_| ProbeKind :: NormalizedSelfTyAssembly ) . enter ( |ecx| {
552+ ecx. assemble_alias_bound_candidates_recur ( goal. predicate . self_ty ( ) , goal, candidates) ;
553+ } ) ;
554+ }
555+
556+ /// For some deeply nested `<T>::A::B::C::D` rigid associated type,
557+ /// we should explore the item bounds for all levels, since the
558+ /// `associated_type_bounds` feature means that a parent associated
559+ /// type may carry bounds for a nested associated type.
560+ ///
561+ /// If we have a projection, check that its self type is a rigid projection.
562+ /// If so, continue searching by recursively calling after normalization.
563+ // FIXME: This may recurse infinitely, but I can't seem to trigger it without
564+ // hitting another overflow error something. Add a depth parameter needed later.
565+ fn assemble_alias_bound_candidates_recur < G : GoalKind < ' tcx > > (
566+ & mut self ,
567+ self_ty : Ty < ' tcx > ,
568+ goal : Goal < ' tcx , G > ,
569+ candidates : & mut Vec < Candidate < ' tcx > > ,
570+ ) {
571+ let ( kind, alias_ty) = match * self_ty. kind ( ) {
552572 ty:: Bool
553573 | ty:: Char
554574 | ty:: Int ( _)
@@ -573,23 +593,56 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
573593 | ty:: Param ( _)
574594 | ty:: Placeholder ( ..)
575595 | ty:: Infer ( ty:: IntVar ( _) | ty:: FloatVar ( _) )
576- | ty:: Alias ( ty:: Inherent , _)
577- | ty:: Alias ( ty:: Weak , _)
578596 | ty:: Error ( _) => return ,
579- ty:: Infer ( ty:: TyVar ( _) | ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) )
580- | ty:: Bound ( ..) => bug ! ( "unexpected self type for `{goal:?}`" ) ,
581- // Excluding IATs and type aliases here as they don't have meaningful item bounds.
582- ty:: Alias ( ty:: Projection | ty:: Opaque , alias_ty) => alias_ty,
597+ ty:: Infer ( ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) ) | ty:: Bound ( ..) => {
598+ bug ! ( "unexpected self type for `{goal:?}`" )
599+ }
600+
601+ ty:: Infer ( ty:: TyVar ( _) ) => {
602+ // If we hit infer when normalizing the self type of an alias,
603+ // then bail with ambiguity. We should never encounter this on
604+ // the *first* iteration of this recursive function.
605+ if let Ok ( result) =
606+ self . evaluate_added_goals_and_make_canonical_response ( Certainty :: AMBIGUOUS )
607+ {
608+ candidates. push ( Candidate { source : CandidateSource :: AliasBound , result } ) ;
609+ }
610+ return ;
611+ }
612+
613+ ty:: Alias ( kind @ ( ty:: Projection | ty:: Opaque ) , alias_ty) => ( kind, alias_ty) ,
614+ ty:: Alias ( ty:: Inherent | ty:: Weak , _) => {
615+ unreachable ! ( "Weak and Inherent aliases should have been normalized away already" )
616+ }
583617 } ;
584618
585619 for assumption in
586620 self . tcx ( ) . item_bounds ( alias_ty. def_id ) . instantiate ( self . tcx ( ) , alias_ty. args )
587621 {
588622 match G :: consider_alias_bound_candidate ( self , goal, assumption) {
589623 Ok ( result) => {
590- candidates. push ( Candidate { source : CandidateSource :: AliasBound , result } )
624+ candidates. push ( Candidate { source : CandidateSource :: AliasBound , result } ) ;
625+ }
626+ Err ( NoSolution ) => { }
627+ }
628+ }
629+
630+ if kind != ty:: Projection {
631+ return ;
632+ }
633+
634+ match self . try_normalize_ty ( goal. param_env , alias_ty. self_ty ( ) ) {
635+ // Recurse on the self type of the projection.
636+ Some ( next_self_ty) => {
637+ self . assemble_alias_bound_candidates_recur ( next_self_ty, goal, candidates) ;
638+ }
639+ // Bail if we overflow when normalizing, adding an ambiguous candidate.
640+ None => {
641+ if let Ok ( result) =
642+ self . evaluate_added_goals_and_make_canonical_response ( Certainty :: OVERFLOW )
643+ {
644+ candidates. push ( Candidate { source : CandidateSource :: AliasBound , result } ) ;
591645 }
592- Err ( NoSolution ) => ( ) ,
593646 }
594647 }
595648 }
0 commit comments