Feedback
- 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:
parent
cb41509601
commit
1f5895b3e3
11 changed files with 205 additions and 229 deletions
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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`
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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, ", ")?;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue