Code change:
This code has UB under Stacked Borrows in Miri, but is fine with , and it should print However, under and above, it prints : cc
Here's a pure-surface Rust reproduction
any guess which MIR opt might be the culprit here?
Even more minimized reproducer: My first guess would be that some MIR analysis assumes that means that no pointer to can exist any more -- with Stacked Borrows that was true, but not with Tree Borrows. I usually push back against making Stacked Borrows assumptions in optimizations but looks like something slipped through? Cc
Even stranger, with Rust 1.69 we get . This goes back all the way to ; before that, we didn't have . Only beta and nightly without optimizations seem to do this correctly.
Does this look like the bad optimization?
yes, very much so. Specifically the is wrong, the rest then follows from that. Did ConstProp never learn that locals that have their address taken cannot be propagated?
I'm about to be busy for a few hours, so if someone else wants to bisect what changed with they should do that. I'll check back later.
I've been suspecting such a bug without managing to reproduce it for a few months. The bug is in the visitor, which mistreats place context. I can make a targeted fix in the hour.
I'm curious, how did you come up with this example?
I'm making a fuzzer targeting custom MIR :D It's still quite incomplete and currently hosted on an ETH Zürich private GitLab instance I guess I should make a public mirror on GitHub soon...
That is awesome! This is exactly the kind of stuff I was hoping to find with one.
Ah so should we report these? I think I read somewhere that custom mir is likely to get wrong and would always cause crashes then or something which is why I have ignored all of the / ICEs that I came across.
This isn't an ICE, this is a change in behavior due to enabling an optimization.
ah right sorry, I was confused with

Related discussion:
text: <ins> - // MIR for `fn0` before ConstProp + // MIR for `fn0` after ConstProp fn fn0() -> bool { let mut _0: bool;                    // return place in scope 0 at $DIR/address_of_pair.rs:+0:17: +0:21 let mut _1: !;                       // in scope 0 at $DIR/address_of_pair.rs:+0:22: +9:2 let mut _2: (i32, bool);             // in scope 0 at $DIR/address_of_pair.rs:+1:9: +1:17 let _4: ();                          // in scope 0 at $DIR/address_of_pair.rs:+4:5: +6:6 let mut _6: bool;                    // in scope 0 at $DIR/address_of_pair.rs:+7:16: +7:22 scope 1 { debug pair => _2;                // in scope 1 at $DIR/address_of_pair.rs:+1:9: +1:17 let _3: *mut bool;               // in scope 1 at $DIR/address_of_pair.rs:+2:9: +2:12 scope 2 { debug ptr => _3;             // in scope 2 at $DIR/address_of_pair.rs:+2:9: +2:12 let _5: bool;                // in scope 2 at $DIR/address_of_pair.rs:+7:9: +7:12 scope 3 { } scope 4 { debug ret => _5;         // in scope 4 at $DIR/address_of_pair.rs:+7:9: +7:12 } } } bb0: { StorageLive(_2);                 // scope 0 at $DIR/address_of_pair.rs:+1:9: +1:17 _2 = (const 1_i32, const false); // scope 0 at $DIR/address_of_pair.rs:+1:20: +1:30 StorageLive(_3);                 // scope 1 at $DIR/address_of_pair.rs:+2:9: +2:12 _3 = &raw mut (_2.1: bool);      // scope 1 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL _2 = (const 1_i32, const false); // scope 2 at $DIR/address_of_pair.rs:+3:5: +3:22 StorageLive(_4);                 // scope 2 at $DIR/address_of_pair.rs:+4:5: +6:6 (*_3) = const true;              // scope 3 at $DIR/address_of_pair.rs:+5:9: +5:20 _4 = const ();                   // scope 3 at $DIR/address_of_pair.rs:+4:5: +6:6 StorageDead(_4);                 // scope 2 at $DIR/address_of_pair.rs:+6:5: +6:6 StorageLive(_5);                 // scope 2 at $DIR/address_of_pair.rs:+7:9: +7:12 StorageLive(_6);                 // scope 2 at $DIR/address_of_pair.rs:+7:16: +7:22 _6 = (_2.1: bool);               // scope 2 at $DIR/address_of_pair.rs:+7:16: +7:22 _5 = Not(move _6);               // scope 2 at $DIR/address_of_pair.rs:+7:15: +7:22 StorageDead(_6);                 // scope 2 at $DIR/address_of_pair.rs:+7:21: +7:22 _0 = _5;                         // scope 4 at $DIR/address_of_pair.rs:+8:12: +8:15 StorageDead(_5);                 // scope 2 at $DIR/address_of_pair.rs:+9:1: +9:2 StorageDead(_3);                 // scope 1 at $DIR/address_of_pair.rs:+9:1: +9:2 StorageDead(_2);                 // scope 0 at $DIR/address_of_pair.rs:+9:1: +9:2 return;                          // scope 0 at $DIR/address_of_pair.rs:+9:2: +9:2 } } </ins>