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

DerefMut borrow method call is too long with Deref arguments #57376

Open
tirr-c opened this issue Jan 6, 2019 · 3 comments
Open

DerefMut borrow method call is too long with Deref arguments #57376

tirr-c opened this issue Jan 6, 2019 · 3 comments
Labels
A-NLL Area: Non-lexical lifetimes (NLL) NLL-complete Working towards the "valid code works" goal P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@tirr-c
Copy link
Contributor

tirr-c commented Jan 6, 2019

Currently with Rust 2018, this code does not compile.

fn main() {
    let mut v = vec![1, 2, 3];
    v.swap(0, v.len() - 1);
    assert_eq!(v, &[3, 2, 1]);
}
error[E0502]: cannot borrow `v` as immutable because it is also borrowed as mutable
  |
3 |     v.swap(0, v.len() - 1);
  |     - ----    ^ immutable borrow occurs here
  |     | |
  |     | mutable borrow later used by call
  |     mutable borrow occurs here

It seems that the compiler desugars the method call like this:

let v0 = &*v;
let v1 = &mut *v;
let arg0 = 0;
let arg1 = v0.len() - 1; // v1 is still alive here
v1.swap(arg0, arg1);

But I think the DerefMut should be deferred, or use only DerefMut reference without any Deref.

let v0 = &*v;
let arg0 = 0;
let arg1 = v0.len() - 1; // no mutable borrows here

let v1 = &mut *v;
v1.swap(arg0, arg1);
let v0 = &mut *v;
let arg0 = 0;
let arg1 = v0.len() - 1;
v0.swap(arg0, arg1);
@jonas-schievink
Copy link
Contributor

jonas-schievink commented Jan 26, 2019

cc #49434

(specifically this comment seems to have found the same problem already: #49434 (comment))

@jonas-schievink jonas-schievink added the A-NLL Area: Non-lexical lifetimes (NLL) label Jan 26, 2019
@pnkfelix pnkfelix added the NLL-complete Working towards the "valid code works" goal label Jan 30, 2019
@pnkfelix
Copy link
Member

pnkfelix commented Mar 6, 2019

NLL triage. Tagging as P-medium, just like #49434.

@pnkfelix pnkfelix added P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 6, 2019
@ChayimFriedman2
Copy link
Contributor

The DerefMut cannot be deferred because we guarantee that the receiver is evaluated before the other operands.

What we can do is to generalize two phase borrows (or just defer the deref) when the deref is pure. I know project-deref-patterns are considering introducing a DerefPure trait, so it may be useful here too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-NLL Area: Non-lexical lifetimes (NLL) NLL-complete Working towards the "valid code works" goal P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants