about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/core/src/intrinsics/mir.rs17
-rw-r--r--tests/mir-opt/building/custom/composite_return.rs21
-rw-r--r--tests/mir-opt/building/custom/composite_return.tuple.built.after.mir11
3 files changed, 48 insertions, 1 deletions
diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs
index 64fc1c0c277..3061f76df04 100644
--- a/library/core/src/intrinsics/mir.rs
+++ b/library/core/src/intrinsics/mir.rs
@@ -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
@@ -342,6 +356,7 @@ define!(
 #[rustc_macro_transparency = "transparent"]
 pub macro mir {
     (
+        $(type RET = $ret_ty:ty ;)?
         $(let $local_decl:ident $(: $local_decl_ty:ty)? ;)*
 
         {
@@ -362,7 +377,7 @@ pub macro mir {
         {
             // Now all locals
             #[allow(non_snake_case)]
-            let RET;
+            let RET $(: $ret_ty)?;
             $(
                 let $local_decl $(: $local_decl_ty)? ;
             )*
diff --git a/tests/mir-opt/building/custom/composite_return.rs b/tests/mir-opt/building/custom/composite_return.rs
new file mode 100644
index 00000000000..701d6b1ab71
--- /dev/null
+++ b/tests/mir-opt/building/custom/composite_return.rs
@@ -0,0 +1,21 @@
+#![feature(custom_mir, core_intrinsics)]
+
+extern crate core;
+use core::intrinsics::mir::*;
+
+// EMIT_MIR composite_return.tuple.built.after.mir
+#[custom_mir(dialect = "runtime", phase = "optimized")]
+fn tuple() -> (i32, bool) {
+    mir!(
+        type RET = (i32, bool);
+        {
+            RET.0 = 1;
+            RET.1 = true;
+            Return()
+        }
+    )
+}
+
+fn main() {
+    assert_eq!(tuple(), (1, true));
+}
diff --git a/tests/mir-opt/building/custom/composite_return.tuple.built.after.mir b/tests/mir-opt/building/custom/composite_return.tuple.built.after.mir
new file mode 100644
index 00000000000..d159c1a655e
--- /dev/null
+++ b/tests/mir-opt/building/custom/composite_return.tuple.built.after.mir
@@ -0,0 +1,11 @@
+// MIR for `tuple` after built
+
+fn tuple() -> (i32, bool) {
+    let mut _0: (i32, bool);             // return place in scope 0 at $DIR/composite_return.rs:+0:15: +0:26
+
+    bb0: {
+        (_0.0: i32) = const 1_i32;       // scope 0 at $DIR/composite_return.rs:+4:13: +4:22
+        (_0.1: bool) = const true;       // scope 0 at $DIR/composite_return.rs:+5:13: +5:25
+        return;                          // scope 0 at $DIR/composite_return.rs:+6:13: +6:21
+    }
+}