1111
1212use std:: assert_matches:: assert_matches;
1313
14- use rustc_infer:: infer:: { DefineOpaqueTypes , InferCtxt , InferOk } ;
14+ use rustc_infer:: infer:: InferCtxt ;
15+ use rustc_infer:: traits:: Obligation ;
1516use rustc_macros:: extension;
1617use rustc_middle:: traits:: ObligationCause ;
1718use rustc_middle:: traits:: solve:: { Certainty , Goal , GoalSource , NoSolution , QueryResult } ;
@@ -20,7 +21,7 @@ use rustc_middle::{bug, ty};
2021use rustc_next_trait_solver:: resolve:: eager_resolve_vars;
2122use rustc_next_trait_solver:: solve:: inspect:: { self , instantiate_canonical_state} ;
2223use rustc_next_trait_solver:: solve:: { GenerateProofTree , MaybeCause , SolverDelegateEvalExt as _} ;
23- use rustc_span:: { DUMMY_SP , Span } ;
24+ use rustc_span:: Span ;
2425use tracing:: instrument;
2526
2627use crate :: solve:: delegate:: SolverDelegate ;
@@ -60,28 +61,29 @@ impl<'tcx> NormalizesToTermHack<'tcx> {
6061 /// Relate the `term` with the new `unconstrained_term` created
6162 /// when computing the proof tree for this `NormalizesTo` goals.
6263 /// This handles nested obligations.
63- fn constrain (
64- self ,
64+ fn constrain_and (
65+ & self ,
6566 infcx : & InferCtxt < ' tcx > ,
6667 span : Span ,
6768 param_env : ty:: ParamEnv < ' tcx > ,
69+ f : impl FnOnce ( & ObligationCtxt < ' _ , ' tcx > ) ,
6870 ) -> Result < Certainty , NoSolution > {
69- infcx
70- . at ( & ObligationCause :: dummy_with_span ( span ) , param_env )
71- . eq ( DefineOpaqueTypes :: Yes , self . term , self . unconstrained_term )
72- . map_err ( |_| NoSolution )
73- . and_then ( | InferOk { value : ( ) , obligations } | {
74- let ocx = ObligationCtxt :: new ( infcx ) ;
75- ocx . register_obligations ( obligations ) ;
76- let errors = ocx . select_all_or_error ( ) ;
77- if errors . is_empty ( ) {
78- Ok ( Certainty :: Yes )
79- } else if errors . iter ( ) . all ( |e| !e . is_true_error ( ) ) {
80- Ok ( Certainty :: AMBIGUOUS )
81- } else {
82- Err ( NoSolution )
83- }
84- } )
71+ let ocx = ObligationCtxt :: new ( infcx) ;
72+ ocx . eq (
73+ & ObligationCause :: dummy_with_span ( span ) ,
74+ param_env ,
75+ self . term ,
76+ self . unconstrained_term ,
77+ ) ? ;
78+ f ( & ocx ) ;
79+ let errors = ocx . select_all_or_error ( ) ;
80+ if errors . is_empty ( ) {
81+ Ok ( Certainty :: Yes )
82+ } else if errors . iter ( ) . all ( |e| !e . is_true_error ( ) ) {
83+ Ok ( Certainty :: AMBIGUOUS )
84+ } else {
85+ Err ( NoSolution )
86+ }
8587 }
8688}
8789
@@ -180,11 +182,11 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
180182 let ( ) =
181183 instantiate_canonical_state ( infcx, span, param_env, & mut orig_values, self . final_state ) ;
182184
183- if let Some ( term_hack) = self . goal . normalizes_to_term_hack {
185+ if let Some ( term_hack) = & self . goal . normalizes_to_term_hack {
184186 // FIXME: We ignore the expected term of `NormalizesTo` goals
185187 // when computing the result of its candidates. This is
186188 // scuffed.
187- let _ = term_hack. constrain ( infcx, span, param_env) ;
189+ let _ = term_hack. constrain_and ( infcx, span, param_env, |_| { } ) ;
188190 }
189191
190192 let opt_impl_args = opt_impl_args. map ( |impl_args| eager_resolve_vars ( infcx, impl_args) ) ;
@@ -218,13 +220,35 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
218220 // building their proof tree, the expected term was unconstrained, but when
219221 // instantiating the candidate it is already constrained to the result of another
220222 // candidate.
221- let proof_tree = infcx
222- . probe ( |_| infcx. evaluate_root_goal_raw ( goal, GenerateProofTree :: Yes , None ) . 1 ) ;
223+ let normalizes_to_term_hack = NormalizesToTermHack { term, unconstrained_term } ;
224+ let ( proof_tree, nested_goals_result) = infcx. probe ( |_| {
225+ let ( w, proof_tree) =
226+ infcx. evaluate_root_goal_raw ( goal, GenerateProofTree :: Yes , None ) ;
227+ let proof_tree = proof_tree. unwrap ( ) ;
228+ let nested_goals_result = w. and_then ( |( nested, _) | {
229+ normalizes_to_term_hack. constrain_and (
230+ infcx,
231+ span,
232+ proof_tree. uncanonicalized_goal . param_env ,
233+ |ocx| {
234+ ocx. register_obligations ( nested. 0 . into_iter ( ) . map ( |( _, goal) | {
235+ Obligation :: new (
236+ infcx. tcx ,
237+ ObligationCause :: dummy_with_span ( span) ,
238+ goal. param_env ,
239+ goal. predicate ,
240+ )
241+ } ) ) ;
242+ } ,
243+ )
244+ } ) ;
245+ ( proof_tree, nested_goals_result)
246+ } ) ;
223247 InspectGoal :: new (
224248 infcx,
225249 self . goal . depth + 1 ,
226- proof_tree. unwrap ( ) ,
227- Some ( NormalizesToTermHack { term , unconstrained_term } ) ,
250+ proof_tree,
251+ Some ( ( normalizes_to_term_hack , nested_goals_result ) ) ,
228252 source,
229253 )
230254 }
@@ -371,20 +395,19 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
371395 infcx : & ' a InferCtxt < ' tcx > ,
372396 depth : usize ,
373397 root : inspect:: GoalEvaluation < TyCtxt < ' tcx > > ,
374- normalizes_to_term_hack : Option < NormalizesToTermHack < ' tcx > > ,
398+ term_hack_and_nested_certainty : Option < (
399+ NormalizesToTermHack < ' tcx > ,
400+ Result < Certainty , NoSolution > ,
401+ ) > ,
375402 source : GoalSource ,
376403 ) -> Self {
377404 let infcx = <& SolverDelegate < ' tcx > >:: from ( infcx) ;
378405
379406 let inspect:: GoalEvaluation { uncanonicalized_goal, orig_values, evaluation } = root;
380407 let result = evaluation. result . and_then ( |ok| {
381- if let Some ( term_hack) = normalizes_to_term_hack {
382- infcx
383- . probe ( |_| term_hack. constrain ( infcx, DUMMY_SP , uncanonicalized_goal. param_env ) )
384- . map ( |certainty| ok. value . certainty . and ( certainty) )
385- } else {
386- Ok ( ok. value . certainty )
387- }
408+ let nested_goals_certainty =
409+ term_hack_and_nested_certainty. map_or ( Ok ( Certainty :: Yes ) , |( _, c) | c) ?;
410+ Ok ( ok. value . certainty . and ( nested_goals_certainty) )
388411 } ) ;
389412
390413 InspectGoal {
@@ -394,7 +417,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
394417 goal : eager_resolve_vars ( infcx, uncanonicalized_goal) ,
395418 result,
396419 evaluation_kind : evaluation. kind ,
397- normalizes_to_term_hack,
420+ normalizes_to_term_hack : term_hack_and_nested_certainty . map ( | ( n , _ ) | n ) ,
398421 source,
399422 }
400423 }
0 commit comments