Skip to content

MIR InstCombine introduces copies of mutable borrows #46420

Closed
@scottmcm

Description

@scottmcm

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlA-borrow-checkerArea: The borrow checkerC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions