Skip to content

Commit ab769a0

Browse files
authored
Rollup merge of #107344 - compiler-errors:new-solver-tweaks, r=lcnr
Minor tweaks in the new solver 1. `InferCtxt::probe` is not needed in `compute_subtype_goal` and `compute_well_formed_goal`. 2. Add a handful of comments. 3. Add a micro-optimization in `consider_assumption` where we check the def-ids of the assumption and goal match before instantiating any binders. r? ``@lcnr``
2 parents a5caa98 + 8a0b215 commit ab769a0

File tree

4 files changed

+54
-23
lines changed

4 files changed

+54
-23
lines changed

compiler/rustc_trait_selection/src/solve/assembly.rs

+25
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//! Code shared by trait and projection goals for candidate assembly.
22
33
use super::infcx_ext::InferCtxtExt;
4+
#[cfg(doc)]
5+
use super::trait_goals::structural_traits::*;
46
use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, QueryResult};
57
use rustc_hir::def_id::DefId;
68
use rustc_infer::traits::query::NoSolution;
@@ -98,52 +100,75 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy + Eq {
98100
assumption: ty::Predicate<'tcx>,
99101
) -> QueryResult<'tcx>;
100102

103+
// A type implements an `auto trait` if its components do as well. These components
104+
// are given by built-in rules from [`instantiate_constituent_tys_for_auto_trait`].
101105
fn consider_auto_trait_candidate(
102106
ecx: &mut EvalCtxt<'_, 'tcx>,
103107
goal: Goal<'tcx, Self>,
104108
) -> QueryResult<'tcx>;
105109

110+
// A trait alias holds if the RHS traits and `where` clauses hold.
106111
fn consider_trait_alias_candidate(
107112
ecx: &mut EvalCtxt<'_, 'tcx>,
108113
goal: Goal<'tcx, Self>,
109114
) -> QueryResult<'tcx>;
110115

116+
// A type is `Copy` or `Clone` if its components are `Sized`. These components
117+
// are given by built-in rules from [`instantiate_constituent_tys_for_sized_trait`].
111118
fn consider_builtin_sized_candidate(
112119
ecx: &mut EvalCtxt<'_, 'tcx>,
113120
goal: Goal<'tcx, Self>,
114121
) -> QueryResult<'tcx>;
115122

123+
// A type is `Copy` or `Clone` if its components are `Copy` or `Clone`. These
124+
// components are given by built-in rules from [`instantiate_constituent_tys_for_copy_clone_trait`].
116125
fn consider_builtin_copy_clone_candidate(
117126
ecx: &mut EvalCtxt<'_, 'tcx>,
118127
goal: Goal<'tcx, Self>,
119128
) -> QueryResult<'tcx>;
120129

130+
// A type is `PointerSized` if we can compute its layout, and that layout
131+
// matches the layout of `usize`.
121132
fn consider_builtin_pointer_sized_candidate(
122133
ecx: &mut EvalCtxt<'_, 'tcx>,
123134
goal: Goal<'tcx, Self>,
124135
) -> QueryResult<'tcx>;
125136

137+
// A callable type (a closure, fn def, or fn ptr) is known to implement the `Fn<A>`
138+
// family of traits where `A` is given by the signature of the type.
126139
fn consider_builtin_fn_trait_candidates(
127140
ecx: &mut EvalCtxt<'_, 'tcx>,
128141
goal: Goal<'tcx, Self>,
129142
kind: ty::ClosureKind,
130143
) -> QueryResult<'tcx>;
131144

145+
// `Tuple` is implemented if the `Self` type is a tuple.
132146
fn consider_builtin_tuple_candidate(
133147
ecx: &mut EvalCtxt<'_, 'tcx>,
134148
goal: Goal<'tcx, Self>,
135149
) -> QueryResult<'tcx>;
136150

151+
// `Pointee` is always implemented.
152+
//
153+
// See the projection implementation for the `Metadata` types for all of
154+
// the built-in types. For structs, the metadata type is given by the struct
155+
// tail.
137156
fn consider_builtin_pointee_candidate(
138157
ecx: &mut EvalCtxt<'_, 'tcx>,
139158
goal: Goal<'tcx, Self>,
140159
) -> QueryResult<'tcx>;
141160

161+
// A generator (that comes from an `async` desugaring) is known to implement
162+
// `Future<Output = O>`, where `O` is given by the generator's return type
163+
// that was computed during type-checking.
142164
fn consider_builtin_future_candidate(
143165
ecx: &mut EvalCtxt<'_, 'tcx>,
144166
goal: Goal<'tcx, Self>,
145167
) -> QueryResult<'tcx>;
146168

