diff options
Diffstat (limited to 'compiler/rustc_middle/src/ty/sty.rs')
-rw-r--r-- | compiler/rustc_middle/src/ty/sty.rs | 197 |
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 |