1
Fork 0
- Take more things by self, not &self
- Clone more things
- Rework namespacing so we can use `ty::` in the canonicalizer
This commit is contained in:
Michael Goulet 2023-12-05 18:10:23 +00:00
parent cb41509601
commit 1f5895b3e3
11 changed files with 205 additions and 229 deletions

View file

@ -29,14 +29,14 @@ pub struct Const<'tcx>(pub(super) Interned<'tcx, WithCachedTypeInfo<ConstData<'t
impl<'tcx> IntoKind for Const<'tcx> { impl<'tcx> IntoKind for Const<'tcx> {
type Kind = ConstKind<'tcx>; type Kind = ConstKind<'tcx>;
fn kind(&self) -> ConstKind<'tcx> { fn kind(self) -> ConstKind<'tcx> {
(*self).kind().clone() self.kind().clone()
} }
} }
impl<'tcx> ConstTy<TyCtxt<'tcx>> for Const<'tcx> { impl<'tcx> ConstTy<TyCtxt<'tcx>> for Const<'tcx> {
fn ty(&self) -> Ty<'tcx> { fn ty(self) -> Ty<'tcx> {
(*self).ty() self.ty()
} }
} }

View file

@ -132,40 +132,29 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
(ty, mutbl) (ty, mutbl)
} }
fn mk_canonical_var_infos( fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
&self, self.mk_canonical_var_infos(infos)
infos: &[rustc_type_ir::CanonicalVarInfo<Self>],
) -> Self::CanonicalVars {
(*self).mk_canonical_var_infos(infos)
} }
fn mk_bound_ty( fn mk_bound_ty(self, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self::Ty {
&self, Ty::new_bound(self, debruijn, ty::BoundTy { var, kind: ty::BoundTyKind::Anon })
debruijn: rustc_type_ir::DebruijnIndex,
var: rustc_type_ir::BoundVar,
) -> Self::Ty {
Ty::new_bound(*self, debruijn, ty::BoundTy { var, kind: ty::BoundTyKind::Anon })
} }
fn mk_bound_region( fn mk_bound_region(self, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self::Region {
&self,
debruijn: rustc_type_ir::DebruijnIndex,
var: rustc_type_ir::BoundVar,
) -> Self::Region {
Region::new_bound( Region::new_bound(
*self, self,
debruijn, debruijn,
ty::BoundRegion { var, kind: ty::BoundRegionKind::BrAnon }, ty::BoundRegion { var, kind: ty::BoundRegionKind::BrAnon },
) )
} }
fn mk_bound_const( fn mk_bound_const(
&self, self,
debruijn: rustc_type_ir::DebruijnIndex, debruijn: ty::DebruijnIndex,
var: rustc_type_ir::BoundVar, var: ty::BoundVar,
ty: Self::Ty, ty: Self::Ty,
) -> Self::Const { ) -> Self::Const {
Const::new_bound(*self, debruijn, var, ty) Const::new_bound(self, debruijn, var, ty)
} }
} }

View file

@ -65,15 +65,10 @@ use std::ops::ControlFlow;
use std::{fmt, str}; use std::{fmt, str};
pub use crate::ty::diagnostics::*; pub use crate::ty::diagnostics::*;
pub use rustc_type_ir::AliasKind::*;
pub use rustc_type_ir::ConstKind::{ pub use rustc_type_ir::ConstKind::{
Bound as BoundCt, Error as ErrorCt, Expr as ExprCt, Infer as InferCt, Param as ParamCt, Bound as BoundCt, Error as ErrorCt, Expr as ExprCt, Infer as InferCt, Param as ParamCt,
Placeholder as PlaceholderCt, Unevaluated, Value, Placeholder as PlaceholderCt, Unevaluated, Value,
}; };
pub use rustc_type_ir::DynKind::*;
pub use rustc_type_ir::InferTy::*;
pub use rustc_type_ir::RegionKind::*;
pub use rustc_type_ir::TyKind::*;
pub use rustc_type_ir::*; pub use rustc_type_ir::*;
pub use self::binding::BindingMode; pub use self::binding::BindingMode;
@ -477,8 +472,8 @@ pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>);
impl<'tcx> IntoKind for Ty<'tcx> { impl<'tcx> IntoKind for Ty<'tcx> {
type Kind = TyKind<'tcx>; type Kind = TyKind<'tcx>;
fn kind(&self) -> TyKind<'tcx> { fn kind(self) -> TyKind<'tcx> {
(*self).kind().clone() self.kind().clone()
} }
} }
@ -1553,17 +1548,17 @@ pub struct Placeholder<T> {
pub type PlaceholderRegion = Placeholder<BoundRegion>; pub type PlaceholderRegion = Placeholder<BoundRegion>;
impl rustc_type_ir::Placeholder for PlaceholderRegion { impl PlaceholderLike for PlaceholderRegion {
fn universe(&self) -> UniverseIndex { fn universe(self) -> UniverseIndex {
self.universe self.universe
} }
fn var(&self) -> BoundVar { fn var(self) -> BoundVar {
self.bound.var self.bound.var
} }
fn with_updated_universe(&self, ui: UniverseIndex) -> Self { fn with_updated_universe(self, ui: UniverseIndex) -> Self {
Placeholder { universe: ui, ..*self } Placeholder { universe: ui, ..self }
} }
fn new(ui: UniverseIndex, var: BoundVar) -> Self { fn new(ui: UniverseIndex, var: BoundVar) -> Self {
@ -1573,17 +1568,17 @@ impl rustc_type_ir::Placeholder for PlaceholderRegion {
pub type PlaceholderType = Placeholder<BoundTy>; pub type PlaceholderType = Placeholder<BoundTy>;
impl rustc_type_ir::Placeholder for PlaceholderType { impl PlaceholderLike for PlaceholderType {
fn universe(&self) -> UniverseIndex { fn universe(self) -> UniverseIndex {
self.universe self.universe
} }
fn var(&self) -> BoundVar { fn var(self) -> BoundVar {
self.bound.var self.bound.var
} }
fn with_updated_universe(&self, ui: UniverseIndex) -> Self { fn with_updated_universe(self, ui: UniverseIndex) -> Self {
Placeholder { universe: ui, ..*self } Placeholder { universe: ui, ..self }
} }
fn new(ui: UniverseIndex, var: BoundVar) -> Self { fn new(ui: UniverseIndex, var: BoundVar) -> Self {
@ -1600,17 +1595,17 @@ pub struct BoundConst<'tcx> {
pub type PlaceholderConst = Placeholder<BoundVar>; pub type PlaceholderConst = Placeholder<BoundVar>;
impl rustc_type_ir::Placeholder for PlaceholderConst { impl PlaceholderLike for PlaceholderConst {
fn universe(&self) -> UniverseIndex { fn universe(self) -> UniverseIndex {
self.universe self.universe
} }
fn var(&self) -> BoundVar { fn var(self) -> BoundVar {
self.bound self.bound
} }
fn with_updated_universe(&self, ui: UniverseIndex) -> Self { fn with_updated_universe(self, ui: UniverseIndex) -> Self {
Placeholder { universe: ui, ..*self } Placeholder { universe: ui, ..self }
} }
fn new(ui: UniverseIndex, var: BoundVar) -> Self { fn new(ui: UniverseIndex, var: BoundVar) -> Self {

View file

@ -1480,8 +1480,8 @@ pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>);
impl<'tcx> IntoKind for Region<'tcx> { impl<'tcx> IntoKind for Region<'tcx> {
type Kind = RegionKind<'tcx>; type Kind = RegionKind<'tcx>;
fn kind(&self) -> RegionKind<'tcx> { fn kind(self) -> RegionKind<'tcx> {
**self *self
} }
} }

View file

@ -2,9 +2,8 @@ use std::cmp::Ordering;
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_type_ir::{ use rustc_type_ir::{
BoundVar, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, ConstKind, self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, ConstTy,
ConstTy, DebruijnIndex, InferConst, InferCtxtLike, InferTy, Interner, IntoKind, Placeholder, InferCtxtLike, Interner, IntoKind, PlaceholderLike,
RegionKind, TyKind, UniverseIndex, INNERMOST,
}; };
/// Whether we're canonicalizing a query input or the query response. /// Whether we're canonicalizing a query input or the query response.
@ -32,33 +31,33 @@ pub enum CanonicalizeMode {
/// ///
/// This doesn't work for universes created inside of the query so /// This doesn't work for universes created inside of the query so
/// we do remember their universe in the response. /// we do remember their universe in the response.
max_input_universe: UniverseIndex, max_input_universe: ty::UniverseIndex,
}, },
} }
pub struct Canonicalizer<'a, Infcx: InferCtxtLike> { pub struct Canonicalizer<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> {
infcx: &'a Infcx, infcx: &'a Infcx,
canonicalize_mode: CanonicalizeMode, canonicalize_mode: CanonicalizeMode,
variables: &'a mut Vec<<Infcx::Interner as Interner>::GenericArg>, variables: &'a mut Vec<I::GenericArg>,
primitive_var_infos: Vec<CanonicalVarInfo<Infcx::Interner>>, primitive_var_infos: Vec<CanonicalVarInfo<I>>,
binder_index: DebruijnIndex, binder_index: ty::DebruijnIndex,
} }
impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infcx> { impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infcx, I> {
pub fn canonicalize<T: TypeFoldable<I>>( pub fn canonicalize<T: TypeFoldable<I>>(
infcx: &'a Infcx, infcx: &'a Infcx,
canonicalize_mode: CanonicalizeMode, canonicalize_mode: CanonicalizeMode,
variables: &'a mut Vec<<I as Interner>::GenericArg>, variables: &'a mut Vec<I::GenericArg>,
value: T, value: T,
) -> Canonical<I, T> { ) -> ty::Canonical<I, T> {
let mut canonicalizer = Canonicalizer { let mut canonicalizer = Canonicalizer {
infcx, infcx,
canonicalize_mode, canonicalize_mode,
variables, variables,
primitive_var_infos: Vec::new(), primitive_var_infos: Vec::new(),
binder_index: INNERMOST, binder_index: ty::INNERMOST,
}; };
let value = value.fold_with(&mut canonicalizer); let value = value.fold_with(&mut canonicalizer);
@ -71,7 +70,7 @@ impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infc
Canonical { max_universe, variables, value } Canonical { max_universe, variables, value }
} }
fn finalize(self) -> (UniverseIndex, <I as Interner>::CanonicalVars) { fn finalize(self) -> (ty::UniverseIndex, I::CanonicalVars) {
let mut var_infos = self.primitive_var_infos; let mut var_infos = self.primitive_var_infos;
// See the rustc-dev-guide section about how we deal with universes // See the rustc-dev-guide section about how we deal with universes
// during canonicalization in the new solver. // during canonicalization in the new solver.
@ -88,15 +87,16 @@ impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infc
CanonicalizeMode::Response { max_input_universe } => { CanonicalizeMode::Response { max_input_universe } => {
for var in var_infos.iter_mut() { for var in var_infos.iter_mut() {
let uv = var.universe(); let uv = var.universe();
let new_uv = let new_uv = ty::UniverseIndex::from(
UniverseIndex::from(uv.index().saturating_sub(max_input_universe.index())); uv.index().saturating_sub(max_input_universe.index()),
);
*var = var.with_updated_universe(new_uv); *var = var.with_updated_universe(new_uv);
} }
let max_universe = var_infos let max_universe = var_infos
.iter() .iter()
.map(|info| info.universe()) .map(|info| info.universe())
.max() .max()
.unwrap_or(UniverseIndex::ROOT); .unwrap_or(ty::UniverseIndex::ROOT);
let var_infos = self.infcx.interner().mk_canonical_var_infos(&var_infos); let var_infos = self.infcx.interner().mk_canonical_var_infos(&var_infos);
return (max_universe, var_infos); return (max_universe, var_infos);
@ -120,9 +120,9 @@ impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infc
// //
// This algorithm runs in `O(n²)` where `n` is the number of different universe // This algorithm runs in `O(n²)` where `n` is the number of different universe
// indices in the input. This should be fine as `n` is expected to be small. // indices in the input. This should be fine as `n` is expected to be small.
let mut curr_compressed_uv = UniverseIndex::ROOT; let mut curr_compressed_uv = ty::UniverseIndex::ROOT;
let mut existential_in_new_uv = false; let mut existential_in_new_uv = false;
let mut next_orig_uv = Some(UniverseIndex::ROOT); let mut next_orig_uv = Some(ty::UniverseIndex::ROOT);
while let Some(orig_uv) = next_orig_uv.take() { while let Some(orig_uv) = next_orig_uv.take() {
let mut update_uv = |var: &mut CanonicalVarInfo<I>, orig_uv, is_existential| { let mut update_uv = |var: &mut CanonicalVarInfo<I>, orig_uv, is_existential| {
let uv = var.universe(); let uv = var.universe();
@ -176,8 +176,7 @@ impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infc
for var in var_infos.iter_mut() { for var in var_infos.iter_mut() {
if var.is_region() { if var.is_region() {
assert!(var.is_existential()); assert!(var.is_existential());
let compressed_var = var.with_updated_universe(curr_compressed_uv); *var = var.with_updated_universe(curr_compressed_uv);
*var = compressed_var;
} }
} }
@ -186,7 +185,9 @@ impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infc
} }
} }
impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I> for Canonicalizer<'_, Infcx> { impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
for Canonicalizer<'_, Infcx, I>
{
fn interner(&self) -> I { fn interner(&self) -> I {
self.infcx.interner() self.infcx.interner()
} }
@ -204,7 +205,7 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I> for Canonica
fn fold_region(&mut self, r: I::Region) -> I::Region { fn fold_region(&mut self, r: I::Region) -> I::Region {
let kind = match r.kind() { let kind = match r.kind() {
RegionKind::ReBound(..) => return r, ty::ReBound(..) => return r,
// We may encounter `ReStatic` in item signatures or the hidden type // We may encounter `ReStatic` in item signatures or the hidden type
// of an opaque. `ReErased` should only be encountered in the hidden // of an opaque. `ReErased` should only be encountered in the hidden
@ -214,23 +215,21 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I> for Canonica
// FIXME: We should investigate the perf implications of not uniquifying // FIXME: We should investigate the perf implications of not uniquifying
// `ReErased`. We may be able to short-circuit registering region // `ReErased`. We may be able to short-circuit registering region
// obligations if we encounter a `ReErased` on one side, for example. // obligations if we encounter a `ReErased` on one side, for example.
RegionKind::ReStatic | RegionKind::ReErased => match self.canonicalize_mode { ty::ReStatic | ty::ReErased => match self.canonicalize_mode {
CanonicalizeMode::Input => CanonicalVarKind::Region(UniverseIndex::ROOT), CanonicalizeMode::Input => CanonicalVarKind::Region(ty::UniverseIndex::ROOT),
CanonicalizeMode::Response { .. } => return r, CanonicalizeMode::Response { .. } => return r,
}, },
RegionKind::ReEarlyParam(_) | RegionKind::ReLateParam(_) => { ty::ReEarlyParam(_) | ty::ReLateParam(_) => match self.canonicalize_mode {
match self.canonicalize_mode { CanonicalizeMode::Input => CanonicalVarKind::Region(ty::UniverseIndex::ROOT),
CanonicalizeMode::Input => CanonicalVarKind::Region(UniverseIndex::ROOT),
CanonicalizeMode::Response { .. } => { CanonicalizeMode::Response { .. } => {
panic!("unexpected region in response: {r:?}") panic!("unexpected region in response: {r:?}")
} }
} },
}
RegionKind::RePlaceholder(placeholder) => match self.canonicalize_mode { ty::RePlaceholder(placeholder) => match self.canonicalize_mode {
// We canonicalize placeholder regions as existentials in query inputs. // We canonicalize placeholder regions as existentials in query inputs.
CanonicalizeMode::Input => CanonicalVarKind::Region(UniverseIndex::ROOT), CanonicalizeMode::Input => CanonicalVarKind::Region(ty::UniverseIndex::ROOT),
CanonicalizeMode::Response { max_input_universe } => { CanonicalizeMode::Response { max_input_universe } => {
// If we have a placeholder region inside of a query, it must be from // If we have a placeholder region inside of a query, it must be from
// a new universe. // a new universe.
@ -241,38 +240,37 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I> for Canonica
} }
}, },
RegionKind::ReVar(vid) => { ty::ReVar(vid) => {
assert_eq!( assert_eq!(
self.infcx.root_lt_var(vid.clone()), self.infcx.root_lt_var(vid),
vid, vid,
"region vid should have been resolved fully before canonicalization" "region vid should have been resolved fully before canonicalization"
); );
assert_eq!( assert_eq!(
self.infcx.probe_lt_var(vid.clone()), self.infcx.probe_lt_var(vid),
None, None,
"region vid should have been resolved fully before canonicalization" "region vid should have been resolved fully before canonicalization"
); );
match self.canonicalize_mode { match self.canonicalize_mode {
CanonicalizeMode::Input => CanonicalVarKind::Region(UniverseIndex::ROOT), CanonicalizeMode::Input => CanonicalVarKind::Region(ty::UniverseIndex::ROOT),
CanonicalizeMode::Response { .. } => { CanonicalizeMode::Response { .. } => {
CanonicalVarKind::Region(self.infcx.universe_of_lt(vid).unwrap()) CanonicalVarKind::Region(self.infcx.universe_of_lt(vid).unwrap())
} }
} }
} }
RegionKind::ReError(_) => return r, ty::ReError(_) => return r,
}; };
let existing_bound_var = match self.canonicalize_mode { let existing_bound_var = match self.canonicalize_mode {
CanonicalizeMode::Input => None, CanonicalizeMode::Input => None,
CanonicalizeMode::Response { .. } => { CanonicalizeMode::Response { .. } => {
let r = r.clone().into(); self.variables.iter().position(|&v| v == r.into()).map(ty::BoundVar::from)
self.variables.iter().position(|v| v == &r).map(BoundVar::from)
} }
}; };
let var = existing_bound_var.unwrap_or_else(|| { let var = existing_bound_var.unwrap_or_else(|| {
let var = BoundVar::from(self.variables.len()); let var = ty::BoundVar::from(self.variables.len());
self.variables.push(r.into()); self.variables.push(r.into());
self.primitive_var_infos.push(CanonicalVarInfo { kind }); self.primitive_var_infos.push(CanonicalVarInfo { kind });
var var
@ -286,8 +284,8 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I> for Canonica
I::Ty: TypeSuperFoldable<I>, I::Ty: TypeSuperFoldable<I>,
{ {
let kind = match t.kind() { let kind = match t.kind() {
TyKind::Infer(i) => match i { ty::Infer(i) => match i {
InferTy::TyVar(vid) => { ty::TyVar(vid) => {
assert_eq!( assert_eq!(
self.infcx.root_ty_var(vid), self.infcx.root_ty_var(vid),
vid, vid,
@ -305,59 +303,59 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I> for Canonica
.unwrap_or_else(|| panic!("ty var should have been resolved: {t:?}")), .unwrap_or_else(|| panic!("ty var should have been resolved: {t:?}")),
)) ))
} }
InferTy::IntVar(_) => CanonicalVarKind::Ty(CanonicalTyVarKind::Int), ty::IntVar(_) => CanonicalVarKind::Ty(CanonicalTyVarKind::Int),
InferTy::FloatVar(_) => CanonicalVarKind::Ty(CanonicalTyVarKind::Float), ty::FloatVar(_) => CanonicalVarKind::Ty(CanonicalTyVarKind::Float),
InferTy::FreshTy(_) | InferTy::FreshIntTy(_) | InferTy::FreshFloatTy(_) => { ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => {
todo!() todo!()
} }
}, },
TyKind::Placeholder(placeholder) => match self.canonicalize_mode { ty::Placeholder(placeholder) => match self.canonicalize_mode {
CanonicalizeMode::Input => CanonicalVarKind::PlaceholderTy(Placeholder::new( CanonicalizeMode::Input => CanonicalVarKind::PlaceholderTy(PlaceholderLike::new(
placeholder.universe(), placeholder.universe(),
self.variables.len().into(), self.variables.len().into(),
)), )),
CanonicalizeMode::Response { .. } => CanonicalVarKind::PlaceholderTy(placeholder), CanonicalizeMode::Response { .. } => CanonicalVarKind::PlaceholderTy(placeholder),
}, },
TyKind::Param(_) => match self.canonicalize_mode { ty::Param(_) => match self.canonicalize_mode {
CanonicalizeMode::Input => CanonicalVarKind::PlaceholderTy(Placeholder::new( CanonicalizeMode::Input => CanonicalVarKind::PlaceholderTy(PlaceholderLike::new(
UniverseIndex::ROOT, ty::UniverseIndex::ROOT,
self.variables.len().into(), self.variables.len().into(),
)), )),
CanonicalizeMode::Response { .. } => panic!("param ty in response: {t:?}"), CanonicalizeMode::Response { .. } => panic!("param ty in response: {t:?}"),
}, },
TyKind::Bool ty::Bool
| TyKind::Char | ty::Char
| TyKind::Int(_) | ty::Int(_)
| TyKind::Uint(_) | ty::Uint(_)
| TyKind::Float(_) | ty::Float(_)
| TyKind::Adt(_, _) | ty::Adt(_, _)
| TyKind::Foreign(_) | ty::Foreign(_)
| TyKind::Str | ty::Str
| TyKind::Array(_, _) | ty::Array(_, _)
| TyKind::Slice(_) | ty::Slice(_)
| TyKind::RawPtr(_) | ty::RawPtr(_)
| TyKind::Ref(_, _, _) | ty::Ref(_, _, _)
| TyKind::FnDef(_, _) | ty::FnDef(_, _)
| TyKind::FnPtr(_) | ty::FnPtr(_)
| TyKind::Dynamic(_, _, _) | ty::Dynamic(_, _, _)
| TyKind::Closure(_, _) | ty::Closure(_, _)
| TyKind::Coroutine(_, _, _) | ty::Coroutine(_, _, _)
| TyKind::CoroutineWitness(..) | ty::CoroutineWitness(..)
| TyKind::Never | ty::Never
| TyKind::Tuple(_) | ty::Tuple(_)
| TyKind::Alias(_, _) | ty::Alias(_, _)
| TyKind::Bound(_, _) | ty::Bound(_, _)
| TyKind::Error(_) => return t.super_fold_with(self), | ty::Error(_) => return t.super_fold_with(self),
}; };
let t = t.clone().into(); let var = ty::BoundVar::from(
let var = self.variables.iter().position(|&v| v == t.into()).unwrap_or_else(|| {
BoundVar::from(self.variables.iter().position(|v| v == &t).unwrap_or_else(|| {
let var = self.variables.len(); let var = self.variables.len();
self.variables.push(t); self.variables.push(t.into());
self.primitive_var_infos.push(CanonicalVarInfo { kind }); self.primitive_var_infos.push(CanonicalVarInfo { kind });
var var
})); }),
);
self.interner().mk_bound_ty(self.binder_index, var) self.interner().mk_bound_ty(self.binder_index, var)
} }
@ -367,10 +365,10 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I> for Canonica
I::Const: TypeSuperFoldable<I>, I::Const: TypeSuperFoldable<I>,
{ {
let kind = match c.kind() { let kind = match c.kind() {
ConstKind::Infer(i) => { ty::ConstKind::Infer(i) => {
// FIXME: we should fold the ty too eventually // FIXME: we should fold the ty too eventually
match i { match i {
InferConst::Var(vid) => { ty::InferConst::Var(vid) => {
assert_eq!( assert_eq!(
self.infcx.root_ct_var(vid), self.infcx.root_ct_var(vid),
vid, vid,
@ -383,43 +381,42 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I> for Canonica
); );
CanonicalVarKind::Const(self.infcx.universe_of_ct(vid).unwrap(), c.ty()) CanonicalVarKind::Const(self.infcx.universe_of_ct(vid).unwrap(), c.ty())
} }
InferConst::EffectVar(_) => CanonicalVarKind::Effect, ty::InferConst::EffectVar(_) => CanonicalVarKind::Effect,
InferConst::Fresh(_) => todo!(), ty::InferConst::Fresh(_) => todo!(),
} }
} }
ConstKind::Placeholder(placeholder) => match self.canonicalize_mode { ty::ConstKind::Placeholder(placeholder) => match self.canonicalize_mode {
CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst( CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst(
Placeholder::new(placeholder.universe(), self.variables.len().into()), PlaceholderLike::new(placeholder.universe(), self.variables.len().into()),
c.ty(), c.ty(),
), ),
CanonicalizeMode::Response { .. } => { CanonicalizeMode::Response { .. } => {
CanonicalVarKind::PlaceholderConst(placeholder, c.ty()) CanonicalVarKind::PlaceholderConst(placeholder, c.ty())
} }
}, },
ConstKind::Param(_) => match self.canonicalize_mode { ty::ConstKind::Param(_) => match self.canonicalize_mode {
CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst( CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst(
Placeholder::new(UniverseIndex::ROOT, self.variables.len().into()), PlaceholderLike::new(ty::UniverseIndex::ROOT, self.variables.len().into()),
c.ty(), c.ty(),
), ),
CanonicalizeMode::Response { .. } => panic!("param ty in response: {c:?}"), CanonicalizeMode::Response { .. } => panic!("param ty in response: {c:?}"),
}, },
ConstKind::Bound(_, _) ty::ConstKind::Bound(_, _)
| ConstKind::Unevaluated(_) | ty::ConstKind::Unevaluated(_)
| ConstKind::Value(_) | ty::ConstKind::Value(_)
| ConstKind::Error(_) | ty::ConstKind::Error(_)
| ConstKind::Expr(_) => return c.super_fold_with(self), | ty::ConstKind::Expr(_) => return c.super_fold_with(self),
}; };
let ty = c.ty(); let var = ty::BoundVar::from(
let c = c.clone().into(); self.variables.iter().position(|&v| v == c.into()).unwrap_or_else(|| {
let var =
BoundVar::from(self.variables.iter().position(|v| v == &c).unwrap_or_else(|| {
let var = self.variables.len(); let var = self.variables.len();
self.variables.push(c); self.variables.push(c.into());
self.primitive_var_infos.push(CanonicalVarInfo { kind }); self.primitive_var_infos.push(CanonicalVarInfo { kind });
var var
})); }),
);
self.interner().mk_bound_const(self.binder_index, var, ty) self.interner().mk_bound_const(self.binder_index, var, c.ty())
} }
} }

View file

@ -4,7 +4,7 @@ use std::ops::ControlFlow;
use crate::fold::{FallibleTypeFolder, TypeFoldable}; use crate::fold::{FallibleTypeFolder, TypeFoldable};
use crate::visit::{TypeVisitable, TypeVisitor}; use crate::visit::{TypeVisitable, TypeVisitor};
use crate::{Interner, Placeholder, UniverseIndex}; use crate::{Interner, PlaceholderLike, UniverseIndex};
/// A "canonicalized" type `V` is one where all free inference /// A "canonicalized" type `V` is one where all free inference
/// variables have been rewritten to "canonical vars". These are /// variables have been rewritten to "canonical vars". These are
@ -157,12 +157,12 @@ where
} }
impl<I: Interner> CanonicalVarInfo<I> { impl<I: Interner> CanonicalVarInfo<I> {
pub fn universe(&self) -> UniverseIndex { pub fn universe(self) -> UniverseIndex {
self.kind.universe() self.kind.universe()
} }
#[must_use] #[must_use]
pub fn with_updated_universe(&self, ui: UniverseIndex) -> CanonicalVarInfo<I> { pub fn with_updated_universe(self, ui: UniverseIndex) -> CanonicalVarInfo<I> {
CanonicalVarInfo { kind: self.kind.with_updated_universe(ui) } CanonicalVarInfo { kind: self.kind.with_updated_universe(ui) }
} }
@ -305,11 +305,11 @@ where
} }
impl<I: Interner> CanonicalVarKind<I> { impl<I: Interner> CanonicalVarKind<I> {
pub fn universe(&self) -> UniverseIndex { pub fn universe(self) -> UniverseIndex {
match self { match self {
CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) => *ui, CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) => ui,
CanonicalVarKind::Region(ui) => *ui, CanonicalVarKind::Region(ui) => ui,
CanonicalVarKind::Const(ui, _) => *ui, CanonicalVarKind::Const(ui, _) => ui,
CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe(), CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe(),
CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe(), CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe(),
CanonicalVarKind::PlaceholderConst(placeholder, _) => placeholder.universe(), CanonicalVarKind::PlaceholderConst(placeholder, _) => placeholder.universe(),
@ -324,13 +324,13 @@ impl<I: Interner> CanonicalVarKind<I> {
/// ///
/// In case this is a float or int variable, this causes an ICE if /// In case this is a float or int variable, this causes an ICE if
/// the updated universe is not the root. /// the updated universe is not the root.
pub fn with_updated_universe(&self, ui: UniverseIndex) -> CanonicalVarKind<I> { pub fn with_updated_universe(self, ui: UniverseIndex) -> CanonicalVarKind<I> {
match self { match self {
CanonicalVarKind::Ty(CanonicalTyVarKind::General(_)) => { CanonicalVarKind::Ty(CanonicalTyVarKind::General(_)) => {
CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui))
} }
CanonicalVarKind::Region(_) => CanonicalVarKind::Region(ui), CanonicalVarKind::Region(_) => CanonicalVarKind::Region(ui),
CanonicalVarKind::Const(_, ty) => CanonicalVarKind::Const(ui, ty.clone()), CanonicalVarKind::Const(_, ty) => CanonicalVarKind::Const(ui, ty),
CanonicalVarKind::PlaceholderTy(placeholder) => { CanonicalVarKind::PlaceholderTy(placeholder) => {
CanonicalVarKind::PlaceholderTy(placeholder.with_updated_universe(ui)) CanonicalVarKind::PlaceholderTy(placeholder.with_updated_universe(ui))
@ -339,15 +339,12 @@ impl<I: Interner> CanonicalVarKind<I> {
CanonicalVarKind::PlaceholderRegion(placeholder.with_updated_universe(ui)) CanonicalVarKind::PlaceholderRegion(placeholder.with_updated_universe(ui))
} }
CanonicalVarKind::PlaceholderConst(placeholder, ty) => { CanonicalVarKind::PlaceholderConst(placeholder, ty) => {
CanonicalVarKind::PlaceholderConst( CanonicalVarKind::PlaceholderConst(placeholder.with_updated_universe(ui), ty)
placeholder.with_updated_universe(ui),
ty.clone(),
)
} }
CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float)
| CanonicalVarKind::Effect => { | CanonicalVarKind::Effect => {
assert_eq!(ui, UniverseIndex::ROOT); assert_eq!(ui, UniverseIndex::ROOT);
self.clone() self
} }
} }
} }

View file

@ -81,7 +81,7 @@ impl<I: Interner> DebugWithInfcx<I> for ConstKind<I> {
match this.data { match this.data {
Param(param) => write!(f, "{param:?}"), Param(param) => write!(f, "{param:?}"),
Infer(var) => write!(f, "{:?}", &this.wrap(var)), Infer(var) => write!(f, "{:?}", &this.wrap(var)),
Bound(debruijn, var) => crate::debug_bound_var(f, *debruijn, var.clone()), Bound(debruijn, var) => crate::debug_bound_var(f, *debruijn, var),
Placeholder(placeholder) => write!(f, "{placeholder:?}"), Placeholder(placeholder) => write!(f, "{placeholder:?}"),
Unevaluated(uv) => { Unevaluated(uv) => {
write!(f, "{:?}", &this.wrap(uv)) write!(f, "{:?}", &this.wrap(uv))

View file

@ -16,7 +16,7 @@ impl<I: Interner> InferCtxtLike for NoInfcx<I> {
None None
} }
fn universe_of_lt(&self, _lt: <I as Interner>::InferRegion) -> Option<UniverseIndex> { fn universe_of_lt(&self, _lt: I::InferRegion) -> Option<UniverseIndex> {
None None
} }
@ -28,21 +28,15 @@ impl<I: Interner> InferCtxtLike for NoInfcx<I> {
vid vid
} }
fn probe_ty_var(&self, _vid: TyVid) -> Option<<Self::Interner as Interner>::Ty> { fn probe_ty_var(&self, _vid: TyVid) -> Option<I::Ty> {
None None
} }
fn root_lt_var( fn root_lt_var(&self, vid: I::InferRegion) -> I::InferRegion {
&self,
vid: <Self::Interner as Interner>::InferRegion,
) -> <Self::Interner as Interner>::InferRegion {
vid vid
} }
fn probe_lt_var( fn probe_lt_var(&self, _vid: I::InferRegion) -> Option<I::Region> {
&self,
_vid: <Self::Interner as Interner>::InferRegion,
) -> Option<<Self::Interner as Interner>::Region> {
None None
} }
@ -50,7 +44,7 @@ impl<I: Interner> InferCtxtLike for NoInfcx<I> {
vid vid
} }
fn probe_ct_var(&self, _vid: ConstVid) -> Option<<Self::Interner as Interner>::Const> { fn probe_ct_var(&self, _vid: ConstVid) -> Option<I::Const> {
None None
} }
} }

View file

@ -7,96 +7,96 @@ use crate::{
TyKind, UniverseIndex, TyKind, UniverseIndex,
}; };
#[allow(rustc::usage_of_ty_tykind)]
pub trait Interner: Sized { pub trait Interner: Sized {
type DefId: Clone + Debug + Hash + Ord; type DefId: Copy + Debug + Hash + Ord;
type AdtDef: Clone + Debug + Hash + Ord; type AdtDef: Copy + Debug + Hash + Ord;
type GenericArgs: Clone type GenericArgs: Copy
+ DebugWithInfcx<Self> + DebugWithInfcx<Self>
+ Hash + Hash
+ Ord + Ord
+ IntoIterator<Item = Self::GenericArg>; + IntoIterator<Item = Self::GenericArg>;
type GenericArg: Clone + DebugWithInfcx<Self> + Hash + Ord; type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Ord;
type Term: Clone + Debug + Hash + Ord; type Term: Copy + Debug + Hash + Ord;
type Binder<T>; type Binder<T>;
type TypeAndMut: Clone + Debug + Hash + Ord; type TypeAndMut: Copy + Debug + Hash + Ord;
type CanonicalVars: Clone + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarInfo<Self>>; type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarInfo<Self>>;
// Kinds of tys // Kinds of tys
type Ty: Clone type Ty: Copy
+ DebugWithInfcx<Self> + DebugWithInfcx<Self>
+ Hash + Hash
+ Ord + Ord
+ Into<Self::GenericArg> + Into<Self::GenericArg>
+ IntoKind<Kind = TyKind<Self>>; + IntoKind<Kind = TyKind<Self>>;
type Tys: Clone + Debug + Hash + Ord + IntoIterator<Item = Self::Ty>; type Tys: Copy + Debug + Hash + Ord + IntoIterator<Item = Self::Ty>;
type AliasTy: Clone + DebugWithInfcx<Self> + Hash + Ord; type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Ord;
type ParamTy: Clone + Debug + Hash + Ord; type ParamTy: Copy + Debug + Hash + Ord;
type BoundTy: Clone + Debug + Hash + Ord; type BoundTy: Copy + Debug + Hash + Ord;
type PlaceholderTy: Clone + Debug + Hash + Ord + Placeholder; type PlaceholderTy: Copy + Debug + Hash + Ord + PlaceholderLike;
// Things stored inside of tys // Things stored inside of tys
type ErrorGuaranteed: Clone + Debug + Hash + Ord; type ErrorGuaranteed: Copy + Debug + Hash + Ord;
type BoundExistentialPredicates: Clone + DebugWithInfcx<Self> + Hash + Ord; type BoundExistentialPredicates: Copy + DebugWithInfcx<Self> + Hash + Ord;
type PolyFnSig: Clone + DebugWithInfcx<Self> + Hash + Ord; type PolyFnSig: Copy + DebugWithInfcx<Self> + Hash + Ord;
type AllocId: Clone + Debug + Hash + Ord; type AllocId: Copy + Debug + Hash + Ord;
// Kinds of consts // Kinds of consts
type Const: Clone type Const: Copy
+ DebugWithInfcx<Self> + DebugWithInfcx<Self>
+ Hash + Hash
+ Ord + Ord
+ Into<Self::GenericArg> + Into<Self::GenericArg>
+ IntoKind<Kind = ConstKind<Self>> + IntoKind<Kind = ConstKind<Self>>
+ ConstTy<Self>; + ConstTy<Self>;
type AliasConst: Clone + DebugWithInfcx<Self> + Hash + Ord; type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Ord;
type PlaceholderConst: Clone + Debug + Hash + Ord + Placeholder; type PlaceholderConst: Copy + Debug + Hash + Ord + PlaceholderLike;
type ParamConst: Clone + Debug + Hash + Ord; type ParamConst: Copy + Debug + Hash + Ord;
type BoundConst: Clone + Debug + Hash + Ord; type BoundConst: Copy + Debug + Hash + Ord;
type ValueConst: Clone + Debug + Hash + Ord; type ValueConst: Copy + Debug + Hash + Ord;
type ExprConst: Clone + DebugWithInfcx<Self> + Hash + Ord; type ExprConst: Copy + DebugWithInfcx<Self> + Hash + Ord;
// Kinds of regions // Kinds of regions
type Region: Clone type Region: Copy
+ DebugWithInfcx<Self> + DebugWithInfcx<Self>
+ Hash + Hash
+ Ord + Ord
+ Into<Self::GenericArg> + Into<Self::GenericArg>
+ IntoKind<Kind = RegionKind<Self>>; + IntoKind<Kind = RegionKind<Self>>;
type EarlyParamRegion: Clone + Debug + Hash + Ord; type EarlyParamRegion: Copy + Debug + Hash + Ord;
type LateParamRegion: Clone + Debug + Hash + Ord; type LateParamRegion: Copy + Debug + Hash + Ord;
type BoundRegion: Clone + Debug + Hash + Ord; type BoundRegion: Copy + Debug + Hash + Ord;
type InferRegion: Clone + DebugWithInfcx<Self> + Hash + Ord; type InferRegion: Copy + DebugWithInfcx<Self> + Hash + Ord;
type PlaceholderRegion: Clone + Debug + Hash + Ord + Placeholder; type PlaceholderRegion: Copy + Debug + Hash + Ord + PlaceholderLike;
// Predicates // Predicates
type Predicate: Clone + Debug + Hash + Eq; type Predicate: Copy + Debug + Hash + Eq;
type TraitPredicate: Clone + Debug + Hash + Eq; type TraitPredicate: Copy + Debug + Hash + Eq;
type RegionOutlivesPredicate: Clone + Debug + Hash + Eq; type RegionOutlivesPredicate: Copy + Debug + Hash + Eq;
type TypeOutlivesPredicate: Clone + Debug + Hash + Eq; type TypeOutlivesPredicate: Copy + Debug + Hash + Eq;
type ProjectionPredicate: Clone + Debug + Hash + Eq; type ProjectionPredicate: Copy + Debug + Hash + Eq;
type NormalizesTo: Clone + Debug + Hash + Eq; type NormalizesTo: Copy + Debug + Hash + Eq;
type SubtypePredicate: Clone + Debug + Hash + Eq; type SubtypePredicate: Copy + Debug + Hash + Eq;
type CoercePredicate: Clone + Debug + Hash + Eq; type CoercePredicate: Copy + Debug + Hash + Eq;
type ClosureKind: Clone + Debug + Hash + Eq; type ClosureKind: Copy + Debug + Hash + Eq;
fn ty_and_mut_to_parts(ty_and_mut: Self::TypeAndMut) -> (Self::Ty, Mutability); fn ty_and_mut_to_parts(ty_and_mut: Self::TypeAndMut) -> (Self::Ty, Mutability);
fn mk_canonical_var_infos(&self, infos: &[CanonicalVarInfo<Self>]) -> Self::CanonicalVars; fn mk_canonical_var_infos(self, infos: &[CanonicalVarInfo<Self>]) -> Self::CanonicalVars;
fn mk_bound_ty(&self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Ty; // FIXME: We should not have all these constructors on `Interner`, but as functions on some trait.
fn mk_bound_region(&self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Region; fn mk_bound_ty(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Ty;
fn mk_bound_const(&self, debruijn: DebruijnIndex, var: BoundVar, ty: Self::Ty) -> Self::Const; fn mk_bound_region(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Region;
fn mk_bound_const(self, debruijn: DebruijnIndex, var: BoundVar, ty: Self::Ty) -> Self::Const;
} }
/// Common capabilities of placeholder kinds /// Common capabilities of placeholder kinds
pub trait Placeholder { pub trait PlaceholderLike {
fn universe(&self) -> UniverseIndex; fn universe(self) -> UniverseIndex;
fn var(&self) -> BoundVar; fn var(self) -> BoundVar;
fn with_updated_universe(&self, ui: UniverseIndex) -> Self; fn with_updated_universe(self, ui: UniverseIndex) -> Self;
fn new(ui: UniverseIndex, var: BoundVar) -> Self; fn new(ui: UniverseIndex, var: BoundVar) -> Self;
} }
@ -104,11 +104,11 @@ pub trait Placeholder {
pub trait IntoKind { pub trait IntoKind {
type Kind; type Kind;
fn kind(&self) -> Self::Kind; fn kind(self) -> Self::Kind;
} }
pub trait ConstTy<I: Interner> { pub trait ConstTy<I: Interner> {
fn ty(&self) -> I::Ty; fn ty(self) -> I::Ty;
} }
/// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter` /// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter`

View file

@ -4,6 +4,7 @@
)] )]
#![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)] #![deny(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::usage_of_ty_tykind)]
#![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", allow(internal_features))]
#[cfg(feature = "nightly")] #[cfg(feature = "nightly")]
@ -52,6 +53,11 @@ pub use predicate_kind::*;
pub use region_kind::*; pub use region_kind::*;
pub use ty_info::*; pub use ty_info::*;
pub use ty_kind::*; pub use ty_kind::*;
pub use AliasKind::*;
pub use DynKind::*;
pub use InferTy::*;
pub use RegionKind::*;
pub use TyKind::*;
rustc_index::newtype_index! { rustc_index::newtype_index! {
/// A [De Bruijn index][dbi] is a standard means of representing /// A [De Bruijn index][dbi] is a standard means of representing

View file

@ -1,5 +1,3 @@
#![allow(rustc::usage_of_ty_tykind)]
#[cfg(feature = "nightly")] #[cfg(feature = "nightly")]
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
#[cfg(feature = "nightly")] #[cfg(feature = "nightly")]
@ -394,7 +392,7 @@ impl<I: Interner> DebugWithInfcx<I> for TyKind<I> {
Float(float) => write!(f, "{float:?}"), Float(float) => write!(f, "{float:?}"),
Adt(d, s) => { Adt(d, s) => {
write!(f, "{d:?}")?; write!(f, "{d:?}")?;
let mut s = s.clone().into_iter(); let mut s = s.into_iter();
let first = s.next(); let first = s.next();
match first { match first {
Some(first) => write!(f, "<{:?}", first)?, Some(first) => write!(f, "<{:?}", first)?,
@ -412,7 +410,7 @@ impl<I: Interner> DebugWithInfcx<I> for TyKind<I> {
Array(t, c) => write!(f, "[{:?}; {:?}]", &this.wrap(t), &this.wrap(c)), Array(t, c) => write!(f, "[{:?}; {:?}]", &this.wrap(t), &this.wrap(c)),
Slice(t) => write!(f, "[{:?}]", &this.wrap(t)), Slice(t) => write!(f, "[{:?}]", &this.wrap(t)),
RawPtr(p) => { RawPtr(p) => {
let (ty, mutbl) = I::ty_and_mut_to_parts(p.clone()); let (ty, mutbl) = I::ty_and_mut_to_parts(*p);
match mutbl { match mutbl {
Mutability::Mut => write!(f, "*mut "), Mutability::Mut => write!(f, "*mut "),
Mutability::Not => write!(f, "*const "), Mutability::Not => write!(f, "*const "),
@ -442,7 +440,7 @@ impl<I: Interner> DebugWithInfcx<I> for TyKind<I> {
Tuple(t) => { Tuple(t) => {
write!(f, "(")?; write!(f, "(")?;
let mut count = 0; let mut count = 0;
for ty in t.clone() { for ty in *t {
if count > 0 { if count > 0 {
write!(f, ", ")?; write!(f, ", ")?;
} }