about summary refs log tree commit diff
path: root/tests/mir-opt/building/custom
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-03-22 20:08:01 +0100
committerGitHub <noreply@github.com>2023-03-22 20:08:01 +0100
commit9545ab8e129e0b93baff2a4bfb01f2ce34bea099 (patch)
treec70fa7e8cd332c271842939b3fac1ae219d71d64 /tests/mir-opt/building/custom
parent56959e5fe33d7e6846aaef544fca8ab548ae733e (diff)
parent9dc275bb54ab088ac85a08dc807984afd57a78c7 (diff)
downloadrust-9545ab8e129e0b93baff2a4bfb01f2ce34bea099.tar.gz
rust-9545ab8e129e0b93baff2a4bfb01f2ce34bea099.zip
Rollup merge of #109392 - cbeuw:composite-ret, r=JakobDegen
Custom MIR: Allow optional RET type annotation

This currently doesn't compile because the type of `RET` is inferred, which fails if RET is a composite type and fields are initialised separately.
```rust
#![feature(custom_mir, core_intrinsics)]
extern crate core;
use core::intrinsics::mir::*;
#[custom_mir(dialect = "runtime", phase = "optimized")]
fn fn0() -> (i32, bool) {
    mir! ({
        RET.0 = 0;
        RET.1 = true;
        Return()
    })
}
```
```
error[E0282]: type annotations needed
 --> src/lib.rs:8:9
  |
8 |         RET.0 = 0;
  |         ^^^ cannot infer type

For more information about this error, try `rustc --explain E0282`.
```

This PR allows the user to manually specify the return type with `type RET = ...;` if required:

```rust
#[custom_mir(dialect = "runtime", phase = "optimized")]
fn fn0() -> (i32, bool) {
    mir! (
        type RET = (i32, bool);
        {
            RET.0 = 0;
            RET.1 = true;
            Return()
        }
    )
}
```

The syntax is not optimal, I'm happy to see other suggestions. Ideally I wanted it to be a normal type annotation like `let RET: ...;`, but this runs into the multiple parsing options error during macro expansion, as it can be parsed as a normal `let` declaration as well.

r? ```@oli-obk``` or ```@tmiasko``` or ```@JakobDegen```
Diffstat (limited to 'tests/mir-opt/building/custom')
-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
2 files changed, 32 insertions, 0 deletions
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
+    }
+}