Skip to content

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

Closed

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

  1. jonas-schievink commented on Aug 18, 2020

    @jonas-schievink
    Contributor

    Duplicate of #72002

  2. smarnach commented on Aug 18, 2020

    @smarnach
    ContributorAuthor

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

  3. jonas-schievink commented on Aug 18, 2020

    @jonas-schievink
    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?

  4. jonas-schievink commented on Aug 18, 2020

    @jonas-schievink
    Contributor

    Maybe #72280?

  5. smarnach commented on Aug 18, 2020

    @smarnach
    ContributorAuthor

    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

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