@@ -548,7 +548,27 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
548
548
goal : Goal < ' tcx , G > ,
549
549
candidates : & mut Vec < Candidate < ' tcx > > ,
550
550
) {
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 ( ) {
552
572
ty:: Bool
553
573
| ty:: Char
554
574
| ty:: Int ( _)
@@ -573,23 +593,56 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
573
593
| ty:: Param ( _)
574
594
| ty:: Placeholder ( ..)
575
595
| ty:: Infer ( ty:: IntVar ( _) | ty:: FloatVar ( _) )
576
- | ty:: Alias ( ty:: Inherent , _)
577
- | ty:: Alias ( ty:: Weak , _)
578
596
| 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
+ }
583
617
} ;
584
618
585
619
for assumption in
586
620
self . tcx ( ) . item_bounds ( alias_ty. def_id ) . instantiate ( self . tcx ( ) , alias_ty. args )
587
621
{
588
622
match G :: consider_alias_bound_candidate ( self , goal, assumption) {
589
623
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 } ) ;
591
645
}
592
- Err ( NoSolution ) => ( ) ,
593
646
}
594
647
}
595
648
}
0 commit comments