rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.34k stars 12.72k forks source link

Improve borrow checking error in cases where `+ use<>` could be used #130545

Closed tmandry closed 1 week ago

tmandry commented 1 month ago

I'm not sure if anyone has raised this, but maybe this error reporting could be improved to also say "consider adding + use<> rather than just complaining about an immutable borrow?


error[E0502]: cannot borrow `data` as mutable because it is also borrowed as immutable

 --> src/main.rs:6:5
  |
5 |     let mut i = indices(&data);
  |                         ----- immutable borrow occurs here
6 |     data.push(4);
  |     ^^^^^^^^^^^^ mutable borrow occurs here
7 |     i.next();
  |     - immutable borrow later used here

Instead,


error[E0502]: cannot borrow `data` as mutable because it is also borrowed as immutable

 --> src/main.rs:6:5
  |
5 |     let mut i = indices(&data);
  |                         ----- immutable borrow occurs here
6 |     data.push(4);
  |     ^^^^^^^^^^^^ mutable borrow occurs here
7 |     i.next();
  |     - immutable borrow later used here

10 | fn indices<T>(
11 |     slice: &[T],
12 | ) -> impl Iterator<Item = usize> + use<> {
  |                                     ----- `impl Trait` must mention all type parameters in scope in `use<...>`

Originally posted by @bsodmike in #125836

bsodmike commented 1 month ago

Thanks for picking this up :)

compiler-errors commented 1 month ago

@bsodmike: The link you shared is broken. Could you share the sample of code you provided?

compiler-errors commented 1 month ago

nvm, I manually extracted it out of gist:

#![allow(warnings)]

fn main() {
    let mut data = vec![1, 2, 3];
    let mut i = indices(&data);
    data.push(4);
    i.next();
}

fn indices<T>(
    slice: &[T],
) -> impl Iterator<Item = usize> {
    0 .. slice.len()
}
bsodmike commented 1 month ago

nvm, I manually extracted it out of gist:

#![allow(warnings)]

fn main() {
    let mut data = vec![1, 2, 3];
    let mut i = indices(&data);
    data.push(4);
    i.next();
}

fn indices<T>(
    slice: &[T],
) -> impl Iterator<Item = usize> {
    0 .. slice.len()
}

Sorry. The Rust playground is having a day off. Excellent!