@@ -13,9 +13,9 @@ use rustc_next_trait_solver::solve::{GenerateProofTree, SolverDelegateEvalExt as
13
13
use rustc_type_ir:: solve:: NoSolution ;
14
14
use tracing:: { instrument, trace} ;
15
15
16
- use crate :: solve:: Certainty ;
17
16
use crate :: solve:: delegate:: SolverDelegate ;
18
17
use crate :: solve:: inspect:: { self , ProofTreeInferCtxtExt , ProofTreeVisitor } ;
18
+ use crate :: solve:: { Certainty , deeply_normalize_for_diagnostics} ;
19
19
use crate :: traits:: { FulfillmentError , FulfillmentErrorCode , wf} ;
20
20
21
21
pub ( super ) fn fulfillment_error_for_no_solution < ' tcx > (
@@ -151,7 +151,7 @@ fn find_best_leaf_obligation<'tcx>(
151
151
//
152
152
// We should probably fix the visitor to not do so instead, as this also
153
153
// means the leaf obligation may be incorrect.
154
- infcx
154
+ let obligation = infcx
155
155
. fudge_inference_if_ok ( || {
156
156
infcx
157
157
. visit_proof_tree (
@@ -161,7 +161,8 @@ fn find_best_leaf_obligation<'tcx>(
161
161
. break_value ( )
162
162
. ok_or ( ( ) )
163
163
} )
164
- . unwrap_or ( obligation)
164
+ . unwrap_or ( obligation) ;
165
+ deeply_normalize_for_diagnostics ( infcx, obligation. param_env , obligation)
165
166
}
166
167
167
168
struct BestObligation < ' tcx > {
@@ -298,7 +299,7 @@ impl<'tcx> BestObligation<'tcx> {
298
299
/// `NormalizesTo` goal, so we don't fall back to the rigid projection check
299
300
/// that should catch when a projection goal fails due to an unsatisfied trait
300
301
/// goal.
301
- fn detect_error_in_higher_ranked_projection (
302
+ fn detect_trait_error_in_higher_ranked_projection (
302
303
& mut self ,
303
304
goal : & inspect:: InspectGoal < ' _ , ' tcx > ,
304
305
) -> ControlFlow < PredicateObligation < ' tcx > > {
@@ -307,7 +308,13 @@ impl<'tcx> BestObligation<'tcx> {
307
308
&& !projection_clause. bound_vars ( ) . is_empty ( )
308
309
{
309
310
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
+ let obligation = Obligation :: new (
312
+ tcx,
313
+ self . obligation . cause . clone ( ) ,
314
+ goal. goal ( ) . param_env ,
315
+ deeply_normalize_for_diagnostics ( goal. infcx ( ) , goal. goal ( ) . param_env , pred) ,
316
+ ) ;
317
+ self . with_derived_obligation ( obligation, |this| {
311
318
goal. infcx ( ) . visit_proof_tree_at_depth (
312
319
goal. goal ( ) . with ( tcx, pred) ,
313
320
goal. depth ( ) + 1 ,
@@ -388,7 +395,8 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
388
395
( true , Ok ( Certainty :: Maybe ( MaybeCause :: Ambiguity ) ) ) | ( false , Err ( _) ) => { }
389
396
_ => return ControlFlow :: Continue ( ( ) ) ,
390
397
}
391
- let pred_kind = goal. goal ( ) . predicate . kind ( ) ;
398
+
399
+ let pred = goal. goal ( ) . predicate ;
392
400
393
401
let candidates = self . non_trivial_candidates ( goal) ;
394
402
let candidate = match candidates. as_slice ( ) {
@@ -410,20 +418,20 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
410
418
411
419
// FIXME: Also, what about considering >1 layer up the stack? May be necessary
412
420
// for normalizes-to.
413
- let child_mode = match pred_kind . skip_binder ( ) {
414
- ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( pred ) ) => {
415
- ChildMode :: Trait ( pred_kind . rebind ( pred ) )
421
+ let child_mode = match pred . kind ( ) . skip_binder ( ) {
422
+ ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( trait_pred ) ) => {
423
+ ChildMode :: Trait ( pred . kind ( ) . rebind ( trait_pred ) )
416
424
}
417
- ty:: PredicateKind :: Clause ( ty:: ClauseKind :: HostEffect ( pred ) ) => {
418
- ChildMode :: Host ( pred_kind . rebind ( pred ) )
425
+ ty:: PredicateKind :: Clause ( ty:: ClauseKind :: HostEffect ( host_pred ) ) => {
426
+ ChildMode :: Host ( pred . kind ( ) . rebind ( host_pred ) )
419
427
}
420
428
ty:: PredicateKind :: NormalizesTo ( normalizes_to)
421
429
if matches ! (
422
430
normalizes_to. alias. kind( tcx) ,
423
431
ty:: AliasTermKind :: ProjectionTy | ty:: AliasTermKind :: ProjectionConst
424
432
) =>
425
433
{
426
- ChildMode :: Trait ( pred_kind . rebind ( ty:: TraitPredicate {
434
+ ChildMode :: Trait ( pred . kind ( ) . rebind ( ty:: TraitPredicate {
427
435
trait_ref : normalizes_to. alias . trait_ref ( tcx) ,
428
436
polarity : ty:: PredicatePolarity :: Positive ,
429
437
} ) )
@@ -457,10 +465,12 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
457
465
for nested_goal in nested_goals {
458
466
trace ! ( nested_goal = ?( nested_goal. goal( ) , nested_goal. source( ) , nested_goal. result( ) ) ) ;
459
467
468
+ let nested_pred = nested_goal. goal ( ) . predicate ;
469
+
460
470
let make_obligation = |cause| Obligation {
461
471
cause,
462
472
param_env : nested_goal. goal ( ) . param_env ,
463
- predicate : nested_goal . goal ( ) . predicate ,
473
+ predicate : nested_pred ,
464
474
recursion_depth : self . obligation . recursion_depth + 1 ,
465
475
} ;
466
476
@@ -510,31 +520,20 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
510
520
511
521
// alias-relate may fail because the lhs or rhs can't be normalized,
512
522
// and therefore is treated as rigid.
513
- if let Some ( ty:: PredicateKind :: AliasRelate ( lhs, rhs, _) ) = pred_kind. no_bound_vars ( ) {
514
- if let Some ( obligation) = goal
515
- . infcx ( )
516
- . visit_proof_tree_at_depth (
517
- goal. goal ( ) . with ( tcx, ty:: ClauseKind :: WellFormed ( lhs. into ( ) ) ) ,
518
- goal. depth ( ) + 1 ,
519
- self ,
520
- )
521
- . break_value ( )
522
- {
523
- return ControlFlow :: Break ( obligation) ;
524
- } else if let Some ( obligation) = goal
525
- . infcx ( )
526
- . visit_proof_tree_at_depth (
527
- goal. goal ( ) . with ( tcx, ty:: ClauseKind :: WellFormed ( rhs. into ( ) ) ) ,
528
- goal. depth ( ) + 1 ,
529
- self ,
530
- )
531
- . break_value ( )
532
- {
533
- return ControlFlow :: Break ( obligation) ;
534
- }
523
+ if let Some ( ty:: PredicateKind :: AliasRelate ( lhs, rhs, _) ) = pred. kind ( ) . no_bound_vars ( ) {
524
+ goal. infcx ( ) . visit_proof_tree_at_depth (
525
+ goal. goal ( ) . with ( tcx, ty:: ClauseKind :: WellFormed ( lhs. into ( ) ) ) ,
526
+ goal. depth ( ) + 1 ,
527
+ self ,
528
+ ) ?;
529
+ goal. infcx ( ) . visit_proof_tree_at_depth (
530
+ goal. goal ( ) . with ( tcx, ty:: ClauseKind :: WellFormed ( rhs. into ( ) ) ) ,
531
+ goal. depth ( ) + 1 ,
532
+ self ,
533
+ ) ?;
535
534
}
536
535
537
- self . detect_error_in_higher_ranked_projection ( goal) ?;
536
+ self . detect_trait_error_in_higher_ranked_projection ( goal) ?;
538
537
539
538
ControlFlow :: Break ( self . obligation . clone ( ) )
540
539
}
0 commit comments