rust/compiler/stable_mir/src/ty.rs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

640 lines
14 KiB
Rust
Raw Normal View History

2023-09-04 15:18:42 +00:00
use super::{
mir::Safety,
mir::{Body, Mutability},
with, AllocId, DefId, Symbol,
2023-09-04 15:18:42 +00:00
};
2023-10-11 09:44:59 +00:00
use crate::{Filename, Opaque};
2023-09-06 11:03:12 +00:00
use std::fmt::{self, Debug, Formatter};
2023-04-24 01:04:44 +00:00
2023-10-24 17:38:05 +00:00
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
2023-04-24 01:04:44 +00:00
pub struct Ty(pub usize);
2023-09-06 11:03:12 +00:00
impl Debug for Ty {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("Ty").field("id", &self.0).field("kind", &self.kind()).finish()
}
}
2023-04-24 01:04:44 +00:00
impl Ty {
pub fn kind(&self) -> TyKind {
with(|context| context.ty_kind(*self))
}
}
/// Represents a constant in MIR or from the Type system.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Const {
/// The constant kind.
pub(crate) kind: ConstantKind,
/// The constant type.
pub(crate) ty: Ty,
/// Used for internal tracking of the internal constant.
pub id: ConstId,
}
impl Const {
/// Build a constant. Note that this should only be used by the compiler.
pub fn new(kind: ConstantKind, ty: Ty, id: ConstId) -> Const {
Const { kind, ty, id }
}
/// Retrieve the constant kind.
pub fn kind(&self) -> &ConstantKind {
&self.kind
}
/// Get the constant type.
pub fn ty(&self) -> Ty {
self.ty
2023-09-04 14:31:14 +00:00
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ConstId(pub usize);
2023-08-04 20:23:26 +00:00
type Ident = Opaque;
2023-09-21 09:18:10 +00:00
#[derive(Clone, Debug, Eq, PartialEq)]
2023-09-21 09:18:10 +00:00
pub struct Region {
2023-09-21 09:12:06 +00:00
pub kind: RegionKind,
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-09-21 09:01:30 +00:00
pub enum RegionKind {
ReEarlyParam(EarlyParamRegion),
ReBound(DebruijnIndex, BoundRegion),
ReStatic,
RePlaceholder(Placeholder<BoundRegion>),
ReErased,
}
pub(crate) type DebruijnIndex = u32;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct EarlyParamRegion {
2023-09-21 09:01:30 +00:00
pub def_id: RegionDef,
pub index: u32,
pub name: Symbol,
}
pub(crate) type BoundVar = u32;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct BoundRegion {
pub var: BoundVar,
pub kind: BoundRegionKind,
}
pub(crate) type UniverseIndex = u32;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Placeholder<T> {
pub universe: UniverseIndex,
pub bound: T,
}
2023-09-12 08:50:50 +00:00
#[derive(Clone, Copy, PartialEq, Eq)]
2023-10-10 08:28:45 +00:00
pub struct Span(usize);
2023-09-12 08:50:50 +00:00
impl Debug for Span {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2023-09-14 15:43:30 +00:00
f.debug_struct("Span")
.field("id", &self.0)
.field("repr", &with(|cx| cx.span_to_string(*self)))
2023-09-14 15:43:30 +00:00
.finish()
2023-09-12 08:50:50 +00:00
}
}
2023-07-12 19:24:33 +00:00
2023-10-11 09:44:59 +00:00
impl Span {
/// Return filename for diagnostic purposes
pub fn get_filename(&self) -> Filename {
with(|c| c.get_filename(self))
}
/// Return lines that corespond to this `Span`
pub fn get_lines(&self) -> LineInfo {
2023-10-11 09:44:59 +00:00
with(|c| c.get_lines(&self))
}
}
#[derive(Clone, Copy, Debug)]
/// Information you get from `Span` in a struct form.
/// Line and col start from 1.
pub struct LineInfo {
pub start_line: usize,
2023-10-11 09:44:59 +00:00
pub start_col: usize,
pub end_line: usize,
2023-10-11 09:44:59 +00:00
pub end_col: usize,
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-04-24 01:04:44 +00:00
pub enum TyKind {
RigidTy(RigidTy),
2023-07-18 00:46:33 +00:00
Alias(AliasKind, AliasTy),
2023-07-21 17:18:32 +00:00
Param(ParamTy),
2023-07-21 17:52:45 +00:00
Bound(usize, BoundTy),
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum RigidTy {
2023-04-24 01:04:44 +00:00
Bool,
2023-07-05 22:01:11 +00:00
Char,
2023-07-05 22:06:49 +00:00
Int(IntTy),
2023-07-05 22:26:52 +00:00
Uint(UintTy),
2023-07-05 22:30:24 +00:00
Float(FloatTy),
2023-07-18 15:11:49 +00:00
Adt(AdtDef, GenericArgs),
2023-07-18 14:18:40 +00:00
Foreign(ForeignDef),
Str,
Array(Ty, Const),
Slice(Ty),
2023-07-13 04:23:22 +00:00
RawPtr(Ty, Mutability),
2023-07-13 05:07:50 +00:00
Ref(Region, Ty, Mutability),
2023-07-18 15:16:38 +00:00
FnDef(FnDef, GenericArgs),
2023-07-21 02:16:55 +00:00
FnPtr(PolyFnSig),
2023-07-18 15:19:41 +00:00
Closure(ClosureDef, GenericArgs),
2023-10-19 16:06:43 +00:00
Coroutine(CoroutineDef, GenericArgs, Movability),
2023-07-24 03:53:08 +00:00
Dynamic(Vec<Binder<ExistentialPredicate>>, Region, DynKind),
2023-07-18 15:02:35 +00:00
Never,
2023-04-24 01:04:44 +00:00
Tuple(Vec<Ty>),
2023-11-10 14:02:08 +00:00
CoroutineWitness(CoroutineWitnessDef, GenericArgs),
2023-04-24 01:04:44 +00:00
}
2023-07-05 22:06:49 +00:00
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum IntTy {
Isize,
I8,
I16,
I32,
I64,
I128,
}
2023-07-05 22:26:52 +00:00
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum UintTy {
Usize,
U8,
U16,
U32,
U64,
U128,
}
2023-07-05 22:30:24 +00:00
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum FloatTy {
F32,
F64,
}
2023-07-12 19:24:33 +00:00
2023-07-18 16:38:16 +00:00
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Movability {
Static,
Movable,
}
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct ForeignDef(pub DefId);
2023-07-18 14:18:40 +00:00
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct FnDef(pub DefId);
2023-07-18 15:16:38 +00:00
2023-09-04 15:18:42 +00:00
impl FnDef {
pub fn body(&self) -> Body {
with(|ctx| ctx.mir_body(self.0))
}
}
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct ClosureDef(pub DefId);
2023-07-18 15:19:41 +00:00
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
2023-10-19 16:06:43 +00:00
pub struct CoroutineDef(pub DefId);
2023-07-18 16:38:16 +00:00
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct ParamDef(pub DefId);
2023-07-21 02:16:55 +00:00
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct BrNamedDef(pub DefId);
2023-07-21 02:16:55 +00:00
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct AdtDef(pub DefId);
2023-07-12 19:24:33 +00:00
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct AliasDef(pub DefId);
2023-07-18 00:46:33 +00:00
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct TraitDef(pub DefId);
2023-07-24 03:53:08 +00:00
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct GenericDef(pub DefId);
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct ConstDef(pub DefId);
2023-08-07 15:29:12 +00:00
2023-08-07 22:03:05 +00:00
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct ImplDef(pub DefId);
2023-08-07 22:03:05 +00:00
2023-09-21 09:01:30 +00:00
#[derive(Clone, PartialEq, Eq, Debug)]
2023-09-28 08:36:53 +00:00
pub struct RegionDef(pub DefId);
2023-09-21 09:01:30 +00:00
2023-11-10 14:02:08 +00:00
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct CoroutineWitnessDef(pub DefId);
/// A list of generic arguments.
#[derive(Clone, Debug, Eq, PartialEq)]
2023-07-18 15:11:49 +00:00
pub struct GenericArgs(pub Vec<GenericArgKind>);
2023-07-12 19:24:33 +00:00
2023-09-04 15:18:53 +00:00
impl std::ops::Index<ParamTy> for GenericArgs {
type Output = Ty;
fn index(&self, index: ParamTy) -> &Self::Output {
self.0[index.index as usize].expect_ty()
}
}
impl std::ops::Index<ParamConst> for GenericArgs {
type Output = Const;
fn index(&self, index: ParamConst) -> &Self::Output {
self.0[index.index as usize].expect_const()
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-07-12 19:24:33 +00:00
pub enum GenericArgKind {
Lifetime(Region),
Type(Ty),
Const(Const),
}
2023-07-21 02:16:55 +00:00
2023-09-04 15:18:53 +00:00
impl GenericArgKind {
/// Panic if this generic argument is not a type, otherwise
/// return the type.
#[track_caller]
pub fn expect_ty(&self) -> &Ty {
match self {
GenericArgKind::Type(ty) => ty,
_ => panic!("{self:?}"),
}
}
/// Panic if this generic argument is not a const, otherwise
/// return the const.
#[track_caller]
pub fn expect_const(&self) -> &Const {
match self {
GenericArgKind::Const(c) => c,
_ => panic!("{self:?}"),
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-07-24 03:53:08 +00:00
pub enum TermKind {
Type(Ty),
Const(Const),
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-07-18 00:46:33 +00:00
pub enum AliasKind {
Projection,
Inherent,
Opaque,
Weak,
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-07-18 00:46:33 +00:00
pub struct AliasTy {
pub def_id: AliasDef,
pub args: GenericArgs,
}
2023-07-21 02:16:55 +00:00
pub type PolyFnSig = Binder<FnSig>;
#[derive(Clone, Debug, Eq, PartialEq)]
2023-07-21 02:16:55 +00:00
pub struct FnSig {
pub inputs_and_output: Vec<Ty>,
pub c_variadic: bool,
pub unsafety: Safety,
2023-07-21 02:16:55 +00:00
pub abi: Abi,
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum Abi {
Rust,
C { unwind: bool },
Cdecl { unwind: bool },
Stdcall { unwind: bool },
Fastcall { unwind: bool },
Vectorcall { unwind: bool },
Thiscall { unwind: bool },
Aapcs { unwind: bool },
Win64 { unwind: bool },
SysV64 { unwind: bool },
PtxKernel,
Msp430Interrupt,
X86Interrupt,
AmdGpuKernel,
EfiApi,
AvrInterrupt,
AvrNonBlockingInterrupt,
CCmseNonSecureCall,
Wasm,
System { unwind: bool },
RustIntrinsic,
RustCall,
PlatformIntrinsic,
Unadjusted,
RustCold,
RiscvInterruptM,
RiscvInterruptS,
2023-07-21 02:16:55 +00:00
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-07-21 02:16:55 +00:00
pub struct Binder<T> {
pub value: T,
pub bound_vars: Vec<BoundVariableKind>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-07 22:03:05 +00:00
pub struct EarlyBinder<T> {
pub value: T,
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-07-21 02:16:55 +00:00
pub enum BoundVariableKind {
Ty(BoundTyKind),
Region(BoundRegionKind),
Const,
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum BoundTyKind {
Anon,
Param(ParamDef, String),
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-07-21 02:16:55 +00:00
pub enum BoundRegionKind {
2023-08-03 15:56:56 +00:00
BrAnon,
2023-07-21 02:16:55 +00:00
BrNamed(BrNamedDef, String),
BrEnv,
}
2023-07-24 03:53:08 +00:00
#[derive(Clone, Debug, Eq, PartialEq)]
2023-07-24 03:53:08 +00:00
pub enum DynKind {
Dyn,
DynStar,
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-07-24 03:53:08 +00:00
pub enum ExistentialPredicate {
Trait(ExistentialTraitRef),
Projection(ExistentialProjection),
AutoTrait(TraitDef),
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-07-24 03:53:08 +00:00
pub struct ExistentialTraitRef {
pub def_id: TraitDef,
pub generic_args: GenericArgs,
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-07-24 03:53:08 +00:00
pub struct ExistentialProjection {
pub def_id: TraitDef,
pub generic_args: GenericArgs,
pub term: TermKind,
}
2023-07-21 17:18:32 +00:00
#[derive(Clone, Debug, Eq, PartialEq)]
2023-07-21 17:18:32 +00:00
pub struct ParamTy {
pub index: u32,
pub name: String,
}
2023-07-21 17:52:45 +00:00
#[derive(Clone, Debug, Eq, PartialEq)]
2023-07-21 17:52:45 +00:00
pub struct BoundTy {
pub var: usize,
pub kind: BoundTyKind,
}
2023-08-02 12:12:38 +00:00
pub type Bytes = Vec<Option<u8>>;
pub type Size = usize;
2023-09-02 05:53:06 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct Prov(pub AllocId);
2023-08-02 12:12:38 +00:00
pub type Align = u64;
2023-08-07 15:29:12 +00:00
pub type Promoted = u32;
2023-08-02 12:12:38 +00:00
pub type InitMaskMaterialized = Vec<u64>;
/// Stores the provenance information of pointers stored in memory.
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-02 12:12:38 +00:00
pub struct ProvenanceMap {
/// Provenance in this map applies from the given offset for an entire pointer-size worth of
/// bytes. Two entries in this map are always at least a pointer size apart.
pub ptrs: Vec<(Size, Prov)>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-02 12:12:38 +00:00
pub struct Allocation {
pub bytes: Bytes,
pub provenance: ProvenanceMap,
pub align: Align,
pub mutability: Mutability,
}
2023-08-04 20:23:26 +00:00
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-07 15:29:12 +00:00
pub enum ConstantKind {
Allocated(Allocation),
Unevaluated(UnevaluatedConst),
2023-09-04 15:17:27 +00:00
Param(ParamConst),
/// Store ZST constants.
/// We have to special handle these constants since its type might be generic.
ZeroSized,
2023-09-04 15:17:27 +00:00
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-09-04 15:17:27 +00:00
pub struct ParamConst {
pub index: u32,
pub name: String,
2023-08-07 15:29:12 +00:00
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-07 15:29:12 +00:00
pub struct UnevaluatedConst {
pub def: ConstDef,
pub args: GenericArgs,
pub promoted: Option<Promoted>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
2023-08-04 20:23:26 +00:00
pub enum TraitSpecializationKind {
None,
Marker,
AlwaysApplicable,
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-04 20:23:26 +00:00
pub struct TraitDecl {
pub def_id: TraitDef,
pub unsafety: Safety,
pub paren_sugar: bool,
pub has_auto_impl: bool,
pub is_marker: bool,
pub is_coinductive: bool,
pub skip_array_during_method_dispatch: bool,
pub specialization_kind: TraitSpecializationKind,
pub must_implement_one_of: Option<Vec<Ident>>,
pub implement_via_object: bool,
pub deny_explicit_impl: bool,
}
2023-08-07 22:03:05 +00:00
impl TraitDecl {
pub fn generics_of(&self) -> Generics {
with(|cx| cx.generics_of(self.def_id.0))
}
pub fn predicates_of(&self) -> GenericPredicates {
with(|cx| cx.predicates_of(self.def_id.0))
}
2023-09-12 15:57:49 +00:00
pub fn explicit_predicates_of(&self) -> GenericPredicates {
with(|cx| cx.explicit_predicates_of(self.def_id.0))
}
}
2023-08-07 22:03:05 +00:00
pub type ImplTrait = EarlyBinder<TraitRef>;
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-07 22:03:05 +00:00
pub struct TraitRef {
pub def_id: TraitDef,
pub args: GenericArgs,
}
2023-08-22 10:01:37 +00:00
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-22 10:01:37 +00:00
pub struct Generics {
pub parent: Option<GenericDef>,
pub parent_count: usize,
pub params: Vec<GenericParamDef>,
pub param_def_id_to_index: Vec<(GenericDef, u32)>,
pub has_self: bool,
pub has_late_bound_regions: Option<Span>,
pub host_effect_index: Option<usize>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-22 10:01:37 +00:00
pub enum GenericParamDefKind {
Lifetime,
Type { has_default: bool, synthetic: bool },
Const { has_default: bool },
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-22 10:01:37 +00:00
pub struct GenericParamDef {
pub name: super::Symbol,
pub def_id: GenericDef,
pub index: u32,
pub pure_wrt_drop: bool,
pub kind: GenericParamDefKind,
}
2023-08-22 04:15:38 +00:00
pub struct GenericPredicates {
2023-08-28 20:39:17 +00:00
pub parent: Option<TraitDef>,
pub predicates: Vec<(PredicateKind, Span)>,
2023-08-22 04:15:38 +00:00
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-22 04:15:38 +00:00
pub enum PredicateKind {
Clause(ClauseKind),
ObjectSafe(TraitDef),
ClosureKind(ClosureDef, GenericArgs, ClosureKind),
SubType(SubtypePredicate),
Coerce(CoercePredicate),
ConstEquate(Const, Const),
Ambiguous,
AliasRelate(TermKind, TermKind, AliasRelationDirection),
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-22 04:15:38 +00:00
pub enum ClauseKind {
Trait(TraitPredicate),
RegionOutlives(RegionOutlivesPredicate),
TypeOutlives(TypeOutlivesPredicate),
Projection(ProjectionPredicate),
ConstArgHasType(Const, Ty),
WellFormed(GenericArgKind),
ConstEvaluatable(Const),
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-22 04:15:38 +00:00
pub enum ClosureKind {
Fn,
FnMut,
FnOnce,
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-22 04:15:38 +00:00
pub struct SubtypePredicate {
pub a: Ty,
pub b: Ty,
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-22 04:15:38 +00:00
pub struct CoercePredicate {
pub a: Ty,
pub b: Ty,
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-22 04:15:38 +00:00
pub enum AliasRelationDirection {
Equate,
Subtype,
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-22 04:15:38 +00:00
pub struct TraitPredicate {
pub trait_ref: TraitRef,
pub polarity: ImplPolarity,
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-22 04:15:38 +00:00
pub struct OutlivesPredicate<A, B>(pub A, pub B);
pub type RegionOutlivesPredicate = OutlivesPredicate<Region, Region>;
pub type TypeOutlivesPredicate = OutlivesPredicate<Ty, Region>;
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-22 04:15:38 +00:00
pub struct ProjectionPredicate {
pub projection_ty: AliasTy,
pub term: TermKind,
}
#[derive(Clone, Debug, Eq, PartialEq)]
2023-08-22 04:15:38 +00:00
pub enum ImplPolarity {
Positive,
Negative,
Reservation,
}
2023-10-10 08:28:45 +00:00
pub trait IndexedVal {
fn to_val(index: usize) -> Self;
fn to_index(&self) -> usize;
}
2023-10-24 17:38:05 +00:00
macro_rules! index_impl {
($name:ident) => {
impl IndexedVal for $name {
fn to_val(index: usize) -> Self {
$name(index)
}
fn to_index(&self) -> usize {
self.0
}
}
};
}
index_impl!(ConstId);
index_impl!(Ty);
index_impl!(Span);