Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 7596998

Browse files
committedFeb 22, 2023
Move some InferCtxt methods to EvalCtxt in new solver
1 parent 375d5ac commit 7596998

File tree

7 files changed

+228
-226
lines changed

7 files changed

+228
-226
lines changed
 

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! Code shared by trait and projection goals for candidate assembly.
22
3-
use super::infcx_ext::InferCtxtExt;
43
#[cfg(doc)]
54
use super::trait_goals::structural_traits::*;
65
use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, MaybeCause, QueryResult};
@@ -206,7 +205,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
206205
&mut self,
207206
goal: Goal<'tcx, G>,
208207
) -> Vec<Candidate<'tcx>> {
209-
debug_assert_eq!(goal, self.infcx.resolve_vars_if_possible(goal));
208+
debug_assert_eq!(goal, self.resolve_vars_if_possible(goal));
210209

211210
// HACK: `_: Trait` is ambiguous, because it may be satisfied via a builtin rule,
212211
// object bound, alias bound, etc. We are unable to determine this until we can at
@@ -250,25 +249,25 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
250249
let &ty::Alias(ty::Projection, projection_ty) = goal.predicate.self_ty().kind() else {
251250
return
252251
};
253-
self.infcx.probe(|_| {
254-
let normalized_ty = self.infcx.next_ty_infer();
252+
self.probe(|this| {
253+
let normalized_ty = this.next_ty_infer();
255254
let normalizes_to_goal = goal.with(
256255
tcx,
257256
ty::Binder::dummy(ty::ProjectionPredicate {
258257
projection_ty,
259258
term: normalized_ty.into(),
260259
}),
261260
);
262-
let normalization_certainty = match self.evaluate_goal(normalizes_to_goal) {
261+
let normalization_certainty = match this.evaluate_goal(normalizes_to_goal) {
263262
Ok((_, certainty)) => certainty,
264263
Err(NoSolution) => return,
265264
};
266-
let normalized_ty = self.infcx.resolve_vars_if_possible(normalized_ty);
265+
let normalized_ty = this.resolve_vars_if_possible(normalized_ty);
267266

268267
// NOTE: Alternatively we could call `evaluate_goal` here and only have a `Normalized` candidate.
269268
// This doesn't work as long as we use `CandidateSource` in winnowing.
270269
let goal = goal.with(tcx, goal.predicate.with_self_ty(tcx, normalized_ty));
271-
let normalized_candidates = self.assemble_and_evaluate_candidates(goal);
270+
let normalized_candidates = this.assemble_and_evaluate_candidates(goal);
272271
for mut normalized_candidate in normalized_candidates {
273272
normalized_candidate.result =
274273
normalized_candidate.result.unchecked_map(|mut response| {
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
use rustc_hir::def_id::DefId;
2+
use rustc_infer::infer::at::ToTrace;
3+
use rustc_infer::infer::canonical::CanonicalVarValues;
4+
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
5+
use rustc_infer::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
6+
use rustc_infer::traits::query::NoSolution;
7+
use rustc_infer::traits::ObligationCause;
8+
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
9+
use rustc_middle::ty::{self, ir::TypeVisitor, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable};
10+
use rustc_span::DUMMY_SP;
11+
use std::ops::ControlFlow;
12+
13+
use super::search_graph::SearchGraph;
14+
use super::Goal;
15+
16+
pub struct EvalCtxt<'a, 'tcx> {
17+
// FIXME: should be private.
18+
pub(super) infcx: &'a InferCtxt<'tcx>,
19+
20+
pub(super) var_values: CanonicalVarValues<'tcx>,
21+
22+
pub(super) search_graph: &'a mut SearchGraph<'tcx>,
23+
24+
/// This field is used by a debug assertion in [`EvalCtxt::evaluate_goal`],
25+
/// see the comment in that method for more details.
26+
pub in_projection_eq_hack: bool,
27+
}
28+
29+
impl<'tcx> EvalCtxt<'_, 'tcx> {
30+
pub(super) fn probe<T>(&mut self, f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> T) -> T {
31+
self.infcx.probe(|_| f(self))
32+
}
33+
34+
pub(super) fn tcx(&self) -> TyCtxt<'tcx> {
35+
self.infcx.tcx
36+
}
37+
38+
pub(super) fn next_ty_infer(&self) -> Ty<'tcx> {
39+
self.infcx.next_ty_var(TypeVariableOrigin {
40+
kind: TypeVariableOriginKind::MiscVariable,
41+
span: DUMMY_SP,
42+
})
43+
}
44+
45+
pub(super) fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx> {
46+
self.infcx.next_const_var(
47+
ty,
48+
ConstVariableOrigin { kind: ConstVariableOriginKind::MiscVariable, span: DUMMY_SP },
49+
)
50+
}
51+
52+
/// Is the projection predicate is of the form `exists<T> <Ty as Trait>::Assoc = T`.
53+
///
54+
/// This is the case if the `term` is an inference variable in the innermost universe
55+
/// and does not occur in any other part of the predicate.
56+
pub(super) fn term_is_fully_unconstrained(
57+
&self,
58+
goal: Goal<'tcx, ty::ProjectionPredicate<'tcx>>,
59+
) -> bool {
60+
let term_is_infer = match goal.predicate.term.unpack() {
61+
ty::TermKind::Ty(ty) => {
62+
if let &ty::Infer(ty::TyVar(vid)) = ty.kind() {
63+
match self.infcx.probe_ty_var(vid) {
64+
Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
65+
Err(universe) => universe == self.universe(),
66+
}
67+
} else {
68+
false
69+
}
70+
}
71+
ty::TermKind::Const(ct) => {
72+
if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() {
73+
match self.infcx.probe_const_var(vid) {
74+
Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
75+
Err(universe) => universe == self.universe(),
76+
}
77+
} else {
78+
false
79+
}
80+
}
81+
};
82+
83+
// Guard against `<T as Trait<?0>>::Assoc = ?0>`.
84+
struct ContainsTerm<'tcx> {
85+
term: ty::Term<'tcx>,
86+
}
87+
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTerm<'tcx> {
88+
type BreakTy = ();
89+
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
90+
if t.needs_infer() {
91+
if ty::Term::from(t) == self.term {
92+
ControlFlow::Break(())
93+
} else {
94+
t.super_visit_with(self)
95+
}
96+
} else {
97+
ControlFlow::Continue(())
98+
}
99+
}
100+
101+
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
102+
if c.needs_infer() {
103+
if ty::Term::from(c) == self.term {
104+
ControlFlow::Break(())
105+
} else {
106+
c.super_visit_with(self)
107+
}
108+
} else {
109+
ControlFlow::Continue(())
110+
}
111+
}
112+
}
113+
114+
let mut visitor = ContainsTerm { term: goal.predicate.term };
115+
116+
term_is_infer
117+
&& goal.predicate.projection_ty.visit_with(&mut visitor).is_continue()
118+
&& goal.param_env.visit_with(&mut visitor).is_continue()
119+
}
120+
121+
#[instrument(level = "debug", skip(self, param_env), ret)]
122+
pub(super) fn eq<T: ToTrace<'tcx>>(
123+
&self,
124+
param_env: ty::ParamEnv<'tcx>,
125+
lhs: T,
126+
rhs: T,
127+
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
128+
self.infcx
129+
.at(&ObligationCause::dummy(), param_env)
130+
.eq(lhs, rhs)
131+
.map(|InferOk { value: (), obligations }| {
132+
obligations.into_iter().map(|o| o.into()).collect()
133+
})
134+
.map_err(|e| {
135+
debug!(?e, "failed to equate");
136+
NoSolution
137+
})
138+
}
139+
140+
pub(super) fn instantiate_binder_with_infer<T: TypeFoldable<'tcx> + Copy>(
141+
&self,
142+
value: ty::Binder<'tcx, T>,
143+
) -> T {
144+
self.infcx.instantiate_binder_with_fresh_vars(
145+
DUMMY_SP,
146+
LateBoundRegionConversionTime::HigherRankedType,
147+
value,
148+
)
149+
}
150+
151+
pub(super) fn instantiate_binder_with_placeholders<T: TypeFoldable<'tcx> + Copy>(
152+
&self,
153+
value: ty::Binder<'tcx, T>,
154+
) -> T {
155+
self.infcx.instantiate_binder_with_placeholders(value)
156+
}
157+
158+
pub(super) fn resolve_vars_if_possible<T>(&self, value: T) -> T
159+
where
160+
T: TypeFoldable<'tcx>,
161+
{
162+
self.infcx.resolve_vars_if_possible(value)
163+
}
164+
165+
pub(super) fn fresh_substs_for_item(&self, def_id: DefId) -> ty::SubstsRef<'tcx> {
166+
self.infcx.fresh_substs_for_item(DUMMY_SP, def_id)
167+
}
168+
169+
pub(super) fn universe(&self) -> ty::UniverseIndex {
170+
self.infcx.universe()
171+
}
172+
}

