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

Poor error message when the LHS of an assignment must be dereferenced #46276

Closed
ghost opened this issue Nov 26, 2017 · 2 comments · Fixed by #94639
Closed

Poor error message when the LHS of an assignment must be dereferenced #46276

ghost opened this issue Nov 26, 2017 · 2 comments · Fixed by #94639
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-inference Area: Type inference C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-diagnostics Working group: Diagnostics

Comments

@ghost
Copy link

ghost commented Nov 26, 2017

Code (also available on playground):

use std::sync::Mutex;

fn main() {
    let a = Mutex::new(7);
    let mut a = a.lock().unwrap();
    a += 1;
}

Error:

error[E0368]: binary assignment operation `+=` cannot be applied to type `std::sync::MutexGuard<'_, {integer}>`
 --> src/main.rs:6:5
  |
6 |     a += 1;
  |     -^^^^^
  |     |
  |     cannot use `+=` on type `std::sync::MutexGuard<'_, {integer}>`

Okay, but why cannot += be applied to Mutexuard<'_, {integer}>? And what can we do about it? :)

I'd prefer if the error message included something like:

help: consider dereferencing the left-hand side: `*a += 1`

Such a help message could be printed whenever the LHS of an assignment must be dereferenced. The same applies to situations in which we must dereference more than once, e.g **a.

@kennytm kennytm added A-diagnostics Area: Messages for errors, warnings, and lints A-inference Area: Type inference C-enhancement Category: An issue proposing an enhancement or a PR with one. labels Nov 26, 2017
@estebank estebank added E-needs-mentor WG-diagnostics Working group: Diagnostics labels Dec 7, 2017
@nyanpasu64
Copy link
Contributor

I encountered a similar issue with terrible error messages. While my case (&mut) was resolved in Rust 1.37.0, OP's test code (MutexGuard) is not resolved.

When I first started learning Rust, I had written code similar to this:

fn f(items: &mut [i16]) {
    for item in items.iter_mut() {
        item = 1;
    }
}

For my original code, the error is now much better (testing in the Rust Playground). The error was apparently fixed in 1e3302d#diff-f6d957f8a5563c729f40e971cc767981 (1.37.0)? Now the error I get is:

error[E0308]: mismatched types
 --> src/lib.rs:3:16
  |
3 |         item = 1;
  |                ^ expected &mut i16, found integer
  |
  = note: expected type `&mut i16`
             found type `{integer}`
help: consider dereferencing here to assign to the mutable borrowed piece of memory
  |
3 |         *item = 1;
  |         ^^^^^

If I switch it to +=, I get:

error[E0368]: binary assignment operation `+=` cannot be applied to type `&mut i16`
 --> src/lib.rs:3:9
  |
3 |         item += 1;
  |         ----^^^^^
  |         |
  |         cannot use `+=` on type `&mut i16`
help: `+=` can be used on 'i16', you can dereference `item`
  |
3 |         *item += 1;
  |         ^^^^^

This message is actually different from the = case. The test case for this message has existed since 2018 or before.


However, OP's case does not work.

error[E0368]: binary assignment operation `+=` cannot be applied to type `std::sync::MutexGuard<'_, {integer}>`
 --> src/main.rs:6:5
  |
6 |     a += 1;
  |     -^^^^^
  |     |
  |     cannot use `+=` on type `std::sync::MutexGuard<'_, {integer}>`
  |
  = note: an implementation of `std::ops::AddAssign` might be missing for `std::sync::MutexGuard<'_, {integer}>`

If I replace += with =, the error is still not meaningful:

error[E0308]: mismatched types
 --> src/main.rs:6:9
  |
6 |     a = 1;
  |         ^ expected struct `std::sync::MutexGuard`, found integer
  |
  = note: expected type `std::sync::MutexGuard<'_, {integer}>`
             found type `{integer}`

If I replace 7 with 7i32, the error is still bad:

error[E0308]: mismatched types
 --> src/main.rs:6:9
  |
6 |     a = 1;
  |         ^ expected struct `std::sync::MutexGuard`, found integer
  |
  = note: expected type `std::sync::MutexGuard<'_, i32>`
             found type `{integer}`

Apparently this bug is not solved for DerefMut types, producing bad errors on both = and +=. I implemented one such type in the playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=d6ade7f9654c41dd867ff72df8519519

@nkaretnikov
Copy link

Similar issue:

use std::sync::Mutex;

fn main() {
    let m = Mutex::new(42);
    
    let x = m.lock().unwrap();

    // println!("{}", *x - 1);
    println!("{}", x - 1);
    
    /*
    error[E0369]: cannot substract `{integer}` from `std::sync::MutexGuard<'_, {integer}>`
 --> src/main.rs:9:22
  |
9 |     println!("{}", x - 1);
  |                    - ^ - {integer}
  |                    |
  |                    std::sync::MutexGuard<'_, {integer}>
  |
  = note: an implementation of `std::ops::Sub` might be missing for `std::sync::MutexGuard<'_, {integer}>`
    */
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-inference Area: Type inference C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-diagnostics Working group: Diagnostics
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants