@@ -291,6 +291,34 @@ impl<'tcx> BestObligation<'tcx> {
291291        } 
292292    } 
293293
294+     /// When a higher-ranked projection goal fails, check that the corresponding 
295+      /// higher-ranked trait goal holds or not. This is because the process of 
296+      /// instantiating and then re-canonicalizing the binder of the projection goal 
297+      /// forces us to be unable to see that the leak check failed in the nested 
298+      /// `NormalizesTo` goal, so we don't fall back to the rigid projection check 
299+      /// that should catch when a projection goal fails due to an unsatisfied trait 
300+      /// goal. 
301+      fn  detect_error_in_higher_ranked_projection ( 
302+         & mut  self , 
303+         goal :  & inspect:: InspectGoal < ' _ ,  ' tcx > , 
304+     )  -> ControlFlow < PredicateObligation < ' tcx > >  { 
305+         let  tcx = goal. infcx ( ) . tcx ; 
306+         if  let  Some ( projection_clause)  = goal. goal ( ) . predicate . as_projection_clause ( ) 
307+             && !projection_clause. bound_vars ( ) . is_empty ( ) 
308+         { 
309+             let  pred = projection_clause. map_bound ( |proj| proj. projection_term . trait_ref ( tcx) ) ; 
310+             self . with_derived_obligation ( self . obligation . with ( tcx,  pred) ,  |this| { 
311+                 goal. infcx ( ) . visit_proof_tree_at_depth ( 
312+                     goal. goal ( ) . with ( tcx,  pred) , 
313+                     goal. depth ( )  + 1 , 
314+                     this, 
315+                 ) 
316+             } ) 
317+         }  else  { 
318+             ControlFlow :: Continue ( ( ) ) 
319+         } 
320+     } 
321+ 
294322    /// It is likely that `NormalizesTo` failed without any applicable candidates 
295323     /// because the alias is not well-formed. 
296324     /// 
@@ -374,7 +402,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
374402            source :  CandidateSource :: Impl ( impl_def_id) , 
375403            result :  _, 
376404        }  = candidate. kind ( ) 
377-             && goal . infcx ( ) . tcx . do_not_recommend_impl ( impl_def_id) 
405+             && tcx. do_not_recommend_impl ( impl_def_id) 
378406        { 
379407            trace ! ( "#[do_not_recommend] -> exit" ) ; 
380408            return  ControlFlow :: Break ( self . obligation . clone ( ) ) ; 
@@ -486,7 +514,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
486514            if  let  Some ( obligation)  = goal
487515                . infcx ( ) 
488516                . visit_proof_tree_at_depth ( 
489-                     goal. goal ( ) . with ( goal . infcx ( ) . tcx ,  ty:: ClauseKind :: WellFormed ( lhs. into ( ) ) ) , 
517+                     goal. goal ( ) . with ( tcx,  ty:: ClauseKind :: WellFormed ( lhs. into ( ) ) ) , 
490518                    goal. depth ( )  + 1 , 
491519                    self , 
492520                ) 
@@ -496,7 +524,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
496524            }  else  if  let  Some ( obligation)  = goal
497525                . infcx ( ) 
498526                . visit_proof_tree_at_depth ( 
499-                     goal. goal ( ) . with ( goal . infcx ( ) . tcx ,  ty:: ClauseKind :: WellFormed ( rhs. into ( ) ) ) , 
527+                     goal. goal ( ) . with ( tcx,  ty:: ClauseKind :: WellFormed ( rhs. into ( ) ) ) , 
500528                    goal. depth ( )  + 1 , 
501529                    self , 
502530                ) 
@@ -506,6 +534,8 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
506534            } 
507535        } 
508536
537+         self . detect_error_in_higher_ranked_projection ( goal) ?; 
538+ 
509539        ControlFlow :: Break ( self . obligation . clone ( ) ) 
510540    } 
511541} 
0 commit comments