Skip to content

Commit

Permalink
Rename InferTy::CanonicalTy to BoundTy and add DebruijnIndex to varia…
Browse files Browse the repository at this point in the history
…nt type
  • Loading branch information
fabric-and-ink committed Oct 20, 2018
1 parent 2581bdc commit 2f41c0d
Show file tree
Hide file tree
Showing 12 changed files with 43 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -915,7 +915,7 @@ impl_stable_hash_for!(enum ty::InferTy {
FreshTy(a),
FreshIntTy(a),
FreshFloatTy(a),
CanonicalTy(a),
BoundTy(a),
});

impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
Expand Down
23 changes: 15 additions & 8 deletions src/librustc/infer/canonical/canonicalizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use infer::InferCtxt;
use std::sync::atomic::Ordering;
use ty::fold::{TypeFoldable, TypeFolder};
use ty::subst::Kind;
use ty::{self, BoundTyIndex, Lift, List, Ty, TyCtxt, TypeFlags};
use ty::{self, BoundTy, BoundTyIndex, Lift, List, Ty, TyCtxt, TypeFlags};

use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::Idx;
Expand Down Expand Up @@ -283,7 +283,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
bug!("encountered a fresh type during canonicalization")
}

ty::Infer(ty::CanonicalTy(_)) => {
ty::Infer(ty::BoundTy(_)) => {
bug!("encountered a canonical type during canonicalization")
}

Expand Down Expand Up @@ -393,7 +393,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
/// or returns an existing variable if `kind` has already been
/// seen. `kind` is expected to be an unbound variable (or
/// potentially a free region).
fn canonical_var(&mut self, info: CanonicalVarInfo, kind: Kind<'tcx>) -> BoundTyIndex {
fn canonical_var(&mut self, info: CanonicalVarInfo, kind: Kind<'tcx>) -> BoundTy {
let Canonicalizer {
variables,
query_state,
Expand All @@ -408,7 +408,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
// avoid allocations in those cases. We also don't use `indices` to
// determine if a kind has been seen before until the limit of 8 has
// been exceeded, to also avoid allocations for `indices`.
if !var_values.spilled() {
let var = if !var_values.spilled() {
// `var_values` is stack-allocated. `indices` isn't used yet. Do a
// direct linear search of `var_values`.
if let Some(idx) = var_values.iter().position(|&k| k == kind) {
Expand Down Expand Up @@ -442,15 +442,21 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
assert_eq!(variables.len(), var_values.len());
BoundTyIndex::new(variables.len() - 1)
})
};

BoundTy {
level: ty::INNERMOST,
var,
}
}

fn canonical_var_for_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
let info = CanonicalVarInfo {
kind: CanonicalVarKind::Region,
};
let cvar = self.canonical_var(info, r.into());
self.tcx().mk_region(ty::ReCanonical(cvar))
let b = self.canonical_var(info, r.into());
debug_assert_eq!(ty::INNERMOST, b.level);
self.tcx().mk_region(ty::ReCanonical(b.var))
}

/// Given a type variable `ty_var` of the given kind, first check
Expand All @@ -466,8 +472,9 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
let info = CanonicalVarInfo {
kind: CanonicalVarKind::Ty(ty_kind),
};
let cvar = self.canonical_var(info, ty_var.into());
self.tcx().mk_infer(ty::InferTy::CanonicalTy(cvar))
let b = self.canonical_var(info, ty_var.into());
debug_assert_eq!(ty::INNERMOST, b.level);
self.tcx().mk_infer(ty::InferTy::BoundTy(b))
}
}
}
4 changes: 2 additions & 2 deletions src/librustc/infer/canonical/query_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,9 +417,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
match result_value.unpack() {
UnpackedKind::Type(result_value) => {
// e.g., here `result_value` might be `?0` in the example above...
if let ty::Infer(ty::InferTy::CanonicalTy(index)) = result_value.sty {
if let ty::Infer(ty::InferTy::BoundTy(b)) = result_value.sty {
// in which case we would set `canonical_vars[0]` to `Some(?U)`.
opt_values[index] = Some(*original_value);
opt_values[b.var] = Some(*original_value);
}
}
UnpackedKind::Lifetime(result_value) => {
Expand Down
7 changes: 4 additions & 3 deletions src/librustc/infer/canonical/substitute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,11 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for CanonicalVarValuesSubst<'cx, 'g

fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
match t.sty {
ty::Infer(ty::InferTy::CanonicalTy(c)) => {
match self.var_values.var_values[c].unpack() {
ty::Infer(ty::InferTy::BoundTy(b)) => {
debug_assert_eq!(ty::INNERMOST, b.level);
match self.var_values.var_values[b.var].unpack() {
UnpackedKind::Type(ty) => ty,
r => bug!("{:?} is a type but value is {:?}", c, r),
r => bug!("{:?} is a type but value is {:?}", b, r),
}
}
_ => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/infer/freshen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
t
}

ty::Infer(ty::CanonicalTy(..)) =>
ty::Infer(ty::BoundTy(..)) =>
bug!("encountered canonical ty during freshening"),

ty::Generator(..) |
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2421,7 +2421,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
ty::Infer(ty::TyVar(_)) => Ambiguous,

ty::UnnormalizedProjection(..)
| ty::Infer(ty::CanonicalTy(_))
| ty::Infer(ty::BoundTy(_))
| ty::Infer(ty::FreshTy(_))
| ty::Infer(ty::FreshIntTy(_))
| ty::Infer(ty::FreshFloatTy(_)) => {
Expand Down Expand Up @@ -2506,7 +2506,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
}

ty::UnnormalizedProjection(..)
| ty::Infer(ty::CanonicalTy(_))
| ty::Infer(ty::BoundTy(_))
| ty::Infer(ty::FreshTy(_))
| ty::Infer(ty::FreshIntTy(_))
| ty::Infer(ty::FreshFloatTy(_)) => {
Expand Down Expand Up @@ -2549,7 +2549,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
| ty::Param(..)
| ty::Foreign(..)
| ty::Projection(..)
| ty::Infer(ty::CanonicalTy(_))
| ty::Infer(ty::BoundTy(_))
| ty::Infer(ty::TyVar(_))
| ty::Infer(ty::FreshTy(_))
| ty::Infer(ty::FreshIntTy(_))
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
ty::Infer(ty::TyVar(_)) => "inferred type".into(),
ty::Infer(ty::IntVar(_)) => "integral variable".into(),
ty::Infer(ty::FloatVar(_)) => "floating-point variable".into(),
ty::Infer(ty::CanonicalTy(_)) |
ty::Infer(ty::BoundTy(_)) |
ty::Infer(ty::FreshTy(_)) => "fresh type".into(),
ty::Infer(ty::FreshIntTy(_)) => "fresh integral type".into(),
ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(),
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ impl FlagComputation {
ty::FreshTy(_) |
ty::FreshIntTy(_) |
ty::FreshFloatTy(_) |
ty::CanonicalTy(_) => {
ty::BoundTy(_) => {
self.add_flags(TypeFlags::HAS_CANONICAL_VARS);
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,

use hir;

pub use self::sty::{Binder, BoundTyIndex, DebruijnIndex, INNERMOST};
pub use self::sty::{Binder, BoundTy, BoundTyIndex, DebruijnIndex, INNERMOST};
pub use self::sty::{FnSig, GenSig, PolyFnSig, PolyGenSig};
pub use self::sty::{InferTy, ParamTy, ProjectionTy, ExistentialPredicate};
pub use self::sty::{ClosureSubsts, GeneratorSubsts, UpvarSubsts, TypeAndMut};
Expand Down
14 changes: 11 additions & 3 deletions src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1217,14 +1217,22 @@ pub enum InferTy {
FreshIntTy(u32),
FreshFloatTy(u32),

/// Canonicalized type variable, used only when preparing a trait query.
CanonicalTy(BoundTyIndex),
/// Bound type variable, used only when preparing a trait query.
BoundTy(BoundTy),
}

newtype_index! {
pub struct BoundTyIndex { .. }
}

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct BoundTy {
pub level: DebruijnIndex,
pub var: BoundTyIndex,
}

impl_stable_hash_for!(struct BoundTy { level, var });

/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct ExistentialProjection<'tcx> {
Expand Down Expand Up @@ -1919,7 +1927,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {

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

ty::Infer(ty::CanonicalTy(_)) |
ty::Infer(ty::BoundTy(_)) |
ty::Infer(ty::FreshTy(_)) |
ty::Infer(ty::FreshIntTy(_)) |
ty::Infer(ty::FreshFloatTy(_)) =>
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/subst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ impl CanonicalUserSubsts<'tcx> {
self.value.substs.iter().zip(BoundTyIndex::new(0)..).all(|(kind, cvar)| {
match kind.unpack() {
UnpackedKind::Type(ty) => match ty.sty {
ty::Infer(ty::CanonicalTy(cvar1)) => cvar == cvar1,
ty::Infer(ty::BoundTy(ref b)) => cvar == b.var,
_ => false,
},

Expand Down
4 changes: 2 additions & 2 deletions src/librustc/util/ppaux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,7 @@ define_print! {
ty::TyVar(_) => write!(f, "_"),
ty::IntVar(_) => write!(f, "{}", "{integer}"),
ty::FloatVar(_) => write!(f, "{}", "{float}"),
ty::CanonicalTy(_) => write!(f, "_"),
ty::BoundTy(_) => write!(f, "_"),
ty::FreshTy(v) => write!(f, "FreshTy({})", v),
ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v),
ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v)
Expand All @@ -996,7 +996,7 @@ define_print! {
ty::TyVar(ref v) => write!(f, "{:?}", v),
ty::IntVar(ref v) => write!(f, "{:?}", v),
ty::FloatVar(ref v) => write!(f, "{:?}", v),
ty::CanonicalTy(v) => write!(f, "?{:?}", v.index()),
ty::BoundTy(v) => write!(f, "?{:?}", v.var.index()),
ty::FreshTy(v) => write!(f, "FreshTy({:?})", v),
ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v)
Expand Down

0 comments on commit 2f41c0d

Please sign in to comment.