I generated the MIR of the following code:
pub fn foo(x: (String, String)) {
let _closure = || {
if std::hint::black_box(true) {
let _a = &x.1;
} else {
let _b = x.0;
}
};
}
I got the following MIR:
MIR
// WARNING: This output format is intended for human consumers only
// and is subject to change without notice. Knock yourself out.
// HINT: See also -Z dump-mir for MIR at specific points during compilation.
fn foo(_1: (String, String)) -> () {
debug x => _1;
let mut _0: ();
let _2: {closure@src/lib.rs:2:20: 2:22};
let mut _3: &std::string::String;
scope 1 {
debug _closure => _2;
}
bb0: {
_3 = &(_1.1: std::string::String);
_2 = {closure@src/lib.rs:2:20: 2:22} { x: move (_1.0: std::string::String) };
drop(_2) -> [return: bb1, unwind: bb4];
}
bb1: {
drop((_1.1: std::string::String)) -> [return: bb3, unwind continue];
}
bb2 (cleanup): {
resume;
}
bb3: {
return;
}
bb4 (cleanup): {
drop((_1.1: std::string::String)) -> [return: bb2, unwind terminate(cleanup)];
}
}
fn foo::{closure#0}(_1: {closure@src/lib.rs:2:20: 2:22}) -> () {
debug x__0 => (_1.0: std::string::String);
debug x__1 => (*(_1.1: &std::string::String));
let mut _0: ();
let mut _2: bool;
let _3: std::string::String;
let mut _4: &std::string::String;
let mut _5: bool;
scope 1 {
debug _a => _4;
}
scope 2 {
debug _b => _3;
}
bb0: {
_5 = const false;
_5 = const true;
_2 = std::hint::black_box::<bool>(const true) -> [return: bb1, unwind: bb9];
}
bb1: {
switchInt(move _2) -> [0: bb3, otherwise: bb2];
}
bb2: {
_4 = copy (_1.1: &std::string::String);
goto -> bb4;
}
bb3: {
_5 = const false;
_3 = move (_1.0: std::string::String);
drop(_3) -> [return: bb4, unwind: bb9];
}
bb4: {
switchInt(copy _5) -> [0: bb6, otherwise: bb7];
}
bb5 (cleanup): {
resume;
}
bb6: {
return;
}
bb7: {
drop((_1.0: std::string::String)) -> [return: bb6, unwind continue];
}
bb8 (cleanup): {
drop((_1.0: std::string::String)) -> [return: bb5, unwind terminate(cleanup)];
}
bb9 (cleanup): {
switchInt(copy _5) -> [0: bb5, otherwise: bb8];
}
}
Notably, here's the code that constructs the closure:
_3 = &(_1.1: std::string::String);
_2 = {closure@src/lib.rs:2:20: 2:22} { x: move (_1.0: std::string::String) };
drop(_2) -> [return: bb1, unwind: bb4];
I think that the MIR printing is printing only the closure capture for one of the fields, instead of both.
Meta
Reproducible on the playground with the "show MIR" option with version 1.96.0-nightly (2026-03-12 3102493c71626b5912d1)
I generated the MIR of the following code:
I got the following MIR:
MIR
Notably, here's the code that constructs the closure:
I think that the MIR printing is printing only the closure capture for one of the fields, instead of both.
Meta
Reproducible on the playground with the "show MIR" option with version
1.96.0-nightly (2026-03-12 3102493c71626b5912d1)