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

borrowck diagnostics: suggest borrowing function inputs in generic positions #132172

Merged
merged 3 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
368 changes: 186 additions & 182 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ note: closure cannot be moved more than once as it is not `Copy` due to moving t
|
LL | if let MultiVariant::Point(ref mut x, _) = point {
| ^^^^^
help: consider mutably borrowing `c`
|
LL | let a = &mut c;
| ++++

error: aborting due to 1 previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ note: closure cannot be moved more than once as it is not `Copy` due to moving t
|
LL | let SingleVariant::Point(ref mut x, _) = point;
| ^^^^^
help: consider mutably borrowing `c`
|
LL | let b = &mut c;
| ++++

error: aborting due to 1 previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ note: closure cannot be moved more than once as it is not `Copy` due to moving t
|
LL | x.y.a += 1;
| ^^^^^
help: consider mutably borrowing `hello`
|
LL | let b = &mut hello;
| ++++

error: aborting due to 1 previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ note: closure cannot be moved more than once as it is not `Copy` due to moving t
|
LL | x.0 += 1;
| ^^^
help: consider mutably borrowing `hello`
|
LL | let b = &mut hello;
| ++++

error: aborting due to 1 previous error

Expand Down
20 changes: 20 additions & 0 deletions tests/ui/moves/auxiliary/suggest-borrow-for-generic-arg-aux.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//! auxiliary definitons for suggest-borrow-for-generic-arg.rs, to ensure the suggestion works on
//! functions defined in other crates.

use std::io::{self, Read, Write};
use std::iter::Sum;

pub fn write_stuff<W: Write>(mut writer: W) -> io::Result<()> {
writeln!(writer, "stuff")
}

pub fn read_and_discard<R: Read>(mut reader: R) -> io::Result<()> {
let mut buf = Vec::new();
reader.read_to_end(&mut buf).map(|_| ())
}

pub fn sum_three<I: IntoIterator>(iter: I) -> <I as IntoIterator>::Item
where <I as IntoIterator>::Item: Sum
{
iter.into_iter().take(3).sum()
}
2 changes: 1 addition & 1 deletion tests/ui/moves/borrow-closures-instead-of-move.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
fn takes_fn(f: impl Fn()) { //~ HELP if `impl Fn()` implemented `Clone`
fn takes_fn(f: impl Fn()) {
loop {
takes_fnonce(f);
//~^ ERROR use of moved value
Expand Down
22 changes: 0 additions & 22 deletions tests/ui/moves/borrow-closures-instead-of-move.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,6 @@ LL | loop {
LL | takes_fnonce(f);
| ^ value moved here, in previous iteration of loop
|
note: consider changing this parameter type in function `takes_fnonce` to borrow instead if owning the value isn't necessary
--> $DIR/borrow-closures-instead-of-move.rs:34:20
|
LL | fn takes_fnonce(_: impl FnOnce()) {}
| ------------ ^^^^^^^^^^^^^ this parameter takes ownership of the value
| |
| in this function
help: if `impl Fn()` implemented `Clone`, you could clone the value
--> $DIR/borrow-closures-instead-of-move.rs:1:16
|
LL | fn takes_fn(f: impl Fn()) {
| ^^^^^^^^^ consider constraining this type parameter with `Clone`
LL | loop {
LL | takes_fnonce(f);
| - you could clone this value
help: consider borrowing `f`
|
LL | takes_fnonce(&f);
Expand All @@ -40,13 +25,6 @@ LL | takes_fnonce(m);
LL | takes_fnonce(m);
| ^ value used here after move
|
note: consider changing this parameter type in function `takes_fnonce` to borrow instead if owning the value isn't necessary
--> $DIR/borrow-closures-instead-of-move.rs:34:20
|
LL | fn takes_fnonce(_: impl FnOnce()) {}
| ------------ ^^^^^^^^^^^^^ this parameter takes ownership of the value
| |
| in this function
help: if `impl FnMut()` implemented `Clone`, you could clone the value
--> $DIR/borrow-closures-instead-of-move.rs:9:20
|
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/moves/moved-value-on-as-ref-arg.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ LL | foo(bar);
LL | let _baa = bar;
| ^^^ value used here after move
|
help: borrow the value to avoid moving it
help: consider borrowing `bar`
|
LL | foo(&bar);
| +
Expand All @@ -31,7 +31,7 @@ LL | struct Bar;
...
LL | qux(bar);
| --- you could clone this value
help: borrow the value to avoid moving it
help: consider mutably borrowing `bar`
|
LL | qux(&mut bar);
| ++++
Expand All @@ -46,7 +46,7 @@ LL | bat(bar);
LL | let _baa = bar;
| ^^^ value used here after move
|
help: borrow the value to avoid moving it
help: consider borrowing `bar`
|
LL | bat(&bar);
| +
Expand All @@ -69,7 +69,7 @@ LL | struct Bar;
...
LL | baz(bar);
| --- you could clone this value
help: borrow the value to avoid moving it
help: consider mutably borrowing `bar`
|
LL | baz(&mut bar);
| ++++
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ LL | fn conspirator<F>(mut f: F) where F: FnMut(&mut R, bool) {
| ^ consider constraining this type parameter with `Clone`
LL | let mut r = R {c: Box::new(f)};
| - you could clone this value
help: consider mutably borrowing `f`
|
LL | let mut r = R {c: Box::new(&mut f)};
| ++++

error: aborting due to 2 previous errors

Expand Down
46 changes: 46 additions & 0 deletions tests/ui/moves/suggest-borrow-for-generic-arg.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//! Test suggetions to borrow generic arguments instead of moving. Tests for other instances of this
//! can be found in `moved-value-on-as-ref-arg.rs` and `borrow-closures-instead-of-move.rs`
//@ run-rustfix
//@ aux-crate:aux=suggest-borrow-for-generic-arg-aux.rs
//@ edition: 2021

#![allow(unused_mut)]
use std::io::{self, Write};

// test for `std::io::Write` (#131413)
fn test_write() -> io::Result<()> {
let mut stdout = io::stdout();
aux::write_stuff(&stdout)?; //~ HELP consider borrowing `stdout`
writeln!(stdout, "second line")?; //~ ERROR borrow of moved value: `stdout`

let mut buf = Vec::new();
aux::write_stuff(&mut buf.clone())?; //~ HELP consider mutably borrowing `buf`
//~^ HELP consider cloning the value
writeln!(buf, "second_line") //~ ERROR borrow of moved value: `buf`
}

/// test for `std::io::Read` (#131413)
fn test_read() -> io::Result<()> {
let stdin = io::stdin();
aux::read_and_discard(&stdin)?; //~ HELP consider borrowing `stdin`
aux::read_and_discard(stdin)?; //~ ERROR use of moved value: `stdin`

let mut bytes = std::collections::VecDeque::from([1, 2, 3, 4, 5, 6]);
aux::read_and_discard(&mut bytes.clone())?; //~ HELP consider mutably borrowing `bytes`
//~^ HELP consider cloning the value
aux::read_and_discard(bytes) //~ ERROR use of moved value: `bytes`
}

/// test that suggestions work with projection types in the callee's signature
fn test_projections() {
let mut iter = [1, 2, 3, 4, 5, 6].into_iter();
let _six: usize = aux::sum_three(&mut iter.clone()); //~ HELP consider mutably borrowing `iter`
//~^ HELP consider cloning the value
let _fifteen: usize = aux::sum_three(iter); //~ ERROR use of moved value: `iter`
}

fn main() {
test_write().unwrap();
test_read().unwrap();
test_projections();
}
46 changes: 46 additions & 0 deletions tests/ui/moves/suggest-borrow-for-generic-arg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//! Test suggetions to borrow generic arguments instead of moving. Tests for other instances of this
//! can be found in `moved-value-on-as-ref-arg.rs` and `borrow-closures-instead-of-move.rs`
//@ run-rustfix
//@ aux-crate:aux=suggest-borrow-for-generic-arg-aux.rs
//@ edition: 2021

#![allow(unused_mut)]
use std::io::{self, Write};

// test for `std::io::Write` (#131413)
fn test_write() -> io::Result<()> {
let mut stdout = io::stdout();
aux::write_stuff(stdout)?; //~ HELP consider borrowing `stdout`
writeln!(stdout, "second line")?; //~ ERROR borrow of moved value: `stdout`

let mut buf = Vec::new();
aux::write_stuff(buf)?; //~ HELP consider mutably borrowing `buf`
//~^ HELP consider cloning the value
writeln!(buf, "second_line") //~ ERROR borrow of moved value: `buf`
}

/// test for `std::io::Read` (#131413)
fn test_read() -> io::Result<()> {
let stdin = io::stdin();
aux::read_and_discard(stdin)?; //~ HELP consider borrowing `stdin`
aux::read_and_discard(stdin)?; //~ ERROR use of moved value: `stdin`

let mut bytes = std::collections::VecDeque::from([1, 2, 3, 4, 5, 6]);
aux::read_and_discard(bytes)?; //~ HELP consider mutably borrowing `bytes`
//~^ HELP consider cloning the value
aux::read_and_discard(bytes) //~ ERROR use of moved value: `bytes`
}

/// test that suggestions work with projection types in the callee's signature
fn test_projections() {
let mut iter = [1, 2, 3, 4, 5, 6].into_iter();
let _six: usize = aux::sum_three(iter); //~ HELP consider mutably borrowing `iter`
//~^ HELP consider cloning the value
let _fifteen: usize = aux::sum_three(iter); //~ ERROR use of moved value: `iter`
}

fn main() {
test_write().unwrap();
test_read().unwrap();
test_projections();
}
93 changes: 93 additions & 0 deletions tests/ui/moves/suggest-borrow-for-generic-arg.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
error[E0382]: borrow of moved value: `stdout`
--> $DIR/suggest-borrow-for-generic-arg.rs:14:14
|
LL | let mut stdout = io::stdout();
| ---------- move occurs because `stdout` has type `Stdout`, which does not implement the `Copy` trait
LL | aux::write_stuff(stdout)?;
| ------ value moved here
LL | writeln!(stdout, "second line")?;
| ^^^^^^ value borrowed here after move
|
help: consider borrowing `stdout`
|
LL | aux::write_stuff(&stdout)?;
| +

error[E0382]: borrow of moved value: `buf`
--> $DIR/suggest-borrow-for-generic-arg.rs:19:14
|
LL | let mut buf = Vec::new();
| ------- move occurs because `buf` has type `Vec<u8>`, which does not implement the `Copy` trait
LL | aux::write_stuff(buf)?;
| --- value moved here
LL |
LL | writeln!(buf, "second_line")
| ^^^ value borrowed here after move
|
help: consider mutably borrowing `buf`
|
LL | aux::write_stuff(&mut buf)?;
| ++++
help: consider cloning the value if the performance cost is acceptable
|
LL | aux::write_stuff(buf.clone())?;
| ++++++++

error[E0382]: use of moved value: `stdin`
--> $DIR/suggest-borrow-for-generic-arg.rs:26:27
|
LL | let stdin = io::stdin();
| ----- move occurs because `stdin` has type `Stdin`, which does not implement the `Copy` trait
LL | aux::read_and_discard(stdin)?;
| ----- value moved here
LL | aux::read_and_discard(stdin)?;
| ^^^^^ value used here after move
|
help: consider borrowing `stdin`
|
LL | aux::read_and_discard(&stdin)?;
| +

error[E0382]: use of moved value: `bytes`
--> $DIR/suggest-borrow-for-generic-arg.rs:31:27
|
LL | let mut bytes = std::collections::VecDeque::from([1, 2, 3, 4, 5, 6]);
| --------- move occurs because `bytes` has type `VecDeque<u8>`, which does not implement the `Copy` trait
LL | aux::read_and_discard(bytes)?;
| ----- value moved here
LL |
LL | aux::read_and_discard(bytes)
| ^^^^^ value used here after move
|
help: consider mutably borrowing `bytes`
|
LL | aux::read_and_discard(&mut bytes)?;
| ++++
help: consider cloning the value if the performance cost is acceptable
|
LL | aux::read_and_discard(bytes.clone())?;
| ++++++++

error[E0382]: use of moved value: `iter`
--> $DIR/suggest-borrow-for-generic-arg.rs:39:42
|
LL | let mut iter = [1, 2, 3, 4, 5, 6].into_iter();
| -------- move occurs because `iter` has type `std::array::IntoIter<usize, 6>`, which does not implement the `Copy` trait
LL | let _six: usize = aux::sum_three(iter);
| ---- value moved here
LL |
LL | let _fifteen: usize = aux::sum_three(iter);
| ^^^^ value used here after move
|
help: consider mutably borrowing `iter`
|
LL | let _six: usize = aux::sum_three(&mut iter);
| ++++
help: consider cloning the value if the performance cost is acceptable
|
LL | let _six: usize = aux::sum_three(iter.clone());
| ++++++++

error: aborting due to 5 previous errors

For more information about this error, try `rustc --explain E0382`.
4 changes: 0 additions & 4 deletions tests/ui/not-copy-closure.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ note: closure cannot be moved more than once as it is not `Copy` due to moving t
|
LL | a += 1;
| ^
help: consider mutably borrowing `hello`
|
LL | let b = &mut hello;
| ++++

error: aborting due to 1 previous error

Expand Down
Loading