@@ -10,13 +10,13 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError};
10
10
use rustc_middle:: ty:: { self , TyCtxt } ;
11
11
use rustc_middle:: { bug, span_bug} ;
12
12
use rustc_next_trait_solver:: solve:: { GenerateProofTree , SolverDelegateEvalExt as _} ;
13
- use rustc_type_ir:: solve:: NoSolution ;
13
+ use rustc_type_ir:: solve:: { Goal , NoSolution } ;
14
14
use tracing:: { instrument, trace} ;
15
15
16
16
use crate :: solve:: Certainty ;
17
17
use crate :: solve:: delegate:: SolverDelegate ;
18
18
use crate :: solve:: inspect:: { self , ProofTreeInferCtxtExt , ProofTreeVisitor } ;
19
- use crate :: traits:: { FulfillmentError , FulfillmentErrorCode } ;
19
+ use crate :: traits:: { FulfillmentError , FulfillmentErrorCode , wf } ;
20
20
21
21
pub ( super ) fn fulfillment_error_for_no_solution < ' tcx > (
22
22
infcx : & InferCtxt < ' tcx > ,
@@ -207,14 +207,10 @@ impl<'tcx> BestObligation<'tcx> {
207
207
| GoalSource :: AliasBoundConstCondition
208
208
| GoalSource :: InstantiateHigherRanked
209
209
| GoalSource :: AliasWellFormed
210
- ) && match self . consider_ambiguities {
211
- true => {
212
- matches ! (
213
- nested_goal. result( ) ,
214
- Ok ( Certainty :: Maybe ( MaybeCause :: Ambiguity ) )
215
- )
216
- }
217
- false => matches ! ( nested_goal. result( ) , Err ( _) ) ,
210
+ ) && match ( self . consider_ambiguities , nested_goal. result ( ) ) {
211
+ ( true , Ok ( Certainty :: Maybe ( MaybeCause :: Ambiguity ) ) )
212
+ | ( false , Err ( _) ) => true ,
213
+ _ => false ,
218
214
}
219
215
} ,
220
216
)
@@ -233,6 +229,39 @@ impl<'tcx> BestObligation<'tcx> {
233
229
234
230
candidates
235
231
}
232
+
233
+ /// HACK: We walk the nested obligations for a well-formed arg manually,
234
+ /// since there's nontrivial logic in `wf.rs` to set up an obligation cause.
235
+ /// Ideally we'd be able to track this better.
236
+ fn visit_well_formed_goal (
237
+ & mut self ,
238
+ candidate : & inspect:: InspectCandidate < ' _ , ' tcx > ,
239
+ arg : ty:: GenericArg < ' tcx > ,
240
+ ) -> ControlFlow < PredicateObligation < ' tcx > > {
241
+ let infcx = candidate. goal ( ) . infcx ( ) ;
242
+ let param_env = candidate. goal ( ) . goal ( ) . param_env ;
243
+ let body_id = self . obligation . cause . body_id ;
244
+
245
+ for obligation in wf:: unnormalized_obligations ( infcx, param_env, arg, self . span ( ) , body_id)
246
+ . into_iter ( )
247
+ . flatten ( )
248
+ {
249
+ let nested_goal = candidate. instantiate_proof_tree_for_nested_goal (
250
+ GoalSource :: Misc ,
251
+ Goal :: new ( infcx. tcx , obligation. param_env , obligation. predicate ) ,
252
+ self . span ( ) ,
253
+ ) ;
254
+ // Skip nested goals that aren't the *reason* for our goal's failure.
255
+ match ( self . consider_ambiguities , nested_goal. result ( ) ) {
256
+ ( true , Ok ( Certainty :: Maybe ( MaybeCause :: Ambiguity ) ) ) | ( false , Err ( _) ) => { }
257
+ _ => continue ,
258
+ }
259
+
260
+ self . with_derived_obligation ( obligation, |this| nested_goal. visit_with ( this) ) ?;
261
+ }
262
+
263
+ ControlFlow :: Break ( self . obligation . clone ( ) )
264
+ }
236
265
}
237
266
238
267
impl < ' tcx > ProofTreeVisitor < ' tcx > for BestObligation < ' tcx > {
@@ -283,6 +312,9 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
283
312
polarity : ty:: PredicatePolarity :: Positive ,
284
313
} ) )
285
314
}
315
+ ty:: PredicateKind :: Clause ( ty:: ClauseKind :: WellFormed ( arg) ) => {
316
+ return self . visit_well_formed_goal ( candidate, arg) ;
317
+ }
286
318
_ => ChildMode :: PassThrough ,
287
319
} ;
288
320
@@ -355,12 +387,8 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
355
387
}
356
388
357
389
// Skip nested goals that aren't the *reason* for our goal's failure.
358
- match self . consider_ambiguities {
359
- true if matches ! (
360
- nested_goal. result( ) ,
361
- Ok ( Certainty :: Maybe ( MaybeCause :: Ambiguity ) )
362
- ) => { }
363
- false if matches ! ( nested_goal. result( ) , Err ( _) ) => { }
390
+ match ( self . consider_ambiguities , nested_goal. result ( ) ) {
391
+ ( true , Ok ( Certainty :: Maybe ( MaybeCause :: Ambiguity ) ) ) | ( false , Err ( _) ) => { }
364
392
_ => continue ,
365
393
}
366
394
0 commit comments