Skip to content

Commit 0e2f912

Browse files
committed
Auto merge of #52984 - fabric-and-ink:remove-canonical-var, r=scalexm
Replace CanonicalVar with DebruijnIndex Close #49887
2 parents 31b97f7 + 2f41c0d commit 0e2f912

File tree

13 files changed

+65
-49
lines changed

13 files changed

+65
-49
lines changed

src/librustc/ich/impls_ty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionVid {
147147
}
148148
}
149149

150-
impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::CanonicalVar {
150+
impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::BoundTyIndex {
151151
#[inline]
152152
fn hash_stable<W: StableHasherResult>(&self,
153153
hcx: &mut StableHashingContext<'gcx>,
@@ -915,7 +915,7 @@ impl_stable_hash_for!(enum ty::InferTy {
915915
FreshTy(a),
916916
FreshIntTy(a),
917917
FreshFloatTy(a),
918-
CanonicalTy(a),
918+
BoundTy(a),
919919
});
920920

921921
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>

src/librustc/infer/canonical/canonicalizer.rs

+20-13
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use infer::InferCtxt;
2323
use std::sync::atomic::Ordering;
2424
use ty::fold::{TypeFoldable, TypeFolder};
2525
use ty::subst::Kind;
26-
use ty::{self, CanonicalVar, Lift, List, Ty, TyCtxt, TypeFlags};
26+
use ty::{self, BoundTy, BoundTyIndex, Lift, List, Ty, TyCtxt, TypeFlags};
2727

2828
use rustc_data_structures::fx::FxHashMap;
2929
use rustc_data_structures::indexed_vec::Idx;
@@ -225,7 +225,7 @@ struct Canonicalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
225225
query_state: &'cx mut OriginalQueryValues<'tcx>,
226226
// Note that indices is only used once `var_values` is big enough to be
227227
// heap-allocated.
228-
indices: FxHashMap<Kind<'tcx>, CanonicalVar>,
228+
indices: FxHashMap<Kind<'tcx>, BoundTyIndex>,
229229
canonicalize_region_mode: &'cx dyn CanonicalizeRegionMode,
230230
needs_canonical_flags: TypeFlags,
231231
}
@@ -283,7 +283,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
283283
bug!("encountered a fresh type during canonicalization")
284284
}
285285

286-
ty::Infer(ty::CanonicalTy(_)) => {
286+
ty::Infer(ty::BoundTy(_)) => {
287287
bug!("encountered a canonical type during canonicalization")
288288
}
289289

@@ -393,7 +393,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
393393
/// or returns an existing variable if `kind` has already been
394394
/// seen. `kind` is expected to be an unbound variable (or
395395
/// potentially a free region).
396-
fn canonical_var(&mut self, info: CanonicalVarInfo, kind: Kind<'tcx>) -> CanonicalVar {
396+
fn canonical_var(&mut self, info: CanonicalVarInfo, kind: Kind<'tcx>) -> BoundTy {
397397
let Canonicalizer {
398398
variables,
399399
query_state,
@@ -408,12 +408,12 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
408408
// avoid allocations in those cases. We also don't use `indices` to
409409
// determine if a kind has been seen before until the limit of 8 has
410410
// been exceeded, to also avoid allocations for `indices`.
411-
if !var_values.spilled() {
411+
let var = if !var_values.spilled() {
412412
// `var_values` is stack-allocated. `indices` isn't used yet. Do a
413413
// direct linear search of `var_values`.
414414
if let Some(idx) = var_values.iter().position(|&k| k == kind) {
415415
// `kind` is already present in `var_values`.
416-
CanonicalVar::new(idx)
416+
BoundTyIndex::new(idx)
417417
} else {
418418
// `kind` isn't present in `var_values`. Append it. Likewise
419419
// for `info` and `variables`.
@@ -428,29 +428,35 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
428428
*indices = var_values
429429
.iter()
430430
.enumerate()
431-
.map(|(i, &kind)| (kind, CanonicalVar::new(i)))
431+
.map(|(i, &kind)| (kind, BoundTyIndex::new(i)))
432432
.collect();
433433
}
434434
// The cv is the index of the appended element.
435-
CanonicalVar::new(var_values.len() - 1)
435+
BoundTyIndex::new(var_values.len() - 1)
436436
}
437437
} else {
438438
// `var_values` is large. Do a hashmap search via `indices`.
439439
*indices.entry(kind).or_insert_with(|| {
440440
variables.push(info);
441441
var_values.push(kind);
442442
assert_eq!(variables.len(), var_values.len());
443-
CanonicalVar::new(variables.len() - 1)
443+
BoundTyIndex::new(variables.len() - 1)
444444
})
445+
};
446+
447+
BoundTy {
448+
level: ty::INNERMOST,
449+
var,
445450
}
446451
}
447452

448453
fn canonical_var_for_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
449454
let info = CanonicalVarInfo {
450455
kind: CanonicalVarKind::Region,
451456
};
452-
let cvar = self.canonical_var(info, r.into());
453-
self.tcx().mk_region(ty::ReCanonical(cvar))
457+
let b = self.canonical_var(info, r.into());
458+
debug_assert_eq!(ty::INNERMOST, b.level);
459+
self.tcx().mk_region(ty::ReCanonical(b.var))
454460
}
455461

456462
/// Given a type variable `ty_var` of the given kind, first check
@@ -466,8 +472,9 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
466472
let info = CanonicalVarInfo {
467473
kind: CanonicalVarKind::Ty(ty_kind),
468474
};
469-
let cvar = self.canonical_var(info, ty_var.into());
470-
self.tcx().mk_infer(ty::InferTy::CanonicalTy(cvar))
475+
let b = self.canonical_var(info, ty_var.into());
476+
debug_assert_eq!(ty::INNERMOST, b.level);
477+
self.tcx().mk_infer(ty::InferTy::BoundTy(b))
471478
}
472479
}
473480
}

src/librustc/infer/canonical/mod.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use std::ops::Index;
4040
use syntax::source_map::Span;
4141
use ty::fold::TypeFoldable;
4242
use ty::subst::Kind;
43-
use ty::{self, CanonicalVar, Lift, Region, List, TyCtxt};
43+
use ty::{self, BoundTyIndex, Lift, Region, List, TyCtxt};
4444

4545
mod canonicalizer;
4646

@@ -72,7 +72,7 @@ impl<'gcx> UseSpecializedDecodable for CanonicalVarInfos<'gcx> {}
7272
/// canonicalized query response.
7373
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
7474
pub struct CanonicalVarValues<'tcx> {
75-
pub var_values: IndexVec<CanonicalVar, Kind<'tcx>>,
75+
pub var_values: IndexVec<BoundTyIndex, Kind<'tcx>>,
7676
}
7777

7878
/// When we canonicalize a value to form a query, we wind up replacing
@@ -264,7 +264,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
264264
span: Span,
265265
variables: &List<CanonicalVarInfo>,
266266
) -> CanonicalVarValues<'tcx> {
267-
let var_values: IndexVec<CanonicalVar, Kind<'tcx>> = variables
267+
let var_values: IndexVec<BoundTyIndex, Kind<'tcx>> = variables
268268
.iter()
269269
.map(|info| self.fresh_inference_var_for_canonical_var(span, *info))
270270
.collect();
@@ -367,10 +367,10 @@ BraceStructLiftImpl! {
367367
} where R: Lift<'tcx>
368368
}
369369

370-
impl<'tcx> Index<CanonicalVar> for CanonicalVarValues<'tcx> {
370+
impl<'tcx> Index<BoundTyIndex> for CanonicalVarValues<'tcx> {
371371
type Output = Kind<'tcx>;
372372

373-
fn index(&self, value: CanonicalVar) -> &Kind<'tcx> {
373+
fn index(&self, value: BoundTyIndex) -> &Kind<'tcx> {
374374
&self.var_values[value]
375375
}
376376
}

src/librustc/infer/canonical/query_response.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use traits::{FulfillmentContext, TraitEngine};
3535
use traits::{Obligation, ObligationCause, PredicateObligation};
3636
use ty::fold::TypeFoldable;
3737
use ty::subst::{Kind, UnpackedKind};
38-
use ty::{self, CanonicalVar, Lift, Ty, TyCtxt};
38+
use ty::{self, BoundTyIndex, Lift, Ty, TyCtxt};
3939

4040
impl<'cx, 'gcx, 'tcx> InferCtxtBuilder<'cx, 'gcx, 'tcx> {
4141
/// The "main method" for a canonicalized trait query. Given the
@@ -273,7 +273,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
273273
for (index, original_value) in original_values.var_values.iter().enumerate() {
274274
// ...with the value `v_r` of that variable from the query.
275275
let result_value = query_response.substitute_projected(self.tcx, &result_subst, |v| {
276-
&v.var_values[CanonicalVar::new(index)]
276+
&v.var_values[BoundTyIndex::new(index)]
277277
});
278278
match (original_value.unpack(), result_value.unpack()) {
279279
(UnpackedKind::Lifetime(ty::ReErased), UnpackedKind::Lifetime(ty::ReErased)) => {
@@ -408,7 +408,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
408408
// is directly equal to one of the canonical variables in the
409409
// result, then we can type the corresponding value from the
410410
// input. See the example above.
411-
let mut opt_values: IndexVec<CanonicalVar, Option<Kind<'tcx>>> =
411+
let mut opt_values: IndexVec<BoundTyIndex, Option<Kind<'tcx>>> =
412412
IndexVec::from_elem_n(None, query_response.variables.len());
413413

414414
// In terms of our example above, we are iterating over pairs like:
@@ -417,9 +417,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
417417
match result_value.unpack() {
418418
UnpackedKind::Type(result_value) => {
419419
// e.g., here `result_value` might be `?0` in the example above...
420-
if let ty::Infer(ty::InferTy::CanonicalTy(index)) = result_value.sty {
420+
if let ty::Infer(ty::InferTy::BoundTy(b)) = result_value.sty {
421421
// in which case we would set `canonical_vars[0]` to `Some(?U)`.
422-
opt_values[index] = Some(*original_value);
422+
opt_values[b.var] = Some(*original_value);
423423
}
424424
}
425425
UnpackedKind::Lifetime(result_value) => {
@@ -440,7 +440,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
440440
.variables
441441
.iter()
442442
.enumerate()
443-
.map(|(index, info)| opt_values[CanonicalVar::new(index)].unwrap_or_else(||
443+
.map(|(index, info)| opt_values[BoundTyIndex::new(index)].unwrap_or_else(||
444444
self.fresh_inference_var_for_canonical_var(cause.span, *info)
445445
))
446446
.collect(),
@@ -470,7 +470,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
470470
// canonical variable; this is taken from
471471
// `query_response.var_values` after applying the substitution
472472
// `result_subst`.
473-
let substituted_query_response = |index: CanonicalVar| -> Kind<'tcx> {
473+
let substituted_query_response = |index: BoundTyIndex| -> Kind<'tcx> {
474474
query_response.substitute_projected(self.tcx, &result_subst, |v| &v.var_values[index])
475475
};
476476

@@ -526,12 +526,12 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
526526
cause: &ObligationCause<'tcx>,
527527
param_env: ty::ParamEnv<'tcx>,
528528
variables1: &OriginalQueryValues<'tcx>,
529-
variables2: impl Fn(CanonicalVar) -> Kind<'tcx>,
529+
variables2: impl Fn(BoundTyIndex) -> Kind<'tcx>,
530530
) -> InferResult<'tcx, ()> {
531531
self.commit_if_ok(|_| {
532532
let mut obligations = vec![];
533533
for (index, value1) in variables1.var_values.iter().enumerate() {
534-
let value2 = variables2(CanonicalVar::new(index));
534+
let value2 = variables2(BoundTyIndex::new(index));
535535

536536
match (value1.unpack(), value2.unpack()) {
537537
(UnpackedKind::Type(v1), UnpackedKind::Type(v2)) => {

src/librustc/infer/canonical/substitute.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,11 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for CanonicalVarValuesSubst<'cx, 'g
8585

8686
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
8787
match t.sty {
88-
ty::Infer(ty::InferTy::CanonicalTy(c)) => {
89-
match self.var_values.var_values[c].unpack() {
88+
ty::Infer(ty::InferTy::BoundTy(b)) => {
89+
debug_assert_eq!(ty::INNERMOST, b.level);
90+
match self.var_values.var_values[b.var].unpack() {
9091
UnpackedKind::Type(ty) => ty,
91-
r => bug!("{:?} is a type but value is {:?}", c, r),
92+
r => bug!("{:?} is a type but value is {:?}", b, r),
9293
}
9394
}
9495
_ => {

src/librustc/infer/freshen.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
171171
t
172172
}
173173

174-
ty::Infer(ty::CanonicalTy(..)) =>
174+
ty::Infer(ty::BoundTy(..)) =>
175175
bug!("encountered canonical ty during freshening"),
176176

177177
ty::Generator(..) |

src/librustc/traits/select.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2421,7 +2421,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
24212421
ty::Infer(ty::TyVar(_)) => Ambiguous,
24222422

24232423
ty::UnnormalizedProjection(..)
2424-
| ty::Infer(ty::CanonicalTy(_))
2424+
| ty::Infer(ty::BoundTy(_))
24252425
| ty::Infer(ty::FreshTy(_))
24262426
| ty::Infer(ty::FreshIntTy(_))
24272427
| ty::Infer(ty::FreshFloatTy(_)) => {
@@ -2506,7 +2506,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
25062506
}
25072507

25082508
ty::UnnormalizedProjection(..)
2509-
| ty::Infer(ty::CanonicalTy(_))
2509+
| ty::Infer(ty::BoundTy(_))
25102510
| ty::Infer(ty::FreshTy(_))
25112511
| ty::Infer(ty::FreshIntTy(_))
25122512
| ty::Infer(ty::FreshFloatTy(_)) => {
@@ -2549,7 +2549,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
25492549
| ty::Param(..)
25502550
| ty::Foreign(..)
25512551
| ty::Projection(..)
2552-
| ty::Infer(ty::CanonicalTy(_))
2552+
| ty::Infer(ty::BoundTy(_))
25532553
| ty::Infer(ty::TyVar(_))
25542554
| ty::Infer(ty::FreshTy(_))
25552555
| ty::Infer(ty::FreshIntTy(_))

src/librustc/ty/error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
217217
ty::Infer(ty::TyVar(_)) => "inferred type".into(),
218218
ty::Infer(ty::IntVar(_)) => "integral variable".into(),
219219
ty::Infer(ty::FloatVar(_)) => "floating-point variable".into(),
220-
ty::Infer(ty::CanonicalTy(_)) |
220+
ty::Infer(ty::BoundTy(_)) |
221221
ty::Infer(ty::FreshTy(_)) => "fresh type".into(),
222222
ty::Infer(ty::FreshIntTy(_)) => "fresh integral type".into(),
223223
ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(),

src/librustc/ty/flags.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ impl FlagComputation {
122122
ty::FreshTy(_) |
123123
ty::FreshIntTy(_) |
124124
ty::FreshFloatTy(_) |
125-
ty::CanonicalTy(_) => {
125+
ty::BoundTy(_) => {
126126
self.add_flags(TypeFlags::HAS_CANONICAL_VARS);
127127
}
128128

src/librustc/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
6363

6464
use hir;
6565

66-
pub use self::sty::{Binder, CanonicalVar, DebruijnIndex, INNERMOST};
66+
pub use self::sty::{Binder, BoundTy, BoundTyIndex, DebruijnIndex, INNERMOST};
6767
pub use self::sty::{FnSig, GenSig, PolyFnSig, PolyGenSig};
6868
pub use self::sty::{InferTy, ParamTy, ProjectionTy, ExistentialPredicate};
6969
pub use self::sty::{ClosureSubsts, GeneratorSubsts, UpvarSubsts, TypeAndMut};

src/librustc/ty/sty.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -1165,7 +1165,7 @@ pub enum RegionKind {
11651165
ReClosureBound(RegionVid),
11661166

11671167
/// Canonicalized region, used only when preparing a trait query.
1168-
ReCanonical(CanonicalVar),
1168+
ReCanonical(BoundTyIndex),
11691169
}
11701170

11711171
impl<'tcx> serialize::UseSpecializedDecodable for Region<'tcx> {}
@@ -1217,14 +1217,22 @@ pub enum InferTy {
12171217
FreshIntTy(u32),
12181218
FreshFloatTy(u32),
12191219

1220-
/// Canonicalized type variable, used only when preparing a trait query.
1221-
CanonicalTy(CanonicalVar),
1220+
/// Bound type variable, used only when preparing a trait query.
1221+
BoundTy(BoundTy),
12221222
}
12231223

12241224
newtype_index! {
1225-
pub struct CanonicalVar { .. }
1225+
pub struct BoundTyIndex { .. }
12261226
}
12271227

1228+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
1229+
pub struct BoundTy {
1230+
pub level: DebruijnIndex,
1231+
pub var: BoundTyIndex,
1232+
}
1233+
1234+
impl_stable_hash_for!(struct BoundTy { level, var });
1235+
12281236
/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
12291237
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
12301238
pub struct ExistentialProjection<'tcx> {
@@ -1919,7 +1927,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
19191927

19201928
ty::Infer(ty::TyVar(_)) => false,
19211929

1922-
ty::Infer(ty::CanonicalTy(_)) |
1930+
ty::Infer(ty::BoundTy(_)) |
19231931
ty::Infer(ty::FreshTy(_)) |
19241932
ty::Infer(ty::FreshIntTy(_)) |
19251933
ty::Infer(ty::FreshFloatTy(_)) =>

src/librustc/ty/subst.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
use hir::def_id::DefId;
1414
use infer::canonical::Canonical;
15-
use ty::{self, CanonicalVar, Lift, List, Ty, TyCtxt};
15+
use ty::{self, BoundTyIndex, Lift, List, Ty, TyCtxt};
1616
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
1717

1818
use serialize::{self, Encodable, Encoder, Decodable, Decoder};
@@ -553,10 +553,10 @@ impl CanonicalUserSubsts<'tcx> {
553553
return false;
554554
}
555555

556-
self.value.substs.iter().zip(CanonicalVar::new(0)..).all(|(kind, cvar)| {
556+
self.value.substs.iter().zip(BoundTyIndex::new(0)..).all(|(kind, cvar)| {
557557
match kind.unpack() {
558558
UnpackedKind::Type(ty) => match ty.sty {
559-
ty::Infer(ty::CanonicalTy(cvar1)) => cvar == cvar1,
559+
ty::Infer(ty::BoundTy(ref b)) => cvar == b.var,
560560
_ => false,
561561
},
562562

src/librustc/util/ppaux.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,7 @@ define_print! {
984984
ty::TyVar(_) => write!(f, "_"),
985985
ty::IntVar(_) => write!(f, "{}", "{integer}"),
986986
ty::FloatVar(_) => write!(f, "{}", "{float}"),
987-
ty::CanonicalTy(_) => write!(f, "_"),
987+
ty::BoundTy(_) => write!(f, "_"),
988988
ty::FreshTy(v) => write!(f, "FreshTy({})", v),
989989
ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v),
990990
ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v)
@@ -996,7 +996,7 @@ define_print! {
996996
ty::TyVar(ref v) => write!(f, "{:?}", v),
997997
ty::IntVar(ref v) => write!(f, "{:?}", v),
998998
ty::FloatVar(ref v) => write!(f, "{:?}", v),
999-
ty::CanonicalTy(v) => write!(f, "?{:?}", v.index()),
999+
ty::BoundTy(v) => write!(f, "?{:?}", v.var.index()),
10001000
ty::FreshTy(v) => write!(f, "FreshTy({:?})", v),
10011001
ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
10021002
ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v)

0 commit comments

Comments
 (0)