‎compiler/rustc_trait_selection/src/solve/infcx_ext.rs

Lines changed: 0 additions & 77 deletions
This file was deleted.

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

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,15 @@ use crate::solve::search_graph::OverflowHandler;
3535
use crate::traits::ObligationCause;
3636

3737
mod assembly;
38+
mod eval_ctxt;
3839
mod fulfill;
39-
mod infcx_ext;
4040
mod project_goals;
4141
mod search_graph;
4242
mod trait_goals;
4343

44+
pub use eval_ctxt::EvalCtxt;
4445
pub use fulfill::FulfillmentCtxt;
4546

46-
use self::infcx_ext::InferCtxtExt;
47-
4847
/// A goal is a statement, i.e. `predicate`, we want to prove
4948
/// given some assumptions, i.e. `param_env`.
5049
///
@@ -180,22 +179,7 @@ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> {
180179
}
181180
}
182181

183-
struct EvalCtxt<'a, 'tcx> {
184-
infcx: &'a InferCtxt<'tcx>,
185-
var_values: CanonicalVarValues<'tcx>,
186-
187-
search_graph: &'a mut search_graph::SearchGraph<'tcx>,
188-
189-
/// This field is used by a debug assertion in [`EvalCtxt::evaluate_goal`],
190-
/// see the comment in that method for more details.
191-
in_projection_eq_hack: bool,
192-
}
193-
194182
impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
195-
fn tcx(&self) -> TyCtxt<'tcx> {
196-
self.infcx.tcx
197-
}
198-
199183
/// The entry point of the solver.
200184
///
201185
/// This function deals with (coinductive) cycles, overflow, and caching
@@ -427,7 +411,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
427411

