rust/compiler/rustc_smir/src/stable_mir/ty.rs

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

500 lines
12 KiB
Rust
Raw Normal View History

2023-08-09 18:05:03 +00:00
use rustc_middle::mir::interpret::{alloc_range, AllocRange, ConstValue, Pointer};
2023-08-07 15:29:12 +00:00
use super::{mir::Mutability, mir::Safety, with, DefId};
2023-08-07 15:29:12 +00:00
use crate::{
2023-08-09 18:05:03 +00:00
rustc_internal::{opaque, Opaque},
2023-08-07 15:29:12 +00:00
rustc_smir::{Stable, Tables},
};
2023-04-24 01:04:44 +00:00
#[derive(Copy, Clone, Debug)]
pub struct Ty(pub usize);
impl Ty {
pub fn kind(&self) -> TyKind {
with(|context| context.ty_kind(*self))
}
}
2023-08-11 20:43:58 +00:00
#[derive(Debug, Clone)]
pub struct Const {
pub literal: ConstantKind,
}
2023-08-04 20:23:26 +00:00
type Ident = Opaque;
2023-07-13 05:07:50 +00:00
pub(crate) type Region = Opaque;
2023-08-22 10:01:37 +00:00
pub type Span = Opaque;
2023-07-12 19:24:33 +00:00
2023-07-05 21:50:13 +00:00
#[derive(Clone, Debug)]
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),
}
2023-07-05 21:50:13 +00:00
#[derive(Clone, Debug)]
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-07-18 16:38:16 +00:00
Generator(GeneratorDef, 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-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)]
2023-07-18 14:18:40 +00:00
pub struct ForeignDef(pub(crate) DefId);
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
2023-07-18 15:16:38 +00:00
pub struct FnDef(pub(crate) DefId);
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
2023-07-18 15:19:41 +00:00
pub struct ClosureDef(pub(crate) DefId);
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
2023-07-18 16:38:16 +00:00
pub struct GeneratorDef(pub(crate) DefId);
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
2023-07-21 02:16:55 +00:00
pub struct ParamDef(pub(crate) DefId);
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
2023-07-21 02:16:55 +00:00
pub struct BrNamedDef(pub(crate) DefId);
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
2023-07-12 19:24:33 +00:00
pub struct AdtDef(pub(crate) DefId);
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
2023-07-18 00:46:33 +00:00
pub struct AliasDef(pub(crate) DefId);
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
2023-07-24 03:53:08 +00:00
pub struct TraitDef(pub(crate) DefId);
2023-08-22 10:01:37 +00:00
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct GenericDef(pub(crate) DefId);
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
2023-08-07 15:29:12 +00:00
pub struct ConstDef(pub(crate) DefId);
2023-08-06 01:08:30 +00:00
impl TraitDef {
pub fn trait_decl(&self) -> TraitDecl {
with(|cx| cx.trait_decl(self))
}
}
2023-08-07 22:03:05 +00:00
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct ImplDef(pub(crate) DefId);
impl ImplDef {
pub fn trait_impl(&self) -> ImplTrait {
with(|cx| cx.trait_impl(self))
}
}
2023-08-22 10:01:37 +00:00
impl GenericDef {
pub fn generics_of(&self) -> Generics {
with(|tcx| tcx.generics_of(self))
}
}
2023-07-12 19:24:33 +00:00
#[derive(Clone, Debug)]
2023-07-18 15:11:49 +00:00
pub struct GenericArgs(pub Vec<GenericArgKind>);
2023-07-12 19:24:33 +00:00
#[derive(Clone, Debug)]
pub enum GenericArgKind {
Lifetime(Region),
Type(Ty),
Const(Const),
}
2023-07-21 02:16:55 +00:00
2023-07-24 03:53:08 +00:00
#[derive(Clone, Debug)]
pub enum TermKind {
Type(Ty),
Const(Const),
}
2023-07-18 00:46:33 +00:00
#[derive(Clone, Debug)]
pub enum AliasKind {
Projection,
Inherent,
Opaque,
Weak,
}
#[derive(Clone, Debug)]
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)]
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)]
pub struct Binder<T> {
pub value: T,
pub bound_vars: Vec<BoundVariableKind>,
}
2023-08-07 22:03:05 +00:00
#[derive(Clone, Debug)]
pub struct EarlyBinder<T> {
pub value: T,
}
2023-07-21 02:16:55 +00:00
#[derive(Clone, Debug)]
pub enum BoundVariableKind {
Ty(BoundTyKind),
Region(BoundRegionKind),
Const,
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum BoundTyKind {
Anon,
Param(ParamDef, String),
}
#[derive(Clone, Debug)]
pub enum BoundRegionKind {
BrAnon(Option<Span>),
BrNamed(BrNamedDef, String),
BrEnv,
}
2023-07-24 03:53:08 +00:00
#[derive(Clone, Debug)]
pub enum DynKind {
Dyn,
DynStar,
}
#[derive(Clone, Debug)]
pub enum ExistentialPredicate {
Trait(ExistentialTraitRef),
Projection(ExistentialProjection),
AutoTrait(TraitDef),
}
#[derive(Clone, Debug)]
pub struct ExistentialTraitRef {
pub def_id: TraitDef,
pub generic_args: GenericArgs,
}
#[derive(Clone, Debug)]
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)]
pub struct ParamTy {
pub index: u32,
pub name: String,
}
2023-07-21 17:52:45 +00:00
#[derive(Clone, Debug)]
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;
pub type Prov = Opaque;
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)]
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)]
pub struct Allocation {
pub bytes: Bytes,
pub provenance: ProvenanceMap,
pub align: Align,
pub mutability: Mutability,
}
2023-08-04 20:23:26 +00:00
2023-08-07 15:29:12 +00:00
impl Allocation {
/// Creates new empty `Allocation` from given `Align`.
fn new_empty_allocation(align: rustc_target::abi::Align) -> Allocation {
Allocation {
bytes: Vec::new(),
provenance: ProvenanceMap { ptrs: Vec::new() },
align: align.bytes(),
mutability: Mutability::Not,
}
}
}
// We need this method instead of a Stable implementation
// because we need to get `Ty` of the const we are trying to create, to do that
// we need to have access to `ConstantKind` but we can't access that inside Stable impl.
pub fn new_allocation<'tcx>(
const_kind: &rustc_middle::mir::ConstantKind<'tcx>,
const_value: ConstValue<'tcx>,
tables: &mut Tables<'tcx>,
) -> Allocation {
match const_value {
ConstValue::Scalar(scalar) => {
let size = scalar.size();
let align = tables
.tcx
.layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty()))
.unwrap()
.align;
let mut allocation = rustc_middle::mir::interpret::Allocation::uninit(size, align.abi);
allocation
.write_scalar(&tables.tcx, alloc_range(rustc_target::abi::Size::ZERO, size), scalar)
.unwrap();
allocation.stable(tables)
}
ConstValue::ZeroSized => {
let align = tables
.tcx
.layout_of(rustc_middle::ty::ParamEnv::empty().and(const_kind.ty()))
.unwrap()
.align;
Allocation::new_empty_allocation(align.abi)
}
ConstValue::Slice { data, start, end } => {
let alloc_id = tables.tcx.create_memory_alloc(data);
let ptr = Pointer::new(alloc_id, rustc_target::abi::Size::from_bytes(start));
let scalar_ptr = rustc_middle::mir::interpret::Scalar::from_pointer(ptr, &tables.tcx);
let scalar_len = rustc_middle::mir::interpret::Scalar::from_target_usize(
(end - start) as u64,
&tables.tcx,
);
let layout = tables
.tcx
.layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty()))
.unwrap();
let mut allocation =
rustc_middle::mir::interpret::Allocation::uninit(layout.size, layout.align.abi);
allocation
.write_scalar(
&tables.tcx,
alloc_range(rustc_target::abi::Size::ZERO, tables.tcx.data_layout.pointer_size),
scalar_ptr,
)
.unwrap();
allocation
.write_scalar(
&tables.tcx,
alloc_range(tables.tcx.data_layout.pointer_size, scalar_len.size()),
scalar_len,
)
.unwrap();
allocation.stable(tables)
}
ConstValue::ByRef { alloc, offset } => {
let ty_size = tables
.tcx
.layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty()))
.unwrap()
.size;
2023-08-09 18:05:03 +00:00
allocation_filter(&alloc.0, alloc_range(offset, ty_size), tables)
2023-08-07 15:29:12 +00:00
}
}
}
2023-08-09 18:05:03 +00:00
/// Creates an `Allocation` only from information within the `AllocRange`.
pub fn allocation_filter<'tcx>(
alloc: &rustc_middle::mir::interpret::Allocation,
alloc_range: AllocRange,
tables: &mut Tables<'tcx>,
) -> Allocation {
let mut bytes: Vec<Option<u8>> = alloc
.inspect_with_uninit_and_ptr_outside_interpreter(
alloc_range.start.bytes_usize()..alloc_range.end().bytes_usize(),
)
.iter()
.copied()
.map(Some)
.collect();
for (i, b) in bytes.iter_mut().enumerate() {
if !alloc
.init_mask()
.get(rustc_target::abi::Size::from_bytes(i + alloc_range.start.bytes_usize()))
{
*b = None;
}
}
let mut ptrs = Vec::new();
for (offset, prov) in alloc
.provenance()
.ptrs()
.iter()
.filter(|a| a.0 >= alloc_range.start && a.0 <= alloc_range.end())
{
ptrs.push((offset.bytes_usize() - alloc_range.start.bytes_usize(), opaque(prov)));
}
Allocation {
bytes: bytes,
provenance: ProvenanceMap { ptrs },
align: alloc.align.bytes(),
mutability: alloc.mutability.stable(tables),
}
}
2023-08-07 15:29:12 +00:00
#[derive(Clone, Debug)]
pub enum ConstantKind {
Allocated(Allocation),
Unevaluated(UnevaluatedConst),
2023-08-10 16:32:45 +00:00
ParamCt(Opaque),
2023-08-07 15:29:12 +00:00
}
#[derive(Clone, Debug)]
pub struct UnevaluatedConst {
pub ty: Ty,
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)]
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
pub type ImplTrait = EarlyBinder<TraitRef>;
#[derive(Clone, Debug)]
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)]
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)]
pub enum GenericParamDefKind {
Lifetime,
Type { has_default: bool, synthetic: bool },
Const { has_default: bool },
}
#[derive(Clone, Debug)]
pub struct GenericParamDef {
pub name: super::Symbol,
pub def_id: GenericDef,
pub index: u32,
pub pure_wrt_drop: bool,
pub kind: GenericParamDefKind,
}