summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/ty/sty.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
commitdc0db358abe19481e475e10c32149b53370f1a1c (patch)
treeab8ce99c4b255ce46f99ef402c27916055b899ee /compiler/rustc_middle/src/ty/sty.rs
parentReleasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff)
downloadrustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz
rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_middle/src/ty/sty.rs')
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs573
1 files changed, 532 insertions, 41 deletions
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index e6d51c4ec..94746fbdc 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -15,16 +15,18 @@ use hir::def::DefKind;
use polonius_engine::Atom;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::intern::Interned;
-use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
+use rustc_error_messages::DiagnosticMessage;
+use rustc_errors::{DiagnosticArgValue, ErrorGuaranteed, IntoDiagnosticArg, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::LangItem;
use rustc_index::Idx;
use rustc_macros::HashStable;
use rustc_span::symbol::{kw, sym, Symbol};
-use rustc_span::Span;
+use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
use rustc_target::spec::abi::{self, Abi};
+use std::assert_matches::debug_assert_matches;
use std::borrow::Cow;
use std::cmp::Ordering;
use std::fmt;
@@ -33,13 +35,17 @@ use std::ops::{ControlFlow, Deref, Range};
use ty::util::IntTypeExt;
use rustc_type_ir::sty::TyKind::*;
-use rustc_type_ir::RegionKind as IrRegionKind;
use rustc_type_ir::TyKind as IrTyKind;
+use rustc_type_ir::{CollectAndApply, ConstKind as IrConstKind};
+use rustc_type_ir::{DynKind, RegionKind as IrRegionKind};
+
+use super::GenericParamDefKind;
// Re-export the `TyKind` from `rustc_type_ir` here for convenience
#[rustc_diagnostic_item = "TyKind"]
pub type TyKind<'tcx> = IrTyKind<TyCtxt<'tcx>>;
pub type RegionKind<'tcx> = IrRegionKind<TyCtxt<'tcx>>;
+pub type ConstKind<'tcx> = IrConstKind<TyCtxt<'tcx>>;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
@@ -568,7 +574,7 @@ impl<'tcx> GeneratorSubsts<'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].ty).subst(tcx, self.substs)
+ ty::EarlyBinder::bind(layout.field_tys[*field].ty).subst(tcx, self.substs)
})
})
}
@@ -715,7 +721,7 @@ impl<'tcx> PolyExistentialPredicate<'tcx> {
/// Given an existential predicate like `?Self: PartialEq<u32>` (e.g., derived from `dyn PartialEq<u32>`),
/// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self`
/// has been replaced with `self_ty` (e.g., `self_ty: PartialEq<u32>`, in our example).
- pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> {
+ pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Clause<'tcx> {
use crate::ty::ToPredicate;
match self.skip_binder() {
ExistentialPredicate::Trait(tr) => {
@@ -1007,7 +1013,10 @@ impl BoundVariableKind {
/// `Decodable` and `Encodable` are implemented for `Binder<T>` using the `impl_binder_encode_decode!` macro.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[derive(HashStable, Lift)]
-pub struct Binder<'tcx, T>(T, &'tcx List<BoundVariableKind>);
+pub struct Binder<'tcx, T> {
+ value: T,
+ bound_vars: &'tcx List<BoundVariableKind>,
+}
impl<'tcx, T> Binder<'tcx, T>
where
@@ -1023,15 +1032,15 @@ where
!value.has_escaping_bound_vars(),
"`{value:?}` has escaping bound vars, so it cannot be wrapped in a dummy binder."
);
- Binder(value, ty::List::empty())
+ Binder { value, bound_vars: ty::List::empty() }
}
- pub fn bind_with_vars(value: T, vars: &'tcx List<BoundVariableKind>) -> Binder<'tcx, T> {
+ pub fn bind_with_vars(value: T, bound_vars: &'tcx List<BoundVariableKind>) -> Binder<'tcx, T> {
if cfg!(debug_assertions) {
- let mut validator = ValidateBoundVars::new(vars);
+ let mut validator = ValidateBoundVars::new(bound_vars);
value.visit_with(&mut validator);
}
- Binder(value, vars)
+ Binder { value, bound_vars }
}
}
@@ -1053,30 +1062,30 @@ impl<'tcx, T> Binder<'tcx, T> {
/// - comparing the self type of a PolyTraitRef to see if it is equal to
/// a type parameter `X`, since the type `X` does not reference any regions
pub fn skip_binder(self) -> T {
- self.0
+ self.value
}
pub fn bound_vars(&self) -> &'tcx List<BoundVariableKind> {
- self.1
+ self.bound_vars
}
pub fn as_ref(&self) -> Binder<'tcx, &T> {
- Binder(&self.0, self.1)
+ Binder { value: &self.value, bound_vars: self.bound_vars }
}
pub fn as_deref(&self) -> Binder<'tcx, &T::Target>
where
T: Deref,
{
- Binder(&self.0, self.1)
+ Binder { value: &self.value, bound_vars: self.bound_vars }
}
pub fn map_bound_ref_unchecked<F, U>(&self, f: F) -> Binder<'tcx, U>
where
F: FnOnce(&T) -> U,
{
- let value = f(&self.0);
- Binder(value, self.1)
+ let value = f(&self.value);
+ Binder { value, bound_vars: self.bound_vars }
}
pub fn map_bound_ref<F, U: TypeVisitable<TyCtxt<'tcx>>>(&self, f: F) -> Binder<'tcx, U>
@@ -1090,12 +1099,13 @@ impl<'tcx, T> Binder<'tcx, T> {
where
F: FnOnce(T) -> U,
{
- let value = f(self.0);
+ let Binder { value, bound_vars } = self;
+ let value = f(value);
if cfg!(debug_assertions) {
- let mut validator = ValidateBoundVars::new(self.1);
+ let mut validator = ValidateBoundVars::new(bound_vars);
value.visit_with(&mut validator);
}
- Binder(value, self.1)
+ Binder { value, bound_vars }
}
pub fn try_map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>, E>(
@@ -1105,12 +1115,13 @@ impl<'tcx, T> Binder<'tcx, T> {
where
F: FnOnce(T) -> Result<U, E>,
{
- let value = f(self.0)?;
+ let Binder { value, bound_vars } = self;
+ let value = f(value)?;
if cfg!(debug_assertions) {
- let mut validator = ValidateBoundVars::new(self.1);
+ let mut validator = ValidateBoundVars::new(bound_vars);
value.visit_with(&mut validator);
}
- Ok(Binder(value, self.1))
+ Ok(Binder { value, bound_vars })
}
/// Wraps a `value` in a binder, using the same bound variables as the
@@ -1126,11 +1137,7 @@ impl<'tcx, T> Binder<'tcx, T> {
where
U: TypeVisitable<TyCtxt<'tcx>>,
{
- if cfg!(debug_assertions) {
- let mut validator = ValidateBoundVars::new(self.bound_vars());
- value.visit_with(&mut validator);
- }
- Binder(value, self.1)
+ Binder::bind_with_vars(value, self.bound_vars)
}
/// Unwraps and returns the value within, but only if it contains
@@ -1147,7 +1154,7 @@ impl<'tcx, T> Binder<'tcx, T> {
where
T: TypeVisitable<TyCtxt<'tcx>>,
{
- if self.0.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
+ if self.value.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
}
/// Splits the contents into two things that share the same binder
@@ -1160,22 +1167,23 @@ impl<'tcx, T> Binder<'tcx, T> {
where
F: FnOnce(T) -> (U, V),
{
- let (u, v) = f(self.0);
- (Binder(u, self.1), Binder(v, self.1))
+ let Binder { value, bound_vars } = self;
+ let (u, v) = f(value);
+ (Binder { value: u, bound_vars }, Binder { value: v, bound_vars })
}
}
impl<'tcx, T> Binder<'tcx, Option<T>> {
pub fn transpose(self) -> Option<Binder<'tcx, T>> {
- let bound_vars = self.1;
- self.0.map(|v| Binder(v, bound_vars))
+ let Binder { value, bound_vars } = self;
+ value.map(|value| Binder { value, bound_vars })
}
}
impl<'tcx, T: IntoIterator> Binder<'tcx, T> {
pub fn iter(self) -> impl Iterator<Item = ty::Binder<'tcx, T::Item>> {
- let bound_vars = self.1;
- self.0.into_iter().map(|v| Binder(v, bound_vars))
+ let Binder { value, bound_vars } = self;
+ value.into_iter().map(|value| Binder { value, bound_vars })
}
}
@@ -1184,7 +1192,7 @@ where
T: IntoDiagnosticArg,
{
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
- self.0.into_diagnostic_arg()
+ self.value.into_diagnostic_arg()
}
}
@@ -1231,12 +1239,13 @@ impl<'tcx> AliasTy<'tcx> {
DefKind::AssocTy if let DefKind::Impl { of_trait: false } = tcx.def_kind(tcx.parent(self.def_id)) => ty::Inherent,
DefKind::AssocTy | DefKind::ImplTraitPlaceholder => ty::Projection,
DefKind::OpaqueTy => ty::Opaque,
+ DefKind::TyAlias => ty::Weak,
kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
}
}
pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
- tcx.mk_alias(self.kind(tcx), self)
+ Ty::new_alias(tcx, self.kind(tcx), self)
}
}
@@ -1427,7 +1436,7 @@ impl<'tcx> ParamTy {
#[inline]
pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
- tcx.mk_ty_param(self.index, self.name)
+ Ty::new_param(tcx, self.index, self.name)
}
pub fn span_from_generics(&self, tcx: TyCtxt<'tcx>, item_with_generics: DefId) -> Span {
@@ -1459,6 +1468,103 @@ impl ParamConst {
#[rustc_pass_by_value]
pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>);
+impl<'tcx> Region<'tcx> {
+ #[inline]
+ pub fn new_early_bound(
+ tcx: TyCtxt<'tcx>,
+ early_bound_region: ty::EarlyBoundRegion,
+ ) -> Region<'tcx> {
+ tcx.intern_region(ty::ReEarlyBound(early_bound_region))
+ }
+
+ #[inline]
+ pub fn new_late_bound(
+ tcx: TyCtxt<'tcx>,
+ debruijn: ty::DebruijnIndex,
+ bound_region: ty::BoundRegion,
+ ) -> Region<'tcx> {
+ // Use a pre-interned one when possible.
+ if let ty::BoundRegion { var, kind: ty::BrAnon(None) } = bound_region
+ && let Some(inner) = tcx.lifetimes.re_late_bounds.get(debruijn.as_usize())
+ && let Some(re) = inner.get(var.as_usize()).copied()
+ {
+ re
+ } else {
+ tcx.intern_region(ty::ReLateBound(debruijn, bound_region))
+ }
+ }
+
+ #[inline]
+ pub fn new_free(
+ tcx: TyCtxt<'tcx>,
+ scope: DefId,
+ bound_region: ty::BoundRegionKind,
+ ) -> Region<'tcx> {
+ tcx.intern_region(ty::ReFree(ty::FreeRegion { scope, bound_region }))
+ }
+
+ #[inline]
+ pub fn new_var(tcx: TyCtxt<'tcx>, v: ty::RegionVid) -> Region<'tcx> {
+ // Use a pre-interned one when possible.
+ tcx.lifetimes
+ .re_vars
+ .get(v.as_usize())
+ .copied()
+ .unwrap_or_else(|| tcx.intern_region(ty::ReVar(v)))
+ }
+
+ #[inline]
+ pub fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderRegion) -> Region<'tcx> {
+ tcx.intern_region(ty::RePlaceholder(placeholder))
+ }
+
+ /// Constructs a `RegionKind::ReError` region.
+ #[track_caller]
+ pub fn new_error(tcx: TyCtxt<'tcx>, reported: ErrorGuaranteed) -> Region<'tcx> {
+ tcx.intern_region(ty::ReError(reported))
+ }
+
+ /// Constructs a `RegionKind::ReError` region and registers a `delay_span_bug` to ensure it
+ /// gets used.
+ #[track_caller]
+ pub fn new_error_misc(tcx: TyCtxt<'tcx>) -> Region<'tcx> {
+ Region::new_error_with_message(
+ tcx,
+ DUMMY_SP,
+ "RegionKind::ReError constructed but no error reported",
+ )
+ }
+
+ /// Constructs a `RegionKind::ReError` region and registers a `delay_span_bug` with the given
+ /// `msg` to ensure it gets used.
+ #[track_caller]
+ pub fn new_error_with_message<S: Into<MultiSpan>>(
+ tcx: TyCtxt<'tcx>,
+ span: S,
+ msg: &'static str,
+ ) -> Region<'tcx> {
+ let reported = tcx.sess.delay_span_bug(span, msg);
+ Region::new_error(tcx, reported)
+ }
+
+ /// Avoid this in favour of more specific `new_*` methods, where possible,
+ /// to avoid the cost of the `match`.
+ pub fn new_from_kind(tcx: TyCtxt<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> {
+ match kind {
+ ty::ReEarlyBound(region) => Region::new_early_bound(tcx, region),
+ ty::ReLateBound(debruijn, region) => Region::new_late_bound(tcx, debruijn, region),
+ ty::ReFree(ty::FreeRegion { scope, bound_region }) => {
+ Region::new_free(tcx, scope, bound_region)
+ }
+ ty::ReStatic => tcx.lifetimes.re_static,
+ ty::ReVar(vid) => Region::new_var(tcx, vid),
+ ty::RePlaceholder(region) => Region::new_placeholder(tcx, region),
+ ty::ReErased => tcx.lifetimes.re_erased,
+ ty::ReError(reported) => Region::new_error(tcx, reported),
+ }
+ }
+}
+
impl<'tcx> Deref for Region<'tcx> {
type Target = RegionKind<'tcx>;
@@ -1484,7 +1590,7 @@ pub struct EarlyBoundRegion {
impl fmt::Debug for EarlyBoundRegion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}, {}", self.index, self.name)
+ write!(f, "{:?}, {}, {}", self.def_id, self.index, self.name)
}
}
@@ -1511,10 +1617,11 @@ impl Atom for RegionVid {
rustc_index::newtype_index! {
#[derive(HashStable)]
+ #[debug_format = "{}"]
pub struct BoundVar {}
}
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable)]
pub struct BoundTy {
pub var: BoundVar,
@@ -1770,6 +1877,390 @@ impl<'tcx> Region<'tcx> {
}
}
+/// Constructors for `Ty`
+impl<'tcx> Ty<'tcx> {
+ // Avoid this in favour of more specific `new_*` methods, where possible.
+ #[allow(rustc::usage_of_ty_tykind)]
+ #[inline]
+ pub fn new(tcx: TyCtxt<'tcx>, st: TyKind<'tcx>) -> Ty<'tcx> {
+ tcx.mk_ty_from_kind(st)
+ }
+
+ #[inline]
+ pub fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferTy) -> Ty<'tcx> {
+ Ty::new(tcx, TyKind::Infer(infer))
+ }
+
+ #[inline]
+ pub fn new_var(tcx: TyCtxt<'tcx>, v: ty::TyVid) -> Ty<'tcx> {
+ // Use a pre-interned one when possible.
+ tcx.types
+ .ty_vars
+ .get(v.as_usize())
+ .copied()
+ .unwrap_or_else(|| Ty::new(tcx, Infer(TyVar(v))))
+ }
+
+ #[inline]
+ pub fn new_int_var(tcx: TyCtxt<'tcx>, v: ty::IntVid) -> Ty<'tcx> {
+ Ty::new_infer(tcx, IntVar(v))
+ }
+
+ #[inline]
+ pub fn new_float_var(tcx: TyCtxt<'tcx>, v: ty::FloatVid) -> Ty<'tcx> {
+ Ty::new_infer(tcx, FloatVar(v))
+ }
+
+ #[inline]
+ pub fn new_fresh(tcx: TyCtxt<'tcx>, n: u32) -> Ty<'tcx> {
+ // Use a pre-interned one when possible.
+ tcx.types
+ .fresh_tys
+ .get(n as usize)
+ .copied()
+ .unwrap_or_else(|| Ty::new_infer(tcx, ty::FreshTy(n)))
+ }
+
+ #[inline]
+ pub fn new_fresh_int(tcx: TyCtxt<'tcx>, n: u32) -> Ty<'tcx> {
+ // Use a pre-interned one when possible.
+ tcx.types
+ .fresh_int_tys
+ .get(n as usize)
+ .copied()
+ .unwrap_or_else(|| Ty::new_infer(tcx, ty::FreshIntTy(n)))
+ }
+
+ #[inline]
+ pub fn new_fresh_float(tcx: TyCtxt<'tcx>, n: u32) -> Ty<'tcx> {
+ // Use a pre-interned one when possible.
+ tcx.types
+ .fresh_float_tys
+ .get(n as usize)
+ .copied()
+ .unwrap_or_else(|| Ty::new_infer(tcx, ty::FreshFloatTy(n)))
+ }
+
+ #[inline]
+ pub fn new_param(tcx: TyCtxt<'tcx>, index: u32, name: Symbol) -> Ty<'tcx> {
+ tcx.mk_ty_from_kind(Param(ParamTy { index, name }))
+ }
+
+ #[inline]
+ pub fn new_bound(
+ tcx: TyCtxt<'tcx>,
+ index: ty::DebruijnIndex,
+ bound_ty: ty::BoundTy,
+ ) -> Ty<'tcx> {
+ Ty::new(tcx, Bound(index, bound_ty))
+ }
+
+ #[inline]
+ pub fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderType) -> Ty<'tcx> {
+ Ty::new(tcx, Placeholder(placeholder))
+ }
+
+ #[inline]
+ pub fn new_alias(
+ tcx: TyCtxt<'tcx>,
+ kind: ty::AliasKind,
+ alias_ty: ty::AliasTy<'tcx>,
+ ) -> Ty<'tcx> {
+ debug_assert_matches!(
+ (kind, tcx.def_kind(alias_ty.def_id)),
+ (ty::Opaque, DefKind::OpaqueTy)
+ | (ty::Projection | ty::Inherent, DefKind::AssocTy)
+ | (ty::Opaque | ty::Projection, DefKind::ImplTraitPlaceholder)
+ | (ty::Weak, DefKind::TyAlias)
+ );
+ Ty::new(tcx, Alias(kind, alias_ty))
+ }
+
+ #[inline]
+ pub fn new_opaque(tcx: TyCtxt<'tcx>, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
+ Ty::new_alias(tcx, ty::Opaque, tcx.mk_alias_ty(def_id, substs))
+ }
+
+ /// Constructs a `TyKind::Error` type with current `ErrorGuaranteed`
+ pub fn new_error(tcx: TyCtxt<'tcx>, reported: ErrorGuaranteed) -> Ty<'tcx> {
+ Ty::new(tcx, Error(reported))
+ }
+
+ /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used.
+ #[track_caller]
+ pub fn new_misc_error(tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
+ Ty::new_error_with_message(tcx, DUMMY_SP, "TyKind::Error constructed but no error reported")
+ }
+
+ /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg` to
+ /// ensure it gets used.
+ #[track_caller]
+ pub fn new_error_with_message<S: Into<MultiSpan>>(
+ tcx: TyCtxt<'tcx>,
+ span: S,
+ msg: impl Into<DiagnosticMessage>,
+ ) -> Ty<'tcx> {
+ let reported = tcx.sess.delay_span_bug(span, msg);
+ Ty::new(tcx, Error(reported))
+ }
+
+ #[inline]
+ pub fn new_int(tcx: TyCtxt<'tcx>, i: ty::IntTy) -> Ty<'tcx> {
+ use ty::IntTy::*;
+ match i {
+ Isize => tcx.types.isize,
+ I8 => tcx.types.i8,
+ I16 => tcx.types.i16,
+ I32 => tcx.types.i32,
+ I64 => tcx.types.i64,
+ I128 => tcx.types.i128,
+ }
+ }
+
+ #[inline]
+ pub fn new_uint(tcx: TyCtxt<'tcx>, ui: ty::UintTy) -> Ty<'tcx> {
+ use ty::UintTy::*;
+ match ui {
+ Usize => tcx.types.usize,
+ U8 => tcx.types.u8,
+ U16 => tcx.types.u16,
+ U32 => tcx.types.u32,
+ U64 => tcx.types.u64,
+ U128 => tcx.types.u128,
+ }
+ }
+
+ #[inline]
+ pub fn new_float(tcx: TyCtxt<'tcx>, f: ty::FloatTy) -> Ty<'tcx> {
+ use ty::FloatTy::*;
+ match f {
+ F32 => tcx.types.f32,
+ F64 => tcx.types.f64,
+ }
+ }
+
+ #[inline]
+ pub fn new_ref(tcx: TyCtxt<'tcx>, r: Region<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
+ Ty::new(tcx, Ref(r, tm.ty, tm.mutbl))
+ }
+
+ #[inline]
+ pub fn new_mut_ref(tcx: TyCtxt<'tcx>, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
+ Ty::new_ref(tcx, r, TypeAndMut { ty, mutbl: hir::Mutability::Mut })
+ }
+
+ #[inline]
+ pub fn new_imm_ref(tcx: TyCtxt<'tcx>, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
+ Ty::new_ref(tcx, r, TypeAndMut { ty, mutbl: hir::Mutability::Not })
+ }
+
+ #[inline]
+ pub fn new_ptr(tcx: TyCtxt<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
+ Ty::new(tcx, RawPtr(tm))
+ }
+
+ #[inline]
+ pub fn new_mut_ptr(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
+ Ty::new_ptr(tcx, TypeAndMut { ty, mutbl: hir::Mutability::Mut })
+ }
+
+ #[inline]
+ pub fn new_imm_ptr(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
+ Ty::new_ptr(tcx, TypeAndMut { ty, mutbl: hir::Mutability::Not })
+ }
+
+ #[inline]
+ pub fn new_adt(tcx: TyCtxt<'tcx>, def: AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
+ Ty::new(tcx, Adt(def, substs))
+ }
+
+ #[inline]
+ pub fn new_foreign(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'tcx> {
+ Ty::new(tcx, Foreign(def_id))
+ }
+
+ #[inline]
+ pub fn new_array(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
+ Ty::new(tcx, Array(ty, ty::Const::from_target_usize(tcx, n)))
+ }
+
+ #[inline]
+ pub fn new_array_with_const_len(
+ tcx: TyCtxt<'tcx>,
+ ty: Ty<'tcx>,
+ ct: ty::Const<'tcx>,
+ ) -> Ty<'tcx> {
+ Ty::new(tcx, Array(ty, ct))
+ }
+
+ #[inline]
+ pub fn new_slice(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
+ Ty::new(tcx, Slice(ty))
+ }
+
+ #[inline]
+ pub fn new_tup(tcx: TyCtxt<'tcx>, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
+ if ts.is_empty() { tcx.types.unit } else { Ty::new(tcx, Tuple(tcx.mk_type_list(&ts))) }
+ }
+
+ pub fn new_tup_from_iter<I, T>(tcx: TyCtxt<'tcx>, iter: I) -> T::Output
+ where
+ I: Iterator<Item = T>,
+ T: CollectAndApply<Ty<'tcx>, Ty<'tcx>>,
+ {
+ T::collect_and_apply(iter, |ts| Ty::new_tup(tcx, ts))
+ }
+
+ #[inline]
+ pub fn new_fn_def(
+ tcx: TyCtxt<'tcx>,
+ def_id: DefId,
+ substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
+ ) -> Ty<'tcx> {
+ let substs = tcx.check_and_mk_substs(def_id, substs);
+ Ty::new(tcx, FnDef(def_id, substs))
+ }
+
+ #[inline]
+ pub fn new_fn_ptr(tcx: TyCtxt<'tcx>, fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
+ Ty::new(tcx, FnPtr(fty))
+ }
+
+ #[inline]
+ pub fn new_dynamic(
+ tcx: TyCtxt<'tcx>,
+ obj: &'tcx List<PolyExistentialPredicate<'tcx>>,
+ reg: ty::Region<'tcx>,
+ repr: DynKind,
+ ) -> Ty<'tcx> {
+ Ty::new(tcx, Dynamic(obj, reg, repr))
+ }
+
+ #[inline]
+ pub fn new_projection(
+ tcx: TyCtxt<'tcx>,
+ item_def_id: DefId,
+ substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
+ ) -> Ty<'tcx> {
+ Ty::new_alias(tcx, ty::Projection, tcx.mk_alias_ty(item_def_id, substs))
+ }
+
+ #[inline]
+ pub fn new_closure(
+ tcx: TyCtxt<'tcx>,
+ def_id: DefId,
+ closure_substs: SubstsRef<'tcx>,
+ ) -> Ty<'tcx> {
+ debug_assert_eq!(
+ closure_substs.len(),
+ tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 3,
+ "closure constructed with incorrect substitutions"
+ );
+ Ty::new(tcx, Closure(def_id, closure_substs))
+ }
+
+ #[inline]
+ pub fn new_generator(
+ tcx: TyCtxt<'tcx>,
+ def_id: DefId,
+ generator_substs: SubstsRef<'tcx>,
+ movability: hir::Movability,
+ ) -> Ty<'tcx> {
+ debug_assert_eq!(
+ generator_substs.len(),
+ tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 5,
+ "generator constructed with incorrect number of substitutions"
+ );
+ Ty::new(tcx, Generator(def_id, generator_substs, movability))
+ }
+
+ #[inline]
+ pub fn new_generator_witness(
+ tcx: TyCtxt<'tcx>,
+ types: ty::Binder<'tcx, &'tcx List<Ty<'tcx>>>,
+ ) -> Ty<'tcx> {
+ Ty::new(tcx, GeneratorWitness(types))
+ }
+
+ #[inline]
+ pub fn new_generator_witness_mir(
+ tcx: TyCtxt<'tcx>,
+ id: DefId,
+ substs: SubstsRef<'tcx>,
+ ) -> Ty<'tcx> {
+ Ty::new(tcx, GeneratorWitnessMIR(id, substs))
+ }
+
+ // misc
+
+ #[inline]
+ pub fn new_unit(tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
+ tcx.types.unit
+ }
+
+ #[inline]
+ pub fn new_static_str(tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
+ Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, tcx.types.str_)
+ }
+
+ #[inline]
+ pub fn new_diverging_default(tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
+ if tcx.features().never_type_fallback { tcx.types.never } else { tcx.types.unit }
+ }
+
+ // lang and diagnostic tys
+
+ fn new_generic_adt(tcx: TyCtxt<'tcx>, wrapper_def_id: DefId, ty_param: Ty<'tcx>) -> Ty<'tcx> {
+ let adt_def = tcx.adt_def(wrapper_def_id);
+ let substs =
+ InternalSubsts::for_item(tcx, wrapper_def_id, |param, substs| match param.kind {
+ GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => bug!(),
+ GenericParamDefKind::Type { has_default, .. } => {
+ if param.index == 0 {
+ ty_param.into()
+ } else {
+ assert!(has_default);
+ tcx.type_of(param.def_id).subst(tcx, substs).into()
+ }
+ }
+ });
+ Ty::new(tcx, Adt(adt_def, substs))
+ }
+
+ #[inline]
+ pub fn new_lang_item(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, item: LangItem) -> Option<Ty<'tcx>> {
+ let def_id = tcx.lang_items().get(item)?;
+ Some(Ty::new_generic_adt(tcx, def_id, ty))
+ }
+
+ #[inline]
+ pub fn new_diagnostic_item(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, name: Symbol) -> Option<Ty<'tcx>> {
+ let def_id = tcx.get_diagnostic_item(name)?;
+ Some(Ty::new_generic_adt(tcx, def_id, ty))
+ }
+
+ #[inline]
+ pub fn new_box(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
+ let def_id = tcx.require_lang_item(LangItem::OwnedBox, None);
+ Ty::new_generic_adt(tcx, def_id, ty)
+ }
+
+ #[inline]
+ pub fn new_maybe_uninit(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
+ let def_id = tcx.require_lang_item(LangItem::MaybeUninit, None);
+ Ty::new_generic_adt(tcx, def_id, ty)
+ }
+
+ /// Creates a `&mut Context<'_>` [`Ty`] with erased lifetimes.
+ pub fn new_task_context(tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
+ let context_did = tcx.require_lang_item(LangItem::Context, None);
+ let context_adt_ref = tcx.adt_def(context_did);
+ let context_substs = tcx.mk_substs(&[tcx.lifetimes.re_erased.into()]);
+ let context_ty = Ty::new_adt(tcx, context_adt_ref, context_substs);
+ Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, context_ty)
+ }
+}
+
/// Type utilities
impl<'tcx> Ty<'tcx> {
#[inline(always)]
@@ -2213,7 +2704,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.mk_substs(&[self.into()]))
+ Ty::new_projection(tcx, assoc_items[0], tcx.mk_substs(&[self.into()]))
}
ty::Bool
@@ -2366,7 +2857,7 @@ impl<'tcx> Ty<'tcx> {
ty::Tuple(tys) => tys.iter().all(|ty| ty.is_trivially_sized(tcx)),
- ty::Adt(def, _substs) => def.sized_constraint(tcx).0.is_empty(),
+ ty::Adt(def, _substs) => def.sized_constraint(tcx).skip_binder().is_empty(),
ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => false,