Skip to content

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

New issue

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

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

Already on GitHub? # to your account

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).

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

No branches or pull requests

3 participants