Skip to content

Commit 9545ab8

Browse files
authoredMar 22, 2023
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```
2 parents 56959e5 + 9dc275b commit 9545ab8

File tree

3 files changed

+48
-1
lines changed

3 files changed

+48
-1
lines changed
 

‎library/core/src/intrinsics/mir.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
//!
5050
//! The input to the [`mir!`] macro is:
5151
//!
52+
//! - An optional return type annotation in the form of `type RET = ...;`. This may be required
53+
//! if the compiler cannot infer the type of RET.
5254
//! - A possibly empty list of local declarations. Locals can also be declared inline on
5355
//! assignments via `let`. Type inference generally works. Shadowing does not.
5456
//! - A list of basic blocks. The first of these is the start block and is where execution begins.
@@ -124,6 +126,18 @@
124126
//! }
125127
//! )
126128
//! }
129+
//!
130+
//! #[custom_mir(dialect = "runtime", phase = "optimized")]
131+
//! fn annotated_return_type() -> (i32, bool) {
132+
//! mir!(
133+
//! type RET = (i32, bool);
134+
//! {
135+
//! RET.0 = 1;
136+
//! RET.1 = true;
137+
//! Return()
138+
//! }
139+
//! )
140+
//! }
127141
//! ```
128142
//!
129143
//! We can also set off compilation failures that happen in sufficiently late stages of the
@@ -342,6 +356,7 @@ define!(
342356
#[rustc_macro_transparency = "transparent"]
343357
pub macro mir {
344358
(
359+
$(type RET = $ret_ty:ty ;)?
345360
$(let $local_decl:ident $(: $local_decl_ty:ty)? ;)*
346361

347362
{
@@ -362,7 +377,7 @@ pub macro mir {
362377
{
363378
// Now all locals
364379
#[allow(non_snake_case)]
365-
let RET;
380+
let RET $(: $ret_ty)?;
366381
$(
367382
let $local_decl $(: $local_decl_ty)? ;
368383
)*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#![feature(custom_mir, core_intrinsics)]
2+
3+
extern crate core;
4+
use core::intrinsics::mir::*;
5+
6+
// EMIT_MIR composite_return.tuple.built.after.mir
7+
#[custom_mir(dialect = "runtime", phase = "optimized")]
8+
fn tuple() -> (i32, bool) {
9+
mir!(
10+
type RET = (i32, bool);
11+
{
12+
RET.0 = 1;
13+
RET.1 = true;
14+
Return()
15+
}
16+
)
17+
}
18+
19+
fn main() {
20+
assert_eq!(tuple(), (1, true));
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// MIR for `tuple` after built
2+
3+
fn tuple() -> (i32, bool) {
4+
let mut _0: (i32, bool); // return place in scope 0 at $DIR/composite_return.rs:+0:15: +0:26
5+
6+
bb0: {
7+
(_0.0: i32) = const 1_i32; // scope 0 at $DIR/composite_return.rs:+4:13: +4:22
8+
(_0.1: bool) = const true; // scope 0 at $DIR/composite_return.rs:+5:13: +5:25
9+
return; // scope 0 at $DIR/composite_return.rs:+6:13: +6:21
10+
}
11+
}

0 commit comments

Comments
 (0)
Please sign in to comment.