2023-09-04 15:18:42 +00:00
|
|
|
use super::{
|
2024-05-17 17:17:48 +00:00
|
|
|
mir::{Body, Mutability, Safety},
|
2023-11-07 22:12:58 +00:00
|
|
|
with, DefId, Error, Symbol,
|
2023-09-04 15:18:42 +00:00
|
|
|
};
|
2023-12-18 19:52:25 +00:00
|
|
|
use crate::abi::Layout;
|
2023-12-06 21:39:55 +00:00
|
|
|
use crate::mir::alloc::{read_target_int, read_target_uint, AllocId};
|
|
|
|
use crate::target::MachineInfo;
|
2024-02-12 19:44:35 +00:00
|
|
|
use crate::{crate_def::CrateDef, mir::mono::StaticDef};
|
2023-10-11 09:44:59 +00:00
|
|
|
use crate::{Filename, Opaque};
|
2023-11-16 20:01:10 +00:00
|
|
|
use std::fmt::{self, Debug, Display, Formatter};
|
2023-12-06 21:39:55 +00:00
|
|
|
use std::ops::Range;
|
2023-04-24 01:04:44 +00:00
|
|
|
|
2023-10-24 17:38:05 +00:00
|
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
2024-01-19 16:37:50 +00:00
|
|
|
pub struct Ty(usize);
|
2023-04-24 01:04:44 +00:00
|
|
|
|
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-11-16 14:24:53 +00:00
|
|
|
/// Constructors for `Ty`.
|
|
|
|
impl Ty {
|
|
|
|
/// Create a new type from a given kind.
|
2023-12-14 00:35:41 +00:00
|
|
|
pub fn from_rigid_kind(kind: RigidTy) -> Ty {
|
2023-11-16 14:24:53 +00:00
|
|
|
with(|cx| cx.new_rigid_ty(kind))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a new array type.
|
|
|
|
pub fn try_new_array(elem_ty: Ty, size: u64) -> Result<Ty, Error> {
|
|
|
|
Ok(Ty::from_rigid_kind(RigidTy::Array(elem_ty, Const::try_from_target_usize(size)?)))
|
|
|
|
}
|
2023-12-01 04:22:20 +00:00
|
|
|
|
2023-12-06 21:45:07 +00:00
|
|
|
/// Create a new array type from Const length.
|
|
|
|
pub fn new_array_with_const_len(elem_ty: Ty, len: Const) -> Ty {
|
|
|
|
Ty::from_rigid_kind(RigidTy::Array(elem_ty, len))
|
|
|
|
}
|
|
|
|
|
2023-12-01 04:22:20 +00:00
|
|
|
/// Create a new pointer type.
|
|
|
|
pub fn new_ptr(pointee_ty: Ty, mutability: Mutability) -> Ty {
|
|
|
|
Ty::from_rigid_kind(RigidTy::RawPtr(pointee_ty, mutability))
|
|
|
|
}
|
|
|
|
|
2023-12-06 21:45:07 +00:00
|
|
|
/// Create a new reference type.
|
|
|
|
pub fn new_ref(reg: Region, pointee_ty: Ty, mutability: Mutability) -> Ty {
|
|
|
|
Ty::from_rigid_kind(RigidTy::Ref(reg, pointee_ty, mutability))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a new pointer type.
|
|
|
|
pub fn new_tuple(tys: &[Ty]) -> Ty {
|
|
|
|
Ty::from_rigid_kind(RigidTy::Tuple(Vec::from(tys)))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a new closure type.
|
|
|
|
pub fn new_closure(def: ClosureDef, args: GenericArgs) -> Ty {
|
|
|
|
Ty::from_rigid_kind(RigidTy::Closure(def, args))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a new coroutine type.
|
2023-12-25 17:04:14 +00:00
|
|
|
pub fn new_coroutine(def: CoroutineDef, args: GenericArgs, mov: Movability) -> Ty {
|
|
|
|
Ty::from_rigid_kind(RigidTy::Coroutine(def, args, mov))
|
2023-12-06 21:45:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a new box type that represents `Box<T>`, for the given inner type `T`.
|
|
|
|
pub fn new_box(inner_ty: Ty) -> Ty {
|
|
|
|
with(|cx| cx.new_box_ty(inner_ty))
|
|
|
|
}
|
|
|
|
|
2023-12-01 04:22:20 +00:00
|
|
|
/// Create a type representing `usize`.
|
|
|
|
pub fn usize_ty() -> Ty {
|
|
|
|
Ty::from_rigid_kind(RigidTy::Uint(UintTy::Usize))
|
|
|
|
}
|
2023-12-06 21:45:07 +00:00
|
|
|
|
|
|
|
/// Create a type representing `bool`.
|
|
|
|
pub fn bool_ty() -> Ty {
|
|
|
|
Ty::from_rigid_kind(RigidTy::Bool)
|
|
|
|
}
|
2023-12-14 00:35:41 +00:00
|
|
|
|
2023-12-15 01:56:33 +00:00
|
|
|
/// Create a type representing a signed integer.
|
|
|
|
pub fn signed_ty(inner: IntTy) -> Ty {
|
|
|
|
Ty::from_rigid_kind(RigidTy::Int(inner))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a type representing an unsigned integer.
|
|
|
|
pub fn unsigned_ty(inner: UintTy) -> Ty {
|
|
|
|
Ty::from_rigid_kind(RigidTy::Uint(inner))
|
2023-12-14 00:35:41 +00:00
|
|
|
}
|
2023-12-18 19:52:25 +00:00
|
|
|
|
|
|
|
/// Get a type layout.
|
|
|
|
pub fn layout(self) -> Result<Layout, Error> {
|
|
|
|
with(|cx| cx.ty_layout(self))
|
|
|
|
}
|
2023-11-16 14:24:53 +00:00
|
|
|
}
|
|
|
|
|
2023-04-24 01:04:44 +00:00
|
|
|
impl Ty {
|
|
|
|
pub fn kind(&self) -> TyKind {
|
|
|
|
with(|context| context.ty_kind(*self))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-02 13:57:36 +00:00
|
|
|
/// Represents a pattern in the type system
|
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
|
|
pub enum Pattern {
|
|
|
|
Range { start: Option<Const>, end: Option<Const>, include_end: bool },
|
|
|
|
}
|
|
|
|
|
2023-10-24 03:32:31 +00:00
|
|
|
/// Represents a constant in MIR or from the Type system.
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-10-24 03:32:31 +00:00
|
|
|
pub struct Const {
|
|
|
|
/// The constant kind.
|
2023-10-30 20:07:02 +00:00
|
|
|
pub(crate) kind: ConstantKind,
|
2023-10-24 03:32:31 +00:00
|
|
|
/// The constant type.
|
2023-10-30 20:07:02 +00:00
|
|
|
pub(crate) ty: Ty,
|
2023-10-24 03:32:31 +00:00
|
|
|
/// 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
|
|
|
}
|
2023-11-16 14:24:53 +00:00
|
|
|
|
|
|
|
/// Creates an interned usize constant.
|
|
|
|
fn try_from_target_usize(val: u64) -> Result<Self, Error> {
|
2024-03-01 19:00:33 +00:00
|
|
|
with(|cx| cx.try_new_const_uint(val.into(), UintTy::Usize))
|
2023-11-16 14:24:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Try to evaluate to a target `usize`.
|
|
|
|
pub fn eval_target_usize(&self) -> Result<u64, Error> {
|
|
|
|
with(|cx| cx.eval_target_usize(self))
|
|
|
|
}
|
2024-03-01 19:00:33 +00:00
|
|
|
|
|
|
|
/// Create a constant that represents a new zero-sized constant of type T.
|
|
|
|
/// Fails if the type is not a ZST or if it doesn't have a known size.
|
|
|
|
pub fn try_new_zero_sized(ty: Ty) -> Result<Const, Error> {
|
|
|
|
with(|cx| cx.try_new_const_zst(ty))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Build a new constant that represents the given string.
|
|
|
|
///
|
|
|
|
/// Note that there is no guarantee today about duplication of the same constant.
|
|
|
|
/// I.e.: Calling this function multiple times with the same argument may or may not return
|
|
|
|
/// the same allocation.
|
|
|
|
pub fn from_str(value: &str) -> Const {
|
|
|
|
with(|cx| cx.new_const_str(value))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Build a new constant that represents the given boolean value.
|
|
|
|
pub fn from_bool(value: bool) -> Const {
|
|
|
|
with(|cx| cx.new_const_bool(value))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Build a new constant that represents the given unsigned integer.
|
|
|
|
pub fn try_from_uint(value: u128, uint_ty: UintTy) -> Result<Const, Error> {
|
|
|
|
with(|cx| cx.try_new_const_uint(value, uint_ty))
|
|
|
|
}
|
2023-09-04 14:31:14 +00:00
|
|
|
}
|
|
|
|
|
2023-10-24 03:32:31 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
2024-01-19 16:37:50 +00:00
|
|
|
pub struct ConstId(usize);
|
2023-10-24 03:32:31 +00:00
|
|
|
|
2023-08-04 20:23:26 +00:00
|
|
|
type Ident = Opaque;
|
2023-09-21 09:18:10 +00:00
|
|
|
|
2023-10-30 20:07:02 +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,
|
2023-09-21 08:52:06 +00:00
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-09-21 09:01:30 +00:00
|
|
|
pub enum RegionKind {
|
2023-11-14 13:13:27 +00:00
|
|
|
ReEarlyParam(EarlyParamRegion),
|
2023-11-13 14:00:05 +00:00
|
|
|
ReBound(DebruijnIndex, BoundRegion),
|
2023-09-21 08:52:06 +00:00
|
|
|
ReStatic,
|
|
|
|
RePlaceholder(Placeholder<BoundRegion>),
|
|
|
|
ReErased,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) type DebruijnIndex = u32;
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-11-14 13:13:27 +00:00
|
|
|
pub struct EarlyParamRegion {
|
2023-09-21 08:52:06 +00:00
|
|
|
pub index: u32,
|
|
|
|
pub name: Symbol,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) type BoundVar = u32;
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-09-21 08:52:06 +00:00
|
|
|
pub struct BoundRegion {
|
|
|
|
pub var: BoundVar,
|
|
|
|
pub kind: BoundRegionKind,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) type UniverseIndex = u32;
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-09-21 08:52:06 +00:00
|
|
|
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)
|
2023-10-13 08:44:38 +00:00
|
|
|
.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`
|
2023-10-13 08:44:38 +00:00
|
|
|
pub fn get_lines(&self) -> LineInfo {
|
2023-11-21 19:07:32 +00:00
|
|
|
with(|c| c.get_lines(self))
|
2023-10-11 09:44:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
|
|
/// Information you get from `Span` in a struct form.
|
|
|
|
/// Line and col start from 1.
|
|
|
|
pub struct LineInfo {
|
2023-10-13 08:44:38 +00:00
|
|
|
pub start_line: usize,
|
2023-10-11 09:44:59 +00:00
|
|
|
pub start_col: usize,
|
2023-10-13 08:44:38 +00:00
|
|
|
pub end_line: usize,
|
2023-10-11 09:44:59 +00:00
|
|
|
pub end_col: usize,
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-04-24 01:04:44 +00:00
|
|
|
pub enum TyKind {
|
2023-06-28 14:31:28 +00:00
|
|
|
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-06-28 14:31:28 +00:00
|
|
|
}
|
|
|
|
|
2023-11-16 20:01:10 +00:00
|
|
|
impl TyKind {
|
|
|
|
pub fn rigid(&self) -> Option<&RigidTy> {
|
|
|
|
if let TyKind::RigidTy(inner) = self { Some(inner) } else { None }
|
|
|
|
}
|
|
|
|
|
2023-12-11 22:53:39 +00:00
|
|
|
#[inline]
|
2023-11-16 20:01:10 +00:00
|
|
|
pub fn is_unit(&self) -> bool {
|
2023-12-02 00:20:35 +00:00
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::Tuple(data)) if data.is_empty())
|
|
|
|
}
|
|
|
|
|
2023-12-11 22:53:39 +00:00
|
|
|
#[inline]
|
2023-12-02 00:20:35 +00:00
|
|
|
pub fn is_bool(&self) -> bool {
|
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::Bool))
|
2023-11-16 20:01:10 +00:00
|
|
|
}
|
|
|
|
|
2023-12-11 22:53:39 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn is_char(&self) -> bool {
|
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::Char))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2023-11-16 20:01:10 +00:00
|
|
|
pub fn is_trait(&self) -> bool {
|
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::Dynamic(_, _, DynKind::Dyn)))
|
|
|
|
}
|
|
|
|
|
2023-12-11 22:53:39 +00:00
|
|
|
#[inline]
|
2023-11-16 20:01:10 +00:00
|
|
|
pub fn is_enum(&self) -> bool {
|
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.kind() == AdtKind::Enum)
|
|
|
|
}
|
|
|
|
|
2023-12-11 22:53:39 +00:00
|
|
|
#[inline]
|
2023-11-16 20:01:10 +00:00
|
|
|
pub fn is_struct(&self) -> bool {
|
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.kind() == AdtKind::Struct)
|
|
|
|
}
|
|
|
|
|
2023-12-11 22:53:39 +00:00
|
|
|
#[inline]
|
2023-11-16 20:01:10 +00:00
|
|
|
pub fn is_union(&self) -> bool {
|
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.kind() == AdtKind::Union)
|
|
|
|
}
|
|
|
|
|
2023-12-11 22:53:39 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn is_adt(&self) -> bool {
|
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::Adt(..)))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn is_ref(&self) -> bool {
|
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::Ref(..)))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2023-12-02 00:20:35 +00:00
|
|
|
pub fn is_fn(&self) -> bool {
|
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::FnDef(..)))
|
|
|
|
}
|
|
|
|
|
2023-12-11 22:53:39 +00:00
|
|
|
#[inline]
|
2023-12-02 00:20:35 +00:00
|
|
|
pub fn is_fn_ptr(&self) -> bool {
|
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::FnPtr(..)))
|
|
|
|
}
|
|
|
|
|
2023-12-11 22:53:39 +00:00
|
|
|
#[inline]
|
2023-12-07 06:13:07 +00:00
|
|
|
pub fn is_primitive(&self) -> bool {
|
|
|
|
matches!(
|
|
|
|
self,
|
|
|
|
TyKind::RigidTy(
|
|
|
|
RigidTy::Bool
|
|
|
|
| RigidTy::Char
|
|
|
|
| RigidTy::Int(_)
|
|
|
|
| RigidTy::Uint(_)
|
|
|
|
| RigidTy::Float(_)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2023-12-11 22:53:39 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn is_float(&self) -> bool {
|
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::Float(_)))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn is_integral(&self) -> bool {
|
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::Int(_) | RigidTy::Uint(_)))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn is_numeric(&self) -> bool {
|
|
|
|
self.is_integral() || self.is_float()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn is_signed(&self) -> bool {
|
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::Int(_)))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn is_str(&self) -> bool {
|
|
|
|
*self == TyKind::RigidTy(RigidTy::Str)
|
|
|
|
}
|
|
|
|
|
2023-12-15 21:18:41 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn is_cstr(&self) -> bool {
|
2024-02-29 23:23:44 +00:00
|
|
|
let TyKind::RigidTy(RigidTy::Adt(def, _)) = self else {
|
|
|
|
return false;
|
|
|
|
};
|
2023-12-15 21:18:41 +00:00
|
|
|
with(|cx| cx.adt_is_cstr(*def))
|
|
|
|
}
|
|
|
|
|
2023-12-11 22:53:39 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn is_slice(&self) -> bool {
|
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::Slice(_)))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn is_array(&self) -> bool {
|
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::Array(..)))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn is_mutable_ptr(&self) -> bool {
|
|
|
|
matches!(
|
|
|
|
self,
|
|
|
|
TyKind::RigidTy(RigidTy::RawPtr(_, Mutability::Mut))
|
|
|
|
| TyKind::RigidTy(RigidTy::Ref(_, _, Mutability::Mut))
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn is_raw_ptr(&self) -> bool {
|
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::RawPtr(..)))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Tests if this is any kind of primitive pointer type (reference, raw pointer, fn pointer).
|
|
|
|
#[inline]
|
|
|
|
pub fn is_any_ptr(&self) -> bool {
|
|
|
|
self.is_ref() || self.is_raw_ptr() || self.is_fn_ptr()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn is_coroutine(&self) -> bool {
|
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::Coroutine(..)))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn is_closure(&self) -> bool {
|
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::Closure(..)))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn is_box(&self) -> bool {
|
|
|
|
match self {
|
|
|
|
TyKind::RigidTy(RigidTy::Adt(def, _)) => def.is_box(),
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn is_simd(&self) -> bool {
|
|
|
|
matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.is_simd())
|
|
|
|
}
|
|
|
|
|
2023-11-16 20:01:10 +00:00
|
|
|
pub fn trait_principal(&self) -> Option<Binder<ExistentialTraitRef>> {
|
|
|
|
if let TyKind::RigidTy(RigidTy::Dynamic(predicates, _, _)) = self {
|
|
|
|
if let Some(Binder { value: ExistentialPredicate::Trait(trait_ref), bound_vars }) =
|
|
|
|
predicates.first()
|
|
|
|
{
|
|
|
|
Some(Binder { value: trait_ref.clone(), bound_vars: bound_vars.clone() })
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
2023-11-16 14:24:53 +00:00
|
|
|
|
|
|
|
/// Returns the type of `ty[i]` for builtin types.
|
|
|
|
pub fn builtin_index(&self) -> Option<Ty> {
|
|
|
|
match self.rigid()? {
|
|
|
|
RigidTy::Array(ty, _) | RigidTy::Slice(ty) => Some(*ty),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the type and mutability of `*ty` for builtin types.
|
|
|
|
///
|
|
|
|
/// The parameter `explicit` indicates if this is an *explicit* dereference.
|
|
|
|
/// Some types -- notably unsafe ptrs -- can only be dereferenced explicitly.
|
|
|
|
pub fn builtin_deref(&self, explicit: bool) -> Option<TypeAndMut> {
|
|
|
|
match self.rigid()? {
|
|
|
|
RigidTy::Adt(def, args) if def.is_box() => {
|
|
|
|
Some(TypeAndMut { ty: *args.0.first()?.ty()?, mutability: Mutability::Not })
|
|
|
|
}
|
|
|
|
RigidTy::Ref(_, ty, mutability) => {
|
|
|
|
Some(TypeAndMut { ty: *ty, mutability: *mutability })
|
|
|
|
}
|
|
|
|
RigidTy::RawPtr(ty, mutability) if explicit => {
|
|
|
|
Some(TypeAndMut { ty: *ty, mutability: *mutability })
|
|
|
|
}
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
2023-12-02 00:20:35 +00:00
|
|
|
|
2023-12-11 22:53:39 +00:00
|
|
|
/// Get the function signature for function like types (Fn, FnPtr, and Closure)
|
2023-12-02 00:20:35 +00:00
|
|
|
pub fn fn_sig(&self) -> Option<PolyFnSig> {
|
|
|
|
match self {
|
|
|
|
TyKind::RigidTy(RigidTy::FnDef(def, args)) => Some(with(|cx| cx.fn_sig(*def, args))),
|
|
|
|
TyKind::RigidTy(RigidTy::FnPtr(sig)) => Some(sig.clone()),
|
2023-12-11 22:53:39 +00:00
|
|
|
TyKind::RigidTy(RigidTy::Closure(_def, args)) => Some(with(|cx| cx.closure_sig(args))),
|
2023-12-02 00:20:35 +00:00
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
2023-12-06 21:45:07 +00:00
|
|
|
|
|
|
|
/// Get the discriminant type for this type.
|
|
|
|
pub fn discriminant_ty(&self) -> Option<Ty> {
|
|
|
|
self.rigid().map(|ty| with(|cx| cx.rigid_ty_discriminant_ty(ty)))
|
|
|
|
}
|
2023-11-16 14:24:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct TypeAndMut {
|
|
|
|
pub ty: Ty,
|
|
|
|
pub mutability: Mutability,
|
2023-11-16 20:01:10 +00:00
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-06-28 14:31:28 +00:00
|
|
|
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),
|
2023-07-12 04:56:45 +00:00
|
|
|
Str,
|
|
|
|
Array(Ty, Const),
|
2023-02-02 13:57:36 +00:00
|
|
|
Pat(Ty, Pattern),
|
2023-07-12 04:56:45 +00:00
|
|
|
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-12-25 17:04:14 +00:00
|
|
|
// FIXME(stable_mir): Movability here is redundant
|
|
|
|
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
|
|
|
|
2023-12-06 21:45:07 +00:00
|
|
|
impl RigidTy {
|
|
|
|
/// Get the discriminant type for this type.
|
|
|
|
pub fn discriminant_ty(&self) -> Ty {
|
|
|
|
with(|cx| cx.rigid_ty_discriminant_ty(self))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-16 14:24:53 +00:00
|
|
|
impl From<RigidTy> for TyKind {
|
|
|
|
fn from(value: RigidTy) -> Self {
|
|
|
|
TyKind::RigidTy(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2023-12-06 21:39:55 +00:00
|
|
|
impl IntTy {
|
|
|
|
pub fn num_bytes(self) -> usize {
|
|
|
|
match self {
|
|
|
|
IntTy::Isize => crate::target::MachineInfo::target_pointer_width().bytes().into(),
|
|
|
|
IntTy::I8 => 1,
|
|
|
|
IntTy::I16 => 2,
|
|
|
|
IntTy::I32 => 4,
|
|
|
|
IntTy::I64 => 8,
|
|
|
|
IntTy::I128 => 16,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2023-12-06 21:39:55 +00:00
|
|
|
impl UintTy {
|
|
|
|
pub fn num_bytes(self) -> usize {
|
|
|
|
match self {
|
|
|
|
UintTy::Usize => crate::target::MachineInfo::target_pointer_width().bytes().into(),
|
|
|
|
UintTy::U8 => 1,
|
|
|
|
UintTy::U16 => 2,
|
|
|
|
UintTy::U32 => 4,
|
|
|
|
UintTy::U64 => 8,
|
|
|
|
UintTy::U128 => 16,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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,
|
|
|
|
}
|
|
|
|
|
2024-02-12 19:44:35 +00:00
|
|
|
crate_def! {
|
|
|
|
pub ForeignModuleDef;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ForeignModuleDef {
|
|
|
|
pub fn module(&self) -> ForeignModule {
|
|
|
|
with(|cx| cx.foreign_module(*self))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct ForeignModule {
|
|
|
|
pub def_id: ForeignModuleDef,
|
|
|
|
pub abi: Abi,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ForeignModule {
|
|
|
|
pub fn items(&self) -> Vec<ForeignDef> {
|
|
|
|
with(|cx| cx.foreign_items(self.def_id))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-21 21:41:02 +00:00
|
|
|
crate_def! {
|
|
|
|
/// Hold information about a ForeignItem in a crate.
|
|
|
|
pub ForeignDef;
|
|
|
|
}
|
2023-07-18 14:18:40 +00:00
|
|
|
|
2024-02-12 19:44:35 +00:00
|
|
|
impl ForeignDef {
|
2024-02-14 17:38:36 +00:00
|
|
|
pub fn kind(&self) -> ForeignItemKind {
|
2024-02-12 19:44:35 +00:00
|
|
|
with(|cx| cx.foreign_item_kind(*self))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
|
|
|
pub enum ForeignItemKind {
|
|
|
|
Fn(FnDef),
|
|
|
|
Static(StaticDef),
|
|
|
|
Type(Ty),
|
|
|
|
}
|
|
|
|
|
2023-11-21 21:41:02 +00:00
|
|
|
crate_def! {
|
|
|
|
/// Hold information about a function definition in a crate.
|
|
|
|
pub FnDef;
|
|
|
|
}
|
2023-07-18 15:16:38 +00:00
|
|
|
|
2023-09-04 15:18:42 +00:00
|
|
|
impl FnDef {
|
2023-12-02 00:20:35 +00:00
|
|
|
// Get the function body if available.
|
|
|
|
pub fn body(&self) -> Option<Body> {
|
|
|
|
with(|ctx| ctx.has_body(self.0).then(|| ctx.mir_body(self.0)))
|
2023-09-04 15:18:42 +00:00
|
|
|
}
|
2024-05-20 18:11:07 +00:00
|
|
|
|
|
|
|
/// Get the information of the intrinsic if this function is a definition of one.
|
|
|
|
pub fn as_intrinsic(&self) -> Option<IntrinsicDef> {
|
|
|
|
with(|cx| cx.intrinsic(self.def_id()))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Check if the function is an intrinsic.
|
|
|
|
#[inline]
|
|
|
|
pub fn is_intrinsic(&self) -> bool {
|
|
|
|
self.as_intrinsic().is_some()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
crate_def! {
|
|
|
|
pub IntrinsicDef;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntrinsicDef {
|
|
|
|
/// Returns the plain name of the intrinsic.
|
|
|
|
/// e.g., `transmute` for `core::intrinsics::transmute`.
|
|
|
|
pub fn fn_name(&self) -> Symbol {
|
|
|
|
with(|cx| cx.intrinsic_name(*self))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns whether the intrinsic has no meaningful body and all backends
|
|
|
|
/// need to shim all calls to it.
|
|
|
|
pub fn must_be_overridden(&self) -> bool {
|
|
|
|
with(|cx| cx.intrinsic_must_be_overridden(*self))
|
|
|
|
}
|
2023-09-04 15:18:42 +00:00
|
|
|
}
|
|
|
|
|
2024-05-23 15:35:18 +00:00
|
|
|
impl From<IntrinsicDef> for FnDef {
|
|
|
|
fn from(def: IntrinsicDef) -> Self {
|
|
|
|
FnDef(def.0)
|
|
|
|
}
|
2023-09-04 15:18:42 +00:00
|
|
|
}
|
|
|
|
|
2023-11-21 21:41:02 +00:00
|
|
|
crate_def! {
|
|
|
|
pub ClosureDef;
|
|
|
|
}
|
2023-07-18 15:19:41 +00:00
|
|
|
|
2023-11-21 21:41:02 +00:00
|
|
|
crate_def! {
|
|
|
|
pub CoroutineDef;
|
|
|
|
}
|
2023-07-18 16:38:16 +00:00
|
|
|
|
2023-11-21 21:41:02 +00:00
|
|
|
crate_def! {
|
|
|
|
pub ParamDef;
|
|
|
|
}
|
2023-07-21 02:16:55 +00:00
|
|
|
|
2023-11-21 21:41:02 +00:00
|
|
|
crate_def! {
|
|
|
|
pub BrNamedDef;
|
|
|
|
}
|
2023-07-21 02:16:55 +00:00
|
|
|
|
2023-11-21 21:41:02 +00:00
|
|
|
crate_def! {
|
|
|
|
pub AdtDef;
|
|
|
|
}
|
2023-07-12 19:24:33 +00:00
|
|
|
|
2023-11-16 20:01:10 +00:00
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
|
|
|
pub enum AdtKind {
|
|
|
|
Enum,
|
|
|
|
Union,
|
|
|
|
Struct,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AdtDef {
|
|
|
|
pub fn kind(&self) -> AdtKind {
|
|
|
|
with(|cx| cx.adt_kind(*self))
|
|
|
|
}
|
2023-11-16 14:24:53 +00:00
|
|
|
|
2023-12-05 04:08:25 +00:00
|
|
|
/// Retrieve the type of this Adt.
|
|
|
|
pub fn ty(&self) -> Ty {
|
|
|
|
with(|cx| cx.def_ty(self.0))
|
|
|
|
}
|
|
|
|
|
2024-03-28 20:19:50 +00:00
|
|
|
/// Retrieve the type of this Adt by instantiating and normalizing it with the given arguments.
|
2023-12-05 20:01:09 +00:00
|
|
|
///
|
|
|
|
/// This will assume the type can be instantiated with these arguments.
|
|
|
|
pub fn ty_with_args(&self, args: &GenericArgs) -> Ty {
|
2023-12-05 04:08:25 +00:00
|
|
|
with(|cx| cx.def_ty_with_args(self.0, args))
|
|
|
|
}
|
|
|
|
|
2023-11-16 14:24:53 +00:00
|
|
|
pub fn is_box(&self) -> bool {
|
|
|
|
with(|cx| cx.adt_is_box(*self))
|
|
|
|
}
|
2023-12-01 04:22:20 +00:00
|
|
|
|
2023-12-11 22:53:39 +00:00
|
|
|
pub fn is_simd(&self) -> bool {
|
|
|
|
with(|cx| cx.adt_is_simd(*self))
|
|
|
|
}
|
|
|
|
|
2023-12-01 04:22:20 +00:00
|
|
|
/// The number of variants in this ADT.
|
|
|
|
pub fn num_variants(&self) -> usize {
|
|
|
|
with(|cx| cx.adt_variants_len(*self))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Retrieve the variants in this ADT.
|
|
|
|
pub fn variants(&self) -> Vec<VariantDef> {
|
|
|
|
self.variants_iter().collect()
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Iterate over the variants in this ADT.
|
|
|
|
pub fn variants_iter(&self) -> impl Iterator<Item = VariantDef> + '_ {
|
|
|
|
(0..self.num_variants())
|
|
|
|
.map(|idx| VariantDef { idx: VariantIdx::to_val(idx), adt_def: *self })
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn variant(&self, idx: VariantIdx) -> Option<VariantDef> {
|
2023-12-05 04:08:25 +00:00
|
|
|
(idx.to_index() < self.num_variants()).then_some(VariantDef { idx, adt_def: *self })
|
2023-12-01 04:22:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Definition of a variant, which can be either a struct / union field or an enum variant.
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
|
|
|
pub struct VariantDef {
|
|
|
|
/// The variant index.
|
|
|
|
///
|
|
|
|
/// ## Warning
|
|
|
|
/// Do not access this field directly!
|
|
|
|
pub idx: VariantIdx,
|
|
|
|
/// The data type where this variant comes from.
|
|
|
|
/// For now, we use this to retrieve information about the variant itself so we don't need to
|
|
|
|
/// cache more information.
|
|
|
|
///
|
|
|
|
/// ## Warning
|
|
|
|
/// Do not access this field directly!
|
|
|
|
pub adt_def: AdtDef,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl VariantDef {
|
|
|
|
pub fn name(&self) -> Symbol {
|
|
|
|
with(|cx| cx.variant_name(*self))
|
|
|
|
}
|
2023-12-05 04:08:25 +00:00
|
|
|
|
|
|
|
/// Retrieve all the fields in this variant.
|
|
|
|
// We expect user to cache this and use it directly since today it is expensive to generate all
|
|
|
|
// fields name.
|
|
|
|
pub fn fields(&self) -> Vec<FieldDef> {
|
|
|
|
with(|cx| cx.variant_fields(*self))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-05 20:01:09 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-12-05 04:08:25 +00:00
|
|
|
pub struct FieldDef {
|
|
|
|
/// The field definition.
|
|
|
|
///
|
|
|
|
/// ## Warning
|
|
|
|
/// Do not access this field directly! This is public for the compiler to have access to it.
|
|
|
|
pub def: DefId,
|
|
|
|
|
|
|
|
/// The field name.
|
|
|
|
pub name: Symbol,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FieldDef {
|
2024-03-28 20:19:50 +00:00
|
|
|
/// Retrieve the type of this field instantiating and normalizing it with the given arguments.
|
2023-12-05 20:01:09 +00:00
|
|
|
///
|
|
|
|
/// This will assume the type can be instantiated with these arguments.
|
|
|
|
pub fn ty_with_args(&self, args: &GenericArgs) -> Ty {
|
2023-12-05 04:08:25 +00:00
|
|
|
with(|cx| cx.def_ty_with_args(self.def, args))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Retrieve the type of this field.
|
|
|
|
pub fn ty(&self) -> Ty {
|
|
|
|
with(|cx| cx.def_ty(self.def))
|
|
|
|
}
|
2023-11-16 20:01:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Display for AdtKind {
|
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
|
|
|
f.write_str(match self {
|
|
|
|
AdtKind::Enum => "enum",
|
|
|
|
AdtKind::Union => "union",
|
|
|
|
AdtKind::Struct => "struct",
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AdtKind {
|
|
|
|
pub fn is_enum(&self) -> bool {
|
|
|
|
matches!(self, AdtKind::Enum)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_struct(&self) -> bool {
|
|
|
|
matches!(self, AdtKind::Struct)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_union(&self) -> bool {
|
|
|
|
matches!(self, AdtKind::Union)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-21 21:41:02 +00:00
|
|
|
crate_def! {
|
|
|
|
pub AliasDef;
|
|
|
|
}
|
2023-07-18 00:46:33 +00:00
|
|
|
|
2023-11-21 21:41:02 +00:00
|
|
|
crate_def! {
|
2024-01-09 23:45:03 +00:00
|
|
|
/// A trait's definition.
|
2023-11-21 21:41:02 +00:00
|
|
|
pub TraitDef;
|
|
|
|
}
|
2023-07-24 03:53:08 +00:00
|
|
|
|
2024-01-09 23:45:03 +00:00
|
|
|
impl TraitDef {
|
|
|
|
pub fn declaration(trait_def: &TraitDef) -> TraitDecl {
|
|
|
|
with(|cx| cx.trait_decl(trait_def))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-21 21:41:02 +00:00
|
|
|
crate_def! {
|
|
|
|
pub GenericDef;
|
|
|
|
}
|
2023-08-22 10:01:37 +00:00
|
|
|
|
2023-11-21 21:41:02 +00:00
|
|
|
crate_def! {
|
|
|
|
pub ConstDef;
|
|
|
|
}
|
2023-08-07 15:29:12 +00:00
|
|
|
|
2023-11-21 21:41:02 +00:00
|
|
|
crate_def! {
|
2024-01-09 23:45:03 +00:00
|
|
|
/// A trait impl definition.
|
2023-11-21 21:41:02 +00:00
|
|
|
pub ImplDef;
|
|
|
|
}
|
2023-08-07 22:03:05 +00:00
|
|
|
|
2024-01-09 23:45:03 +00:00
|
|
|
impl ImplDef {
|
|
|
|
/// Retrieve information about this implementation.
|
|
|
|
pub fn trait_impl(&self) -> ImplTrait {
|
|
|
|
with(|cx| cx.trait_impl(self))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-21 21:41:02 +00:00
|
|
|
crate_def! {
|
|
|
|
pub RegionDef;
|
|
|
|
}
|
2023-09-21 09:01:30 +00:00
|
|
|
|
2023-11-21 21:41:02 +00:00
|
|
|
crate_def! {
|
|
|
|
pub CoroutineWitnessDef;
|
|
|
|
}
|
2023-11-10 14:02:08 +00:00
|
|
|
|
2023-10-20 00:06:53 +00:00
|
|
|
/// A list of generic arguments.
|
2023-10-30 20:07:02 +00:00
|
|
|
#[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()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[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:?}"),
|
|
|
|
}
|
|
|
|
}
|
2023-11-16 14:24:53 +00:00
|
|
|
|
|
|
|
/// Return the generic argument type if applicable, otherwise return `None`.
|
|
|
|
pub fn ty(&self) -> Option<&Ty> {
|
|
|
|
match self {
|
|
|
|
GenericArgKind::Type(ty) => Some(ty),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
2023-09-04 15:18:53 +00:00
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-07-24 03:53:08 +00:00
|
|
|
pub enum TermKind {
|
|
|
|
Type(Ty),
|
|
|
|
Const(Const),
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-07-18 00:46:33 +00:00
|
|
|
pub enum AliasKind {
|
|
|
|
Projection,
|
|
|
|
Inherent,
|
|
|
|
Opaque,
|
|
|
|
Weak,
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-07-18 00:46:33 +00:00
|
|
|
pub struct AliasTy {
|
|
|
|
pub def_id: AliasDef,
|
|
|
|
pub args: GenericArgs,
|
|
|
|
}
|
|
|
|
|
2024-05-13 14:00:38 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
|
|
pub struct AliasTerm {
|
|
|
|
pub def_id: AliasDef,
|
|
|
|
pub args: GenericArgs,
|
|
|
|
}
|
|
|
|
|
2023-07-21 02:16:55 +00:00
|
|
|
pub type PolyFnSig = Binder<FnSig>;
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[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,
|
2024-05-17 17:17:48 +00:00
|
|
|
pub safety: Safety,
|
2023-07-21 02:16:55 +00:00
|
|
|
pub abi: Abi,
|
|
|
|
}
|
|
|
|
|
2023-12-02 00:20:35 +00:00
|
|
|
impl FnSig {
|
|
|
|
pub fn output(&self) -> Ty {
|
|
|
|
self.inputs_and_output[self.inputs_and_output.len() - 1]
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn inputs(&self) -> &[Ty] {
|
|
|
|
&self.inputs_and_output[..self.inputs_and_output.len() - 1]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-21 02:16:55 +00:00
|
|
|
#[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,
|
|
|
|
EfiApi,
|
|
|
|
AvrInterrupt,
|
|
|
|
AvrNonBlockingInterrupt,
|
|
|
|
CCmseNonSecureCall,
|
|
|
|
Wasm,
|
|
|
|
System { unwind: bool },
|
|
|
|
RustIntrinsic,
|
|
|
|
RustCall,
|
|
|
|
Unadjusted,
|
|
|
|
RustCold,
|
2023-07-29 17:56:07 +00:00
|
|
|
RiscvInterruptM,
|
|
|
|
RiscvInterruptS,
|
2023-07-21 02:16:55 +00:00
|
|
|
}
|
|
|
|
|
2023-12-12 00:37:33 +00:00
|
|
|
/// A binder represents a possibly generic type and its bound vars.
|
2023-10-30 20:07:02 +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>,
|
|
|
|
}
|
|
|
|
|
2023-11-16 20:01:10 +00:00
|
|
|
impl<T> Binder<T> {
|
2023-12-11 22:53:39 +00:00
|
|
|
/// Create a new binder with the given bound vars.
|
2023-12-12 03:02:54 +00:00
|
|
|
pub fn bind_with_vars(value: T, bound_vars: Vec<BoundVariableKind>) -> Self {
|
2023-12-11 22:53:39 +00:00
|
|
|
Binder { value, bound_vars }
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a new binder with no bounded variable.
|
|
|
|
pub fn dummy(value: T) -> Self {
|
|
|
|
Binder { value, bound_vars: vec![] }
|
|
|
|
}
|
|
|
|
|
2023-11-16 20:01:10 +00:00
|
|
|
pub fn skip_binder(self) -> T {
|
|
|
|
self.value
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn map_bound_ref<F, U>(&self, f: F) -> Binder<U>
|
|
|
|
where
|
|
|
|
F: FnOnce(&T) -> U,
|
|
|
|
{
|
|
|
|
let Binder { value, bound_vars } = self;
|
|
|
|
let new_value = f(value);
|
|
|
|
Binder { value: new_value, bound_vars: bound_vars.clone() }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn map_bound<F, U>(self, f: F) -> Binder<U>
|
|
|
|
where
|
|
|
|
F: FnOnce(T) -> U,
|
|
|
|
{
|
|
|
|
let Binder { value, bound_vars } = self;
|
|
|
|
let new_value = f(value);
|
|
|
|
Binder { value: new_value, bound_vars }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-08-07 22:03:05 +00:00
|
|
|
pub struct EarlyBinder<T> {
|
|
|
|
pub value: T,
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[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),
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[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
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-07-24 03:53:08 +00:00
|
|
|
pub enum DynKind {
|
|
|
|
Dyn,
|
|
|
|
DynStar,
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-07-24 03:53:08 +00:00
|
|
|
pub enum ExistentialPredicate {
|
|
|
|
Trait(ExistentialTraitRef),
|
|
|
|
Projection(ExistentialProjection),
|
|
|
|
AutoTrait(TraitDef),
|
|
|
|
}
|
|
|
|
|
2023-11-16 20:01:10 +00:00
|
|
|
/// An existential reference to a trait where `Self` is not included.
|
|
|
|
///
|
|
|
|
/// The `generic_args` will include any other known argument.
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-07-24 03:53:08 +00:00
|
|
|
pub struct ExistentialTraitRef {
|
|
|
|
pub def_id: TraitDef,
|
|
|
|
pub generic_args: GenericArgs,
|
|
|
|
}
|
|
|
|
|
2023-11-16 20:01:10 +00:00
|
|
|
impl Binder<ExistentialTraitRef> {
|
|
|
|
pub fn with_self_ty(&self, self_ty: Ty) -> Binder<TraitRef> {
|
|
|
|
self.map_bound_ref(|trait_ref| trait_ref.with_self_ty(self_ty))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ExistentialTraitRef {
|
|
|
|
pub fn with_self_ty(&self, self_ty: Ty) -> TraitRef {
|
|
|
|
TraitRef::new(self.def_id, self_ty, &self.generic_args)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[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
|
|
|
|
2023-10-30 20:07:02 +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
|
|
|
|
2023-10-30 20:07:02 +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>>;
|
2024-02-29 23:23:44 +00:00
|
|
|
|
|
|
|
/// Size in bytes.
|
2023-08-02 12:12:38 +00:00
|
|
|
pub type Size = usize;
|
2023-09-02 05:53:06 +00:00
|
|
|
|
2023-12-06 21:39:55 +00:00
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
2023-09-14 15:50:11 +00:00
|
|
|
pub struct Prov(pub AllocId);
|
2024-02-29 23:23:44 +00:00
|
|
|
|
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.
|
2023-12-06 21:39:55 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
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)>,
|
|
|
|
}
|
|
|
|
|
2023-12-06 21:39:55 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
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
|
|
|
|
2023-12-06 21:39:55 +00:00
|
|
|
impl Allocation {
|
|
|
|
/// Get a vector of bytes for an Allocation that has been fully initialized
|
|
|
|
pub fn raw_bytes(&self) -> Result<Vec<u8>, Error> {
|
|
|
|
self.bytes
|
|
|
|
.iter()
|
|
|
|
.copied()
|
|
|
|
.collect::<Option<Vec<_>>>()
|
|
|
|
.ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Read a uint value from the specified range.
|
|
|
|
pub fn read_partial_uint(&self, range: Range<usize>) -> Result<u128, Error> {
|
|
|
|
if range.end - range.start > 16 {
|
|
|
|
return Err(error!("Allocation is bigger than largest integer"));
|
|
|
|
}
|
|
|
|
if range.end > self.bytes.len() {
|
|
|
|
return Err(error!(
|
|
|
|
"Range is out of bounds. Allocation length is `{}`, but requested range `{:?}`",
|
|
|
|
self.bytes.len(),
|
|
|
|
range
|
|
|
|
));
|
|
|
|
}
|
|
|
|
let raw = self.bytes[range]
|
|
|
|
.iter()
|
|
|
|
.copied()
|
|
|
|
.collect::<Option<Vec<_>>>()
|
|
|
|
.ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))?;
|
|
|
|
read_target_uint(&raw)
|
|
|
|
}
|
|
|
|
|
2023-12-07 21:15:43 +00:00
|
|
|
/// Read this allocation and try to convert it to an unassigned integer.
|
2023-12-06 21:39:55 +00:00
|
|
|
pub fn read_uint(&self) -> Result<u128, Error> {
|
|
|
|
if self.bytes.len() > 16 {
|
|
|
|
return Err(error!("Allocation is bigger than largest integer"));
|
|
|
|
}
|
|
|
|
let raw = self.raw_bytes()?;
|
|
|
|
read_target_uint(&raw)
|
|
|
|
}
|
|
|
|
|
2023-12-07 21:15:43 +00:00
|
|
|
/// Read this allocation and try to convert it to a signed integer.
|
2023-12-06 21:39:55 +00:00
|
|
|
pub fn read_int(&self) -> Result<i128, Error> {
|
|
|
|
if self.bytes.len() > 16 {
|
|
|
|
return Err(error!("Allocation is bigger than largest integer"));
|
|
|
|
}
|
|
|
|
let raw = self.raw_bytes()?;
|
|
|
|
read_target_int(&raw)
|
|
|
|
}
|
|
|
|
|
2023-12-07 21:15:43 +00:00
|
|
|
/// Read this allocation and try to convert it to a boolean.
|
2023-12-06 21:39:55 +00:00
|
|
|
pub fn read_bool(&self) -> Result<bool, Error> {
|
|
|
|
match self.read_int()? {
|
|
|
|
0 => Ok(false),
|
|
|
|
1 => Ok(true),
|
|
|
|
val @ _ => Err(error!("Unexpected value for bool: `{val}`")),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-07 21:15:43 +00:00
|
|
|
/// Read this allocation as a pointer and return whether it represents a `null` pointer.
|
2023-12-06 21:39:55 +00:00
|
|
|
pub fn is_null(&self) -> Result<bool, Error> {
|
|
|
|
let len = self.bytes.len();
|
|
|
|
let ptr_len = MachineInfo::target_pointer_width().bytes();
|
|
|
|
if len != ptr_len {
|
|
|
|
return Err(error!("Expected width of pointer (`{ptr_len}`), but found: `{len}`"));
|
|
|
|
}
|
2023-12-07 21:15:43 +00:00
|
|
|
Ok(self.read_uint()? == 0 && self.provenance.ptrs.is_empty())
|
2023-12-06 21:39:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +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),
|
2023-10-27 03:10:54 +00:00
|
|
|
/// 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
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +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
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +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>,
|
|
|
|
}
|
|
|
|
|
2023-08-16 16:10:52 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
2023-08-04 20:23:26 +00:00
|
|
|
pub enum TraitSpecializationKind {
|
|
|
|
None,
|
|
|
|
Marker,
|
|
|
|
AlwaysApplicable,
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-08-04 20:23:26 +00:00
|
|
|
pub struct TraitDecl {
|
|
|
|
pub def_id: TraitDef,
|
2024-05-17 17:17:48 +00:00
|
|
|
pub safety: Safety,
|
2023-08-04 20:23:26 +00:00
|
|
|
pub paren_sugar: bool,
|
|
|
|
pub has_auto_impl: bool,
|
|
|
|
pub is_marker: bool,
|
|
|
|
pub is_coinductive: bool,
|
|
|
|
pub skip_array_during_method_dispatch: bool,
|
2024-04-17 20:32:17 +00:00
|
|
|
pub skip_boxed_slice_during_method_dispatch: bool,
|
2023-08-04 20:23:26 +00:00
|
|
|
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
|
|
|
|
2023-08-28 20:39:52 +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-28 20:39:52 +00:00
|
|
|
}
|
|
|
|
|
2023-08-07 22:03:05 +00:00
|
|
|
pub type ImplTrait = EarlyBinder<TraitRef>;
|
|
|
|
|
2023-11-16 20:01:10 +00:00
|
|
|
/// A complete reference to a trait, i.e., one where `Self` is known.
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-08-07 22:03:05 +00:00
|
|
|
pub struct TraitRef {
|
|
|
|
pub def_id: TraitDef,
|
2023-11-16 20:01:10 +00:00
|
|
|
/// The generic arguments for this definition.
|
|
|
|
/// The first element must always be type, and it represents `Self`.
|
|
|
|
args: GenericArgs,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TraitRef {
|
|
|
|
pub fn new(def_id: TraitDef, self_ty: Ty, gen_args: &GenericArgs) -> TraitRef {
|
|
|
|
let mut args = vec![GenericArgKind::Type(self_ty)];
|
|
|
|
args.extend_from_slice(&gen_args.0);
|
|
|
|
TraitRef { def_id, args: GenericArgs(args) }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn try_new(def_id: TraitDef, args: GenericArgs) -> Result<TraitRef, ()> {
|
|
|
|
match &args.0[..] {
|
|
|
|
[GenericArgKind::Type(_), ..] => Ok(TraitRef { def_id, args }),
|
|
|
|
_ => Err(()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn args(&self) -> &GenericArgs {
|
|
|
|
&self.args
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn self_ty(&self) -> Ty {
|
|
|
|
let GenericArgKind::Type(self_ty) = self.args.0[0] else {
|
|
|
|
panic!("Self must be a type, but found: {:?}", self.args.0[0])
|
|
|
|
};
|
|
|
|
self_ty
|
|
|
|
}
|
2023-08-07 22:03:05 +00:00
|
|
|
}
|
2023-08-22 10:01:37 +00:00
|
|
|
|
2023-10-30 20:07:02 +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>,
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[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 },
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[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
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-08-22 04:15:38 +00:00
|
|
|
pub enum PredicateKind {
|
|
|
|
Clause(ClauseKind),
|
|
|
|
ObjectSafe(TraitDef),
|
|
|
|
SubType(SubtypePredicate),
|
|
|
|
Coerce(CoercePredicate),
|
|
|
|
ConstEquate(Const, Const),
|
|
|
|
Ambiguous,
|
|
|
|
AliasRelate(TermKind, TermKind, AliasRelationDirection),
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[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),
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-08-22 04:15:38 +00:00
|
|
|
pub enum ClosureKind {
|
|
|
|
Fn,
|
|
|
|
FnMut,
|
|
|
|
FnOnce,
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-08-22 04:15:38 +00:00
|
|
|
pub struct SubtypePredicate {
|
|
|
|
pub a: Ty,
|
|
|
|
pub b: Ty,
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-08-22 04:15:38 +00:00
|
|
|
pub struct CoercePredicate {
|
|
|
|
pub a: Ty,
|
|
|
|
pub b: Ty,
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-08-22 04:15:38 +00:00
|
|
|
pub enum AliasRelationDirection {
|
|
|
|
Equate,
|
|
|
|
Subtype,
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-08-22 04:15:38 +00:00
|
|
|
pub struct TraitPredicate {
|
|
|
|
pub trait_ref: TraitRef,
|
2024-03-21 19:45:28 +00:00
|
|
|
pub polarity: PredicatePolarity,
|
2023-08-22 04:15:38 +00:00
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[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>;
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-08-22 04:15:38 +00:00
|
|
|
pub struct ProjectionPredicate {
|
2024-05-13 14:00:38 +00:00
|
|
|
pub projection_term: AliasTerm,
|
2023-08-22 04:15:38 +00:00
|
|
|
pub term: TermKind,
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:07:02 +00:00
|
|
|
#[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
|
|
|
|
2024-03-21 19:45:28 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
|
|
pub enum PredicatePolarity {
|
|
|
|
Positive,
|
|
|
|
Negative,
|
|
|
|
}
|
|
|
|
|
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);
|
2023-12-01 04:22:20 +00:00
|
|
|
|
|
|
|
/// The source-order index of a variant in a type.
|
|
|
|
///
|
|
|
|
/// For example, in the following types,
|
|
|
|
/// ```ignore(illustrative)
|
|
|
|
/// enum Demo1 {
|
|
|
|
/// Variant0 { a: bool, b: i32 },
|
|
|
|
/// Variant1 { c: u8, d: u64 },
|
|
|
|
/// }
|
|
|
|
/// struct Demo2 { e: u8, f: u16, g: u8 }
|
|
|
|
/// ```
|
|
|
|
/// `a` is in the variant with the `VariantIdx` of `0`,
|
|
|
|
/// `c` is in the variant with the `VariantIdx` of `1`, and
|
|
|
|
/// `g` is in the variant with the `VariantIdx` of `0`.
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
|
|
|
pub struct VariantIdx(usize);
|
|
|
|
|
|
|
|
index_impl!(VariantIdx);
|