Skip to content

Commit d1d761f

Browse files
authoredDec 7, 2023
Rollup merge of rust-lang#117586 - compiler-errors:the-canonicalizer, r=lcnr
Uplift the (new solver) canonicalizer into `rustc_next_trait_solver` Uplifts the new trait solver's canonicalizer into a new crate called `rustc_next_trait_solver`. The crate name is literally a bikeshed-avoidance name, so let's not block this PR on that -- renames are welcome later. There are a host of other changes that were required to make this possible: * Expose a `ConstTy` trait to get the `Interner::Ty` from a `Interner::Const`. * Expose some constructor methods to construct `Bound` variants. These are currently methods defined on the interner themselves, but they could be pulled into traits later. * Expose a `IntoKind` trait to turn a `Ty`/`Const`/`Region` into their corresponding `*Kind`s. * Some minor tweaks to other APIs in `rustc_type_ir`. The canonicalizer code itself is best reviewed **with whitespace ignored.** r? `@lcnr`
2 parents 95aa0b4 + 1c1df45 commit d1d761f

File tree

20 files changed

+478
-260
lines changed

20 files changed

+478
-260
lines changed
 

‎Cargo.lock

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4308,6 +4308,13 @@ dependencies = [
43084308
"tracing",
43094309
]
43104310

4311+
[[package]]
4312+
name = "rustc_next_trait_solver"
4313+
version = "0.0.0"
4314+
dependencies = [
4315+
"rustc_type_ir",
4316+
]
4317+
43114318
[[package]]
43124319
name = "rustc_parse"
43134320
version = "0.0.0"
@@ -4576,6 +4583,7 @@ dependencies = [
45764583
"rustc_infer",
45774584
"rustc_macros",
45784585
"rustc_middle",
4586+
"rustc_next_trait_solver",
45794587
"rustc_parse_format",
45804588
"rustc_query_system",
45814589
"rustc_session",

‎compiler/rustc_infer/src/infer/mod.rs

Lines changed: 50 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -345,37 +345,61 @@ pub struct InferCtxt<'tcx> {
345345
impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
346346
type Interner = TyCtxt<'tcx>;
347347

348-
fn universe_of_ty(&self, ty: ty::InferTy) -> Option<ty::UniverseIndex> {
349-
use InferTy::*;
350-
match ty {
351-
// FIXME(BoxyUwU): this is kind of jank and means that printing unresolved
352-
// ty infers will give you the universe of the var it resolved to not the universe
353-
// it actually had. It also means that if you have a `?0.1` and infer it to `u8` then
354-
// try to print out `?0.1` it will just print `?0`.
355-
TyVar(ty_vid) => match self.probe_ty_var(ty_vid) {
356-
Err(universe) => Some(universe),
357-
Ok(_) => None,
358-
},
359-
IntVar(_) | FloatVar(_) | FreshTy(_) | FreshIntTy(_) | FreshFloatTy(_) => None,
348+
fn interner(&self) -> TyCtxt<'tcx> {
349+
self.tcx
350+
}
351+
352+
fn universe_of_ty(&self, vid: TyVid) -> Option<ty::UniverseIndex> {
353+
// FIXME(BoxyUwU): this is kind of jank and means that printing unresolved
354+
// ty infers will give you the universe of the var it resolved to not the universe
355+
// it actually had. It also means that if you have a `?0.1` and infer it to `u8` then
356+
// try to print out `?0.1` it will just print `?0`.
357+
match self.probe_ty_var(vid) {
358+
Err(universe) => Some(universe),
359+
Ok(_) => None,
360360
}
361361
}
362362

363-
fn universe_of_ct(&self, ct: ty::InferConst) -> Option<ty::UniverseIndex> {
364-
use ty::InferConst::*;
365-
match ct {
366-
// Same issue as with `universe_of_ty`
367-
Var(ct_vid) => match self.probe_const_var(ct_vid) {
368-
Err(universe) => Some(universe),
369-
Ok(_) => None,
370-
},
371-
EffectVar(_) => None,
372-
Fresh(_) => None,
363+
fn universe_of_ct(&self, ct: ConstVid) -> Option<ty::UniverseIndex> {
364+
// Same issue as with `universe_of_ty`
365+
match self.probe_const_var(ct) {
366+
Err(universe) => Some(universe),
367+
Ok(_) => None,
373368
}
374369
}
375370

376371
fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex> {
377372
Some(self.universe_of_region_vid(lt))
378373
}
374+
375+
fn root_ty_var(&self, vid: TyVid) -> TyVid {
376+
self.root_var(vid)
377+
}
378+
379+
fn probe_ty_var(&self, vid: TyVid) -> Option<Ty<'tcx>> {
380+
self.probe_ty_var(vid).ok()
381+
}
382+
383+
fn root_lt_var(&self, vid: ty::RegionVid) -> ty::RegionVid {
384+
self.root_region_var(vid)
385+
}
386+
387+
fn probe_lt_var(&self, vid: ty::RegionVid) -> Option<ty::Region<'tcx>> {
388+
let re = self
389+
.inner
390+
.borrow_mut()
391+
.unwrap_region_constraints()
392+
.opportunistic_resolve_var(self.tcx, vid);
393+
if re.is_var() { None } else { Some(re) }
394+
}
395+
396+
fn root_ct_var(&self, vid: ConstVid) -> ConstVid {
397+
self.root_const_var(vid)
398+
}
399+
400+
fn probe_ct_var(&self, vid: ConstVid) -> Option<ty::Const<'tcx>> {
401+
self.probe_const_var(vid).ok()
402+
}
379403
}
380404