169+
// A generator (that doesn't come from an `async` desugaring) is known to
170+
// implement `Generator<R, Yield = Y, Return = O>`, given the resume, yield,
171+
// and return types of the generator computed during type-checking.
147172
fn consider_builtin_generator_candidate(
148173
ecx: &mut EvalCtxt<'_, 'tcx>,
149174
goal: Goal<'tcx, Self>,

compiler/rustc_trait_selection/src/solve/mod.rs

+23-21
Original file line numberDiff line numberDiff line change
@@ -335,15 +335,13 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
335335
// That won't actually reflect in the query response, so it seems moot.
336336
self.make_canonical_response(Certainty::AMBIGUOUS)
337337
} else {
338-
self.infcx.probe(|_| {
339-
let InferOk { value: (), obligations } = self
340-
.infcx
341-
.at(&ObligationCause::dummy(), goal.param_env)
342-
.sub(goal.predicate.a, goal.predicate.b)?;
343-
self.evaluate_all_and_make_canonical_response(
344-
obligations.into_iter().map(|pred| pred.into()).collect(),
345-
)
346-
})
338+
let InferOk { value: (), obligations } = self
339+
.infcx
340+
.at(&ObligationCause::dummy(), goal.param_env)
341+
.sub(goal.predicate.a, goal.predicate.b)?;
342+
self.evaluate_all_and_make_canonical_response(
343+
obligations.into_iter().map(|pred| pred.into()).collect(),
344+
)
347345
}
348346
}
349347

@@ -376,22 +374,22 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
376374
&mut self,
377375
goal: Goal<'tcx, ty::GenericArg<'tcx>>,
378376
) -> QueryResult<'tcx> {
379-
self.infcx.probe(|_| {
380-
match crate::traits::wf::unnormalized_obligations(
381-
self.infcx,
382-
goal.param_env,
383-
goal.predicate,
384-
) {
385-
Some(obligations) => self.evaluate_all_and_make_canonical_response(
386-
obligations.into_iter().map(|o| o.into()).collect(),
387-
),
388-
None => self.make_canonical_response(Certainty::AMBIGUOUS),
389-
}
390-
})
377+
match crate::traits::wf::unnormalized_obligations(
378+
self.infcx,
379+
goal.param_env,
380+
goal.predicate,
381+
) {
382+
Some(obligations) => self.evaluate_all_and_make_canonical_response(
383+
obligations.into_iter().map(|o| o.into()).collect(),
384+
),
385+
None => self.make_canonical_response(Certainty::AMBIGUOUS),
386+
}
391387
}
392388
}
393389

394390
impl<'tcx> EvalCtxt<'_, 'tcx> {
391+
// Recursively evaluates a list of goals to completion, returning the certainty
392+
// of all of the goals.
395393
fn evaluate_all(
396394
&mut self,
397395
mut goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
@@ -428,6 +426,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
428426
})
429427
}
430428

429+
// Recursively evaluates a list of goals to completion, making a query response.
430+
//
431+
// This is just a convenient way of calling [`EvalCtxt::evaluate_all`],
432+
// then [`EvalCtxt::make_canonical_response`].
431433
fn evaluate_all_and_make_canonical_response(
432434
&mut self,
433435
goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,

compiler/rustc_trait_selection/src/solve/project_goals.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
296296
goal: Goal<'tcx, Self>,
297297
assumption: ty::Predicate<'tcx>,
298298
) -> QueryResult<'tcx> {
299-
if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred() {
299+
if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred()
300+
&& poly_projection_pred.projection_def_id() == goal.predicate.def_id()
301+
{
300302
ecx.infcx.probe(|_| {
301303
let assumption_projection_pred =
302304
ecx.infcx.instantiate_bound_vars_with_infer(poly_projection_pred);

compiler/rustc_trait_selection/src/solve/trait_goals.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
6565
goal: Goal<'tcx, Self>,
6666
assumption: ty::Predicate<'tcx>,
6767
) -> QueryResult<'tcx> {
68-
if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred() {
68+
if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred()
69+
&& poly_trait_pred.def_id() == goal.predicate.def_id()
70+
{
6971
// FIXME: Constness and polarity
7072
ecx.infcx.probe(|_| {
7173
let assumption_trait_pred =

0 commit comments

Comments
 (0)