summaryrefslogtreecommitdiffstats
path: root/library/core/src/intrinsics
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
commit1376c5a617be5c25655d0d7cb63e3beaa5a6e026 (patch)
tree3bb8d61aee02bc7a15eab3f36e3b921afc2075d0 /library/core/src/intrinsics
parentReleasing progress-linux version 1.69.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.tar.xz
rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.zip
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/core/src/intrinsics')
-rw-r--r--library/core/src/intrinsics/mir.rs34
1 files changed, 29 insertions, 5 deletions
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<T>(place: T, goto: BasicBlock));
-define!("mir_drop_and_replace", fn DropAndReplace<T>(place: T, value: T, goto: BasicBlock));
define!("mir_call", fn Call<T>(place: T, goto: BasicBlock, call: T));
define!("mir_storage_live", fn StorageLive<T>(local: T));
define!("mir_storage_dead", fn StorageDead<T>(local: T));
@@ -276,6 +290,7 @@ define!(
fn Discriminant<T>(place: T) -> <T as ::core::marker::DiscriminantKind>::Discriminant
);
define!("mir_set_discriminant", fn SetDiscriminant<T>(place: T, index: u32));
+define!("mir_offset", fn Offset<T, U>(ptr: T, count: U) -> T);
define!(
"mir_field",
/// Access the field with the given index of some place.
@@ -331,6 +346,14 @@ define!(
fn Variant<T>(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<T, U>(operand: T) -> U
+);
+define!(
"mir_make_place",
#[doc(hidden)]
fn __internal_make_place<T>(place: T) -> *mut T
@@ -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)? ;
)*