diff options
Diffstat (limited to 'compiler/stable_mir')
| -rw-r--r-- | compiler/stable_mir/src/abi.rs | 4 | ||||
| -rw-r--r-- | compiler/stable_mir/src/compiler_interface.rs | 25 | ||||
| -rw-r--r-- | compiler/stable_mir/src/lib.rs | 2 | ||||
| -rw-r--r-- | compiler/stable_mir/src/mir/body.rs | 39 | ||||
| -rw-r--r-- | compiler/stable_mir/src/mir/mono.rs | 9 | ||||
| -rw-r--r-- | compiler/stable_mir/src/mir/pretty.rs | 5 | ||||
| -rw-r--r-- | compiler/stable_mir/src/ty.rs | 52 |
7 files changed, 109 insertions, 27 deletions
diff --git a/compiler/stable_mir/src/abi.rs b/compiler/stable_mir/src/abi.rs index 92bc2e34561..e1c14fe0b38 100644 --- a/compiler/stable_mir/src/abi.rs +++ b/compiler/stable_mir/src/abi.rs @@ -6,7 +6,7 @@ use crate::ty::{Align, IndexedVal, Ty, VariantIdx}; use crate::Error; use crate::Opaque; use std::fmt::{self, Debug}; -use std::num::NonZeroUsize; +use std::num::NonZero; use std::ops::RangeInclusive; /// A function ABI definition. @@ -133,7 +133,7 @@ pub enum FieldsShape { Primitive, /// All fields start at no offset. The `usize` is the field count. - Union(NonZeroUsize), + Union(NonZero<usize>), /// Array/vector-like placement, with all fields of identical types. Array { stride: Size, count: u64 }, diff --git a/compiler/stable_mir/src/compiler_interface.rs b/compiler/stable_mir/src/compiler_interface.rs index 94c552199bc..858ce5301d8 100644 --- a/compiler/stable_mir/src/compiler_interface.rs +++ b/compiler/stable_mir/src/compiler_interface.rs @@ -8,13 +8,13 @@ use std::cell::Cell; use crate::abi::{FnAbi, Layout, LayoutShape}; use crate::mir::alloc::{AllocId, GlobalAlloc}; use crate::mir::mono::{Instance, InstanceDef, StaticDef}; -use crate::mir::{BinOp, Body, Place}; +use crate::mir::{BinOp, Body, Place, UnOp}; use crate::target::MachineInfo; use crate::ty::{ AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, ForeignDef, ForeignItemKind, ForeignModule, ForeignModuleDef, GenericArgs, GenericPredicates, Generics, - ImplDef, ImplTrait, LineInfo, PolyFnSig, RigidTy, Span, TraitDecl, TraitDef, Ty, TyKind, - UintTy, VariantDef, + ImplDef, ImplTrait, IntrinsicDef, LineInfo, PolyFnSig, RigidTy, Span, TraitDecl, TraitDef, Ty, + TyKind, UintTy, VariantDef, }; use crate::{ mir, Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls, ItemKind, @@ -88,6 +88,16 @@ pub trait Context { /// Retrieve the function signature for the given generic arguments. fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig; + /// Retrieve the intrinsic definition if the item corresponds one. + fn intrinsic(&self, item: DefId) -> Option<IntrinsicDef>; + + /// Retrieve the plain function name of an intrinsic. + fn intrinsic_name(&self, def: IntrinsicDef) -> Symbol; + + /// Returns whether the intrinsic has no meaningful body and all backends + /// need to shim all calls to it. + fn intrinsic_must_be_overridden(&self, def: IntrinsicDef) -> bool; + /// Retrieve the closure signature for the given generic arguments. fn closure_sig(&self, args: &GenericArgs) -> PolyFnSig; @@ -158,6 +168,9 @@ pub trait Context { /// Check if this is an empty DropGlue shim. fn is_empty_drop_shim(&self, def: InstanceDef) -> bool; + /// Check if this is an empty AsyncDropGlueCtor shim. + fn is_empty_async_drop_ctor_shim(&self, def: InstanceDef) -> bool; + /// Convert a non-generic crate item into an instance. /// This function will panic if the item is generic. fn mono_instance(&self, def_id: DefId) -> Instance; @@ -195,7 +208,6 @@ pub trait Context { fn vtable_allocation(&self, global_alloc: &GlobalAlloc) -> Option<AllocId>; fn krate(&self, def_id: DefId) -> Crate; fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol; - fn intrinsic_name(&self, def: InstanceDef) -> Symbol; /// Return information about the target machine. fn target_info(&self) -> MachineInfo; @@ -214,11 +226,14 @@ pub trait Context { /// Get the resulting type of binary operation. fn binop_ty(&self, bin_op: BinOp, rhs: Ty, lhs: Ty) -> Ty; + + /// Get the resulting type of unary operation. + fn unop_ty(&self, un_op: UnOp, arg: Ty) -> Ty; } // A thread local variable that stores a pointer to the tables mapping between TyCtxt // datastructures and stable MIR datastructures -scoped_thread_local!(static TLV: Cell<*const ()>); +scoped_tls::scoped_thread_local!(static TLV: Cell<*const ()>); pub fn run<F, T>(context: &dyn Context, f: F) -> Result<T, Error> where diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs index d1a2948ea77..d9f988935ab 100644 --- a/compiler/stable_mir/src/lib.rs +++ b/compiler/stable_mir/src/lib.rs @@ -16,8 +16,6 @@ //! //! The goal is to eventually be published on //! [crates.io](https://crates.io). -#[macro_use] -extern crate scoped_tls; use std::fmt; use std::fmt::Debug; diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index 1ad05633d62..4c779ae96a8 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -346,6 +346,15 @@ impl BinOp { pub enum UnOp { Not, Neg, + PtrMetadata, +} + +impl UnOp { + /// Return the type of this operation for the given input Ty. + /// This function does not perform type checking, and it currently doesn't handle SIMD. + pub fn ty(&self, arg_ty: Ty) -> Ty { + with(|ctx| ctx.unop_ty(*self, arg_ty)) + } } #[derive(Clone, Debug, Eq, PartialEq)] @@ -580,7 +589,10 @@ impl Rvalue { let ty = op.ty(lhs_ty, rhs_ty); Ok(Ty::new_tuple(&[ty, Ty::bool_ty()])) } - Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, operand) => operand.ty(locals), + Rvalue::UnaryOp(op, operand) => { + let arg_ty = operand.ty(locals)?; + Ok(op.ty(arg_ty)) + } Rvalue::Discriminant(place) => { let place_ty = place.ty(locals)?; place_ty @@ -602,6 +614,7 @@ impl Rvalue { AggregateKind::Coroutine(def, ref args, mov) => { Ok(Ty::new_coroutine(def, args.clone(), mov)) } + AggregateKind::RawPtr(ty, mutability) => Ok(Ty::new_ptr(ty, mutability)), }, Rvalue::ShallowInitBox(_, ty) => Ok(Ty::new_box(*ty)), Rvalue::CopyForDeref(place) => place.ty(locals), @@ -617,6 +630,7 @@ pub enum AggregateKind { Closure(ClosureDef, GenericArgs), // FIXME(stable_mir): Movability here is redundant Coroutine(CoroutineDef, GenericArgs, Movability), + RawPtr(Ty, Mutability), } #[derive(Clone, Debug, Eq, PartialEq)] @@ -865,11 +879,9 @@ pub enum BorrowKind { /// Data must be immutable and is aliasable. Shared, - /// The immediately borrowed place must be immutable, but projections from - /// it don't need to be. This is used to prevent match guards from replacing - /// the scrutinee. For example, a fake borrow of `a.b` doesn't - /// conflict with a mutable borrow of `a.b.c`. - Fake, + /// An immutable, aliasable borrow that is discarded after borrow-checking. Can behave either + /// like a normal shared borrow or like a special shallow borrow (see [`FakeBorrowKind`]). + Fake(FakeBorrowKind), /// Data is mutable and not aliasable. Mut { @@ -884,7 +896,7 @@ impl BorrowKind { BorrowKind::Mut { .. } => Mutability::Mut, BorrowKind::Shared => Mutability::Not, // FIXME: There's no type corresponding to a shallow borrow, so use `&` as an approximation. - BorrowKind::Fake => Mutability::Not, + BorrowKind::Fake(_) => Mutability::Not, } } } @@ -896,6 +908,17 @@ pub enum MutBorrowKind { ClosureCapture, } +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum FakeBorrowKind { + /// A shared (deep) borrow. Data must be immutable and is aliasable. + Deep, + /// The immediately borrowed place must be immutable, but projections from + /// it don't need to be. This is used to prevent match guards from replacing + /// the scrutinee. For example, a fake borrow of `a.b` doesn't + /// conflict with a mutable borrow of `a.b.c`. + Shallow, +} + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum Mutability { Not, @@ -904,8 +927,8 @@ pub enum Mutability { #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum Safety { + Safe, Unsafe, - Normal, } #[derive(Copy, Clone, Debug, Eq, PartialEq)] diff --git a/compiler/stable_mir/src/mir/mono.rs b/compiler/stable_mir/src/mir/mono.rs index a032a180fcf..572f1499c5a 100644 --- a/compiler/stable_mir/src/mir/mono.rs +++ b/compiler/stable_mir/src/mir/mono.rs @@ -106,7 +106,9 @@ impl Instance { /// which is more convenient to match with intrinsic symbols. pub fn intrinsic_name(&self) -> Option<Symbol> { match self.kind { - InstanceKind::Intrinsic => Some(with(|context| context.intrinsic_name(self.def))), + InstanceKind::Intrinsic => { + Some(with(|context| context.intrinsic(self.def.def_id()).unwrap().fn_name())) + } InstanceKind::Item | InstanceKind::Virtual { .. } | InstanceKind::Shim => None, } } @@ -157,7 +159,10 @@ impl Instance { /// When generating code for a Drop terminator, users can ignore an empty drop glue. /// These shims are only needed to generate a valid Drop call done via VTable. pub fn is_empty_shim(&self) -> bool { - self.kind == InstanceKind::Shim && with(|cx| cx.is_empty_drop_shim(self.def)) + self.kind == InstanceKind::Shim + && with(|cx| { + cx.is_empty_drop_shim(self.def) || cx.is_empty_async_drop_ctor_shim(self.def) + }) } /// Try to constant evaluate the instance into a constant with the given type. diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs index 4ac4833add7..bbca3965852 100644 --- a/compiler/stable_mir/src/mir/pretty.rs +++ b/compiler/stable_mir/src/mir/pretty.rs @@ -8,7 +8,7 @@ use std::{fmt, io, iter}; use super::{AssertMessage, BinOp, TerminatorKind}; -use super::BorrowKind; +use super::{BorrowKind, FakeBorrowKind}; impl Display for Ty { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { @@ -352,7 +352,8 @@ fn pretty_rvalue<W: Write>(writer: &mut W, rval: &Rvalue) -> io::Result<()> { Rvalue::Ref(_, borrowkind, place) => { let kind = match borrowkind { BorrowKind::Shared => "&", - BorrowKind::Fake => "&fake ", + BorrowKind::Fake(FakeBorrowKind::Deep) => "&fake ", + BorrowKind::Fake(FakeBorrowKind::Shallow) => "&fake shallow ", BorrowKind::Mut { .. } => "&mut ", }; write!(writer, "{kind}{:?}", place) diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index bc6fb34493a..d62054eff60 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -1,6 +1,5 @@ use super::{ - mir::Safety, - mir::{Body, Mutability}, + mir::{Body, Mutability, Safety}, with, DefId, Error, Symbol, }; use crate::abi::Layout; @@ -191,7 +190,6 @@ pub(crate) type DebruijnIndex = u32; #[derive(Clone, Debug, Eq, PartialEq)] pub struct EarlyParamRegion { - pub def_id: RegionDef, pub index: u32, pub name: Symbol, } @@ -622,6 +620,41 @@ impl FnDef { pub fn body(&self) -> Option<Body> { with(|ctx| ctx.has_body(self.0).then(|| ctx.mir_body(self.0))) } + + /// 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)) + } +} + +impl From<IntrinsicDef> for FnDef { + fn from(def: IntrinsicDef) -> Self { + FnDef(def.0) + } } crate_def! { @@ -897,13 +930,19 @@ pub struct AliasTy { pub args: GenericArgs, } +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AliasTerm { + pub def_id: AliasDef, + pub args: GenericArgs, +} + pub type PolyFnSig = Binder<FnSig>; #[derive(Clone, Debug, Eq, PartialEq)] pub struct FnSig { pub inputs_and_output: Vec<Ty>, pub c_variadic: bool, - pub unsafety: Safety, + pub safety: Safety, pub abi: Abi, } @@ -1194,12 +1233,13 @@ pub enum TraitSpecializationKind { #[derive(Clone, Debug, Eq, PartialEq)] pub struct TraitDecl { pub def_id: TraitDef, - pub unsafety: Safety, + pub safety: 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 skip_boxed_slice_during_method_dispatch: bool, pub specialization_kind: TraitSpecializationKind, pub must_implement_one_of: Option<Vec<Ident>>, pub implement_via_object: bool, @@ -1350,7 +1390,7 @@ pub type TypeOutlivesPredicate = OutlivesPredicate<Ty, Region>; #[derive(Clone, Debug, Eq, PartialEq)] pub struct ProjectionPredicate { - pub projection_ty: AliasTy, + pub projection_term: AliasTerm, pub term: TermKind, } |
