Skip to content

Commit aa6fb1c

Browse files
Rollup merge of #126496 - compiler-errors:more-generics, r=lcnr
Make proof tree probing and `Candidate`/`CandidateSource` generic over interner `<TyCtxt<'tcx>>` is ugly, but will become `<I>` when things actually become generic. r? lcnr
2 parents 1f076c2 + c2e416c commit aa6fb1c

File tree

6 files changed

+157
-143
lines changed

6 files changed

+157
-143
lines changed

compiler/rustc_infer/src/infer/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,10 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
471471
{
472472
self.resolve_vars_if_possible(value)
473473
}
474+
475+
fn probe<T>(&self, probe: impl FnOnce() -> T) -> T {
476+
self.probe(|_| probe())
477+
}
474478
}
475479

476480
/// See the `error_reporting` module for more details.

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

+50-49
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
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_hir::LangItem;
56
use rustc_infer::infer::InferCtxt;
67
use rustc_infer::traits::query::NoSolution;
78
use rustc_middle::bug;
89
use 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};
1211
use rustc_middle::traits::BuiltinImplSource;
1312
use rustc_middle::ty::fast_reject::{SimplifiedType, TreatParams};
1413
use rustc_middle::ty::{self, Ty, TyCtxt};
1514
use rustc_middle::ty::{fast_reject, TypeFoldable};
1615
use rustc_middle::ty::{TypeVisitableExt, Upcast};
1716
use 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

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

276277
impl<'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

Comments
 (0)