Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MIR InstCombine introduces copies of mutable borrows #46420

Closed
scottmcm opened this issue Dec 1, 2017 · 5 comments · Fixed by #72093
Closed

MIR InstCombine introduces copies of mutable borrows #46420

scottmcm opened this issue Dec 1, 2017 · 5 comments · Fixed by #72093
Labels
A-borrow-checker Area: The borrow checker A-mir Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@scottmcm
Copy link
Member

scottmcm commented Dec 1, 2017

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

@scottmcm scottmcm changed the title MIR InstCombine introduces copies of &mut String MIR InstCombine introduces copies of mutable borrows Dec 1, 2017
@eddyb
Copy link
Member

eddyb commented Dec 1, 2017

cc @nikomatsakis

@pietroalbini pietroalbini added A-borrow-checker Area: The borrow checker T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 23, 2018
@XAMPPRocky XAMPPRocky added the C-bug Category: This is a bug. label Feb 26, 2018
@oli-obk
Copy link
Contributor

oli-obk commented Mar 6, 2018

Is the solution to change &mut *_4 to move _4 and &*_4 to just _4?

@eddyb
Copy link
Member

eddyb commented Mar 6, 2018

@oli-obk You really don't want move semantics. I think copying is correct at those lower levels, even if the type doesn't implement Copy (you can consider it "an unsafe copy").

@nikomatsakis
Copy link
Contributor

I personally consider this at least potentially OK. My view has been that 'the thing we call MIR' is really at least two IRs -- maybe more! -- that are represented using one set of data structures, with different invariants:

When first constructed, we have MIR proper.

Then, after drop elaboration has completed, we have a lower-level IR. Plausibly, in this IR, the aliasing rules are weaker.

That said, we may want to keep the stricter rules, so that we can optimize more on that basis!

Regardless of all of that, it would be great to document the assumptions at each point (e.g., in the rustc-guide).

fpoli referenced this issue in facebookexperimental/MIRAI Dec 14, 2018
@jonas-schievink jonas-schievink added the A-mir Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html label May 13, 2020
@bors bors closed this as completed in cb272d5 May 26, 2020
@scottmcm
Copy link
Member Author

scottmcm commented Aug 3, 2020

This is now also fixed by #72820, which removed this fold in InstCombine

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-borrow-checker Area: The borrow checker A-mir Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants