@@ -11,7 +11,7 @@ use rustc_middle::ty::{self, TyCtxt};
1111use rustc_middle:: { bug, span_bug} ;
1212use rustc_next_trait_solver:: solve:: { GenerateProofTree , SolverDelegateEvalExt as _} ;
1313use rustc_type_ir:: solve:: { Goal , NoSolution } ;
14- use tracing:: { instrument, trace} ;
14+ use tracing:: { debug , instrument, trace} ;
1515
1616use crate :: solve:: Certainty ;
1717use crate :: solve:: delegate:: SolverDelegate ;
@@ -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 > ,
@@ -189,6 +190,7 @@ impl<'tcx> BestObligation<'tcx> {
189190 goal : & ' a inspect:: InspectGoal < ' a , ' tcx > ,
190191 ) -> Vec < inspect:: InspectCandidate < ' a , ' tcx > > {
191192 let mut candidates = goal. candidates ( ) ;
193+ debug ! ( candidates = ?candidates. iter( ) . map( |c| ( c. kind( ) , c. result( ) ) ) . collect:: <Vec <_>>( ) ) ;
192194 match self . consider_ambiguities {
193195 true => {
194196 // If we have an ambiguous obligation, we must consider *all* candidates
@@ -211,11 +213,7 @@ impl<'tcx> BestObligation<'tcx> {
211213 | GoalSource :: AliasBoundConstCondition
212214 | GoalSource :: InstantiateHigherRanked
213215 | GoalSource :: AliasWellFormed
214- ) && match ( self . consider_ambiguities , nested_goal. result ( ) ) {
215- ( true , Ok ( Certainty :: Maybe ( MaybeCause :: Ambiguity ) ) )
216- | ( false , Err ( _) ) => true ,
217- _ => false ,
218- }
216+ ) && nested_goal. result ( ) . is_err ( )
219217 } ,
220218 )
221219 } )
@@ -277,11 +275,37 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
277275
278276 #[ instrument( level = "trace" , skip( self , goal) , fields( goal = ?goal. goal( ) ) ) ]
279277 fn visit_goal ( & mut self , goal : & inspect:: InspectGoal < ' _ , ' tcx > ) -> Self :: Result {
278+ let tcx = goal. infcx ( ) . tcx ;
279+ let pred_kind = goal. goal ( ) . predicate . kind ( ) ;
280+
280281 let candidates = self . non_trivial_candidates ( goal) ;
281- trace ! ( candidates = ?candidates. iter( ) . map( |c| c. kind( ) ) . collect:: <Vec <_>>( ) ) ;
282+ let candidate = match candidates. as_slice ( ) {
283+ [ ] => {
284+ // Similar to `AliasRelate` goals, `NormalizesTo` may fail because the
285+ // used alias is not well-formed. We only enter an actual `RigidAlias`
286+ // candidate if its trait bound was proven via the environment. We therefore
287+ // manually check whether the alias is even well-formed here.
288+ if let Some ( ty:: PredicateKind :: NormalizesTo ( pred) ) = pred_kind. no_bound_vars ( ) {
289+ if let Some ( obligation) = goal
290+ . infcx ( )
291+ . visit_proof_tree_at_depth (
292+ goal. goal ( ) . with (
293+ goal. infcx ( ) . tcx ,
294+ ty:: ClauseKind :: WellFormed ( pred. alias . to_term ( tcx) . into ( ) ) ,
295+ ) ,
296+ goal. depth ( ) + 1 ,
297+ self ,
298+ )
299+ . break_value ( )
300+ {
301+ return ControlFlow :: Break ( obligation) ;
302+ }
303+ }
282304
283- let [ candidate] = candidates. as_slice ( ) else {
284- return ControlFlow :: Break ( self . obligation . clone ( ) ) ;
305+ return ControlFlow :: Break ( self . obligation . clone ( ) ) ;
306+ }
307+ [ candidate] => candidate,
308+ _ => return ControlFlow :: Break ( self . obligation . clone ( ) ) ,
285309 } ;
286310
287311 // Don't walk into impls that have `do_not_recommend`.
@@ -291,13 +315,12 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
291315 } = candidate. kind ( )
292316 && goal. infcx ( ) . tcx . do_not_recommend_impl ( impl_def_id)
293317 {
318+ trace ! ( "#[do_not_recommend] -> exit" ) ;
294319 return ControlFlow :: Break ( self . obligation . clone ( ) ) ;
295320 }
296321
297- let tcx = goal. infcx ( ) . tcx ;
298322 // FIXME: Also, what about considering >1 layer up the stack? May be necessary
299323 // for normalizes-to.
300- let pred_kind = goal. goal ( ) . predicate . kind ( ) ;
301324 let child_mode = match pred_kind. skip_binder ( ) {
302325 ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( pred) ) => {
303326 ChildMode :: Trait ( pred_kind. rebind ( pred) )
0 commit comments