11//! Code shared by trait and projection goals for candidate assembly.
22
33use super :: infcx_ext:: InferCtxtExt ;
4- use super :: {
5- instantiate_canonical_query_response, CanonicalGoal , CanonicalResponse , Certainty , EvalCtxt ,
6- Goal ,
7- } ;
4+ use super :: { CanonicalResponse , Certainty , EvalCtxt , Goal } ;
85use rustc_hir:: def_id:: DefId ;
9- use rustc_infer:: infer:: TyCtxtInferExt ;
10- use rustc_infer:: infer:: {
11- canonical:: { CanonicalVarValues , OriginalQueryValues } ,
12- InferCtxt ,
13- } ;
146use rustc_infer:: traits:: query:: NoSolution ;
157use rustc_middle:: ty:: TypeFoldable ;
168use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
17- use rustc_span:: DUMMY_SP ;
189use std:: fmt:: Debug ;
1910
2011/// A candidate is a possible way to prove a goal.
@@ -40,7 +31,7 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy {
4031 fn trait_def_id ( self , tcx : TyCtxt < ' tcx > ) -> DefId ;
4132
4233 fn consider_impl_candidate (
43- acx : & mut AssemblyCtxt < ' _ , ' tcx , Self > ,
34+ acx : & mut AssemblyCtxt < ' _ , ' _ , ' tcx , Self > ,
4435 goal : Goal < ' tcx , Self > ,
4536 impl_def_id : DefId ,
4637 ) ;
@@ -49,21 +40,17 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy {
4940/// An abstraction which correctly deals with the canonical results for candidates.
5041///
5142/// It also deduplicates the behavior between trait and projection predicates.
52- pub ( super ) struct AssemblyCtxt < ' a , ' tcx , G : GoalKind < ' tcx > > {
53- pub ( super ) cx : & ' a mut EvalCtxt < ' tcx > ,
54- pub ( super ) infcx : & ' a InferCtxt < ' tcx > ,
55- var_values : CanonicalVarValues < ' tcx > ,
43+ pub ( super ) struct AssemblyCtxt < ' a , ' b , ' tcx , G : GoalKind < ' tcx > > {
44+ pub ( super ) cx : & ' a mut EvalCtxt < ' b , ' tcx > ,
5645 candidates : Vec < Candidate < ' tcx , G > > ,
5746}
5847
59- impl < ' a , ' tcx , G : GoalKind < ' tcx > > AssemblyCtxt < ' a , ' tcx , G > {
48+ impl < ' a , ' b , ' tcx , G : GoalKind < ' tcx > > AssemblyCtxt < ' a , ' b , ' tcx , G > {
6049 pub ( super ) fn assemble_and_evaluate_candidates (
61- cx : & ' a mut EvalCtxt < ' tcx > ,
62- goal : CanonicalGoal < ' tcx , G > ,
50+ cx : & ' a mut EvalCtxt < ' b , ' tcx > ,
51+ goal : Goal < ' tcx , G > ,
6352 ) -> Vec < Candidate < ' tcx , G > > {
64- let ( ref infcx, goal, var_values) =
65- cx. tcx . infer_ctxt ( ) . build_with_canonical ( DUMMY_SP , & goal) ;
66- let mut acx = AssemblyCtxt { cx, infcx, var_values, candidates : Vec :: new ( ) } ;
53+ let mut acx = AssemblyCtxt { cx, candidates : Vec :: new ( ) } ;
6754
6855 acx. assemble_candidates_after_normalizing_self_ty ( goal) ;
6956
@@ -77,7 +64,7 @@ impl<'a, 'tcx, G: GoalKind<'tcx>> AssemblyCtxt<'a, 'tcx, G> {
7764 source : G :: CandidateSource ,
7865 certainty : Certainty ,
7966 ) {
80- match self . infcx . make_canonical_response ( self . var_values . clone ( ) , certainty) {
67+ match self . cx . make_canonical_response ( certainty) {
8168 Ok ( result) => self . candidates . push ( Candidate { source, result } ) ,
8269 Err ( NoSolution ) => debug ! ( ?source, ?certainty, "failed leakcheck" ) ,
8370 }
@@ -89,57 +76,46 @@ impl<'a, 'tcx, G: GoalKind<'tcx>> AssemblyCtxt<'a, 'tcx, G> {
8976 /// self type to the list of candidates in case that succeeds. Note that we can't just eagerly return in
9077 /// this case as projections as self types add `
9178 fn assemble_candidates_after_normalizing_self_ty ( & mut self , goal : Goal < ' tcx , G > ) {
92- let tcx = self . cx . tcx ;
79+ let tcx = self . cx . tcx ( ) ;
80+ let infcx = self . cx . infcx ;
9381 // FIXME: We also have to normalize opaque types, not sure where to best fit that in.
9482 let & ty:: Alias ( ty:: Projection , projection_ty) = goal. predicate . self_ty ( ) . kind ( ) else {
9583 return
9684 } ;
97- self . infcx . probe ( |_| {
98- let normalized_ty = self . infcx . next_ty_infer ( ) ;
85+ infcx. probe ( |_| {
86+ let normalized_ty = infcx. next_ty_infer ( ) ;
9987 let normalizes_to_goal = goal. with (
10088 tcx,
10189 ty:: Binder :: dummy ( ty:: ProjectionPredicate {
10290 projection_ty,
10391 term : normalized_ty. into ( ) ,
10492 } ) ,
10593 ) ;
106- let normalization_certainty =
107- match self . cx . evaluate_goal ( & self . infcx , normalizes_to_goal) {
108- Ok ( ( _, certainty) ) => certainty,
109- Err ( NoSolution ) => return ,
110- } ;
94+ let normalization_certainty = match self . cx . evaluate_goal ( normalizes_to_goal) {
95+ Ok ( ( _, certainty) ) => certainty,
96+ Err ( NoSolution ) => return ,
97+ } ;
11198
11299 // NOTE: Alternatively we could call `evaluate_goal` here and only have a `Normalized` candidate.
113100 // This doesn't work as long as we use `CandidateSource` in both winnowing and to resolve associated items.
114101 let goal = goal. with ( tcx, goal. predicate . with_self_ty ( tcx, normalized_ty) ) ;
115- let mut orig_values = OriginalQueryValues :: default ( ) ;
116- let goal = self . infcx . canonicalize_query ( goal, & mut orig_values) ;
117102 let normalized_candidates =
118103 AssemblyCtxt :: assemble_and_evaluate_candidates ( self . cx , goal) ;
119-
120- // Map each candidate from being canonical wrt the current inference context to being
121- // canonical wrt the caller.
122- for Candidate { source, result } in normalized_candidates {
123- self . infcx . probe ( |_| {
124- let candidate_certainty =
125- instantiate_canonical_query_response ( & self . infcx , & orig_values, result) ;
126-
127- // FIXME: This is a bit scary if the `normalizes_to_goal` overflows.
128- //
129- // If we have an ambiguous candidate it hides that normalization
130- // caused an overflow which may cause issues.
131- self . try_insert_candidate (
132- source,
133- normalization_certainty. unify_and ( candidate_certainty) ,
134- )
135- } )
104+ for mut normalized_candidate in normalized_candidates {
105+ normalized_candidate. result =
106+ normalized_candidate. result . unchecked_map ( |mut response| {
107+ response. certainty = response. certainty . unify_and ( normalization_certainty) ;
108+ response
109+ } ) ;
110+ self . candidates . push ( normalized_candidate) ;
136111 }
137112 } )
138113 }
139114
140115 fn assemble_impl_candidates ( & mut self , goal : Goal < ' tcx , G > ) {
141- self . cx . tcx . for_each_relevant_impl (
142- goal. predicate . trait_def_id ( self . cx . tcx ) ,
116+ let tcx = self . cx . tcx ( ) ;
117+ tcx. for_each_relevant_impl (
118+ goal. predicate . trait_def_id ( tcx) ,
143119 goal. predicate . self_ty ( ) ,
144120 |impl_def_id| G :: consider_impl_candidate ( self , goal, impl_def_id) ,
145121 ) ;
0 commit comments