428412
let evaluate_normalizes_to = |ecx: &mut EvalCtxt<'_, 'tcx>, alias, other| {
429413
debug!("evaluate_normalizes_to(alias={:?}, other={:?})", alias, other);
430-
let r = ecx.infcx.probe(|_| {
414+
let r = ecx.probe(|ecx| {
431415
let (_, certainty) = ecx.evaluate_goal(goal.with(
432416
tcx,
433417
ty::Binder::dummy(ty::ProjectionPredicate {
@@ -462,10 +446,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
462446
// Evaluate all 3 potential candidates for the alias' being equal
463447
candidates.push(evaluate_normalizes_to(self, alias_lhs, goal.predicate.1));
464448
candidates.push(evaluate_normalizes_to(self, alias_rhs, goal.predicate.0));
465-
candidates.push(self.infcx.probe(|_| {
449+
candidates.push(self.probe(|this| {
466450
debug!("compute_alias_eq_goal: alias defids are equal, equating substs");
467-
let nested_goals = self.infcx.eq(goal.param_env, alias_lhs, alias_rhs)?;
468-
self.evaluate_all_and_make_canonical_response(nested_goals)
451+
let nested_goals = this.eq(goal.param_env, alias_lhs, alias_rhs)?;
452+
this.evaluate_all_and_make_canonical_response(nested_goals)
469453
}));
470454

471455
debug!(?candidates);
@@ -481,7 +465,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
481465
goal: Goal<'tcx, (ty::Const<'tcx>, Ty<'tcx>)>,
482466
) -> QueryResult<'tcx> {
483467
let (ct, ty) = goal.predicate;
484-
let nested_goals = self.infcx.eq(goal.param_env, ct.ty(), ty)?;
468+
let nested_goals = self.eq(goal.param_env, ct.ty(), ty)?;
485469
self.evaluate_all_and_make_canonical_response(nested_goals)
486470
}
487471
}

‎compiler/rustc_trait_selection/src/solve/project_goals.rs

Lines changed: 12 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use crate::traits::{specialization_graph, translate_substs};
22

33
use super::assembly;
4-
use super::infcx_ext::InferCtxtExt;
54
use super::trait_goals::structural_traits;
65
use super::{Certainty, EvalCtxt, Goal, QueryResult};
76
use rustc_errors::ErrorGuaranteed;
@@ -13,12 +12,11 @@ use rustc_infer::traits::query::NoSolution;
1312
use rustc_infer::traits::specialization_graph::LeafDef;
1413
use rustc_infer::traits::Reveal;
1514
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
15+
use rustc_middle::ty::ProjectionPredicate;
1616
use rustc_middle::ty::{self, Ty, TyCtxt};
17-
use rustc_middle::ty::{ir::TypeVisitor, ProjectionPredicate, TypeSuperVisitable};
1817
use rustc_middle::ty::{ToPredicate, TypeVisitable};
1918
use rustc_span::{sym, DUMMY_SP};
2019
use std::iter;
21-
use std::ops::ControlFlow;
2220

2321
impl<'tcx> EvalCtxt<'_, 'tcx> {
2422
pub(super) fn compute_projection_goal(
@@ -38,8 +36,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
3836
} else {
3937
let predicate = goal.predicate;
4038
let unconstrained_rhs = match predicate.term.unpack() {
41-
ty::TermKind::Ty(_) => self.infcx.next_ty_infer().into(),
42-
ty::TermKind::Const(ct) => self.infcx.next_const_infer(ct.ty()).into(),
39+
ty::TermKind::Ty(_) => self.next_ty_infer().into(),
40+
ty::TermKind::Const(ct) => self.next_const_infer(ct.ty()).into(),
4341
};
4442
let unconstrained_predicate = ty::Clause::Projection(ProjectionPredicate {
4543
projection_ty: goal.predicate.projection_ty,
@@ -49,8 +47,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
4947
this.evaluate_goal(goal.with(this.tcx(), unconstrained_predicate))
5048
})?;
5149

52-
let nested_eq_goals =
53-
self.infcx.eq(goal.param_env, unconstrained_rhs, predicate.term)?;
50+
let nested_eq_goals = self.eq(goal.param_env, unconstrained_rhs, predicate.term)?;
5451
let eval_certainty = self.evaluate_all(nested_eq_goals)?;
5552
self.make_canonical_response(normalize_certainty.unify_and(eval_certainty))
5653
}
@@ -65,73 +62,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
6562
result
6663
}
6764

68-
/// Is the projection predicate is of the form `exists<T> <Ty as Trait>::Assoc = T`.
69-
///
70-
/// This is the case if the `term` is an inference variable in the innermost universe
71-
/// and does not occur in any other part of the predicate.
72-
fn term_is_fully_unconstrained(&self, goal: Goal<'tcx, ProjectionPredicate<'tcx>>) -> bool {
73-
let infcx = self.infcx;
74-
let term_is_infer = match goal.predicate.term.unpack() {
75-
ty::TermKind::Ty(ty) => {
76-
if let &ty::Infer(ty::TyVar(vid)) = ty.kind() {
77-
match infcx.probe_ty_var(vid) {
78-
Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
79-
Err(universe) => universe == infcx.universe(),
80-
}
81-
} else {
82-
false
83-
}
84-
}
85-
ty::TermKind::Const(ct) => {
86-
if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() {
87-
match self.infcx.probe_const_var(vid) {
88-
Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
89-
Err(universe) => universe == infcx.universe(),
90-
}
91-
} else {
92-
false
93-
}
94-
}
95-
};
96-
97-
// Guard against `<T as Trait<?0>>::Assoc = ?0>`.
98-
struct ContainsTerm<'tcx> {
99-
term: ty::Term<'tcx>,
100-
}
101-
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTerm<'tcx> {
102-
type BreakTy = ();
103-
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
104-
if t.needs_infer() {
105-
if ty::Term::from(t) == self.term {
106-
ControlFlow::Break(())
107-
} else {
108-
t.super_visit_with(self)
109-
}
110-
} else {
111-
ControlFlow::Continue(())
112-
}
113-
}
114-
115-
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
116-
if c.needs_infer() {
117-
if ty::Term::from(c) == self.term {
118-
ControlFlow::Break(())
119-
} else {
120-
c.super_visit_with(self)
121-
}
122-
} else {
123-
ControlFlow::Continue(())
124-
}
125-
}
126-
}
127-
128-
let mut visitor = ContainsTerm { term: goal.predicate.term };
129-
130-
term_is_infer
131-
&& goal.predicate.projection_ty.visit_with(&mut visitor).is_continue()
132-
&& goal.param_env.visit_with(&mut visitor).is_continue()
133-
}
134-
13565
/// After normalizing the projection to `normalized_alias` with the given
13666
/// `normalization_certainty`, constrain the inference variable `term` to it
13767
/// and return a query response.
@@ -145,7 +75,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
14575
//
14676
// It can however be ambiguous when the `normalized_alias` contains a projection.
14777
let nested_goals = self
148-
.infcx
14978
.eq(goal.param_env, goal.predicate.term, normalized_alias.into())
15079
.expect("failed to unify with unconstrained term");
15180
let rhs_certainty =
@@ -177,10 +106,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
177106
if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred()
178107
&& poly_projection_pred.projection_def_id() == goal.predicate.def_id()
179108
{
180-
ecx.infcx.probe(|_| {
109+
ecx.probe(|ecx| {
181110
let assumption_projection_pred =
182-
ecx.infcx.instantiate_binder_with_infer(poly_projection_pred);
183-
let mut nested_goals = ecx.infcx.eq(
111+
ecx.instantiate_binder_with_infer(poly_projection_pred);
112+
let mut nested_goals = ecx.eq(
184113
goal.param_env,
185114
goal.predicate.projection_ty,
186115
assumption_projection_pred.projection_ty,
@@ -215,11 +144,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
215144
return Err(NoSolution);
216145
}
217146

218-
ecx.infcx.probe(|_| {
219-
let impl_substs = ecx.infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
147+
ecx.probe(|ecx| {
148+
let impl_substs = ecx.fresh_substs_for_item(impl_def_id);
220149
let impl_trait_ref = impl_trait_ref.subst(tcx, impl_substs);
221150

222-
let mut nested_goals = ecx.infcx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?;
151+
let mut nested_goals = ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?;
223152
let where_clause_bounds = tcx
224153
.predicates_of(impl_def_id)
225154
.instantiate(tcx, impl_substs)
@@ -367,7 +296,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
367296
goal: Goal<'tcx, Self>,
368297
) -> QueryResult<'tcx> {
369298
let tcx = ecx.tcx();
370-
ecx.infcx.probe(|_| {
299+
ecx.probe(|ecx| {
371300
let metadata_ty = match goal.predicate.self_ty().kind() {
372301
ty::Bool
373302
| ty::Char
@@ -546,8 +475,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
546475
goal: Goal<'tcx, Self>,
547476
) -> QueryResult<'tcx> {
548477
let discriminant = goal.predicate.self_ty().discriminant_ty(ecx.tcx());
549-
ecx.infcx
550-
.probe(|_| ecx.eq_term_and_make_canonical_response(goal, Certainty::Yes, discriminant))
478+
ecx.probe(|ecx| ecx.eq_term_and_make_canonical_response(goal, Certainty::Yes, discriminant))
551479
}
552480
}
553481

‎compiler/rustc_trait_selection/src/solve/trait_goals.rs

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@
33
use std::iter;
44

55
use super::assembly;
6-
use super::infcx_ext::InferCtxtExt;
76
use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, QueryResult};
87
use rustc_hir::def_id::DefId;
98
use rustc_hir::LangItem;
10-
use rustc_infer::infer::InferCtxt;
119
use rustc_infer::traits::query::NoSolution;
1210
use rustc_infer::traits::util::supertraits;
1311
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
@@ -45,12 +43,12 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
4543
return Err(NoSolution);
4644
}
4745

48-
ecx.infcx.probe(|_| {
49-
let impl_substs = ecx.infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
46+
ecx.probe(|ecx| {
47+
let impl_substs = ecx.fresh_substs_for_item(impl_def_id);
5048
let impl_trait_ref = impl_trait_ref.subst(tcx, impl_substs);
5149

5250
let mut nested_goals =
53-
ecx.infcx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?;
51+
ecx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?;
5452
let where_clause_bounds = tcx
5553
.predicates_of(impl_def_id)
5654
.instantiate(tcx, impl_substs)
@@ -72,10 +70,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
7270
&& poly_trait_pred.def_id() == goal.predicate.def_id()
7371
{
7472
// FIXME: Constness and polarity
75-
ecx.infcx.probe(|_| {
73+
ecx.probe(|ecx| {
7674
let assumption_trait_pred =
77-
ecx.infcx.instantiate_binder_with_infer(poly_trait_pred);
78-
let mut nested_goals = ecx.infcx.eq(
75+
ecx.instantiate_binder_with_infer(poly_trait_pred);
76+
let mut nested_goals = ecx.eq(
7977
goal.param_env,
8078
goal.predicate.trait_ref,
8179
assumption_trait_pred.trait_ref,
@@ -118,7 +116,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
118116
) -> QueryResult<'tcx> {
119117
let tcx = ecx.tcx();
120118

121-
ecx.infcx.probe(|_| {
119+
ecx.probe(|ecx| {
122120
let nested_obligations = tcx
123121
.predicates_of(goal.predicate.def_id())
124122
.instantiate(tcx, goal.predicate.trait_ref.substs);
@@ -275,7 +273,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
275273
if b_ty.is_ty_var() {
276274
return ecx.make_canonical_response(Certainty::AMBIGUOUS);
277275
}
278-
ecx.infcx.probe(|_| {
276+
ecx.probe(|ecx| {
279277
match (a_ty.kind(), b_ty.kind()) {
280278
// Trait upcasting, or `dyn Trait + Auto + 'a` -> `dyn Trait + 'b`
281279
(&ty::Dynamic(_, _, ty::Dyn), &ty::Dynamic(_, _, ty::Dyn)) => {
@@ -318,7 +316,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
318316
// `[T; n]` -> `[T]` unsizing
319317
(&ty::Array(a_elem_ty, ..), &ty::Slice(b_elem_ty)) => {
320318
// We just require that the element type stays the same
321-
let nested_goals = ecx.infcx.eq(goal.param_env, a_elem_ty, b_elem_ty)?;
319+
let nested_goals = ecx.eq(goal.param_env, a_elem_ty, b_elem_ty)?;
322320
ecx.evaluate_all_and_make_canonical_response(nested_goals)
323321
}
324322
// Struct unsizing `Struct<T>` -> `Struct<U>` where `T: Unsize<U>`
@@ -352,7 +350,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
352350

353351
// Finally, we require that `TailA: Unsize<TailB>` for the tail field
354352
// types.
355-
let mut nested_goals = ecx.infcx.eq(goal.param_env, unsized_a_ty, b_ty)?;
353+
let mut nested_goals = ecx.eq(goal.param_env, unsized_a_ty, b_ty)?;
356354
nested_goals.push(goal.with(
357355
tcx,
358356
ty::Binder::dummy(
@@ -371,7 +369,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
371369

372370
// Substitute just the tail field of B., and require that they're equal.
373371
let unsized_a_ty = tcx.mk_tup(a_rest_tys.iter().chain([b_last_ty]).copied());
374-
let mut nested_goals = ecx.infcx.eq(goal.param_env, unsized_a_ty, b_ty)?;
372+
let mut nested_goals = ecx.eq(goal.param_env, unsized_a_ty, b_ty)?;
375373

376374
// Similar to ADTs, require that the rest of the fields are equal.
377375
nested_goals.push(goal.with(
@@ -411,7 +409,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
411409
}
412410

413411
let mut unsize_dyn_to_principal = |principal: Option<ty::PolyExistentialTraitRef<'tcx>>| {
414-
ecx.infcx.probe(|_| -> Result<_, NoSolution> {
412+
ecx.probe(|ecx| -> Result<_, NoSolution> {
415413
// Require that all of the trait predicates from A match B, except for
416414
// the auto traits. We do this by constructing a new A type with B's
417415
// auto traits, and equating these types.
@@ -431,7 +429,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
431429
let new_a_ty = tcx.mk_dynamic(new_a_data, b_region, ty::Dyn);
432430

433431
// We also require that A's lifetime outlives B's lifetime.
434-
let mut nested_obligations = ecx.infcx.eq(goal.param_env, new_a_ty, b_ty)?;
432+
let mut nested_obligations = ecx.eq(goal.param_env, new_a_ty, b_ty)?;
435433
nested_obligations.push(
436434
goal.with(tcx, ty::Binder::dummy(ty::OutlivesPredicate(a_region, b_region))),
437435
);
@@ -482,16 +480,16 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
482480
fn probe_and_evaluate_goal_for_constituent_tys(
483481
&mut self,
484482
goal: Goal<'tcx, TraitPredicate<'tcx>>,
485-
constituent_tys: impl Fn(&InferCtxt<'tcx>, Ty<'tcx>) -> Result<Vec<Ty<'tcx>>, NoSolution>,
483+
constituent_tys: impl Fn(&EvalCtxt<'_, 'tcx>, Ty<'tcx>) -> Result<Vec<Ty<'tcx>>, NoSolution>,
486484
) -> QueryResult<'tcx> {
487-
self.infcx.probe(|_| {
488-
self.evaluate_all_and_make_canonical_response(
489-
constituent_tys(self.infcx, goal.predicate.self_ty())?
485+
self.probe(|this| {
486+
this.evaluate_all_and_make_canonical_response(
487+
constituent_tys(this, goal.predicate.self_ty())?
490488
.into_iter()
491489
.map(|ty| {
492490
goal.with(
493-
self.tcx(),
494-
ty::Binder::dummy(goal.predicate.with_self_ty(self.tcx(), ty)),
491+
this.tcx(),
492+
ty::Binder::dummy(goal.predicate.with_self_ty(this.tcx(), ty)),
495493
)
496494
})
497495
.collect(),

‎compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
use rustc_hir::{Movability, Mutability};
2-
use rustc_infer::{infer::InferCtxt, traits::query::NoSolution};
2+
use rustc_infer::traits::query::NoSolution;
33
use rustc_middle::ty::{self, Ty, TyCtxt};
44

5+
use crate::solve::EvalCtxt;
6+
57
// Calculates the constituent types of a type for `auto trait` purposes.
68
//
79
// For types with an "existential" binder, i.e. generator witnesses, we also
810
// instantiate the binder with placeholders eagerly.
911
pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
10-
infcx: &InferCtxt<'tcx>,
12+
ecx: &EvalCtxt<'_, 'tcx>,
1113
ty: Ty<'tcx>,
1214
) -> Result<Vec<Ty<'tcx>>, NoSolution> {
13-
let tcx = infcx.tcx;
15+
let tcx = ecx.tcx();
1416
match *ty.kind() {
1517
ty::Uint(_)
1618
| ty::Int(_)
@@ -53,9 +55,7 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
5355
Ok(vec![generator_substs.tupled_upvars_ty(), generator_substs.witness()])
5456
}
5557

56-
ty::GeneratorWitness(types) => {
57-
Ok(infcx.instantiate_binder_with_placeholders(types).to_vec())
58-
}
58+
ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()),
5959

6060
ty::GeneratorWitnessMIR(..) => todo!(),
6161

@@ -74,7 +74,7 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
7474
}
7575

7676
pub(super) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
77-
infcx: &InferCtxt<'tcx>,
77+
ecx: &EvalCtxt<'_, 'tcx>,
7878
ty: Ty<'tcx>,
7979
) -> Result<Vec<Ty<'tcx>>, NoSolution> {
8080
match *ty.kind() {
@@ -113,18 +113,18 @@ pub(super) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
113113
ty::Tuple(tys) => Ok(tys.to_vec()),
114114

115115
ty::Adt(def, substs) => {
116-
let sized_crit = def.sized_constraint(infcx.tcx);
116+
let sized_crit = def.sized_constraint(ecx.tcx());
117117
Ok(sized_crit
118118
.0
119119
.iter()
120-
.map(|ty| sized_crit.rebind(*ty).subst(infcx.tcx, substs))
120+
.map(|ty| sized_crit.rebind(*ty).subst(ecx.tcx(), substs))
121121
.collect())
122122
}
123123
}
124124
}
125125

126126
pub(super) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
127-
infcx: &InferCtxt<'tcx>,
127+
ecx: &EvalCtxt<'_, 'tcx>,
128128
ty: Ty<'tcx>,
129129
) -> Result<Vec<Ty<'tcx>>, NoSolution> {
130130
match *ty.kind() {
@@ -165,17 +165,15 @@ pub(super) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
165165
ty::Closure(_, substs) => Ok(vec![substs.as_closure().tupled_upvars_ty()]),
166166

167167
ty::Generator(_, substs, Movability::Movable) => {
168-
if infcx.tcx.features().generator_clone {
168+
if ecx.tcx().features().generator_clone {
169169
let generator = substs.as_generator();
170170
Ok(vec![generator.tupled_upvars_ty(), generator.witness()])
171171
} else {
172172
Err(NoSolution)
173173
}
174174
}
175175

176-
ty::GeneratorWitness(types) => {
177-
Ok(infcx.instantiate_binder_with_placeholders(types).to_vec())
178-
}
176+
ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()),
179177

180178
ty::GeneratorWitnessMIR(..) => todo!(),
181179
}

0 commit comments

Comments
 (0)
Please sign in to comment.