Skip to content

Commit 8a8bbc0

Browse files
Make Candidate generic over interner
1 parent f8e5660 commit 8a8bbc0

File tree

4 files changed

+107
-106
lines changed

4 files changed

+107
-106
lines changed

compiler/rustc_trait_selection/src/solve/assembly/mod.rs

Lines changed: 50 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
//! Code shared by trait and projection goals for candidate assembly.
22
3+
use derivative::Derivative;
34
use rustc_hir::def_id::DefId;
45
use rustc_infer::infer::InferCtxt;
56
use rustc_infer::traits::query::NoSolution;
67
use rustc_middle::bug;
78
use 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};
1110
use rustc_middle::traits::BuiltinImplSource;
1211
use rustc_middle::ty::fast_reject::{SimplifiedType, TreatParams};
1312
use rustc_middle::ty::{self, Ty, TyCtxt};
1413
use rustc_middle::ty::{fast_reject, TypeFoldable};
1514
use rustc_middle::ty::{TypeVisitableExt, Upcast};
1615
use 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

1919
use crate::solve::GoalSource;
2020
use 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

275276
impl<'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<_>>();

compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ where
6565
pub(in crate::solve) fn enter(
6666
self,
6767
f: impl FnOnce(&mut EvalCtxt<'_, InferCtxt<'tcx>>) -> QueryResult<'tcx>,
68-
) -> Result<Candidate<'tcx>, NoSolution> {
68+
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
6969
self.cx.enter(|ecx| f(ecx)).map(|result| Candidate { source: self.source, result })
7070
}
7171
}

0 commit comments

Comments
 (0)