summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/ty/sty.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src/ty/sty.rs')
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs128
1 files changed, 94 insertions, 34 deletions
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 91a7d5d38..e6a73e8bb 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -8,7 +8,7 @@ use crate::ty::visit::ValidateBoundVars;
use crate::ty::InferTy::*;
use crate::ty::{
self, AdtDef, DefIdTree, Discr, FallibleTypeFolder, Term, Ty, TyCtxt, TypeFlags, TypeFoldable,
- TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor,
+ TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
};
use crate::ty::{List, ParamEnv};
use hir::def::DefKind;
@@ -107,6 +107,15 @@ impl BoundRegionKind {
_ => None,
}
}
+
+ pub fn expect_anon(&self) -> u32 {
+ match *self {
+ BoundRegionKind::BrNamed(_, _) | BoundRegionKind::BrEnv => {
+ bug!("expected anon region: {self:?}")
+ }
+ BoundRegionKind::BrAnon(idx, _) => idx,
+ }
+ }
}
pub trait Article {
@@ -250,7 +259,7 @@ impl<'tcx> ClosureSubsts<'tcx> {
parts: ClosureSubstsParts<'tcx, Ty<'tcx>>,
) -> ClosureSubsts<'tcx> {
ClosureSubsts {
- substs: tcx.mk_substs(
+ substs: tcx.mk_substs_from_iter(
parts.parent_substs.iter().copied().chain(
[parts.closure_kind_ty, parts.closure_sig_as_fn_ptr_ty, parts.tupled_upvars_ty]
.iter()
@@ -377,7 +386,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
parts: GeneratorSubstsParts<'tcx, Ty<'tcx>>,
) -> GeneratorSubsts<'tcx> {
GeneratorSubsts {
- substs: tcx.mk_substs(
+ substs: tcx.mk_substs_from_iter(
parts.parent_substs.iter().copied().chain(
[
parts.resume_ty,
@@ -568,12 +577,12 @@ impl<'tcx> GeneratorSubsts<'tcx> {
self,
def_id: DefId,
tcx: TyCtxt<'tcx>,
- ) -> impl Iterator<Item = impl Iterator<Item = Ty<'tcx>> + Captures<'tcx>> {
+ ) -> impl Iterator<Item: Iterator<Item = Ty<'tcx>> + Captures<'tcx>> {
let layout = tcx.generator_layout(def_id).unwrap();
layout.variant_fields.iter().map(move |variant| {
- variant
- .iter()
- .map(move |field| ty::EarlyBinder(layout.field_tys[*field]).subst(tcx, self.substs))
+ variant.iter().map(move |field| {
+ ty::EarlyBinder(layout.field_tys[*field].ty).subst(tcx, self.substs)
+ })
})
}
@@ -655,7 +664,7 @@ impl<'tcx> InlineConstSubsts<'tcx> {
parts: InlineConstSubstsParts<'tcx, Ty<'tcx>>,
) -> InlineConstSubsts<'tcx> {
InlineConstSubsts {
- substs: tcx.mk_substs(
+ substs: tcx.mk_substs_from_iter(
parts.parent_substs.iter().copied().chain(std::iter::once(parts.ty.into())),
),
}
@@ -853,7 +862,7 @@ impl<'tcx> TraitRef<'tcx> {
substs: SubstsRef<'tcx>,
) -> ty::TraitRef<'tcx> {
let defs = tcx.generics_of(trait_id);
- tcx.mk_trait_ref(trait_id, tcx.intern_substs(&substs[..defs.params.len()]))
+ tcx.mk_trait_ref(trait_id, tcx.mk_substs(&substs[..defs.params.len()]))
}
}
@@ -899,7 +908,7 @@ impl<'tcx> ExistentialTraitRef<'tcx> {
ty::ExistentialTraitRef {
def_id: trait_ref.def_id,
- substs: tcx.intern_substs(&trait_ref.substs[1..]),
+ substs: tcx.mk_substs(&trait_ref.substs[1..]),
}
}
@@ -983,7 +992,7 @@ pub struct Binder<'tcx, T>(T, &'tcx List<BoundVariableKind>);
impl<'tcx, T> Binder<'tcx, T>
where
- T: TypeVisitable<'tcx>,
+ T: TypeVisitable<TyCtxt<'tcx>>,
{
/// Wraps `value` in a binder, asserting that `value` does not
/// contain any bound vars that would be bound by the
@@ -1051,14 +1060,14 @@ impl<'tcx, T> Binder<'tcx, T> {
Binder(value, self.1)
}
- pub fn map_bound_ref<F, U: TypeVisitable<'tcx>>(&self, f: F) -> Binder<'tcx, U>
+ pub fn map_bound_ref<F, U: TypeVisitable<TyCtxt<'tcx>>>(&self, f: F) -> Binder<'tcx, U>
where
F: FnOnce(&T) -> U,
{
self.as_ref().map_bound(f)
}
- pub fn map_bound<F, U: TypeVisitable<'tcx>>(self, f: F) -> Binder<'tcx, U>
+ pub fn map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>>(self, f: F) -> Binder<'tcx, U>
where
F: FnOnce(T) -> U,
{
@@ -1070,7 +1079,10 @@ impl<'tcx, T> Binder<'tcx, T> {
Binder(value, self.1)
}
- pub fn try_map_bound<F, U: TypeVisitable<'tcx>, E>(self, f: F) -> Result<Binder<'tcx, U>, E>
+ pub fn try_map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>, E>(
+ self,
+ f: F,
+ ) -> Result<Binder<'tcx, U>, E>
where
F: FnOnce(T) -> Result<U, E>,
{
@@ -1093,7 +1105,7 @@ impl<'tcx, T> Binder<'tcx, T> {
/// in `bind`. This may be (debug) asserted in the future.
pub fn rebind<U>(&self, value: U) -> Binder<'tcx, U>
where
- U: TypeVisitable<'tcx>,
+ U: TypeVisitable<TyCtxt<'tcx>>,
{
if cfg!(debug_assertions) {
let mut validator = ValidateBoundVars::new(self.bound_vars());
@@ -1114,7 +1126,7 @@ impl<'tcx, T> Binder<'tcx, T> {
/// would not be that useful.)
pub fn no_bound_vars(self) -> Option<T>
where
- T: TypeVisitable<'tcx>,
+ T: TypeVisitable<TyCtxt<'tcx>>,
{
if self.0.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
}
@@ -1153,16 +1165,16 @@ struct SkipBindersAt<'tcx> {
index: ty::DebruijnIndex,
}
-impl<'tcx> FallibleTypeFolder<'tcx> for SkipBindersAt<'tcx> {
+impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for SkipBindersAt<'tcx> {
type Error = ();
- fn tcx(&self) -> TyCtxt<'tcx> {
+ fn interner(&self) -> TyCtxt<'tcx> {
self.tcx
}
fn try_fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, Self::Error>
where
- T: ty::TypeFoldable<'tcx>,
+ T: ty::TypeFoldable<TyCtxt<'tcx>>,
{
self.index.shift_in(1);
let value = t.try_map_bound(|t| t.try_fold_with(self));
@@ -1177,7 +1189,7 @@ impl<'tcx> FallibleTypeFolder<'tcx> for SkipBindersAt<'tcx> {
if index == self.index {
Err(())
} else {
- Ok(self.tcx().mk_ty(ty::Bound(index.shifted_out(1), bv)))
+ Ok(self.interner().mk_bound(index.shifted_out(1), bv))
}
} else {
ty.try_super_fold_with(self)
@@ -1191,7 +1203,7 @@ impl<'tcx> FallibleTypeFolder<'tcx> for SkipBindersAt<'tcx> {
if index == self.index {
Err(())
} else {
- Ok(self.tcx().mk_region(ty::ReLateBound(index.shifted_out(1), bv)))
+ Ok(self.interner().mk_re_late_bound(index.shifted_out(1), bv))
}
} else {
r.try_super_fold_with(self)
@@ -1205,7 +1217,7 @@ impl<'tcx> FallibleTypeFolder<'tcx> for SkipBindersAt<'tcx> {
if index == self.index {
Err(())
} else {
- Ok(self.tcx().mk_const(
+ Ok(self.interner().mk_const(
ty::ConstKind::Bound(index.shifted_out(1), bv),
ct.ty().try_fold_with(self)?,
))
@@ -1266,7 +1278,7 @@ impl<'tcx> AliasTy<'tcx> {
}
pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
- tcx.mk_ty(ty::Alias(self.kind(tcx), self))
+ tcx.mk_alias(self.kind(tcx), self)
}
}
@@ -1510,13 +1522,22 @@ pub struct BoundTy {
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable)]
pub enum BoundTyKind {
- Anon,
- Param(Symbol),
+ Anon(u32),
+ Param(DefId, Symbol),
+}
+
+impl BoundTyKind {
+ pub fn expect_anon(self) -> u32 {
+ match self {
+ BoundTyKind::Anon(i) => i,
+ _ => bug!(),
+ }
+ }
}
impl From<BoundVar> for BoundTy {
fn from(var: BoundVar) -> Self {
- BoundTy { var, kind: BoundTyKind::Anon }
+ BoundTy { var, kind: BoundTyKind::Anon(var.as_u32()) }
}
}
@@ -1539,7 +1560,7 @@ impl<'tcx> ExistentialProjection<'tcx> {
pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::ExistentialTraitRef<'tcx> {
let def_id = tcx.parent(self.def_id);
let subst_count = tcx.generics_of(def_id).count() - 1;
- let substs = tcx.intern_substs(&self.substs[..subst_count]);
+ let substs = tcx.mk_substs(&self.substs[..subst_count]);
ty::ExistentialTraitRef { def_id, substs }
}
@@ -1567,7 +1588,7 @@ impl<'tcx> ExistentialProjection<'tcx> {
Self {
def_id: projection_predicate.projection_ty.def_id,
- substs: tcx.intern_substs(&projection_predicate.projection_ty.substs[1..]),
+ substs: tcx.mk_substs(&projection_predicate.projection_ty.substs[1..]),
term: projection_predicate.term,
}
}
@@ -1620,10 +1641,16 @@ impl<'tcx> Region<'tcx> {
ty::ReVar(..) => false,
ty::RePlaceholder(placeholder) => placeholder.name.is_named(),
ty::ReErased => false,
+ ty::ReError(_) => false,
}
}
#[inline]
+ pub fn is_error(self) -> bool {
+ matches!(*self, ty::ReError(_))
+ }
+
+ #[inline]
pub fn is_static(self) -> bool {
matches!(*self, ty::ReStatic)
}
@@ -1683,6 +1710,7 @@ impl<'tcx> Region<'tcx> {
ty::ReErased => {
flags = flags | TypeFlags::HAS_RE_ERASED;
}
+ ty::ReError(_) => {}
}
debug!("type_flags({:?}) = {:?}", self, flags);
@@ -1733,6 +1761,13 @@ impl<'tcx> Region<'tcx> {
pub fn is_var(self) -> bool {
matches!(self.kind(), ty::ReVar(_))
}
+
+ pub fn as_var(self) -> Option<RegionVid> {
+ match self.kind() {
+ ty::ReVar(vid) => Some(vid),
+ _ => None,
+ }
+ }
}
/// Type utilities
@@ -1867,7 +1902,7 @@ impl<'tcx> Ty<'tcx> {
// The way we evaluate the `N` in `[T; N]` here only works since we use
// `simd_size_and_type` post-monomorphization. It will probably start to ICE
// if we use it in generic code. See the `simd-array-trait` ui test.
- (f0_len.eval_usize(tcx, ParamEnv::empty()) as u64, *f0_elem_ty)
+ (f0_len.eval_target_usize(tcx, ParamEnv::empty()) as u64, *f0_elem_ty)
}
// Otherwise, the fields of this Adt are the SIMD components (and we assume they
// all have the same type).
@@ -2028,7 +2063,7 @@ impl<'tcx> Ty<'tcx> {
pub fn contains(self, other: Ty<'tcx>) -> bool {
struct ContainsTyVisitor<'tcx>(Ty<'tcx>);
- impl<'tcx> TypeVisitor<'tcx> for ContainsTyVisitor<'tcx> {
+ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTyVisitor<'tcx> {
type BreakTy = ();
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
@@ -2040,6 +2075,28 @@ impl<'tcx> Ty<'tcx> {
cf.is_break()
}
+ /// Checks whether a type recursively contains any closure
+ ///
+ /// Example: `Option<[closure@file.rs:4:20]>` returns true
+ pub fn contains_closure(self) -> bool {
+ struct ContainsClosureVisitor;
+
+ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsClosureVisitor {
+ type BreakTy = ();
+
+ fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
+ if let ty::Closure(_, _) = t.kind() {
+ ControlFlow::Break(())
+ } else {
+ t.super_visit_with(self)
+ }
+ }
+ }
+
+ let cf = self.visit_with(&mut ContainsClosureVisitor);
+ cf.is_break()
+ }
+
/// Returns the type and mutability of `*ty`.
///
/// The parameter `explicit` indicates if this is an *explicit* dereference.
@@ -2065,7 +2122,7 @@ impl<'tcx> Ty<'tcx> {
pub fn fn_sig(self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> {
match self.kind() {
- FnDef(def_id, substs) => tcx.bound_fn_sig(*def_id).subst(tcx, substs),
+ FnDef(def_id, substs) => tcx.fn_sig(*def_id).subst(tcx, substs),
FnPtr(f) => *f,
Error(_) => {
// ignore errors (#54954)
@@ -2161,7 +2218,7 @@ impl<'tcx> Ty<'tcx> {
let assoc_items = tcx.associated_item_def_ids(
tcx.require_lang_item(hir::LangItem::DiscriminantKind, None),
);
- tcx.mk_projection(assoc_items[0], tcx.intern_substs(&[self.into()]))
+ tcx.mk_projection(assoc_items[0], tcx.mk_substs(&[self.into()]))
}
ty::Bool
@@ -2181,6 +2238,7 @@ impl<'tcx> Ty<'tcx> {
| ty::Dynamic(..)
| ty::Closure(..)
| ty::GeneratorWitness(..)
+ | ty::GeneratorWitnessMIR(..)
| ty::Never
| ty::Tuple(_)
| ty::Error(_)
@@ -2216,6 +2274,7 @@ impl<'tcx> Ty<'tcx> {
| ty::Ref(..)
| ty::Generator(..)
| ty::GeneratorWitness(..)
+ | ty::GeneratorWitnessMIR(..)
| ty::Array(..)
| ty::Closure(..)
| ty::Never
@@ -2232,7 +2291,7 @@ impl<'tcx> Ty<'tcx> {
ty::Str | ty::Slice(_) => (tcx.types.usize, false),
ty::Dynamic(..) => {
let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None);
- (tcx.bound_type_of(dyn_metadata).subst(tcx, &[tail.into()]), false)
+ (tcx.type_of(dyn_metadata).subst(tcx, &[tail.into()]), false)
},
// type parameters only have unit metadata if they're sized, so return true
@@ -2302,6 +2361,7 @@ impl<'tcx> Ty<'tcx> {
| ty::Ref(..)
| ty::Generator(..)
| ty::GeneratorWitness(..)
+ | ty::GeneratorWitnessMIR(..)
| ty::Array(..)
| ty::Closure(..)
| ty::Never
@@ -2366,7 +2426,7 @@ impl<'tcx> Ty<'tcx> {
// anything with custom metadata it might be more complicated.
ty::Ref(_, _, hir::Mutability::Not) | ty::RawPtr(..) => false,
- ty::Generator(..) | ty::GeneratorWitness(..) => false,
+ ty::Generator(..) | ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => false,
// Might be, but not "trivial" so just giving the safe answer.
ty::Adt(..) | ty::Closure(..) => false,