@@ -139,6 +139,7 @@ pub(super) fn fulfillment_error_for_overflow<'tcx>(
139139 }
140140}
141141
142+ #[ instrument( level = "debug" , skip( infcx) , ret) ]
142143fn find_best_leaf_obligation < ' tcx > (
143144 infcx : & InferCtxt < ' tcx > ,
144145 obligation : & PredicateObligation < ' tcx > ,
@@ -211,11 +212,7 @@ impl<'tcx> BestObligation<'tcx> {
211212 | GoalSource :: AliasBoundConstCondition
212213 | GoalSource :: InstantiateHigherRanked
213214 | GoalSource :: AliasWellFormed
214- ) && match ( self . consider_ambiguities , nested_goal. result ( ) ) {
215- ( true , Ok ( Certainty :: Maybe ( MaybeCause :: Ambiguity ) ) )
216- | ( false , Err ( _) ) => true ,
217- _ => false ,
218- }
215+ ) && nested_goal. result ( ) . is_err ( )
219216 } ,
220217 )
221218 } )
@@ -277,11 +274,37 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
277274
278275 #[ instrument( level = "trace" , skip( self , goal) , fields( goal = ?goal. goal( ) ) ) ]
279276 fn visit_goal ( & mut self , goal : & inspect:: InspectGoal < ' _ , ' tcx > ) -> Self :: Result {
277+ let tcx = goal. infcx ( ) . tcx ;
278+ let pred_kind = goal. goal ( ) . predicate . kind ( ) ;
279+
280280 let candidates = self . non_trivial_candidates ( goal) ;
281- trace ! ( candidates = ?candidates. iter( ) . map( |c| c. kind( ) ) . collect:: <Vec <_>>( ) ) ;
281+ let candidate = match candidates. as_slice ( ) {
282+ [ ] => {
283+ // Similar to `AliasRelate` goals, `NormalizesTo` may fail because the
284+ // used alias is not well-formed. We only enter an actual `RigidAlias`
285+ // candidate if its trait bound was proven via the environment. We therefore
286+ // manually check whether the alias is even well-formed here.
287+ if let Some ( ty:: PredicateKind :: NormalizesTo ( pred) ) = pred_kind. no_bound_vars ( ) {
288+ if let Some ( obligation) = goal
289+ . infcx ( )
290+ . visit_proof_tree_at_depth (
291+ goal. goal ( ) . with (
292+ goal. infcx ( ) . tcx ,
293+ ty:: ClauseKind :: WellFormed ( pred. alias . to_term ( tcx) . into ( ) ) ,
294+ ) ,
295+ goal. depth ( ) + 1 ,
296+ self ,
297+ )
298+ . break_value ( )
299+ {
300+ return ControlFlow :: Break ( obligation) ;
301+ }
302+ }
282303
283- let [ candidate] = candidates. as_slice ( ) else {
284- return ControlFlow :: Break ( self . obligation . clone ( ) ) ;
304+ return ControlFlow :: Break ( self . obligation . clone ( ) ) ;
305+ }
306+ [ candidate] => candidate,
307+ _ => return ControlFlow :: Break ( self . obligation . clone ( ) ) ,
285308 } ;
286309
287310 // Don't walk into impls that have `do_not_recommend`.
@@ -291,13 +314,12 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
291314 } = candidate. kind ( )
292315 && goal. infcx ( ) . tcx . do_not_recommend_impl ( impl_def_id)
293316 {
317+ trace ! ( "#[do_not_recommend] -> exit" ) ;
294318 return ControlFlow :: Break ( self . obligation . clone ( ) ) ;
295319 }
296320
297- let tcx = goal. infcx ( ) . tcx ;
298321 // FIXME: Also, what about considering >1 layer up the stack? May be necessary
299322 // for normalizes-to.
300- let pred_kind = goal. goal ( ) . predicate . kind ( ) ;
301323 let child_mode = match pred_kind. skip_binder ( ) {
302324 ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( pred) ) => {
303325 ChildMode :: Trait ( pred_kind. rebind ( pred) )
0 commit comments