From 1376c5a617be5c25655d0d7cb63e3beaa5a6e026 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:20:39 +0200 Subject: Merging upstream version 1.70.0+dfsg1. Signed-off-by: Daniel Baumann --- library/core/src/intrinsics/mir.rs | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'library/core/src/intrinsics') diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs index 72db1d87c..45498a54b 100644 --- a/library/core/src/intrinsics/mir.rs +++ b/library/core/src/intrinsics/mir.rs @@ -8,7 +8,7 @@ //! //! The documentation for this module describes how to use this feature. If you are interested in //! hacking on the implementation, most of that documentation lives at -//! `rustc_mir_building/src/build/custom/mod.rs`. +//! `rustc_mir_build/src/build/custom/mod.rs`. //! //! Typical usage will look like this: //! @@ -49,6 +49,8 @@ //! //! The input to the [`mir!`] macro is: //! +//! - An optional return type annotation in the form of `type RET = ...;`. This may be required +//! if the compiler cannot infer the type of RET. //! - A possibly empty list of local declarations. Locals can also be declared inline on //! assignments via `let`. Type inference generally works. Shadowing does not. //! - A list of basic blocks. The first of these is the start block and is where execution begins. @@ -124,6 +126,18 @@ //! } //! ) //! } +//! +//! #[custom_mir(dialect = "runtime", phase = "optimized")] +//! fn annotated_return_type() -> (i32, bool) { +//! mir!( +//! type RET = (i32, bool); +//! { +//! RET.0 = 1; +//! RET.1 = true; +//! Return() +//! } +//! ) +//! } //! ``` //! //! We can also set off compilation failures that happen in sufficiently late stages of the @@ -218,6 +232,7 @@ //! - `&`, `&mut`, `addr_of!`, and `addr_of_mut!` all work to create their associated rvalue. //! - [`Discriminant`] and [`Len`] have associated functions. //! - Unary and binary operations use their normal Rust syntax - `a * b`, `!c`, etc. +//! - The binary operation `Offset` can be created via [`Offset`]. //! - Checked binary operations are represented by wrapping the associated binop in [`Checked`]. //! - Array repetition syntax (`[foo; 10]`) creates the associated rvalue. //! @@ -227,12 +242,12 @@ //! are no resume and abort terminators, and terminators that might unwind do not have any way to //! indicate the unwind block. //! -//! - [`Goto`], [`Return`], [`Unreachable`], [`Drop`](Drop()), and [`DropAndReplace`] have associated functions. +//! - [`Goto`], [`Return`], [`Unreachable`] and [`Drop`](Drop()) have associated functions. //! - `match some_int_operand` becomes a `SwitchInt`. Each arm should be `literal => basic_block` //! - The exception is the last arm, which must be `_ => basic_block` and corresponds to the //! otherwise branch. //! - [`Call`] has an associated function as well. The third argument of this function is a normal -//! function call expresion, for example `my_other_function(a, 5)`. +//! function call expression, for example `my_other_function(a, 5)`. //! #![unstable( @@ -259,7 +274,6 @@ define!("mir_return", fn Return() -> BasicBlock); define!("mir_goto", fn Goto(destination: BasicBlock) -> BasicBlock); define!("mir_unreachable", fn Unreachable() -> BasicBlock); define!("mir_drop", fn Drop(place: T, goto: BasicBlock)); -define!("mir_drop_and_replace", fn DropAndReplace(place: T, value: T, goto: BasicBlock)); define!("mir_call", fn Call(place: T, goto: BasicBlock, call: T)); define!("mir_storage_live", fn StorageLive(local: T)); define!("mir_storage_dead", fn StorageDead(local: T)); @@ -276,6 +290,7 @@ define!( fn Discriminant(place: T) -> ::Discriminant ); define!("mir_set_discriminant", fn SetDiscriminant(place: T, index: u32)); +define!("mir_offset", fn Offset(ptr: T, count: U) -> T); define!( "mir_field", /// Access the field with the given index of some place. @@ -330,6 +345,14 @@ define!( /// See [`Field`] for documentation. fn Variant(place: T, index: u32) -> () ); +define!( + "mir_cast_transmute", + /// Emits a `CastKind::Transmute` cast. + /// + /// Needed to test the UB when `sizeof(T) != sizeof(U)`, which can't be + /// generated via the normal `mem::transmute`. + fn CastTransmute(operand: T) -> U +); define!( "mir_make_place", #[doc(hidden)] @@ -343,6 +366,7 @@ define!( #[rustc_macro_transparency = "transparent"] pub macro mir { ( + $(type RET = $ret_ty:ty ;)? $(let $local_decl:ident $(: $local_decl_ty:ty)? ;)* { @@ -363,7 +387,7 @@ pub macro mir { { // Now all locals #[allow(non_snake_case)] - let RET; + let RET $(: $ret_ty)?; $( let $local_decl $(: $local_decl_ty)? ; )* -- cgit v1.2.3