@@ -34,9 +34,9 @@ pub struct InspectConfig {
3434pub struct InspectGoal < ' a , ' tcx > {
3535 infcx : & ' a InferCtxt < ' tcx > ,
3636 depth : usize ,
37- orig_values : & ' a [ ty:: GenericArg < ' tcx > ] ,
37+ orig_values : Vec < ty:: GenericArg < ' tcx > > ,
3838 goal : Goal < ' tcx , ty:: Predicate < ' tcx > > ,
39- evaluation : & ' a inspect:: GoalEvaluation < ' tcx > ,
39+ evaluation : inspect:: CanonicalGoalEvaluation < ' tcx > ,
4040}
4141
4242pub struct InspectCandidate < ' a , ' tcx > {
@@ -57,6 +57,10 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
5757 self . result . map ( |c| c. value . certainty )
5858 }
5959
60+ pub fn goal ( & self ) -> & ' a InspectGoal < ' a , ' tcx > {
61+ self . goal
62+ }
63+
6064 /// Certainty passed into `evaluate_added_goals_and_make_canonical_response`.
6165 ///
6266 /// If this certainty is `Yes`, then we must be confident that the candidate
@@ -74,46 +78,55 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
7478 /// the state of the `infcx`.
7579 pub fn visit_nested_no_probe < V : ProofTreeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> V :: Result {
7680 if self . goal . depth < visitor. config ( ) . max_depth {
77- let infcx = self . goal . infcx ;
78- let param_env = self . goal . goal . param_env ;
79- let mut orig_values = self . goal . orig_values . to_vec ( ) ;
80- let mut instantiated_goals = vec ! [ ] ;
81- for goal in & self . nested_goals {
82- let goal = canonical:: instantiate_canonical_state (
81+ for goal in self . instantiate_nested_goals ( visitor. span ( ) ) {
82+ try_visit ! ( visitor. visit_goal( & goal) ) ;
83+ }
84+ }
85+
86+ V :: Result :: output ( )
87+ }
88+
89+ /// Instantiate the nested goals for the candidate without rolling back their
90+ /// inference constraints. This function modifies the state of the `infcx`.
91+ pub fn instantiate_nested_goals ( & self , span : Span ) -> Vec < InspectGoal < ' a , ' tcx > > {
92+ let infcx = self . goal . infcx ;
93+ let param_env = self . goal . goal . param_env ;
94+ let mut orig_values = self . goal . orig_values . to_vec ( ) ;
95+ let instantiated_goals: Vec < _ > = self
96+ . nested_goals
97+ . iter ( )
98+ . map ( |goal| {
99+ canonical:: instantiate_canonical_state (
83100 infcx,
84- visitor . span ( ) ,
101+ span,
85102 param_env,
86103 & mut orig_values,
87104 * goal,
88- ) ;
89- instantiated_goals . push ( goal ) ;
90- }
105+ )
106+ } )
107+ . collect ( ) ;
91108
92- let ( ) = canonical:: instantiate_canonical_state (
93- infcx,
94- visitor . span ( ) ,
95- param_env,
96- & mut orig_values,
97- self . final_state ,
98- ) ;
109+ let ( ) = canonical:: instantiate_canonical_state (
110+ infcx,
111+ span,
112+ param_env,
113+ & mut orig_values,
114+ self . final_state ,
115+ ) ;
99116
100- for & goal in & instantiated_goals {
117+ instantiated_goals
118+ . into_iter ( )
119+ . map ( |goal| {
101120 let proof_tree = match goal. predicate . kind ( ) . no_bound_vars ( ) {
102121 Some ( ty:: PredicateKind :: NormalizesTo ( ty:: NormalizesTo { alias, term } ) ) => {
103122 let unconstrained_term = match term. unpack ( ) {
104123 ty:: TermKind :: Ty ( _) => infcx
105- . next_ty_var ( TypeVariableOrigin {
106- param_def_id : None ,
107- span : visitor. span ( ) ,
108- } )
124+ . next_ty_var ( TypeVariableOrigin { param_def_id : None , span } )
109125 . into ( ) ,
110126 ty:: TermKind :: Const ( ct) => infcx
111127 . next_const_var (
112128 ct. ty ( ) ,
113- ConstVariableOrigin {
114- param_def_id : None ,
115- span : visitor. span ( ) ,
116- } ,
129+ ConstVariableOrigin { param_def_id : None , span } ,
117130 )
118131 . into ( ) ,
119132 } ;
@@ -129,22 +142,16 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
129142 } )
130143 . 1 ;
131144 let InferOk { value : ( ) , obligations : _ } = infcx
132- . at ( & ObligationCause :: dummy ( ) , param_env)
145+ . at ( & ObligationCause :: dummy_with_span ( span ) , param_env)
133146 . eq ( DefineOpaqueTypes :: Yes , term, unconstrained_term)
134147 . unwrap ( ) ;
135148 proof_tree
136149 }
137150 _ => infcx. evaluate_root_goal ( goal, GenerateProofTree :: Yes ) . 1 ,
138151 } ;
139- try_visit ! ( visitor. visit_goal( & InspectGoal :: new(
140- infcx,
141- self . goal. depth + 1 ,
142- & proof_tree. unwrap( ) ,
143- ) ) ) ;
144- }
145- }
146-
147- V :: Result :: output ( )
152+ InspectGoal :: new ( infcx, self . goal . depth + 1 , proof_tree. unwrap ( ) )
153+ } )
154+ . collect ( )
148155 }
149156
150157 /// Visit all nested goals of this candidate, rolling back
@@ -164,7 +171,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
164171 }
165172
166173 pub fn result ( & self ) -> Result < Certainty , NoSolution > {
167- self . evaluation . evaluation . result . map ( |c| c. value . certainty )
174+ self . evaluation . result . map ( |c| c. value . certainty )
168175 }
169176
170177 fn candidates_recur (
@@ -221,7 +228,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
221228
222229 pub fn candidates ( & ' a self ) -> Vec < InspectCandidate < ' a , ' tcx > > {
223230 let mut candidates = vec ! [ ] ;
224- let last_eval_step = match self . evaluation . evaluation . kind {
231+ let last_eval_step = match self . evaluation . kind {
225232 inspect:: CanonicalGoalEvaluationKind :: Overflow
226233 | inspect:: CanonicalGoalEvaluationKind :: CycleInStack
227234 | inspect:: CanonicalGoalEvaluationKind :: ProvisionalCacheHit => {
@@ -254,18 +261,15 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
254261 candidates. pop ( ) . filter ( |_| candidates. is_empty ( ) )
255262 }
256263
257- fn new (
258- infcx : & ' a InferCtxt < ' tcx > ,
259- depth : usize ,
260- root : & ' a inspect:: GoalEvaluation < ' tcx > ,
261- ) -> Self {
262- match root. kind {
263- inspect:: GoalEvaluationKind :: Root { ref orig_values } => InspectGoal {
264+ fn new ( infcx : & ' a InferCtxt < ' tcx > , depth : usize , root : inspect:: GoalEvaluation < ' tcx > ) -> Self {
265+ let inspect:: GoalEvaluation { uncanonicalized_goal, kind, evaluation } = root;
266+ match kind {
267+ inspect:: GoalEvaluationKind :: Root { orig_values } => InspectGoal {
264268 infcx,
265269 depth,
266270 orig_values,
267- goal : root . uncanonicalized_goal . fold_with ( & mut EagerResolver :: new ( infcx) ) ,
268- evaluation : root ,
271+ goal : uncanonicalized_goal. fold_with ( & mut EagerResolver :: new ( infcx) ) ,
272+ evaluation,
269273 } ,
270274 inspect:: GoalEvaluationKind :: Nested { .. } => unreachable ! ( ) ,
271275 }
@@ -294,6 +298,6 @@ impl<'tcx> InferCtxt<'tcx> {
294298 ) -> V :: Result {
295299 let ( _, proof_tree) = self . evaluate_root_goal ( goal, GenerateProofTree :: Yes ) ;
296300 let proof_tree = proof_tree. unwrap ( ) ;
297- visitor. visit_goal ( & InspectGoal :: new ( self , 0 , & proof_tree) )
301+ visitor. visit_goal ( & InspectGoal :: new ( self , 0 , proof_tree) )
298302 }
299303}
0 commit comments