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

Two-phase borrows don't allow mutably splitting an array based on its length #53723

Open
shepmaster opened this issue Aug 26, 2018 · 7 comments
Labels
A-array Area: `[T; N]` 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

@shepmaster
Copy link
Member

#![feature(nll)]
fn main() {
    let mut x = [1, 2];
    x.split_at_mut(x.len() / 2);
}
error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
 --> src/main.rs:4:20
  |
4 |     x.split_at_mut(x.len() / 2);
  |     ---------------^-----------
  |     |              |
  |     |              immutable borrow occurs here
  |     mutable borrow occurs here
  |     borrow later used here

1.30.0-nightly (2018-08-24 d41f21f)

/cc @nikomatsakis @pnkfelix

@shepmaster shepmaster added the A-NLL Area: Non-lexical lifetimes (NLL) label Aug 26, 2018
@nikomatsakis nikomatsakis added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-compiler-nll labels Aug 26, 2018
@nikomatsakis nikomatsakis added this to the Edition RC 2 milestone Aug 26, 2018
@nikomatsakis nikomatsakis removed this from the Edition RC 2 milestone Aug 26, 2018
@nikomatsakis
Copy link
Contributor

Nominating for triage.

@eddyb
Copy link
Member

eddyb commented Aug 27, 2018

This has to do with two-phase not affecting auto-slicing, if we pre-slice it works:

#![feature(nll)]
fn main() {
    let x = &mut [1, 2][..];
    x.split_at_mut(x.len() / 2);
}

Whereas the original example compiles & checks like this:

#![feature(nll)]
fn main() {
    let mut x = [1, 2];
    (&mut x as &mut [_]).split_at_mut((&mut x as &mut [_]).len() / 2);
}

@nikomatsakis
Copy link
Contributor

@eddyb yes, that was my suspicion, though I realize now that there won't be an easy fix, since we need the auto-slicing to convert from [u32; 2] type to [u32]. (I was hoping that this was a result of adding some redundant &mut * that we could omit.)

@nikomatsakis
Copy link
Contributor

I think this is likely a "won't fix" -- but we should accumulate examples where 2PB fails to live up to its promises (and I would count this among them).

@pnkfelix
Copy link
Member

pnkfelix commented Aug 28, 2018

Seasoned Rust hackers are probably already aware of this, but here's another way to get the effect described by @eddyb which may be more in line typical code in the wild. (Namely, add a type annotation to force the auto-slice to occur earlier.)

#![feature(nll)]
fn main() {
    let x: &mut [u32] = &mut [1, 2];
    x.split_at_mut(x.len() / 2);
}

@nikomatsakis
Copy link
Contributor

We discussed expanding two-phase borrows in our weekly meeting on Tuesday and ultimately settled on "not right now but maybe later", so I'm marking this as deferred.

@pnkfelix
Copy link
Member

Re-triaging for #56754. NLL-complete. P-medium. CC #49434

@pnkfelix pnkfelix added P-medium Medium priority and removed NLL-deferred labels Dec 19, 2018
@matthewjasper matthewjasper added the NLL-complete Working towards the "valid code works" goal label Jan 19, 2019
@workingjubilee workingjubilee added the A-array Area: `[T; N]` label Mar 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-array Area: `[T; N]` 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

6 participants