Skip to content

Commit b0f1afd

Browse files
Rework var resolution in InferCtxtLike, uplift EagerResolver
1 parent 569fb43 commit b0f1afd

File tree

12 files changed

+198
-159
lines changed

12 files changed

+198
-159
lines changed

compiler/rustc_infer/src/infer/mod.rs

+27-17
Original file line numberDiff line numberDiff line change
@@ -369,33 +369,43 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
369369
}
370370
}
371371

372-
fn root_ty_var(&self, vid: TyVid) -> TyVid {
373-
self.root_var(vid)
372+
fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> {
373+
self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid)
374374
}
375375

376-
fn probe_ty_var(&self, vid: TyVid) -> Option<Ty<'tcx>> {
377-
self.probe_ty_var(vid).ok()
376+
fn defining_opaque_types(&self) -> &'tcx ty::List<LocalDefId> {
377+
self.defining_opaque_types
378378
}
379379

380-
fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> Option<ty::Region<'tcx>> {
381-
let re = self
382-
.inner
383-
.borrow_mut()
384-
.unwrap_region_constraints()
385-
.opportunistic_resolve_var(self.tcx, vid);
386-
if *re == ty::ReVar(vid) { None } else { Some(re) }
380+
fn opportunistic_resolve_ty_var(&self, vid: TyVid) -> Ty<'tcx> {
381+
match self.probe_ty_var(vid) {
382+
Ok(ty) => ty,
383+
Err(_) => Ty::new_var(self.tcx, self.root_var(vid)),
384+
}
387385
}
388386

389-
fn root_ct_var(&self, vid: ConstVid) -> ConstVid {
390-
self.root_const_var(vid)
387+
fn opportunistic_resolve_int_var(&self, vid: IntVid) -> Ty<'tcx> {
388+
self.opportunistic_resolve_int_var(vid)
391389
}
392390

393-
fn probe_ct_var(&self, vid: ConstVid) -> Option<ty::Const<'tcx>> {
394-
self.probe_const_var(vid).ok()
391+
fn opportunistic_resolve_float_var(&self, vid: FloatVid) -> Ty<'tcx> {
392+
self.opportunistic_resolve_float_var(vid)
395393
}
396394

397-
fn defining_opaque_types(&self) -> &'tcx ty::List<LocalDefId> {
398-
self.defining_opaque_types
395+
fn opportunistic_resolve_ct_var(&self, vid: ConstVid, ty: Ty<'tcx>) -> ty::Const<'tcx> {
396+
match self.probe_const_var(vid) {
397+
Ok(ct) => ct,
398+
Err(_) => ty::Const::new_var(self.tcx, self.root_const_var(vid), ty),
399+
}
400+
}
401+
402+
fn opportunistic_resolve_effect_var(&self, vid: EffectVid, ty: Ty<'tcx>) -> ty::Const<'tcx> {
403+
match self.probe_effect_var(vid) {
404+
Some(ct) => ct,
405+
None => {
406+
ty::Const::new_infer(self.tcx, InferConst::EffectVar(self.root_effect_var(vid)), ty)
407+
}
408+
}
399409
}
400410
}
401411

compiler/rustc_infer/src/infer/resolve.rs

-81
Original file line numberDiff line numberDiff line change
@@ -173,84 +173,3 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for FullTypeResolver<'a, 'tcx> {
173173
}
174174
}
175175
}
176-
177-
///////////////////////////////////////////////////////////////////////////
178-
// EAGER RESOLUTION
179-
180-
/// Resolves ty, region, and const vars to their inferred values or their root vars.
181-
pub struct EagerResolver<'a, 'tcx> {
182-
infcx: &'a InferCtxt<'tcx>,
183-
}
184-
185-
impl<'a, 'tcx> EagerResolver<'a, 'tcx> {
186-
pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self {
187-
EagerResolver { infcx }
188-
}
189-
}
190-
191-
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EagerResolver<'_, 'tcx> {
192-
fn interner(&self) -> TyCtxt<'tcx> {
193-
self.infcx.tcx
194-
}
195-
196-
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
197-
match *t.kind() {
198-
ty::Infer(ty::TyVar(vid)) => match self.infcx.probe_ty_var(vid) {
199-
Ok(t) => t.fold_with(self),
200-
Err(_) => Ty::new_var(self.infcx.tcx, self.infcx.root_var(vid)),
201-
},
202-
ty::Infer(ty::IntVar(vid)) => self.infcx.opportunistic_resolve_int_var(vid),
203-
ty::Infer(ty::FloatVar(vid)) => self.infcx.opportunistic_resolve_float_var(vid),
204-
_ => {
205-
if t.has_infer() {
206-
t.super_fold_with(self)
207-
} else {
208-
t
209-
}
210-
}
211-
}
212-
}
213-
214-
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
215-
match *r {
216-
ty::ReVar(vid) => self
217-
.infcx
218-
.inner
219-
.borrow_mut()
220-
.unwrap_region_constraints()
221-
.opportunistic_resolve_var(self.infcx.tcx, vid),
222-
_ => r,
223-
}
224-
}
225-
226-
fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
227-
match c.kind() {
228-
ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
229-
// FIXME: we need to fold the ty too, I think.
230-
match self.infcx.probe_const_var(vid) {
231-
Ok(c) => c.fold_with(self),
232-
Err(_) => {
233-
ty::Const::new_var(self.infcx.tcx, self.infcx.root_const_var(vid), c.ty())
234-
}
235-
}
236-
}
237-
ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)) => {
238-
debug_assert_eq!(c.ty(), self.infcx.tcx.types.bool);
239-
self.infcx.probe_effect_var(vid).unwrap_or_else(|| {
240-
ty::Const::new_infer(
241-
self.infcx.tcx,
242-
ty::InferConst::EffectVar(self.infcx.root_effect_var(vid)),
243-
self.infcx.tcx.types.bool,
244-
)
245-
})
246-
}
247-
_ => {
248-
if c.has_infer() {
249-
c.super_fold_with(self)
250-
} else {
251-
c
252-
}
253-
}
254-
}
255-
}
256-
}

compiler/rustc_middle/src/ty/consts.rs

+8
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,14 @@ impl<'tcx> Const<'tcx> {
175175
}
176176

177177
impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
178+
fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferConst, ty: Ty<'tcx>) -> Self {
179+
Const::new_infer(tcx, infer, ty)
180+
}
181+
182+
fn new_var(tcx: TyCtxt<'tcx>, vid: ty::ConstVid, ty: Ty<'tcx>) -> Self {
183+
Const::new_var(tcx, vid, ty)
184+
}
185+
178186
fn new_anon_bound(
179187
tcx: TyCtxt<'tcx>,
180188
debruijn: ty::DebruijnIndex,

compiler/rustc_middle/src/ty/sty.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1611,6 +1611,14 @@ impl<'tcx> rustc_type_ir::inherent::Ty<TyCtxt<'tcx>> for Ty<'tcx> {
16111611
tcx.types.bool
16121612
}
16131613

1614+
fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferTy) -> Self {
1615+
Ty::new_infer(tcx, infer)
1616+
}
1617+
1618+
fn new_var(tcx: TyCtxt<'tcx>, vid: ty::TyVid) -> Self {
1619+
Ty::new_var(tcx, vid)
1620+
}
1621+
16141622
fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
16151623
Ty::new_bound(tcx, debruijn, ty::BoundTy { var, kind: ty::BoundTyKind::Anon })
16161624
}

compiler/rustc_next_trait_solver/src/canonicalizer.rs

+24-18
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
268268
ty::ReVar(vid) => {
269269
assert_eq!(
270270
self.infcx.opportunistic_resolve_lt_var(vid),
271-
None,
271+
r,
272272
"region vid should have been resolved fully before canonicalization"
273273
);
274274
match self.canonicalize_mode {
@@ -302,13 +302,8 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
302302
ty::Infer(i) => match i {
303303
ty::TyVar(vid) => {
304304
assert_eq!(
305-
self.infcx.root_ty_var(vid),
306-
vid,
307-
"ty vid should have been resolved fully before canonicalization"
308-
);
309-
assert_eq!(
310-
self.infcx.probe_ty_var(vid),
311-
None,
305+
self.infcx.opportunistic_resolve_ty_var(vid),
306+
t,
312307
"ty vid should have been resolved fully before canonicalization"
313308
);
314309

@@ -318,10 +313,24 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
318313
.unwrap_or_else(|| panic!("ty var should have been resolved: {t:?}")),
319314
))
320315
}
321-
ty::IntVar(_) => CanonicalVarKind::Ty(CanonicalTyVarKind::Int),
322-
ty::FloatVar(_) => CanonicalVarKind::Ty(CanonicalTyVarKind::Float),
316+
ty::IntVar(vid) => {
317+
assert_eq!(
318+
self.infcx.opportunistic_resolve_int_var(vid),
319+
t,
320+
"ty vid should have been resolved fully before canonicalization"
321+
);
322+
CanonicalVarKind::Ty(CanonicalTyVarKind::Int)
323+
}
324+
ty::FloatVar(vid) => {
325+
assert_eq!(
326+
self.infcx.opportunistic_resolve_float_var(vid),
327+
t,
328+
"ty vid should have been resolved fully before canonicalization"
329+
);
330+
CanonicalVarKind::Ty(CanonicalTyVarKind::Float)
331+
}
323332
ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => {
324-
todo!()
333+
panic!("fresh vars not expected in canonicalization")
325334
}
326335
},
327336
ty::Placeholder(placeholder) => match self.canonicalize_mode {
@@ -387,14 +396,11 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
387396
let kind = match c.kind() {
388397
ty::ConstKind::Infer(i) => match i {
389398
ty::InferConst::Var(vid) => {
399+
// We compare `kind`s here because we've folded the `ty` with `RegionsToStatic`
400+
// so we'll get a mismatch in types if it actually changed any regions.
390401
assert_eq!(
391-
self.infcx.root_ct_var(vid),
392-
vid,
393-
"region vid should have been resolved fully before canonicalization"
394-
);
395-
assert_eq!(
396-
self.infcx.probe_ct_var(vid),
397-
None,
402+
self.infcx.opportunistic_resolve_ct_var(vid, ty).kind(),
403+
c.kind(),
398404
"region vid should have been resolved fully before canonicalization"
399405
);
400406
CanonicalVarKind::Const(self.infcx.universe_of_ct(vid).unwrap(), ty)
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
pub mod canonicalizer;
2+
pub mod resolve;
23
pub mod solve;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
2+
use rustc_type_ir::inherent::*;
3+
use rustc_type_ir::visit::TypeVisitableExt;
4+
use rustc_type_ir::{self as ty, InferCtxtLike, Interner};
5+
6+
///////////////////////////////////////////////////////////////////////////
7+
// EAGER RESOLUTION
8+
9+
/// Resolves ty, region, and const vars to their inferred values or their root vars.
10+
pub struct EagerResolver<
11+
'a,
12+
Infcx: InferCtxtLike<Interner = I>,
13+
I: Interner = <Infcx as InferCtxtLike>::Interner,
14+
> {
15+
infcx: &'a Infcx,
16+
}
17+
18+
impl<'a, Infcx: InferCtxtLike> EagerResolver<'a, Infcx> {
19+
pub fn new(infcx: &'a Infcx) -> Self {
20+
EagerResolver { infcx }
21+
}
22+
}
23+
24+
impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I> for EagerResolver<'_, Infcx> {
25+
fn interner(&self) -> I {
26+
self.infcx.interner()
27+
}
28+
29+
fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
30+
match t.kind() {
31+
ty::Infer(ty::TyVar(vid)) => {
32+
let resolved = self.infcx.opportunistic_resolve_ty_var(vid);
33+
if t != resolved && resolved.has_infer() {
34+
resolved.fold_with(self)
35+
} else {
36+
resolved
37+
}
38+
}
39+
ty::Infer(ty::IntVar(vid)) => self.infcx.opportunistic_resolve_int_var(vid),
40+
ty::Infer(ty::FloatVar(vid)) => self.infcx.opportunistic_resolve_float_var(vid),
41+
_ => {
42+
if t.has_infer() {
43+
t.super_fold_with(self)
44+
} else {
45+
t
46+
}
47+
}
48+
}
49+
}
50+
51+
fn fold_region(&mut self, r: I::Region) -> I::Region {
52+
match r.kind() {
53+
ty::ReVar(vid) => self.infcx.opportunistic_resolve_lt_var(vid),
54+
_ => r,
55+
}
56+
}
57+
58+
fn fold_const(&mut self, c: I::Const) -> I::Const {
59+
match c.kind() {
60+
ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
61+
let ty = c.ty().fold_with(self);
62+
let resolved = self.infcx.opportunistic_resolve_ct_var(vid, ty);
63+
if c != resolved && resolved.has_infer() {
64+
resolved.fold_with(self)
65+
} else {
66+
resolved
67+
}
68+
}
69+
ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)) => {
70+
let bool = Ty::new_bool(self.infcx.interner());
71+
debug_assert_eq!(c.ty(), bool);
72+
self.infcx.opportunistic_resolve_effect_var(vid, bool)
73+
}
74+
_ => {
75+
if c.has_infer() {
76+
c.super_fold_with(self)
77+
} else {
78+
c
79+
}
80+
}
81+
}
82+
}
83+
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use rustc_index::IndexVec;
1818
use rustc_infer::infer::canonical::query_response::make_query_region_constraints;
1919
use rustc_infer::infer::canonical::CanonicalVarValues;
2020
use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints};
21-
use rustc_infer::infer::resolve::EagerResolver;
2221
use rustc_infer::infer::RegionVariableOrigin;
2322
use rustc_infer::infer::{InferCtxt, InferOk};
2423
use rustc_infer::traits::solve::NestedNormalizationGoals;
@@ -31,6 +30,7 @@ use rustc_middle::traits::solve::{
3130
use rustc_middle::traits::ObligationCause;
3231
use rustc_middle::ty::{self, BoundVar, GenericArgKind, Ty, TyCtxt, TypeFoldable};
3332
use rustc_next_trait_solver::canonicalizer::{CanonicalizeMode, Canonicalizer};
33+
use rustc_next_trait_solver::resolve::EagerResolver;
3434
use rustc_span::{Span, DUMMY_SP};
3535
use std::assert_matches::assert_matches;
3636
use std::iter;

compiler/rustc_trait_selection/src/solve/inspect/analyse.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
1212
use rustc_ast_ir::try_visit;
1313
use rustc_ast_ir::visit::VisitorResult;
14-
use rustc_infer::infer::resolve::EagerResolver;
1514
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
1615
use rustc_macros::extension;
1716
use rustc_middle::traits::query::NoSolution;
@@ -20,6 +19,7 @@ use rustc_middle::traits::solve::{Certainty, Goal};
2019
use rustc_middle::traits::ObligationCause;
2120
use rustc_middle::ty::{TyCtxt, TypeFoldable};
2221
use rustc_middle::{bug, ty};
22+
use rustc_next_trait_solver::resolve::EagerResolver;
2323
use rustc_span::{Span, DUMMY_SP};
2424

2525
use crate::solve::eval_ctxt::canonical;

0 commit comments

Comments
 (0)