@@ -608,8 +608,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
608608
609609 /// Is the projection predicate is of the form `exists<T> <Ty as Trait>::Assoc = T`.
610610 ///
611- /// This is the case if the `term` is an inference variable in the innermost universe
612- /// and does not occur in any other part of the predicate .
611+ /// This is the case if the `term` does not occur in any other part of the predicate
612+ /// and is able to name all other placeholder and inference variables .
613613 #[ instrument( level = "debug" , skip( self ) , ret) ]
614614 pub ( super ) fn term_is_fully_unconstrained (
615615 & self ,
@@ -632,55 +632,67 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
632632 }
633633 } ;
634634
635- // Guard against `<T as Trait<?0>>::Assoc = ?0>`.
636635 struct ContainsTermOrNotNameable < ' a , ' tcx > {
637636 term : ty:: Term < ' tcx > ,
638637 universe_of_term : ty:: UniverseIndex ,
639638 infcx : & ' a InferCtxt < ' tcx > ,
640639 }
640+
641+ impl < ' a , ' tcx > ContainsTermOrNotNameable < ' a , ' tcx > {
642+ fn check_nameable ( & self , universe : ty:: UniverseIndex ) -> ControlFlow < ( ) > {
643+ if self . universe_of_term . can_name ( universe) {
644+ ControlFlow :: Continue ( ( ) )
645+ } else {
646+ ControlFlow :: Break ( ( ) )
647+ }
648+ }
649+ }
650+
641651 impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for ContainsTermOrNotNameable < ' _ , ' tcx > {
642652 type BreakTy = ( ) ;
643653 fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
644- if let Some ( vid) = t. ty_vid ( ) {
645- if let ty:: TermKind :: Ty ( term) = self . term . unpack ( )
646- && let Some ( term_vid) = term. ty_vid ( )
647- && self . infcx . root_var ( vid) == self . infcx . root_var ( term_vid)
648- {
649- ControlFlow :: Break ( ( ) )
650- } else if self
651- . universe_of_term
652- . cannot_name ( self . infcx . universe_of_ty ( vid) . unwrap ( ) )
653- {
654- ControlFlow :: Break ( ( ) )
655- } else {
656- ControlFlow :: Continue ( ( ) )
654+ match * t. kind ( ) {
655+ ty:: Infer ( ty:: TyVar ( vid) ) => {
656+ if let ty:: TermKind :: Ty ( term) = self . term . unpack ( )
657+ && let Some ( term_vid) = term. ty_vid ( )
658+ && self . infcx . root_var ( vid) == self . infcx . root_var ( term_vid)
659+ {
660+ ControlFlow :: Break ( ( ) )
661+ } else {
662+ self . check_nameable ( self . infcx . universe_of_ty ( vid) . unwrap ( ) )
663+ }
664+ }
665+ ty:: Placeholder ( p) => self . check_nameable ( p. universe ) ,
666+ _ => {
667+ if t. has_non_region_infer ( ) || t. has_placeholders ( ) {
668+ t. super_visit_with ( self )
669+ } else {
670+ ControlFlow :: Continue ( ( ) )
671+ }
657672 }
658- } else if t. has_non_region_infer ( ) {
659- t. super_visit_with ( self )
660- } else {
661- ControlFlow :: Continue ( ( ) )
662673 }
663674 }
664675
665676 fn visit_const ( & mut self , c : ty:: Const < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
666- if let ty:: ConstKind :: Infer ( ty:: InferConst :: Var ( vid) ) = c. kind ( ) {
667- if let ty:: TermKind :: Const ( term) = self . term . unpack ( )
668- && let ty:: ConstKind :: Infer ( ty:: InferConst :: Var ( term_vid) ) = term. kind ( )
669- && self . infcx . root_const_var ( vid) == self . infcx . root_const_var ( term_vid)
670- {
671- ControlFlow :: Break ( ( ) )
672- } else if self
673- . universe_of_term
674- . cannot_name ( self . infcx . universe_of_ct ( vid) . unwrap ( ) )
675- {
676- ControlFlow :: Break ( ( ) )
677- } else {
678- ControlFlow :: Continue ( ( ) )
677+ match c. kind ( ) {
678+ ty:: ConstKind :: Infer ( ty:: InferConst :: Var ( vid) ) => {
679+ if let ty:: TermKind :: Const ( term) = self . term . unpack ( )
680+ && let ty:: ConstKind :: Infer ( ty:: InferConst :: Var ( term_vid) ) = term. kind ( )
681+ && self . infcx . root_const_var ( vid) == self . infcx . root_const_var ( term_vid)
682+ {
683+ ControlFlow :: Break ( ( ) )
684+ } else {
685+ self . check_nameable ( self . infcx . universe_of_ct ( vid) . unwrap ( ) )
686+ }
687+ }
688+ ty:: ConstKind :: Placeholder ( p) => self . check_nameable ( p. universe ) ,
689+ _ => {
690+ if c. has_non_region_infer ( ) || c. has_placeholders ( ) {
691+ c. super_visit_with ( self )
692+ } else {
693+ ControlFlow :: Continue ( ( ) )
694+ }
679695 }
680- } else if c. has_non_region_infer ( ) {
681- c. super_visit_with ( self )
682- } else {
683- ControlFlow :: Continue ( ( ) )
684696 }
685697 }
686698 }
0 commit comments