Closed
Description
https://play.rust-lang.org/?gist=9f782298cc5b0f6cd557baef9e443096&version=nightly
fn blah(mut x: String) {
do_something(&mut x);
}
generates the following MIR:
let mut _0: (); // return pointer
let mut _2: ();
let mut _3: &mut std::string::String;
let mut _4: &mut std::string::String;
bb0: {
StorageLive(_3); // scope 0 at src/main.rs:5:18: 5:24
StorageLive(_4); // scope 0 at src/main.rs:5:18: 5:24
_4 = &mut _1; // scope 0 at src/main.rs:5:18: 5:24
_3 = _4; // scope 0 at src/main.rs:5:18: 5:24
_2 = const do_something(move _3) -> [return: bb1, unwind: bb3]; // scope 0 at src/main.rs:5:5: 5:25
}
Which -- though we don't run it again after optimizations -- wouldn't pass TypeckMir
since it's a copy of a &mut String
.
That came from InstCombine on the following
_3 = &mut (*_4); // scope 0 at lib.rs:33:18: 33:24
This may or may not be a problem, but I wanted to file it in case it impacts any of the assumptions desired from the Copy/Move split on Operand.
Edit: I suppose this instcombine has long potentially changed the type of the operand, since it doesn't check mutability of the outer &
or the borrow being *
d.
cc @eddyb