11//! Code shared by trait and projection goals for candidate assembly.
22
3+ use derivative:: Derivative ;
34use rustc_hir:: def_id:: DefId ;
45use rustc_hir:: LangItem ;
56use rustc_infer:: infer:: InferCtxt ;
67use rustc_infer:: traits:: query:: NoSolution ;
78use rustc_middle:: bug;
89use rustc_middle:: traits:: solve:: inspect:: ProbeKind ;
9- use rustc_middle:: traits:: solve:: {
10- CandidateSource , CanonicalResponse , Certainty , Goal , MaybeCause , QueryResult ,
11- } ;
10+ use rustc_middle:: traits:: solve:: { Certainty , Goal , MaybeCause , QueryResult } ;
1211use rustc_middle:: traits:: BuiltinImplSource ;
1312use rustc_middle:: ty:: fast_reject:: { SimplifiedType , TreatParams } ;
1413use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
1514use rustc_middle:: ty:: { fast_reject, TypeFoldable } ;
1615use rustc_middle:: ty:: { TypeVisitableExt , Upcast } ;
1716use rustc_span:: { ErrorGuaranteed , DUMMY_SP } ;
18- use std:: fmt:: Debug ;
17+ use rustc_type_ir:: solve:: { CandidateSource , CanonicalResponse } ;
18+ use rustc_type_ir:: Interner ;
1919
2020use crate :: solve:: GoalSource ;
2121use crate :: solve:: { EvalCtxt , SolverMode } ;
@@ -26,10 +26,11 @@ pub(super) mod structural_traits;
2626///
2727/// It consists of both the `source`, which describes how that goal would be proven,
2828/// and the `result` when using the given `source`.
29- #[ derive( Debug , Clone ) ]
30- pub ( super ) struct Candidate < ' tcx > {
31- pub ( super ) source : CandidateSource < ' tcx > ,
32- pub ( super ) result : CanonicalResponse < ' tcx > ,
29+ #[ derive( Derivative ) ]
30+ #[ derivative( Debug ( bound = "" ) , Clone ( bound = "" ) ) ]
31+ pub ( super ) struct Candidate < I : Interner > {
32+ pub ( super ) source : CandidateSource < I > ,
33+ pub ( super ) result : CanonicalResponse < I > ,
3334}
3435
3536/// Methods used to assemble candidates for either trait or projection goals.
@@ -50,22 +51,22 @@ pub(super) trait GoalKind<'tcx>:
5051 /// [`EvalCtxt::evaluate_added_goals_and_make_canonical_response`]).
5152 fn probe_and_match_goal_against_assumption (
5253 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
53- source : CandidateSource < ' tcx > ,
54+ source : CandidateSource < TyCtxt < ' tcx > > ,
5455 goal : Goal < ' tcx , Self > ,
5556 assumption : ty:: Clause < ' tcx > ,
5657 then : impl FnOnce ( & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ) -> QueryResult < ' tcx > ,
57- ) -> Result < Candidate < ' tcx > , NoSolution > ;
58+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
5859
5960 /// Consider a clause, which consists of a "assumption" and some "requirements",
6061 /// to satisfy a goal. If the requirements hold, then attempt to satisfy our
6162 /// goal by equating it with the assumption.
6263 fn probe_and_consider_implied_clause (
6364 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
64- parent_source : CandidateSource < ' tcx > ,
65+ parent_source : CandidateSource < TyCtxt < ' tcx > > ,
6566 goal : Goal < ' tcx , Self > ,
6667 assumption : ty:: Clause < ' tcx > ,
6768 requirements : impl IntoIterator < Item = ( GoalSource , Goal < ' tcx , ty:: Predicate < ' tcx > > ) > ,
68- ) -> Result < Candidate < ' tcx > , NoSolution > {
69+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > {
6970 Self :: probe_and_match_goal_against_assumption ( ecx, parent_source, goal, assumption, |ecx| {
7071 for ( nested_source, goal) in requirements {
7172 ecx. add_goal ( nested_source, goal) ;
@@ -79,10 +80,10 @@ pub(super) trait GoalKind<'tcx>:
7980 /// since they're not implied by the well-formedness of the object type.
8081 fn probe_and_consider_object_bound_candidate (
8182 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
82- source : CandidateSource < ' tcx > ,
83+ source : CandidateSource < TyCtxt < ' tcx > > ,
8384 goal : Goal < ' tcx , Self > ,
8485 assumption : ty:: Clause < ' tcx > ,
85- ) -> Result < Candidate < ' tcx > , NoSolution > {
86+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > {
8687 Self :: probe_and_match_goal_against_assumption ( ecx, source, goal, assumption, |ecx| {
8788 let tcx = ecx. interner ( ) ;
8889 let ty:: Dynamic ( bounds, _, _) = * goal. predicate . self_ty ( ) . kind ( ) else {
@@ -105,7 +106,7 @@ pub(super) trait GoalKind<'tcx>:
105106 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
106107 goal : Goal < ' tcx , Self > ,
107108 impl_def_id : DefId ,
108- ) -> Result < Candidate < ' tcx > , NoSolution > ;
109+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
109110
110111 /// If the predicate contained an error, we want to avoid emitting unnecessary trait
111112 /// errors but still want to emit errors for other trait goals. We have some special
@@ -116,7 +117,7 @@ pub(super) trait GoalKind<'tcx>:
116117 fn consider_error_guaranteed_candidate (
117118 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
118119 guar : ErrorGuaranteed ,
119- ) -> Result < Candidate < ' tcx > , NoSolution > ;
120+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
120121
121122 /// A type implements an `auto trait` if its components do as well.
122123 ///
@@ -125,13 +126,13 @@ pub(super) trait GoalKind<'tcx>:
125126 fn consider_auto_trait_candidate (
126127 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
127128 goal : Goal < ' tcx , Self > ,
128- ) -> Result < Candidate < ' tcx > , NoSolution > ;
129+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
129130
130131 /// A trait alias holds if the RHS traits and `where` clauses hold.
131132 fn consider_trait_alias_candidate (
132133 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
133134 goal : Goal < ' tcx , Self > ,
134- ) -> Result < Candidate < ' tcx > , NoSolution > ;
135+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
135136
136137 /// A type is `Sized` if its tail component is `Sized`.
137138 ///
@@ -140,7 +141,7 @@ pub(super) trait GoalKind<'tcx>:
140141 fn consider_builtin_sized_candidate (
141142 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
142143 goal : Goal < ' tcx , Self > ,
143- ) -> Result < Candidate < ' tcx > , NoSolution > ;
144+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
144145
145146 /// A type is `Copy` or `Clone` if its components are `Copy` or `Clone`.
146147 ///
@@ -149,50 +150,50 @@ pub(super) trait GoalKind<'tcx>:
149150 fn consider_builtin_copy_clone_candidate (
150151 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
151152 goal : Goal < ' tcx , Self > ,
152- ) -> Result < Candidate < ' tcx > , NoSolution > ;
153+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
153154
154155 /// A type is `PointerLike` if we can compute its layout, and that layout
155156 /// matches the layout of `usize`.
156157 fn consider_builtin_pointer_like_candidate (
157158 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
158159 goal : Goal < ' tcx , Self > ,
159- ) -> Result < Candidate < ' tcx > , NoSolution > ;
160+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
160161
161162 /// A type is a `FnPtr` if it is of `FnPtr` type.
162163 fn consider_builtin_fn_ptr_trait_candidate (
163164 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
164165 goal : Goal < ' tcx , Self > ,
165- ) -> Result < Candidate < ' tcx > , NoSolution > ;
166+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
166167
167168 /// A callable type (a closure, fn def, or fn ptr) is known to implement the `Fn<A>`
168169 /// family of traits where `A` is given by the signature of the type.
169170 fn consider_builtin_fn_trait_candidates (
170171 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
171172 goal : Goal < ' tcx , Self > ,
172173 kind : ty:: ClosureKind ,
173- ) -> Result < Candidate < ' tcx > , NoSolution > ;
174+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
174175
175176 /// An async closure is known to implement the `AsyncFn<A>` family of traits
176177 /// where `A` is given by the signature of the type.
177178 fn consider_builtin_async_fn_trait_candidates (
178179 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
179180 goal : Goal < ' tcx , Self > ,
180181 kind : ty:: ClosureKind ,
181- ) -> Result < Candidate < ' tcx > , NoSolution > ;
182+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
182183
183184 /// Compute the built-in logic of the `AsyncFnKindHelper` helper trait, which
184185 /// is used internally to delay computation for async closures until after
185186 /// upvar analysis is performed in HIR typeck.
186187 fn consider_builtin_async_fn_kind_helper_candidate (
187188 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
188189 goal : Goal < ' tcx , Self > ,
189- ) -> Result < Candidate < ' tcx > , NoSolution > ;
190+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
190191
191192 /// `Tuple` is implemented if the `Self` type is a tuple.
192193 fn consider_builtin_tuple_candidate (
193194 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
194195 goal : Goal < ' tcx , Self > ,
195- ) -> Result < Candidate < ' tcx > , NoSolution > ;
196+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
196197
197198 /// `Pointee` is always implemented.
198199 ///
@@ -202,63 +203,63 @@ pub(super) trait GoalKind<'tcx>:
202203 fn consider_builtin_pointee_candidate (
203204 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
204205 goal : Goal < ' tcx , Self > ,
205- ) -> Result < Candidate < ' tcx > , NoSolution > ;
206+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
206207
207208 /// A coroutine (that comes from an `async` desugaring) is known to implement
208209 /// `Future<Output = O>`, where `O` is given by the coroutine's return type
209210 /// that was computed during type-checking.
210211 fn consider_builtin_future_candidate (
211212 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
212213 goal : Goal < ' tcx , Self > ,
213- ) -> Result < Candidate < ' tcx > , NoSolution > ;
214+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
214215
215216 /// A coroutine (that comes from a `gen` desugaring) is known to implement
216217 /// `Iterator<Item = O>`, where `O` is given by the generator's yield type
217218 /// that was computed during type-checking.
218219 fn consider_builtin_iterator_candidate (
219220 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
220221 goal : Goal < ' tcx , Self > ,
221- ) -> Result < Candidate < ' tcx > , NoSolution > ;
222+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
222223
223224 /// A coroutine (that comes from a `gen` desugaring) is known to implement
224225 /// `FusedIterator`
225226 fn consider_builtin_fused_iterator_candidate (
226227 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
227228 goal : Goal < ' tcx , Self > ,
228- ) -> Result < Candidate < ' tcx > , NoSolution > ;
229+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
229230
230231 fn consider_builtin_async_iterator_candidate (
231232 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
232233 goal : Goal < ' tcx , Self > ,
233- ) -> Result < Candidate < ' tcx > , NoSolution > ;
234+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
234235
235236 /// A coroutine (that doesn't come from an `async` or `gen` desugaring) is known to
236237 /// implement `Coroutine<R, Yield = Y, Return = O>`, given the resume, yield,
237238 /// and return types of the coroutine computed during type-checking.
238239 fn consider_builtin_coroutine_candidate (
239240 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
240241 goal : Goal < ' tcx , Self > ,
241- ) -> Result < Candidate < ' tcx > , NoSolution > ;
242+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
242243
243244 fn consider_builtin_discriminant_kind_candidate (
244245 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
245246 goal : Goal < ' tcx , Self > ,
246- ) -> Result < Candidate < ' tcx > , NoSolution > ;
247+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
247248
248249 fn consider_builtin_async_destruct_candidate (
249250 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
250251 goal : Goal < ' tcx , Self > ,
251- ) -> Result < Candidate < ' tcx > , NoSolution > ;
252+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
252253
253254 fn consider_builtin_destruct_candidate (
254255 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
255256 goal : Goal < ' tcx , Self > ,
256- ) -> Result < Candidate < ' tcx > , NoSolution > ;
257+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
257258
258259 fn consider_builtin_transmute_candidate (
259260 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
260261 goal : Goal < ' tcx , Self > ,
261- ) -> Result < Candidate < ' tcx > , NoSolution > ;
262+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > ;
262263
263264 /// Consider (possibly several) candidates to upcast or unsize a type to another
264265 /// type, excluding the coercion of a sized type into a `dyn Trait`.
@@ -270,14 +271,14 @@ pub(super) trait GoalKind<'tcx>:
270271 fn consider_structural_builtin_unsize_candidates (
271272 ecx : & mut EvalCtxt < ' _ , InferCtxt < ' tcx > > ,
272273 goal : Goal < ' tcx , Self > ,
273- ) -> Vec < Candidate < ' tcx > > ;
274+ ) -> Vec < Candidate < TyCtxt < ' tcx > > > ;
274275}
275276
276277impl < ' tcx > EvalCtxt < ' _ , InferCtxt < ' tcx > > {
277278 pub ( super ) fn assemble_and_evaluate_candidates < G : GoalKind < ' tcx > > (
278279 & mut self ,
279280 goal : Goal < ' tcx , G > ,
280- ) -> Vec < Candidate < ' tcx > > {
281+ ) -> Vec < Candidate < TyCtxt < ' tcx > > > {
281282 let Ok ( normalized_self_ty) =
282283 self . structurally_normalize_ty ( goal. param_env , goal. predicate . self_ty ( ) )
283284 else {
@@ -324,7 +325,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
324325 pub ( super ) fn forced_ambiguity (
325326 & mut self ,
326327 cause : MaybeCause ,
327- ) -> Result < Candidate < ' tcx > , NoSolution > {
328+ ) -> Result < Candidate < TyCtxt < ' tcx > > , NoSolution > {
328329 // This may fail if `try_evaluate_added_goals` overflows because it
329330 // fails to reach a fixpoint but ends up getting an error after
330331 // running for some additional step.
@@ -340,7 +341,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
340341 fn assemble_non_blanket_impl_candidates < G : GoalKind < ' tcx > > (
341342 & mut self ,
342343 goal : Goal < ' tcx , G > ,
343- candidates : & mut Vec < Candidate < ' tcx > > ,
344+ candidates : & mut Vec < Candidate < TyCtxt < ' tcx > > > ,
344345 ) {
345346 let tcx = self . interner ( ) ;
346347 let self_ty = goal. predicate . self_ty ( ) ;
@@ -456,7 +457,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
456457 fn assemble_blanket_impl_candidates < G : GoalKind < ' tcx > > (
457458 & mut self ,
458459 goal : Goal < ' tcx , G > ,
459- candidates : & mut Vec < Candidate < ' tcx > > ,
460+ candidates : & mut Vec < Candidate < TyCtxt < ' tcx > > > ,
460461 ) {
461462 let tcx = self . interner ( ) ;
462463 let trait_impls = tcx. trait_impls_of ( goal. predicate . trait_def_id ( tcx) ) ;
@@ -479,7 +480,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
479480 fn assemble_builtin_impl_candidates < G : GoalKind < ' tcx > > (
480481 & mut self ,
481482 goal : Goal < ' tcx , G > ,
482- candidates : & mut Vec < Candidate < ' tcx > > ,
483+ candidates : & mut Vec < Candidate < TyCtxt < ' tcx > > > ,
483484 ) {
484485 let tcx = self . interner ( ) ;
485486 let trait_def_id = goal. predicate . trait_def_id ( tcx) ;
@@ -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