381405
/// See the `error_reporting` module for more details.
@@ -1347,6 +1371,10 @@ impl<'tcx> InferCtxt<'tcx> {
13471371
self.inner.borrow_mut().type_variables().root_var(var)
13481372
}
13491373

1374+
pub fn root_region_var(&self, var: ty::RegionVid) -> ty::RegionVid {
1375+
self.inner.borrow_mut().unwrap_region_constraints().root_var(var)
1376+
}
1377+
13501378
pub fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid {
13511379
self.inner.borrow_mut().const_unification_table().find(var).vid
13521380
}

‎compiler/rustc_infer/src/infer/region_constraints/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,11 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
623623
}
624624
}
625625

626+
pub fn root_var(&mut self, vid: ty::RegionVid) -> ty::RegionVid {
627+
let mut ut = self.unification_table_mut(); // FIXME(rust-lang/ena#42): unnecessary mut
628+
ut.find(vid).vid
629+
}
630+
626631
fn combine_map(&mut self, t: CombineMapType) -> &mut CombineMap<'tcx> {
627632
match t {
628633
Glb => &mut self.glbs,

‎compiler/rustc_middle/src/ty/consts.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use crate::middle::resolve_bound_vars as rbv;
22
use crate::mir::interpret::{AllocId, ErrorHandled, LitToConstInput, Scalar};
3-
use crate::ty::{self, GenericArgs, ParamEnv, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt};
3+
use crate::ty::{
4+
self, ConstTy, GenericArgs, IntoKind, ParamEnv, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt,
5+
};
46
use rustc_data_structures::intern::Interned;
57
use rustc_error_messages::MultiSpan;
68
use rustc_hir as hir;
@@ -26,6 +28,20 @@ use super::sty::ConstKind;
2628
#[rustc_pass_by_value]
2729
pub struct Const<'tcx>(pub(super) Interned<'tcx, WithCachedTypeInfo<ConstData<'tcx>>>);
2830

31+
impl<'tcx> IntoKind for Const<'tcx> {
32+
type Kind = ConstKind<'tcx>;
33+
34+
fn kind(self) -> ConstKind<'tcx> {
35+
self.kind().clone()
36+
}
37+
}
38+
39+
impl<'tcx> ConstTy<TyCtxt<'tcx>> for Const<'tcx> {
40+
fn ty(self) -> Ty<'tcx> {
41+
self.ty()
42+
}
43+
}
44+
2945
/// Typed constant value.
3046
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, TyEncodable, TyDecodable)]
3147
pub struct ConstData<'tcx> {

