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

v[v.len()-1] not accepted by borrow checker #105678

Closed
Danvil opened this issue Dec 14, 2022 · 2 comments
Closed

v[v.len()-1] not accepted by borrow checker #105678

Danvil opened this issue Dec 14, 2022 · 2 comments
Labels
C-bug Category: This is a bug.

Comments

@Danvil
Copy link
Contributor

Danvil commented Dec 14, 2022

I tried this code:

let mut v = vec![1,2,3];
v[v.len()-1] = 5;

and expected it to compile, but the borrow checker does not accept it.

This looks like a bug, because the following similar code works thanks to two-phase borrow:

use std::ops::IndexMut;
let mut v = vec![1,2,3];
*v.index_mut(v.len() - 1) = 5;

Another case which works fine:

let mut v = vec![1,2,3];
v.push(v.len());
@Danvil Danvil added the C-bug Category: This is a bug. label Dec 14, 2022
@guchengxi1994
Copy link

let mut v = vec![1,2,3];
let v_len = v.len() -1;
v[v_len] = 5;
println!("{:?}",v)

this works fine.
image

@pnkfelix
Copy link
Member

pnkfelix commented Dec 14, 2022

This is a duplicate of #74319 #58419.

We deliberately made a (conservative) choice to not apply two-phase borrow in the v[...] = ... scenario today:

// Deref/indexing can be desugared to a method call,
// so maybe we could use two-phase here.
// See the documentation of AllowTwoPhase for why that's
// not the case today.
allow_two_phase_borrow: AllowTwoPhase::No,

as documented here:

/// At least for initial deployment, we want to limit two-phase borrows to
/// only a few specific cases. Right now, those are mostly "things that desugar"
/// into method calls:
/// - using `x.some_method()` syntax, where some_method takes `&mut self`,
/// - using `Foo::some_method(&mut x, ...)` syntax,
/// - binary assignment operators (`+=`, `-=`, `*=`, etc.).
/// Anything else should be rejected until generalized two-phase borrow support
/// is implemented. Right now, dataflow can't handle the general case where there
/// is more than one use of a mutable borrow, and we don't want to accept too much
/// new code via two-phase borrows, so we try to limit where we create two-phase
/// capable mutable borrows.
/// See #49434 for tracking.
#[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)]
pub enum AllowTwoPhase {
Yes,
No,
}

Closing as duplicate of #74319 #58419 (I'll post some more thoughts there though while this is on my mind).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

3 participants