11//! Code shared by trait and projection goals for candidate assembly.
22
3+ use derivative:: Derivative ;
34use rustc_hir:: def_id:: DefId ;
45use rustc_infer:: infer:: InferCtxt ;
56use rustc_infer:: traits:: query:: NoSolution ;
67use rustc_middle:: bug;
78use rustc_middle:: traits:: solve:: inspect:: ProbeKind ;
8- use rustc_middle:: traits:: solve:: {
9- CandidateSource , CanonicalResponse , Certainty , Goal , MaybeCause , QueryResult ,
10- } ;
9+ use rustc_middle:: traits:: solve:: { Certainty , Goal , MaybeCause , QueryResult } ;
1110use rustc_middle:: traits:: BuiltinImplSource ;
1211use rustc_middle:: ty:: fast_reject:: { SimplifiedType , TreatParams } ;
1312use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
1413use rustc_middle:: ty:: { fast_reject, TypeFoldable } ;
1514use rustc_middle:: ty:: { TypeVisitableExt , Upcast } ;
1615use rustc_span:: { ErrorGuaranteed , DUMMY_SP } ;
17- use std:: fmt:: Debug ;
16+ use rustc_type_ir:: solve:: { CandidateSource , CanonicalResponse } ;
17+ use rustc_type_ir:: Interner ;
1818
1919use crate :: solve:: GoalSource ;
2020use crate :: solve:: { EvalCtxt , SolverMode } ;
@@ -25,10 +25,11 @@ pub(super) mod structural_traits;
2525///
2626/// It consists of both the `source`, which describes how that goal would be proven,
2727/// and the `result` when using the given `source`.
28- #[ derive( Debug , Clone ) ]
29- pub ( super ) struct Candidate < ' tcx > {
30- pub ( super ) source : CandidateSource < ' tcx > ,
31- pub ( super ) result : CanonicalResponse < ' tcx > ,
28+ #[ derive( Derivative ) ]
29+ #[ derivative( Debug ( bound = "" ) , Clone ( bound = "" ) ) ]
30+ pub ( super ) struct Candidate < I : Interner > {
31+ pub ( super ) source : CandidateSource < I > ,
32+ pub ( super ) result : CanonicalResponse < I > ,
3233}
3334
3435/// Methods used to assemble candidates for either trait or projection goals.
@@ -49,22 +50,22 @@ pub(super) trait GoalKind<'tcx>:
4950 /// [`EvalCtxt::evaluate_added_goals_and_make_canonical_response`]).
5051 fn probe_and_match_goal_against_assumption (
5152 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
52- source : CandidateSource < ' tcx > ,
53+ source : CandidateSource < TyCtxt < ' tcx > > ,
5354 goal : Goal < ' tcx , Self > ,
5455 assumption : ty:: Clause < ' tcx > ,
5556 then : impl FnOnce ( & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ) -> QueryResult < ' tcx > ,
56- ) -> Result < Candidate < ' tcx > , NoSolution > ;
57+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
5758
5859 /// Consider a clause, which consists of a "assumption" and some "requirements",
5960 /// to satisfy a goal. If the requirements hold, then attempt to satisfy our
6061 /// goal by equating it with the assumption.
6162 fn probe_and_consider_implied_clause (
6263 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
63- parent_source : CandidateSource < ' tcx > ,
64+ parent_source : CandidateSource < TyCtxt < ' tcx > > ,
6465 goal : Goal < ' tcx , Self > ,
6566 assumption : ty:: Clause < ' tcx > ,
6667 requirements : impl IntoIterator < Item = ( GoalSource , Goal < ' tcx , ty:: Predicate < ' tcx > > ) > ,
67- ) -> Result < Candidate < ' tcx > , NoSolution > {
68+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > {
6869 Self :: probe_and_match_goal_against_assumption ( ecx, parent_source, goal, assumption, |ecx| {
6970 for ( nested_source, goal) in requirements {
7071 ecx. add_goal ( nested_source, goal) ;
@@ -78,10 +79,10 @@ pub(super) trait GoalKind<'tcx>:
7879 /// since they're not implied by the well-formedness of the object type.
7980 fn probe_and_consider_object_bound_candidate (
8081 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
81- source : CandidateSource < ' tcx > ,
82+ source : CandidateSource < TyCtxt < ' tcx > > ,
8283 goal : Goal < ' tcx , Self > ,
8384 assumption : ty:: Clause < ' tcx > ,
84- ) -> Result < Candidate < ' tcx > , NoSolution > {
85+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > {
8586 Self :: probe_and_match_goal_against_assumption ( ecx, source, goal, assumption, |ecx| {
8687 let tcx = ecx. interner ( ) ;
8788 let ty:: Dynamic ( bounds, _, _) = * goal. predicate . self_ty ( ) . kind ( ) else {
@@ -104,7 +105,7 @@ pub(super) trait GoalKind<'tcx>:
104105 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
105106 goal : Goal < ' tcx , Self > ,
106107 impl_def_id : DefId ,
107- ) -> Result < Candidate < ' tcx > , NoSolution > ;
108+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
108109
109110 /// If the predicate contained an error, we want to avoid emitting unnecessary trait
110111 /// errors but still want to emit errors for other trait goals. We have some special
@@ -115,7 +116,7 @@ pub(super) trait GoalKind<'tcx>:
115116 fn consider_error_guaranteed_candidate (
116117 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
117118 guar : ErrorGuaranteed ,
118- ) -> Result < Candidate < ' tcx > , NoSolution > ;
119+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
119120
120121 /// A type implements an `auto trait` if its components do as well.
121122 ///
@@ -124,13 +125,13 @@ pub(super) trait GoalKind<'tcx>:
124125 fn consider_auto_trait_candidate (
125126 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
126127 goal : Goal < ' tcx , Self > ,
127- ) -> Result < Candidate < ' tcx > , NoSolution > ;
128+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
128129
129130 /// A trait alias holds if the RHS traits and `where` clauses hold.
130131 fn consider_trait_alias_candidate (
131132 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
132133 goal : Goal < ' tcx , Self > ,
133- ) -> Result < Candidate < ' tcx > , NoSolution > ;
134+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
134135
135136 /// A type is `Sized` if its tail component is `Sized`.
136137 ///
@@ -139,7 +140,7 @@ pub(super) trait GoalKind<'tcx>:
139140 fn consider_builtin_sized_candidate (
140141 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
141142 goal : Goal < ' tcx , Self > ,
142- ) -> Result < Candidate < ' tcx > , NoSolution > ;
143+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
143144
144145 /// A type is `Copy` or `Clone` if its components are `Copy` or `Clone`.
145146 ///
@@ -148,50 +149,50 @@ pub(super) trait GoalKind<'tcx>:
148149 fn consider_builtin_copy_clone_candidate (
149150 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
150151 goal : Goal < ' tcx , Self > ,
151- ) -> Result < Candidate < ' tcx > , NoSolution > ;
152+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
152153
153154 /// A type is `PointerLike` if we can compute its layout, and that layout
154155 /// matches the layout of `usize`.
155156 fn consider_builtin_pointer_like_candidate (
156157 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
157158 goal : Goal < ' tcx , Self > ,
158- ) -> Result < Candidate < ' tcx > , NoSolution > ;
159+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
159160
160161 /// A type is a `FnPtr` if it is of `FnPtr` type.
161162 fn consider_builtin_fn_ptr_trait_candidate (
162163 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
163164 goal : Goal < ' tcx , Self > ,
164- ) -> Result < Candidate < ' tcx > , NoSolution > ;
165+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
165166
166167 /// A callable type (a closure, fn def, or fn ptr) is known to implement the `Fn<A>`
167168 /// family of traits where `A` is given by the signature of the type.
168169 fn consider_builtin_fn_trait_candidates (
169170 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
170171 goal : Goal < ' tcx , Self > ,
171172 kind : ty:: ClosureKind ,
172- ) -> Result < Candidate < ' tcx > , NoSolution > ;
173+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
173174
174175 /// An async closure is known to implement the `AsyncFn<A>` family of traits
175176 /// where `A` is given by the signature of the type.
176177 fn consider_builtin_async_fn_trait_candidates (
177178 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
178179 goal : Goal < ' tcx , Self > ,
179180 kind : ty:: ClosureKind ,
180- ) -> Result < Candidate < ' tcx > , NoSolution > ;
181+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
181182
182183 /// Compute the built-in logic of the `AsyncFnKindHelper` helper trait, which
183184 /// is used internally to delay computation for async closures until after
184185 /// upvar analysis is performed in HIR typeck.
185186 fn consider_builtin_async_fn_kind_helper_candidate (
186187 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
187188 goal : Goal < ' tcx , Self > ,
188- ) -> Result < Candidate < ' tcx > , NoSolution > ;
189+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
189190
190191 /// `Tuple` is implemented if the `Self` type is a tuple.
191192 fn consider_builtin_tuple_candidate (
192193 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
193194 goal : Goal < ' tcx , Self > ,
194- ) -> Result < Candidate < ' tcx > , NoSolution > ;
195+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
195196
196197 /// `Pointee` is always implemented.
197198 ///
@@ -201,63 +202,63 @@ pub(super) trait GoalKind<'tcx>:
201202 fn consider_builtin_pointee_candidate (
202203 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
203204 goal : Goal < ' tcx , Self > ,
204- ) -> Result < Candidate < ' tcx > , NoSolution > ;
205+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
205206
206207 /// A coroutine (that comes from an `async` desugaring) is known to implement
207208 /// `Future<Output = O>`, where `O` is given by the coroutine's return type
208209 /// that was computed during type-checking.
209210 fn consider_builtin_future_candidate (
210211 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
211212 goal : Goal < ' tcx , Self > ,
212- ) -> Result < Candidate < ' tcx > , NoSolution > ;
213+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
213214
214215 /// A coroutine (that comes from a `gen` desugaring) is known to implement
215216 /// `Iterator<Item = O>`, where `O` is given by the generator's yield type
216217 /// that was computed during type-checking.
217218 fn consider_builtin_iterator_candidate (
218219 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
219220 goal : Goal < ' tcx , Self > ,
220- ) -> Result < Candidate < ' tcx > , NoSolution > ;
221+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
221222
222223 /// A coroutine (that comes from a `gen` desugaring) is known to implement
223224 /// `FusedIterator`
224225 fn consider_builtin_fused_iterator_candidate (
225226 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
226227 goal : Goal < ' tcx , Self > ,
227- ) -> Result < Candidate < ' tcx > , NoSolution > ;
228+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
228229
229230 fn consider_builtin_async_iterator_candidate (
230231 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
231232 goal : Goal < ' tcx , Self > ,
232- ) -> Result < Candidate < ' tcx > , NoSolution > ;
233+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
233234
234235 /// A coroutine (that doesn't come from an `async` or `gen` desugaring) is known to
235236 /// implement `Coroutine<R, Yield = Y, Return = O>`, given the resume, yield,
236237 /// and return types of the coroutine computed during type-checking.
237238 fn consider_builtin_coroutine_candidate (
238239 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
239240 goal : Goal < ' tcx , Self > ,
240- ) -> Result < Candidate < ' tcx > , NoSolution > ;
241+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
241242
242243 fn consider_builtin_discriminant_kind_candidate (
243244 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
244245 goal : Goal < ' tcx , Self > ,
245- ) -> Result < Candidate < ' tcx > , NoSolution > ;
246+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
246247
247248 fn consider_builtin_async_destruct_candidate (
248249 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
249250 goal : Goal < ' tcx , Self > ,
250- ) -> Result < Candidate < ' tcx > , NoSolution > ;
251+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
251252
252253 fn consider_builtin_destruct_candidate (
253254 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
254255 goal : Goal < ' tcx , Self > ,
255- ) -> Result < Candidate < ' tcx > , NoSolution > ;
256+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
256257
257258 fn consider_builtin_transmute_candidate (
258259 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
259260 goal : Goal < ' tcx , Self > ,
260- ) -> Result < Candidate < ' tcx > , NoSolution > ;
261+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
261262
262263 /// Consider (possibly several) candidates to upcast or unsize a type to another
263264 /// type, excluding the coercion of a sized type into a `dyn Trait`.
@@ -269,14 +270,14 @@ pub(super) trait GoalKind<'tcx>:
269270 fn consider_structural_builtin_unsize_candidates (
270271 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
271272 goal : Goal < ' tcx , Self > ,
272- ) -> Vec < Candidate < ' tcx > > ;
273+ ) -> Vec < Candidate < TyCtxt < ' tcx > > > ;
273274}
274275
275276impl < ' tcx > EvalCtxt < ' _ , InferCtxt < ' tcx > > {
276277 pub ( super ) fn assemble_and_evaluate_candidates < G : GoalKind < ' tcx > > (
277278 & mut self ,
278279 goal : Goal < ' tcx , G > ,
279- ) -> Vec < Candidate < ' tcx > > {
280+ ) -> Vec < Candidate < TyCtxt < ' tcx > > > {
280281 let Ok ( normalized_self_ty) =
281282 self . structurally_normalize_ty ( goal. param_env , goal. predicate . self_ty ( ) )
282283 else {
@@ -323,7 +324,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
323324 pub ( super ) fn forced_ambiguity (
324325 & mut self ,
325326 cause : MaybeCause ,
326- ) -> Result < Candidate < ' tcx > , NoSolution > {
327+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > {
327328 // This may fail if `try_evaluate_added_goals` overflows because it
328329 // fails to reach a fixpoint but ends up getting an error after
329330 // running for some additional step.
@@ -339,7 +340,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
339340 fn assemble_non_blanket_impl_candidates < G : GoalKind < ' tcx > > (
340341 & mut self ,
341342 goal : Goal < ' tcx , G > ,
342- candidates : & mut Vec < Candidate < ' tcx > > ,
343+ candidates : & mut Vec < Candidate < TyCtxt < ' tcx > > > ,
343344 ) {
344345 let tcx = self . interner ( ) ;
345346 let self_ty = goal. predicate . self_ty ( ) ;
@@ -455,7 +456,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
455456 fn assemble_blanket_impl_candidates < G : GoalKind < ' tcx > > (
456457 & mut self ,
457458 goal : Goal < ' tcx , G > ,
458- candidates : & mut Vec < Candidate < ' tcx > > ,
459+ candidates : & mut Vec < Candidate < TyCtxt < ' tcx > > > ,
459460 ) {
460461 let tcx = self . interner ( ) ;
461462 let trait_impls = tcx. trait_impls_of ( goal. predicate . trait_def_id ( tcx) ) ;
@@ -478,7 +479,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
478479 fn assemble_builtin_impl_candidates < G : GoalKind < ' tcx > > (
479480 & mut self ,
480481 goal : Goal < ' tcx , G > ,
481- candidates : & mut Vec < Candidate < ' tcx > > ,
482+ candidates : & mut Vec < Candidate < TyCtxt < ' tcx > > > ,
482483 ) {
483484 let tcx = self . interner ( ) ;
484485 let lang_items = tcx. lang_items ( ) ;
@@ -552,7 +553,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
552553 fn assemble_param_env_candidates < G : GoalKind < ' tcx > > (
553554 & mut self ,
554555 goal : Goal < ' tcx , G > ,
555- candidates : & mut Vec < Candidate < ' tcx > > ,
556+ candidates : & mut Vec < Candidate < TyCtxt < ' tcx > > > ,
556557 ) {
557558 for ( i, assumption) in goal. param_env . caller_bounds ( ) . iter ( ) . enumerate ( ) {
558559 candidates. extend ( G :: probe_and_consider_implied_clause (
@@ -569,7 +570,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
569570 fn assemble_alias_bound_candidates < G : GoalKind < ' tcx > > (
570571 & mut self ,
571572 goal : Goal < ' tcx , G > ,
572- candidates : & mut Vec < Candidate < ' tcx > > ,
573+ candidates : & mut Vec < Candidate < TyCtxt < ' tcx > > > ,
573574 ) {
574575 let ( ) = self . probe ( |_| ProbeKind :: NormalizedSelfTyAssembly ) . enter ( |ecx| {
575576 ecx. assemble_alias_bound_candidates_recur ( goal. predicate . self_ty ( ) , goal, candidates) ;
@@ -589,7 +590,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
589590 & mut self ,
590591 self_ty : Ty < ' tcx > ,
591592 goal : Goal < ' tcx , G > ,
592- candidates : & mut Vec < Candidate < ' tcx > > ,
593+ candidates : & mut Vec < Candidate < TyCtxt < ' tcx > > > ,
593594 ) {
594595 let ( kind, alias_ty) = match * self_ty. kind ( ) {
595596 ty:: Bool
@@ -673,7 +674,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
673674 fn assemble_object_bound_candidates < G : GoalKind < ' tcx > > (
674675 & mut self ,
675676 goal : Goal < ' tcx , G > ,
676- candidates : & mut Vec < Candidate < ' tcx > > ,
677+ candidates : & mut Vec < Candidate < TyCtxt < ' tcx > > > ,
677678 ) {
678679 let tcx = self . interner ( ) ;
679680 if !tcx. trait_def ( goal. predicate . trait_def_id ( tcx) ) . implement_via_object {
@@ -764,7 +765,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
764765 fn assemble_coherence_unknowable_candidates < G : GoalKind < ' tcx > > (
765766 & mut self ,
766767 goal : Goal < ' tcx , G > ,
767- candidates : & mut Vec < Candidate < ' tcx > > ,
768+ candidates : & mut Vec < Candidate < TyCtxt < ' tcx > > > ,
768769 ) {
769770 let tcx = self . interner ( ) ;
770771
@@ -793,7 +794,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
793794 fn discard_impls_shadowed_by_env < G : GoalKind < ' tcx > > (
794795 & mut self ,
795796 goal : Goal < ' tcx , G > ,
796- candidates : & mut Vec < Candidate < ' tcx > > ,
797+ candidates : & mut Vec < Candidate < TyCtxt < ' tcx > > > ,
797798 ) {
798799 let tcx = self . interner ( ) ;
799800 let trait_goal: Goal < ' tcx , ty:: TraitPredicate < ' tcx > > =
@@ -841,7 +842,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
841842 #[ instrument( level = "debug" , skip( self ) , ret) ]
842843 pub ( super ) fn merge_candidates (
843844 & mut self ,
844- candidates : Vec < Candidate < ' tcx > > ,
845+ candidates : Vec < Candidate < TyCtxt < ' tcx > > > ,
845846 ) -> QueryResult < ' tcx > {
846847 // First try merging all candidates. This is complete and fully sound.
847848 let responses = candidates. iter ( ) . map ( |c| c. result ) . collect :: < Vec < _ > > ( ) ;
0 commit comments