‎compiler/rustc_middle/src/ty/context.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,31 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
130130
) -> (Self::Ty, ty::Mutability) {
131131
(ty, mutbl)
132132
}
133+
134+
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
135+
self.mk_canonical_var_infos(infos)
136+
}
137+
138+
fn mk_bound_ty(self, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self::Ty {
139+
Ty::new_bound(self, debruijn, ty::BoundTy { var, kind: ty::BoundTyKind::Anon })
140+
}
141+
142+
fn mk_bound_region(self, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self::Region {
143+
Region::new_bound(
144+
self,
145+
debruijn,
146+
ty::BoundRegion { var, kind: ty::BoundRegionKind::BrAnon },
147+
)
148+
}
149+
150+
fn mk_bound_const(
151+
self,
152+
debruijn: ty::DebruijnIndex,
153+
var: ty::BoundVar,
154+
ty: Self::Ty,
155+
) -> Self::Const {
156+
Const::new_bound(self, debruijn, var, ty)
157+
}
133158
}
134159

135160
type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;

‎compiler/rustc_middle/src/ty/mod.rs

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,10 @@ use std::ops::ControlFlow;
6565
use std::{fmt, str};
6666

6767
pub use crate::ty::diagnostics::*;
68-
pub use rustc_type_ir::AliasKind::*;
6968
pub use rustc_type_ir::ConstKind::{
7069
Bound as BoundCt, Error as ErrorCt, Expr as ExprCt, Infer as InferCt, Param as ParamCt,
7170
Placeholder as PlaceholderCt, Unevaluated, Value,
7271
};
73-
pub use rustc_type_ir::DynKind::*;
74-
pub use rustc_type_ir::InferTy::*;
75-
pub use rustc_type_ir::RegionKind::*;
76-
pub use rustc_type_ir::TyKind::*;
7772
pub use rustc_type_ir::*;
7873

7974
pub use self::binding::BindingMode;
@@ -474,6 +469,14 @@ pub struct CReaderCacheKey {
474469
#[rustc_pass_by_value]
475470
pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>);
476471

472+
impl<'tcx> IntoKind for Ty<'tcx> {
473+
type Kind = TyKind<'tcx>;
474+
475+
fn kind(self) -> TyKind<'tcx> {
476+
self.kind().clone()
477+
}
478+
}
479+
477480
impl EarlyParamRegion {
478481
/// Does this early bound region have a name? Early bound regions normally
479482
/// always have names except when using anonymous lifetimes (`'_`).
@@ -1506,34 +1509,42 @@ pub struct Placeholder<T> {
15061509

15071510
pub type PlaceholderRegion = Placeholder<BoundRegion>;
15081511

1509-
impl rustc_type_ir::Placeholder for PlaceholderRegion {
1510-
fn universe(&self) -> UniverseIndex {
1512+
impl PlaceholderLike for PlaceholderRegion {
1513+
fn universe(self) -> UniverseIndex {
15111514
self.universe
15121515
}
15131516

1514-
fn var(&self) -> BoundVar {
1517+
fn var(self) -> BoundVar {
15151518
self.bound.var
15161519
}
15171520

15181521
fn with_updated_universe(self, ui: UniverseIndex) -> Self {
15191522
Placeholder { universe: ui, ..self }
15201523
}
1524+
1525+
fn new(ui: UniverseIndex, var: BoundVar) -> Self {
1526+
Placeholder { universe: ui, bound: BoundRegion { var, kind: BoundRegionKind::BrAnon } }
1527+
}
15211528
}
15221529

15231530
pub type PlaceholderType = Placeholder<BoundTy>;
15241531

1525-
impl rustc_type_ir::Placeholder for PlaceholderType {
1526-
fn universe(&self) -> UniverseIndex {
1532+
impl PlaceholderLike for PlaceholderType {
1533+
fn universe(self) -> UniverseIndex {
15271534
self.universe
15281535
}
15291536

1530-
fn var(&self) -> BoundVar {
1537+
fn var(self) -> BoundVar {
15311538
self.bound.var
15321539
}
15331540

15341541
fn with_updated_universe(self, ui: UniverseIndex) -> Self {
15351542
Placeholder { universe: ui, ..self }
15361543
}
1544+
1545+
fn new(ui: UniverseIndex, var: BoundVar) -> Self {
1546+
Placeholder { universe: ui, bound: BoundTy { var, kind: BoundTyKind::Anon } }
1547+
}
15371548
}
15381549

15391550
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
@@ -1545,18 +1556,22 @@ pub struct BoundConst<'tcx> {
15451556

15461557
pub type PlaceholderConst = Placeholder<BoundVar>;
15471558

1548-
impl rustc_type_ir::Placeholder for PlaceholderConst {
1549-
fn universe(&self) -> UniverseIndex {
1559+
impl PlaceholderLike for PlaceholderConst {
1560+
fn universe(self) -> UniverseIndex {
15501561
self.universe
15511562
}
15521563

1553-
fn var(&self) -> BoundVar {
1564+
fn var(self) -> BoundVar {
15541565
self.bound
15551566
}
15561567

15571568
fn with_updated_universe(self, ui: UniverseIndex) -> Self {
15581569
Placeholder { universe: ui, ..self }
15591570
}
1571+
1572+
fn new(ui: UniverseIndex, var: BoundVar) -> Self {
1573+
Placeholder { universe: ui, bound: var }
1574+
}
15601575
}
15611576

15621577
/// When type checking, we use the `ParamEnv` to track

‎compiler/rustc_middle/src/ty/sty.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::infer::canonical::Canonical;
66
use crate::ty::visit::ValidateBoundVars;
77
use crate::ty::InferTy::*;
88
use crate::ty::{
9-
self, AdtDef, Discr, Term, Ty, TyCtxt, TypeFlags, TypeSuperVisitable, TypeVisitable,
9+
self, AdtDef, Discr, IntoKind, Term, Ty, TyCtxt, TypeFlags, TypeSuperVisitable, TypeVisitable,
1010
TypeVisitableExt, TypeVisitor,
1111
};
1212
use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
@@ -1477,6 +1477,14 @@ impl ParamConst {
14771477
#[rustc_pass_by_value]
14781478
pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>);
14791479

1480+
impl<'tcx> IntoKind for Region<'tcx> {
1481+
type Kind = RegionKind<'tcx>;
1482+
1483+
fn kind(self) -> RegionKind<'tcx> {
1484+
*self
1485+
}
1486+
}
1487+
14801488
impl<'tcx> Region<'tcx> {
14811489
#[inline]
14821490
pub fn new_early_param(
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "rustc_next_trait_solver"
3+
version = "0.0.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
rustc_type_ir = { path = "../rustc_type_ir", default-features = false }
8+
9+
[features]
10+
default = ["nightly"]
11+
nightly = [
12+
"rustc_type_ir/nightly",
13+
]

‎compiler/rustc_trait_selection/src/solve/canonicalize.rs renamed to ‎compiler/rustc_next_trait_solver/src/canonicalizer.rs

Lines changed: 127 additions & 133 deletions
Large diffs are not rendered by default.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod canonicalizer;

‎compiler/rustc_trait_selection/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ rustc_index = { path = "../rustc_index" }
1515
rustc_infer = { path = "../rustc_infer" }
1616
rustc_macros = { path = "../rustc_macros" }
1717
rustc_middle = { path = "../rustc_middle" }
18+
rustc_next_trait_solver = { path = "../rustc_next_trait_solver" }
1819
rustc_parse_format = { path = "../rustc_parse_format" }
1920
rustc_query_system = { path = "../rustc_query_system" }
2021
rustc_session = { path = "../rustc_session" }

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
//!
1010
//! [c]: https://rustc-dev-guide.rust-lang.org/solve/canonicalization.html
1111
use super::{CanonicalInput, Certainty, EvalCtxt, Goal};
12-
use crate::solve::canonicalize::{CanonicalizeMode, Canonicalizer};
1312
use crate::solve::{
1413
inspect, response_no_constraints_raw, CanonicalResponse, QueryResult, Response,
1514
};
@@ -27,6 +26,7 @@ use rustc_middle::traits::solve::{
2726
};
2827
use rustc_middle::traits::ObligationCause;
2928
use rustc_middle::ty::{self, BoundVar, GenericArgKind, Ty, TyCtxt, TypeFoldable};
29+
use rustc_next_trait_solver::canonicalizer::{CanonicalizeMode, Canonicalizer};
3030
use rustc_span::DUMMY_SP;
3131
use std::iter;
3232
use std::ops::Deref;

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ use rustc_middle::ty::{
3030

3131
mod alias_relate;
3232
mod assembly;
33-
mod canonicalize;
3433
mod eval_ctxt;
3534
mod fulfill;
3635
pub mod inspect;

‎compiler/rustc_type_ir/src/canonical.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::ops::ControlFlow;
44

55
use crate::fold::{FallibleTypeFolder, TypeFoldable};
66
use crate::visit::{TypeVisitable, TypeVisitor};
7-
use crate::{Interner, Placeholder, UniverseIndex};
7+
use crate::{Interner, PlaceholderLike, UniverseIndex};
88

99
/// A "canonicalized" type `V` is one where all free inference
1010
/// variables have been rewritten to "canonical vars". These are
@@ -157,7 +157,7 @@ where
157157
}
158158

159159
impl<I: Interner> CanonicalVarInfo<I> {
160-
pub fn universe(&self) -> UniverseIndex {
160+
pub fn universe(self) -> UniverseIndex {
161161
self.kind.universe()
162162
}
163163

@@ -305,11 +305,11 @@ where
305305
}
306306

307307
impl<I: Interner> CanonicalVarKind<I> {
308-
pub fn universe(&self) -> UniverseIndex {
308+
pub fn universe(self) -> UniverseIndex {
309309
match self {
310-
CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) => *ui,
311-
CanonicalVarKind::Region(ui) => *ui,
312-
CanonicalVarKind::Const(ui, _) => *ui,
310+
CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) => ui,
311+
CanonicalVarKind::Region(ui) => ui,
312+
CanonicalVarKind::Const(ui, _) => ui,
313313
CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe(),
314314
CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe(),
315315
CanonicalVarKind::PlaceholderConst(placeholder, _) => placeholder.universe(),

‎compiler/rustc_type_ir/src/const_kind.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ impl<I: Interner> DebugWithInfcx<I> for ConstKind<I> {
8181
match this.data {
8282
Param(param) => write!(f, "{param:?}"),
8383
Infer(var) => write!(f, "{:?}", &this.wrap(var)),
84-
Bound(debruijn, var) => crate::debug_bound_var(f, *debruijn, var.clone()),
84+
Bound(debruijn, var) => crate::debug_bound_var(f, *debruijn, var),
8585
Placeholder(placeholder) => write!(f, "{placeholder:?}"),
8686
Unevaluated(uv) => {
8787
write!(f, "{:?}", &this.wrap(uv))
@@ -146,15 +146,15 @@ impl<I: Interner> DebugWithInfcx<I> for InferConst {
146146
this: WithInfcx<'_, Infcx, &Self>,
147147
f: &mut core::fmt::Formatter<'_>,
148148
) -> core::fmt::Result {
149-
match this.infcx.universe_of_ct(*this.data) {
150-
None => write!(f, "{:?}", this.data),
151-
Some(universe) => match *this.data {
152-
InferConst::Var(vid) => write!(f, "?{}_{}c", vid.index(), universe.index()),
153-
InferConst::EffectVar(vid) => write!(f, "?{}_{}e", vid.index(), universe.index()),
154-
InferConst::Fresh(_) => {
155-
unreachable!()
156-
}
149+
match *this.data {
150+
InferConst::Var(vid) => match this.infcx.universe_of_ct(vid) {
151+
None => write!(f, "{:?}", this.data),
152+
Some(universe) => write!(f, "?{}_{}c", vid.index(), universe.index()),
157153
},
154+
InferConst::EffectVar(vid) => write!(f, "?{}e", vid.index()),
155+
InferConst::Fresh(_) => {
156+
unreachable!()
157+
}
158158
}
159159
}
160160
}

‎compiler/rustc_type_ir/src/debug.rs

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,50 @@
1-
use crate::{InferConst, InferTy, Interner, UniverseIndex};
1+
use crate::{ConstVid, InferCtxtLike, Interner, TyVid, UniverseIndex};
22

33
use core::fmt;
44
use std::marker::PhantomData;
55

6-
pub trait InferCtxtLike {
7-
type Interner: Interner;
6+
pub struct NoInfcx<I>(PhantomData<I>);
87

9-
fn universe_of_ty(&self, ty: InferTy) -> Option<UniverseIndex>;
8+
impl<I: Interner> InferCtxtLike for NoInfcx<I> {
9+
type Interner = I;
1010

11-
fn universe_of_lt(
12-
&self,
13-
lt: <Self::Interner as Interner>::InferRegion,
14-
) -> Option<UniverseIndex>;
11+
fn interner(&self) -> Self::Interner {
12+
unreachable!()
13+
}
1514

16-
fn universe_of_ct(&self, ct: InferConst) -> Option<UniverseIndex>;
17-
}
15+
fn universe_of_ty(&self, _ty: TyVid) -> Option<UniverseIndex> {
16+
None
17+
}
1818

19-
pub struct NoInfcx<I>(PhantomData<I>);
19+
fn universe_of_lt(&self, _lt: I::InferRegion) -> Option<UniverseIndex> {
20+
None
21+
}
2022

21-
impl<I: Interner> InferCtxtLike for NoInfcx<I> {
22-
type Interner = I;
23+
fn universe_of_ct(&self, _ct: ConstVid) -> Option<UniverseIndex> {
24+
None
25+
}
26+
27+
fn root_ty_var(&self, vid: TyVid) -> TyVid {
28+
vid
29+
}
2330

24-
fn universe_of_ty(&self, _ty: InferTy) -> Option<UniverseIndex> {
31+
fn probe_ty_var(&self, _vid: TyVid) -> Option<I::Ty> {
2532
None
2633
}
2734

28-
fn universe_of_ct(&self, _ct: InferConst) -> Option<UniverseIndex> {
35+
fn root_lt_var(&self, vid: I::InferRegion) -> I::InferRegion {
36+
vid
37+
}
38+
39+
fn probe_lt_var(&self, _vid: I::InferRegion) -> Option<I::Region> {
2940
None
3041
}
3142

32-
fn universe_of_lt(&self, _lt: <I as Interner>::InferRegion) -> Option<UniverseIndex> {
43+
fn root_ct_var(&self, vid: ConstVid) -> ConstVid {
44+
vid
45+
}
46+
47+
fn probe_ct_var(&self, _vid: ConstVid) -> Option<I::Const> {
3348
None
3449
}
3550
}

‎compiler/rustc_type_ir/src/infcx.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
use crate::{ConstVid, Interner, TyVid, UniverseIndex};
2+
3+
pub trait InferCtxtLike {
4+
type Interner: Interner;
5+
6+
fn interner(&self) -> Self::Interner;
7+
8+
fn universe_of_ty(&self, ty: TyVid) -> Option<UniverseIndex>;
9+
10+
/// Resolve `TyVid` to its root `TyVid`.
11+
fn root_ty_var(&self, vid: TyVid) -> TyVid;
12+
13+
/// Resolve `TyVid` to its inferred type, if it has been equated with a non-infer type.
14+
fn probe_ty_var(&self, vid: TyVid) -> Option<<Self::Interner as Interner>::Ty>;
15+
16+
fn universe_of_lt(
17+
&self,
18+
lt: <Self::Interner as Interner>::InferRegion,
19+
) -> Option<UniverseIndex>;
20+
21+
/// Resolve `InferRegion` to its root `InferRegion`.
22+
fn root_lt_var(
23+
&self,
24+
vid: <Self::Interner as Interner>::InferRegion,
25+
) -> <Self::Interner as Interner>::InferRegion;
26+
27+
/// Resolve `InferRegion` to its inferred region, if it has been equated with a non-infer region.
28+
fn probe_lt_var(
29+
&self,
30+
vid: <Self::Interner as Interner>::InferRegion,
31+
) -> Option<<Self::Interner as Interner>::Region>;
32+
33+
fn universe_of_ct(&self, ct: ConstVid) -> Option<UniverseIndex>;
34+
35+
/// Resolve `ConstVid` to its root `ConstVid`.
36+
fn root_ct_var(&self, vid: ConstVid) -> ConstVid;
37+
38+
/// Resolve `ConstVid` to its inferred type, if it has been equated with a non-infer type.
39+
fn probe_ct_var(&self, vid: ConstVid) -> Option<<Self::Interner as Interner>::Const>;
40+
}

‎compiler/rustc_type_ir/src/interner.rs

Lines changed: 80 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,74 +2,112 @@ use smallvec::SmallVec;
22
use std::fmt::Debug;
33
use std::hash::Hash;
44

5-
use crate::{BoundVar, DebugWithInfcx, Mutability, UniverseIndex};
5+
use crate::{
6+
BoundVar, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, Mutability, RegionKind,
7+
TyKind, UniverseIndex,
8+
};
69

710
pub trait Interner: Sized {
8-
type DefId: Clone + Debug + Hash + Ord;
9-
type AdtDef: Clone + Debug + Hash + Ord;
11+
type DefId: Copy + Debug + Hash + Ord;
12+
type AdtDef: Copy + Debug + Hash + Ord;
1013

11-
type GenericArgs: Clone
14+
type GenericArgs: Copy
1215
+ DebugWithInfcx<Self>
1316
+ Hash
1417
+ Ord
1518
+ IntoIterator<Item = Self::GenericArg>;
16-
type GenericArg: Clone + DebugWithInfcx<Self> + Hash + Ord;
17-
type Term: Clone + Debug + Hash + Ord;
19+
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Ord;
20+
type Term: Copy + Debug + Hash + Ord;
1821

1922
type Binder<T>;
20-
type TypeAndMut: Clone + Debug + Hash + Ord;
21-
type CanonicalVars: Clone + Debug + Hash + Eq;
23+
type TypeAndMut: Copy + Debug + Hash + Ord;
24+
type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarInfo<Self>>;
2225

2326
// Kinds of tys
24-
type Ty: Clone + DebugWithInfcx<Self> + Hash + Ord;
25-
type Tys: Clone + Debug + Hash + Ord + IntoIterator<Item = Self::Ty>;
26-
type AliasTy: Clone + DebugWithInfcx<Self> + Hash + Ord;
27-
type ParamTy: Clone + Debug + Hash + Ord;
28-
type BoundTy: Clone + Debug + Hash + Ord;
29-
type PlaceholderTy: Clone + Debug + Hash + Ord + Placeholder;
27+
type Ty: Copy
28+
+ DebugWithInfcx<Self>
29+
+ Hash
30+
+ Ord
31+
+ Into<Self::GenericArg>
32+
+ IntoKind<Kind = TyKind<Self>>;
33+
type Tys: Copy + Debug + Hash + Ord + IntoIterator<Item = Self::Ty>;
34+
type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Ord;
35+
type ParamTy: Copy + Debug + Hash + Ord;
36+
type BoundTy: Copy + Debug + Hash + Ord;
37+
type PlaceholderTy: Copy + Debug + Hash + Ord + PlaceholderLike;
3038

3139
// Things stored inside of tys
32-
type ErrorGuaranteed: Clone + Debug + Hash + Ord;
33-
type BoundExistentialPredicates: Clone + DebugWithInfcx<Self> + Hash + Ord;
34-
type PolyFnSig: Clone + DebugWithInfcx<Self> + Hash + Ord;
35-
type AllocId: Clone + Debug + Hash + Ord;
40+
type ErrorGuaranteed: Copy + Debug + Hash + Ord;
41+
type BoundExistentialPredicates: Copy + DebugWithInfcx<Self> + Hash + Ord;
42+
type PolyFnSig: Copy + DebugWithInfcx<Self> + Hash + Ord;
43+
type AllocId: Copy + Debug + Hash + Ord;
3644

3745
// Kinds of consts
38-
type Const: Clone + DebugWithInfcx<Self> + Hash + Ord;
39-
type AliasConst: Clone + DebugWithInfcx<Self> + Hash + Ord;
40-
type PlaceholderConst: Clone + Debug + Hash + Ord + Placeholder;
41-
type ParamConst: Clone + Debug + Hash + Ord;
42-
type BoundConst: Clone + Debug + Hash + Ord;
43-
type ValueConst: Clone + Debug + Hash + Ord;
44-
type ExprConst: Clone + DebugWithInfcx<Self> + Hash + Ord;
46+
type Const: Copy
47+
+ DebugWithInfcx<Self>
48+
+ Hash
49+
+ Ord
50+
+ Into<Self::GenericArg>
51+
+ IntoKind<Kind = ConstKind<Self>>
52+
+ ConstTy<Self>;
53+
type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Ord;
54+
type PlaceholderConst: Copy + Debug + Hash + Ord + PlaceholderLike;
55+
type ParamConst: Copy + Debug + Hash + Ord;
56+
type BoundConst: Copy + Debug + Hash + Ord;
57+
type ValueConst: Copy + Debug + Hash + Ord;
58+
type ExprConst: Copy + DebugWithInfcx<Self> + Hash + Ord;
4559

4660
// Kinds of regions
47-
type Region: Clone + DebugWithInfcx<Self> + Hash + Ord;
48-
type EarlyParamRegion: Clone + Debug + Hash + Ord;
49-
type BoundRegion: Clone + Debug + Hash + Ord;
50-
type LateParamRegion: Clone + Debug + Hash + Ord;
51-
type InferRegion: Clone + DebugWithInfcx<Self> + Hash + Ord;
52-
type PlaceholderRegion: Clone + Debug + Hash + Ord + Placeholder;
61+
type Region: Copy
62+
+ DebugWithInfcx<Self>
63+
+ Hash
64+
+ Ord
65+
+ Into<Self::GenericArg>
66+
+ IntoKind<Kind = RegionKind<Self>>;
67+
type EarlyParamRegion: Copy + Debug + Hash + Ord;
68+
type LateParamRegion: Copy + Debug + Hash + Ord;
69+
type BoundRegion: Copy + Debug + Hash + Ord;
70+
type InferRegion: Copy + DebugWithInfcx<Self> + Hash + Ord;
71+
type PlaceholderRegion: Copy + Debug + Hash + Ord + PlaceholderLike;
5372

5473
// Predicates
55-
type Predicate: Clone + Debug + Hash + Eq;
56-
type TraitPredicate: Clone + Debug + Hash + Eq;
57-
type RegionOutlivesPredicate: Clone + Debug + Hash + Eq;
58-
type TypeOutlivesPredicate: Clone + Debug + Hash + Eq;
59-
type ProjectionPredicate: Clone + Debug + Hash + Eq;
60-
type SubtypePredicate: Clone + Debug + Hash + Eq;
61-
type CoercePredicate: Clone + Debug + Hash + Eq;
62-
type ClosureKind: Clone + Debug + Hash + Eq;
74+
type Predicate: Copy + Debug + Hash + Eq;
75+
type TraitPredicate: Copy + Debug + Hash + Eq;
76+
type RegionOutlivesPredicate: Copy + Debug + Hash + Eq;
77+
type TypeOutlivesPredicate: Copy + Debug + Hash + Eq;
78+
type ProjectionPredicate: Copy + Debug + Hash + Eq;
79+
type SubtypePredicate: Copy + Debug + Hash + Eq;
80+
type CoercePredicate: Copy + Debug + Hash + Eq;
81+
type ClosureKind: Copy + Debug + Hash + Eq;
6382

6483
fn ty_and_mut_to_parts(ty_and_mut: Self::TypeAndMut) -> (Self::Ty, Mutability);
84+
85+
fn mk_canonical_var_infos(self, infos: &[CanonicalVarInfo<Self>]) -> Self::CanonicalVars;
86+
87+
// FIXME: We should not have all these constructors on `Interner`, but as functions on some trait.
88+
fn mk_bound_ty(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Ty;
89+
fn mk_bound_region(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Region;
90+
fn mk_bound_const(self, debruijn: DebruijnIndex, var: BoundVar, ty: Self::Ty) -> Self::Const;
6591
}
6692

6793
/// Common capabilities of placeholder kinds
68-
pub trait Placeholder {
69-
fn universe(&self) -> UniverseIndex;
70-
fn var(&self) -> BoundVar;
94+
pub trait PlaceholderLike {
95+
fn universe(self) -> UniverseIndex;
96+
fn var(self) -> BoundVar;
7197

7298
fn with_updated_universe(self, ui: UniverseIndex) -> Self;
99+
100+
fn new(ui: UniverseIndex, var: BoundVar) -> Self;
101+
}
102+
103+
pub trait IntoKind {
104+
type Kind;
105+
106+
fn kind(self) -> Self::Kind;
107+
}
108+
109+
pub trait ConstTy<I: Interner> {
110+
fn ty(self) -> I::Ty;
73111
}
74112

75113
/// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter`

‎compiler/rustc_type_ir/src/lib.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
)]
55
#![deny(rustc::untranslatable_diagnostic)]
66
#![deny(rustc::diagnostic_outside_of_impl)]
7+
#![allow(rustc::usage_of_ty_tykind)]
78
#![cfg_attr(feature = "nightly", allow(internal_features))]
89

910
#[cfg(feature = "nightly")]
@@ -35,6 +36,7 @@ mod canonical;
3536
mod const_kind;
3637
mod debug;
3738
mod flags;
39+
mod infcx;
3840
mod interner;
3941
mod predicate_kind;
4042
mod region_kind;
@@ -43,13 +45,19 @@ pub use canonical::*;
4345
#[cfg(feature = "nightly")]
4446
pub use codec::*;
4547
pub use const_kind::*;
46-
pub use debug::{DebugWithInfcx, InferCtxtLike, WithInfcx};
48+
pub use debug::{DebugWithInfcx, WithInfcx};
4749
pub use flags::*;
50+
pub use infcx::InferCtxtLike;
4851
pub use interner::*;
4952
pub use predicate_kind::*;
5053
pub use region_kind::*;
5154
pub use ty_info::*;
5255
pub use ty_kind::*;
56+
pub use AliasKind::*;
57+
pub use DynKind::*;
58+
pub use InferTy::*;
59+
pub use RegionKind::*;
60+
pub use TyKind::*;
5361

5462
rustc_index::newtype_index! {
5563
/// A [De Bruijn index][dbi] is a standard means of representing
@@ -337,6 +345,12 @@ impl UniverseIndex {
337345
}
338346
}
339347

348+
impl Default for UniverseIndex {
349+
fn default() -> Self {
350+
Self::ROOT
351+
}
352+
}
353+
340354
rustc_index::newtype_index! {
341355
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
342356
#[encodable]

‎compiler/rustc_type_ir/src/ty_kind.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![allow(rustc::usage_of_ty_tykind)]
2-
31
#[cfg(feature = "nightly")]
42
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
53
#[cfg(feature = "nightly")]
@@ -394,7 +392,7 @@ impl<I: Interner> DebugWithInfcx<I> for TyKind<I> {
394392
Float(float) => write!(f, "{float:?}"),
395393
Adt(d, s) => {
396394
write!(f, "{d:?}")?;
397-
let mut s = s.clone().into_iter();
395+
let mut s = s.into_iter();
398396
let first = s.next();
399397
match first {
400398
Some(first) => write!(f, "<{:?}", first)?,
@@ -412,7 +410,7 @@ impl<I: Interner> DebugWithInfcx<I> for TyKind<I> {
412410
Array(t, c) => write!(f, "[{:?}; {:?}]", &this.wrap(t), &this.wrap(c)),
413411
Slice(t) => write!(f, "[{:?}]", &this.wrap(t)),
414412
RawPtr(p) => {
415-
let (ty, mutbl) = I::ty_and_mut_to_parts(p.clone());
413+
let (ty, mutbl) = I::ty_and_mut_to_parts(*p);
416414
match mutbl {
417415
Mutability::Mut => write!(f, "*mut "),
418416
Mutability::Not => write!(f, "*const "),
@@ -442,7 +440,7 @@ impl<I: Interner> DebugWithInfcx<I> for TyKind<I> {
442440
Tuple(t) => {
443441
write!(f, "(")?;
444442
let mut count = 0;
445-
for ty in t.clone() {
443+
for ty in *t {
446444
if count > 0 {
447445
write!(f, ", ")?;
448446
}
@@ -820,15 +818,15 @@ impl<I: Interner> DebugWithInfcx<I> for InferTy {
820818
this: WithInfcx<'_, Infcx, &Self>,
821819
f: &mut fmt::Formatter<'_>,
822820
) -> fmt::Result {
823-
use InferTy::*;
824-
match this.infcx.universe_of_ty(*this.data) {
825-
None => write!(f, "{:?}", this.data),
826-
Some(universe) => match *this.data {
827-
TyVar(ty_vid) => write!(f, "?{}_{}t", ty_vid.index(), universe.index()),
828-
IntVar(_) | FloatVar(_) | FreshTy(_) | FreshIntTy(_) | FreshFloatTy(_) => {
829-
unreachable!()
821+
match this.data {
822+
InferTy::TyVar(vid) => {
823+
if let Some(universe) = this.infcx.universe_of_ty(*vid) {
824+
write!(f, "?{}_{}t", vid.index(), universe.index())
825+
} else {
826+
write!(f, "{:?}", this.data)
830827
}
831-
},
828+
}
829+
_ => write!(f, "{:?}", this.data),
832830
}
833831
}
834832
}

0 commit comments

Comments
 (0)
Please sign in to comment.