Skip to content

Diagnostics for mutating non-DerefMut types are confusing #58864

Closed
@Manishearth

Description

@Manishearth
use std::rc::Rc;

fn main() {
    let mut x = Rc::new(vec![1,2,3,4]);
    x.push(5);
}

emits

warning: variable does not need to be mutable
 --> src/main.rs:5:9
  |
5 |     let mut x = Rc::new(vec![1,2,3,4]);
  |         ----^
  |         |
  |         help: remove this `mut`
  |
  = note: #[warn(unused_mut)] on by default

error[E0596]: cannot borrow data in a `&` reference as mutable
 --> src/main.rs:6:5
  |
6 |     x.push(5);
  |     ^ cannot borrow as mutable

error: aborting due to previous error

which is super confusing. Firstly, I have what appears to be two conflicting error messages. The second one tells me to make things mutable, and if I listen to it I get told that things don't need to be mutable. Secondly, the relevant error message (the second one) talks about & references which don't exist.

The actual issue here is that x is not DerefMut, of course. Which is obvious in this case, but that's not always true. I've often hit this error in other situations and I've basically learned to pattern match it to mean "something something DerefMut", but people seeing it for the first time typically don't.

We should explicitly make the diagnostics say something like "x is an Rc<T> which cannot be dereferenced mutably"

Metadata

Metadata

Assignees

Labels

A-borrow-checkerArea: The borrow checkerA-diagnosticsArea: Messages for errors, warnings, and lintsNLL-diagnosticsWorking towards the "diagnostic parity" goal

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions