Skip to content

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

Description

@smarnach

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions