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.rs197
1 files changed, 103 insertions, 94 deletions
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 44592b10d..a0debc8a1 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -6,7 +6,7 @@ use crate::infer::canonical::Canonical;
use crate::ty::visit::ValidateBoundVars;
use crate::ty::InferTy::*;
use crate::ty::{
- self, AdtDef, Discr, Term, Ty, TyCtxt, TypeFlags, TypeSuperVisitable, TypeVisitable,
+ self, AdtDef, Discr, IntoKind, Term, Ty, TyCtxt, TypeFlags, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt, TypeVisitor,
};
use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
@@ -15,7 +15,9 @@ use hir::def::DefKind;
use polonius_engine::Atom;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::intern::Interned;
-use rustc_errors::{DiagnosticArgValue, ErrorGuaranteed, IntoDiagnosticArg, MultiSpan};
+use rustc_errors::{
+ DiagnosticArgValue, DiagnosticMessage, ErrorGuaranteed, IntoDiagnosticArg, MultiSpan,
+};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::LangItem;
@@ -32,6 +34,7 @@ use std::fmt;
use std::ops::{ControlFlow, Deref, Range};
use ty::util::IntTypeExt;
+use rustc_type_ir::BoundVar;
use rustc_type_ir::ClauseKind as IrClauseKind;
use rustc_type_ir::CollectAndApply;
use rustc_type_ir::ConstKind as IrConstKind;
@@ -41,29 +44,24 @@ use rustc_type_ir::PredicateKind as IrPredicateKind;
use rustc_type_ir::RegionKind as IrRegionKind;
use rustc_type_ir::TyKind as IrTyKind;
use rustc_type_ir::TyKind::*;
+use rustc_type_ir::TypeAndMut as IrTypeAndMut;
use super::GenericParamDefKind;
-// Re-export the `TyKind` from `rustc_type_ir` here for convenience
+// Re-export and re-parameterize some `I = TyCtxt<'tcx>` types here
#[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>>;
pub type PredicateKind<'tcx> = IrPredicateKind<TyCtxt<'tcx>>;
pub type ClauseKind<'tcx> = IrClauseKind<TyCtxt<'tcx>>;
-
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
-#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
-pub struct TypeAndMut<'tcx> {
- pub ty: Ty<'tcx>,
- pub mutbl: hir::Mutability,
-}
+pub type TypeAndMut<'tcx> = IrTypeAndMut<TyCtxt<'tcx>>;
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)]
#[derive(HashStable)]
-/// A "free" region `fr` can be interpreted as "some region
+/// The parameter representation of late-bound function parameters, "some region
/// at least as big as the scope `fr.scope`".
-pub struct FreeRegion {
+pub struct LateParamRegion {
pub scope: DefId,
pub bound_region: BoundRegionKind,
}
@@ -467,16 +465,6 @@ impl<'tcx> CoroutineArgs<'tcx> {
self.split().return_ty.expect_ty()
}
- /// Returns the "coroutine signature", which consists of its yield
- /// and return types.
- ///
- /// N.B., some bits of the code prefers to see this wrapped in a
- /// binder, but it never contains bound regions. Probably this
- /// function should be removed.
- pub fn poly_sig(self) -> PolyGenSig<'tcx> {
- ty::Binder::dummy(self.sig())
- }
-
/// Returns the "coroutine signature", which consists of its resume, yield
/// and return types.
pub fn sig(self) -> GenSig<'tcx> {
@@ -1036,7 +1024,7 @@ impl<'tcx, T> Binder<'tcx, T> {
/// risky thing to do because it's easy to get confused about
/// De Bruijn indices and the like. It is usually better to
/// discharge the binder using `no_bound_vars` or
- /// `replace_late_bound_regions` or something like
+ /// `instantiate_bound_regions` or something like
/// that. `skip_binder` is only valid when you are either
/// extracting data that has nothing to do with bound vars, you
/// are doing some sort of test that does not involve bound
@@ -1245,6 +1233,28 @@ impl<'tcx> AliasTy<'tcx> {
}
}
+ /// Whether this alias type is an opaque.
+ pub fn is_opaque(self, tcx: TyCtxt<'tcx>) -> bool {
+ matches!(self.opt_kind(tcx), Some(ty::AliasKind::Opaque))
+ }
+
+ /// FIXME: rename `AliasTy` to `AliasTerm` and always handle
+ /// constants. This function can then be removed.
+ pub fn opt_kind(self, tcx: TyCtxt<'tcx>) -> Option<ty::AliasKind> {
+ match tcx.def_kind(self.def_id) {
+ DefKind::AssocTy
+ if let DefKind::Impl { of_trait: false } =
+ tcx.def_kind(tcx.parent(self.def_id)) =>
+ {
+ Some(ty::Inherent)
+ }
+ DefKind::AssocTy => Some(ty::Projection),
+ DefKind::OpaqueTy => Some(ty::Opaque),
+ DefKind::TyAlias => Some(ty::Weak),
+ _ => None,
+ }
+ }
+
pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
Ty::new_alias(tcx, self.kind(tcx), self)
}
@@ -1329,8 +1339,6 @@ pub struct GenSig<'tcx> {
pub return_ty: Ty<'tcx>,
}
-pub type PolyGenSig<'tcx> = Binder<'tcx, GenSig<'tcx>>;
-
/// Signature of a function type, which we have arbitrarily
/// decided to use to refer to the input/output types.
///
@@ -1466,17 +1474,25 @@ impl ParamConst {
#[rustc_pass_by_value]
pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>);
+impl<'tcx> IntoKind for Region<'tcx> {
+ type Kind = RegionKind<'tcx>;
+
+ fn kind(self) -> RegionKind<'tcx> {
+ *self
+ }
+}
+
impl<'tcx> Region<'tcx> {
#[inline]
- pub fn new_early_bound(
+ pub fn new_early_param(
tcx: TyCtxt<'tcx>,
- early_bound_region: ty::EarlyBoundRegion,
+ early_bound_region: ty::EarlyParamRegion,
) -> Region<'tcx> {
- tcx.intern_region(ty::ReEarlyBound(early_bound_region))
+ tcx.intern_region(ty::ReEarlyParam(early_bound_region))
}
#[inline]
- pub fn new_late_bound(
+ pub fn new_bound(
tcx: TyCtxt<'tcx>,
debruijn: ty::DebruijnIndex,
bound_region: ty::BoundRegion,
@@ -1488,17 +1504,17 @@ impl<'tcx> Region<'tcx> {
{
re
} else {
- tcx.intern_region(ty::ReLateBound(debruijn, bound_region))
+ tcx.intern_region(ty::ReBound(debruijn, bound_region))
}
}
#[inline]
- pub fn new_free(
+ pub fn new_late_param(
tcx: TyCtxt<'tcx>,
scope: DefId,
bound_region: ty::BoundRegionKind,
) -> Region<'tcx> {
- tcx.intern_region(ty::ReFree(ty::FreeRegion { scope, bound_region }))
+ tcx.intern_region(ty::ReLateParam(ty::LateParamRegion { scope, bound_region }))
}
#[inline]
@@ -1522,7 +1538,7 @@ impl<'tcx> Region<'tcx> {
tcx.intern_region(ty::ReError(reported))
}
- /// Constructs a `RegionKind::ReError` region and registers a `delay_span_bug` to ensure it
+ /// Constructs a `RegionKind::ReError` region and registers a `span_delayed_bug` to ensure it
/// gets used.
#[track_caller]
pub fn new_error_misc(tcx: TyCtxt<'tcx>) -> Region<'tcx> {
@@ -1533,7 +1549,7 @@ impl<'tcx> Region<'tcx> {
)
}
- /// Constructs a `RegionKind::ReError` region and registers a `delay_span_bug` with the given
+ /// Constructs a `RegionKind::ReError` region and registers a `span_delayed_bug` with the given
/// `msg` to ensure it gets used.
#[track_caller]
pub fn new_error_with_message<S: Into<MultiSpan>>(
@@ -1541,7 +1557,7 @@ impl<'tcx> Region<'tcx> {
span: S,
msg: &'static str,
) -> Region<'tcx> {
- let reported = tcx.sess.delay_span_bug(span, msg);
+ let reported = tcx.sess.span_delayed_bug(span, msg);
Region::new_error(tcx, reported)
}
@@ -1549,10 +1565,10 @@ impl<'tcx> Region<'tcx> {
/// 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::ReEarlyParam(region) => Region::new_early_param(tcx, region),
+ ty::ReBound(debruijn, region) => Region::new_bound(tcx, debruijn, region),
+ ty::ReLateParam(ty::LateParamRegion { scope, bound_region }) => {
+ Region::new_late_param(tcx, scope, bound_region)
}
ty::ReStatic => tcx.lifetimes.re_static,
ty::ReVar(vid) => Region::new_var(tcx, vid),
@@ -1568,45 +1584,29 @@ impl<'tcx> Deref for Region<'tcx> {
#[inline]
fn deref(&self) -> &RegionKind<'tcx> {
- &self.0.0
+ self.0.0
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, PartialOrd, Ord)]
#[derive(HashStable)]
-pub struct EarlyBoundRegion {
+pub struct EarlyParamRegion {
pub def_id: DefId,
pub index: u32,
pub name: Symbol,
}
-impl fmt::Debug for EarlyBoundRegion {
+impl fmt::Debug for EarlyParamRegion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}, {}, {}", self.def_id, self.index, self.name)
}
}
rustc_index::newtype_index! {
- /// A **`const`** **v**ariable **ID**.
- #[debug_format = "?{}c"]
- pub struct ConstVid {}
-}
-
-rustc_index::newtype_index! {
- /// An **effect** **v**ariable **ID**.
- ///
- /// Handling effect infer variables happens separately from const infer variables
- /// because we do not want to reuse any of the const infer machinery. If we try to
- /// relate an effect variable with a normal one, we would ICE, which can catch bugs
- /// where we are not correctly using the effect var for an effect param. Fallback
- /// is also implemented on top of having separate effect and normal const variables.
- #[debug_format = "?{}e"]
- pub struct EffectVid {}
-}
-
-rustc_index::newtype_index! {
/// A **region** (lifetime) **v**ariable **ID**.
#[derive(HashStable)]
+ #[encodable]
+ #[orderable]
#[debug_format = "'?{}"]
pub struct RegionVid {}
}
@@ -1617,12 +1617,6 @@ impl Atom for RegionVid {
}
}
-rustc_index::newtype_index! {
- #[derive(HashStable)]
- #[debug_format = "{}"]
- pub struct BoundVar {}
-}
-
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable)]
pub struct BoundTy {
@@ -1722,9 +1716,9 @@ impl<'tcx> Region<'tcx> {
pub fn get_name(self) -> Option<Symbol> {
if self.has_name() {
match *self {
- ty::ReEarlyBound(ebr) => Some(ebr.name),
- ty::ReLateBound(_, br) => br.kind.get_name(),
- ty::ReFree(fr) => fr.bound_region.get_name(),
+ ty::ReEarlyParam(ebr) => Some(ebr.name),
+ ty::ReBound(_, br) => br.kind.get_name(),
+ ty::ReLateParam(fr) => fr.bound_region.get_name(),
ty::ReStatic => Some(kw::StaticLifetime),
ty::RePlaceholder(placeholder) => placeholder.bound.kind.get_name(),
_ => None,
@@ -1744,9 +1738,9 @@ impl<'tcx> Region<'tcx> {
/// Is this region named by the user?
pub fn has_name(self) -> bool {
match *self {
- ty::ReEarlyBound(ebr) => ebr.has_name(),
- ty::ReLateBound(_, br) => br.kind.is_named(),
- ty::ReFree(fr) => fr.bound_region.is_named(),
+ ty::ReEarlyParam(ebr) => ebr.has_name(),
+ ty::ReBound(_, br) => br.kind.is_named(),
+ ty::ReLateParam(fr) => fr.bound_region.is_named(),
ty::ReStatic => true,
ty::ReVar(..) => false,
ty::RePlaceholder(placeholder) => placeholder.bound.kind.is_named(),
@@ -1771,8 +1765,8 @@ impl<'tcx> Region<'tcx> {
}
#[inline]
- pub fn is_late_bound(self) -> bool {
- matches!(*self, ty::ReLateBound(..))
+ pub fn is_bound(self) -> bool {
+ matches!(*self, ty::ReBound(..))
}
#[inline]
@@ -1783,7 +1777,7 @@ impl<'tcx> Region<'tcx> {
#[inline]
pub fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool {
match *self {
- ty::ReLateBound(debruijn, _) => debruijn >= index,
+ ty::ReBound(debruijn, _) => debruijn >= index,
_ => false,
}
}
@@ -1802,20 +1796,20 @@ impl<'tcx> Region<'tcx> {
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
flags = flags | TypeFlags::HAS_RE_PLACEHOLDER;
}
- ty::ReEarlyBound(..) => {
+ ty::ReEarlyParam(..) => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
flags = flags | TypeFlags::HAS_RE_PARAM;
}
- ty::ReFree { .. } => {
+ ty::ReLateParam { .. } => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
}
ty::ReStatic => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
}
- ty::ReLateBound(..) => {
- flags = flags | TypeFlags::HAS_RE_LATE_BOUND;
+ ty::ReBound(..) => {
+ flags = flags | TypeFlags::HAS_RE_BOUND;
}
ty::ReErased => {
flags = flags | TypeFlags::HAS_RE_ERASED;
@@ -1851,22 +1845,28 @@ impl<'tcx> Region<'tcx> {
/// function might return the `DefId` of a closure.
pub fn free_region_binding_scope(self, tcx: TyCtxt<'_>) -> DefId {
match *self {
- ty::ReEarlyBound(br) => tcx.parent(br.def_id),
- ty::ReFree(fr) => fr.scope,
+ ty::ReEarlyParam(br) => tcx.parent(br.def_id),
+ ty::ReLateParam(fr) => fr.scope,
_ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self),
}
}
/// True for free regions other than `'static`.
- pub fn is_free(self) -> bool {
- matches!(*self, ty::ReEarlyBound(_) | ty::ReFree(_))
+ pub fn is_param(self) -> bool {
+ matches!(*self, ty::ReEarlyParam(_) | ty::ReLateParam(_))
}
- /// True if `self` is a free region or static.
- pub fn is_free_or_static(self) -> bool {
+ /// True for free region in the current context.
+ ///
+ /// This is the case for `'static` and param regions.
+ pub fn is_free(self) -> bool {
match *self {
- ty::ReStatic => true,
- _ => self.is_free(),
+ ty::ReStatic | ty::ReEarlyParam(..) | ty::ReLateParam(..) => true,
+ ty::ReVar(..)
+ | ty::RePlaceholder(..)
+ | ty::ReBound(..)
+ | ty::ReErased
+ | ty::ReError(..) => false,
}
}
@@ -1990,21 +1990,21 @@ impl<'tcx> Ty<'tcx> {
Ty::new(tcx, Error(reported))
}
- /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used.
+ /// Constructs a `TyKind::Error` type and registers a `span_delayed_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
+ /// Constructs a `TyKind::Error` type and registers a `span_delayed_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<String>,
+ msg: impl Into<DiagnosticMessage>,
) -> Ty<'tcx> {
- let reported = tcx.sess.delay_span_bug(span, msg);
+ let reported = tcx.sess.span_delayed_bug(span, msg);
Ty::new(tcx, Error(reported))
}
@@ -2104,7 +2104,7 @@ impl<'tcx> Ty<'tcx> {
#[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))) }
+ 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
@@ -2260,7 +2260,7 @@ impl<'tcx> Ty<'tcx> {
impl<'tcx> Ty<'tcx> {
#[inline(always)]
pub fn kind(self) -> &'tcx TyKind<'tcx> {
- &self.0.0
+ self.0.0
}
#[inline(always)]
@@ -2271,7 +2271,7 @@ impl<'tcx> Ty<'tcx> {
#[inline]
pub fn is_unit(self) -> bool {
match self.kind() {
- Tuple(ref tys) => tys.is_empty(),
+ Tuple(tys) => tys.is_empty(),
_ => false,
}
}
@@ -2813,6 +2813,15 @@ impl<'tcx> Ty<'tcx> {
}
}
+ /// Inverse of [`Ty::to_opt_closure_kind`].
+ pub fn from_closure_kind(tcx: TyCtxt<'tcx>, kind: ty::ClosureKind) -> Ty<'tcx> {
+ match kind {
+ ty::ClosureKind::Fn => tcx.types.i8,
+ ty::ClosureKind::FnMut => tcx.types.i16,
+ ty::ClosureKind::FnOnce => tcx.types.i32,
+ }
+ }
+
/// Fast path helper for testing if a type is `Sized`.
///
/// Returning true means the type is known to be sized. Returning