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

Index chosen over IndexMut incorrectly, with a confusing error message. #75680

Closed
smarnach opened this issue Aug 18, 2020 · 5 comments
Closed
Labels
C-bug Category: This is a bug.

Comments

@smarnach
Copy link
Contributor

Retrieving an element from a vector of mutable references works fine calling index_mut() directly

use std::ops::IndexMut;

fn explicit_trait_call(mut a: Vec<&mut i32>) {
    let _i: &mut i32 = *a.index_mut(0);
}

but fails when using supposedly equivalent indexing syntax:

fn indexing(mut a: Vec<&mut i32>) {
    let _i: &mut i32 = a[0];
}

(Playground)

The error message is rather surprising:

error[E0596]: cannot borrow data in an index of `std::vec::Vec<&mut i32>` as mutable
 --> src/lib.rs:4:24
  |
4 |     let _i: &mut i32 = a[0];
  |                        ^^^^ cannot borrow as mutable
  |
  = help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `std::vec::Vec<&mut i32>`

It's clearly not true that IndexMut is not implemented for Vec, as evidenced by the first implementation.

The explicit trait call version only works because the explicit type annotation for _i triggers an implicit reborrow. My gut feeling is that the compiler is selecting Index instead of IndexMut here since the assignment looks like a move when not taking into account the implicit reborrow. I feel that the rejected code should be accepted. In any case, the error message should be fixed.

This post was inspired by a question of StackOverflow today, and I discussed this on the user forum as well.

@smarnach smarnach added the C-bug Category: This is a bug. label Aug 18, 2020
@jonas-schievink
Copy link
Contributor

Duplicate of #72002

@jonas-schievink jonas-schievink marked this as a duplicate of #72002 Aug 18, 2020
@smarnach
Copy link
Contributor Author

@jonas-schievink I looked at that issue before filing this bug, but came to the conclusion this is separate. The problem with the error message is the same, but the reason that Index is chosen instead of IndexMut is a different one. (I should have linked the other issue here.)

@jonas-schievink
Copy link
Contributor

Hmm, right, this still doesn't work on stable, but #72068 is on stable. Any idea what might have fixed your example on beta/nightly?

@jonas-schievink
Copy link
Contributor

Maybe #72280?

@smarnach
Copy link
Contributor Author

Huh, I didn't realize it's fixed on beta and nightly! And no, I don't know why.

On the one hand, it convinces me that this actually isn't a dupe of the linked issue, because the code in that issue is already fixed on stable. On the other hand, it doesn't really matter anymore. :)

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

2 participants