Skip to content

Commit e46416e

Browse files
committed
Change pattern borrowing suggestions to be verbose
Synthesize a more accurate span and use verbose suggestion output to make the message clearer.
1 parent ed620cf commit e46416e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1309
-766
lines changed

Diff for: compiler/rustc_borrowck/src/diagnostics/move_errors.rs

+35-29
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_middle::ty;
44
use rustc_mir_dataflow::move_paths::{
55
IllegalMoveOrigin, IllegalMoveOriginKind, LookupResult, MoveError, MovePathIndex,
66
};
7-
use rustc_span::Span;
7+
use rustc_span::{BytePos, Span};
88

99
use crate::diagnostics::{DescribePlaceOpt, UseSpans};
1010
use crate::prefixes::PrefixSet;
@@ -148,7 +148,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
148148
match_span: Span,
149149
statement_span: Span,
150150
) {
151-
debug!("append_binding_error(match_place={:?}, match_span={:?})", match_place, match_span);
151+
debug!(?match_place, ?match_span, "append_binding_error");
152152

153153
let from_simple_let = match_place.is_none();
154154
let match_place = match_place.unwrap_or(move_from);
@@ -160,7 +160,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
160160
if let GroupedMoveError::MovesFromPlace { span, binds_to, .. } = ge
161161
&& match_span == *span
162162
{
163-
debug!("appending local({:?}) to list", bind_to);
163+
debug!("appending local({bind_to:?}) to list");
164164
if !binds_to.is_empty() {
165165
binds_to.push(bind_to);
166166
}
@@ -198,7 +198,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
198198
} = ge
199199
{
200200
if match_span == *span && mpi == *other_mpi {
201-
debug!("appending local({:?}) to list", bind_to);
201+
debug!("appending local({bind_to:?}) to list");
202202
binds_to.push(bind_to);
203203
return;
204204
}
@@ -410,14 +410,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
410410
fn add_move_hints(&self, error: GroupedMoveError<'tcx>, err: &mut Diagnostic, span: Span) {
411411
match error {
412412
GroupedMoveError::MovesFromPlace { mut binds_to, move_from, .. } => {
413-
if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
414-
err.span_suggestion(
415-
span,
416-
"consider borrowing here",
417-
format!("&{snippet}"),
418-
Applicability::Unspecified,
419-
);
420-
}
413+
err.span_suggestion_verbose(
414+
span.shrink_to_lo(),
415+
"consider borrowing here",
416+
"&".to_string(),
417+
Applicability::Unspecified,
418+
);
421419

422420
if binds_to.is_empty() {
423421
let place_ty = move_from.ty(self.body, self.infcx.tcx).ty;
@@ -469,28 +467,36 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
469467
VarBindingForm { pat_span, .. },
470468
)))) = bind_to.local_info
471469
{
472-
if let Ok(pat_snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(pat_span)
470+
let Ok(pat_snippet) =
471+
self.infcx.tcx.sess.source_map().span_to_snippet(pat_span) else { continue; };
472+
let Some(stripped) = pat_snippet.strip_prefix('&') else { continue; };
473+
let inner_pat_snippet = stripped.trim_start();
474+
let (pat_span, suggestion, to_remove) = if inner_pat_snippet.starts_with("mut")
475+
&& inner_pat_snippet["mut".len()..].starts_with(rustc_lexer::is_whitespace)
473476
{
474-
if let Some(stripped) = pat_snippet.strip_prefix('&') {
475-
let pat_snippet = stripped.trim_start();
476-
let (suggestion, to_remove) = if pat_snippet.starts_with("mut")
477-
&& pat_snippet["mut".len()..].starts_with(rustc_lexer::is_whitespace)
478-
{
479-
(pat_snippet["mut".len()..].trim_start(), "&mut")
480-
} else {
481-
(pat_snippet, "&")
482-
};
483-
suggestions.push((pat_span, to_remove, suggestion.to_owned()));
484-
}
485-
}
477+
let pat_span = pat_span.with_hi(
478+
pat_span.lo()
479+
+ BytePos((pat_snippet.len() - inner_pat_snippet.len()) as u32),
480+
);
481+
(pat_span, String::new(), "mutable borrow")
482+
} else {
483+
let pat_span = pat_span.with_hi(
484+
pat_span.lo()
485+
+ BytePos(
486+
(pat_snippet.len() - inner_pat_snippet.trim_start().len()) as u32,
487+
),
488+
);
489+
(pat_span, String::new(), "borrow")
490+
};
491+
suggestions.push((pat_span, to_remove, suggestion.to_owned()));
486492
}
487493
}
488494
suggestions.sort_unstable_by_key(|&(span, _, _)| span);
489495
suggestions.dedup_by_key(|&mut (span, _, _)| span);
490496
for (span, to_remove, suggestion) in suggestions {
491-
err.span_suggestion(
497+
err.span_suggestion_verbose(
492498
span,
493-
&format!("consider removing the `{to_remove}`"),
499+
&format!("consider removing the {to_remove}"),
494500
suggestion,
495501
Applicability::MachineApplicable,
496502
);
@@ -521,8 +527,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
521527

522528
if binds_to.len() > 1 {
523529
err.note(
524-
"move occurs because these variables have types that \
525-
don't implement the `Copy` trait",
530+
"move occurs because these variables have types that don't implement the `Copy` \
531+
trait",
526532
);
527533
}
528534
}

Diff for: src/test/ui/borrowck/access-mode-in-closures.stderr

+8-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@ error[E0507]: cannot move out of `s` which is behind a shared reference
33
|
44
LL | match *s { S(v) => v }
55
| ^^ -
6-
| | |
7-
| | data moved here
8-
| | move occurs because `v` has type `Vec<isize>`, which does not implement the `Copy` trait
9-
| help: consider borrowing here: `&*s`
6+
| |
7+
| data moved here
8+
| move occurs because `v` has type `Vec<isize>`, which does not implement the `Copy` trait
9+
|
10+
help: consider borrowing here
11+
|
12+
LL | match &*s { S(v) => v }
13+
| +
1014

1115
error: aborting due to previous error
1216

Diff for: src/test/ui/borrowck/borrowck-for-loop-correct-cmt-for-pattern.stderr

+30-15
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,46 @@ error[E0507]: cannot move out of a shared reference
22
--> $DIR/borrowck-for-loop-correct-cmt-for-pattern.rs:12:15
33
|
44
LL | for &a in x.iter() {
5-
| -- ^^^^^^^^
6-
| ||
7-
| |data moved here
8-
| |move occurs because `a` has type `&mut i32`, which does not implement the `Copy` trait
9-
| help: consider removing the `&`: `a`
5+
| - ^^^^^^^^
6+
| |
7+
| data moved here
8+
| move occurs because `a` has type `&mut i32`, which does not implement the `Copy` trait
9+
|
10+
help: consider removing the borrow
11+
|
12+
LL - for &a in x.iter() {
13+
LL + for a in x.iter() {
14+
|
1015

1116
error[E0507]: cannot move out of a shared reference
1217
--> $DIR/borrowck-for-loop-correct-cmt-for-pattern.rs:18:15
1318
|
1419
LL | for &a in &f.a {
15-
| -- ^^^^
16-
| ||
17-
| |data moved here
18-
| |move occurs because `a` has type `Box<isize>`, which does not implement the `Copy` trait
19-
| help: consider removing the `&`: `a`
20+
| - ^^^^
21+
| |
22+
| data moved here
23+
| move occurs because `a` has type `Box<isize>`, which does not implement the `Copy` trait
24+
|
25+
help: consider removing the borrow
26+
|
27+
LL - for &a in &f.a {
28+
LL + for a in &f.a {
29+
|
2030

2131
error[E0507]: cannot move out of a shared reference
2232
--> $DIR/borrowck-for-loop-correct-cmt-for-pattern.rs:22:15
2333
|
2434
LL | for &a in x.iter() {
25-
| -- ^^^^^^^^
26-
| ||
27-
| |data moved here
28-
| |move occurs because `a` has type `Box<i32>`, which does not implement the `Copy` trait
29-
| help: consider removing the `&`: `a`
35+
| - ^^^^^^^^
36+
| |
37+
| data moved here
38+
| move occurs because `a` has type `Box<i32>`, which does not implement the `Copy` trait
39+
|
40+
help: consider removing the borrow
41+
|
42+
LL - for &a in x.iter() {
43+
LL + for a in x.iter() {
44+
|
3045

3146
error: aborting due to 3 previous errors
3247

Diff for: src/test/ui/borrowck/borrowck-issue-2657-2.stderr

+6-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ error[E0507]: cannot move out of `*y` which is behind a shared reference
22
--> $DIR/borrowck-issue-2657-2.rs:7:18
33
|
44
LL | let _b = *y;
5-
| ^^
6-
| |
7-
| move occurs because `*y` has type `Box<i32>`, which does not implement the `Copy` trait
8-
| help: consider borrowing here: `&*y`
5+
| ^^ move occurs because `*y` has type `Box<i32>`, which does not implement the `Copy` trait
6+
|
7+
help: consider borrowing here
8+
|
9+
LL | let _b = &*y;
10+
| +
911

1012
error: aborting due to previous error
1113

Diff for: src/test/ui/borrowck/borrowck-move-error-with-note.stderr

+11-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0507]: cannot move out of `f` as enum variant `Foo1` which is behind a sh
22
--> $DIR/borrowck-move-error-with-note.rs:11:11
33
|
44
LL | match *f {
5-
| ^^ help: consider borrowing here: `&*f`
5+
| ^^
66
LL | Foo::Foo1(num1,
77
| ---- data moved here
88
LL | num2) => (),
@@ -11,6 +11,10 @@ LL | Foo::Foo2(num) => (),
1111
| --- ...and here
1212
|
1313
= note: move occurs because these variables have types that don't implement the `Copy` trait
14+
help: consider borrowing here
15+
|
16+
LL | match &*f {
17+
| +
1418

1519
error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
1620
--> $DIR/borrowck-move-error-with-note.rs:28:11
@@ -29,12 +33,17 @@ error[E0507]: cannot move out of `a.a` which is behind a shared reference
2933
--> $DIR/borrowck-move-error-with-note.rs:46:11
3034
|
3135
LL | match a.a {
32-
| ^^^ help: consider borrowing here: `&a.a`
36+
| ^^^
3337
LL | n => {
3438
| -
3539
| |
3640
| data moved here
3741
| move occurs because `n` has type `Box<isize>`, which does not implement the `Copy` trait
42+
|
43+
help: consider borrowing here
44+
|
45+
LL | match &a.a {
46+
| +
3847

3948
error: aborting due to 3 previous errors
4049

Diff for: src/test/ui/borrowck/borrowck-move-from-unsafe-ptr.stderr

+6-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ error[E0507]: cannot move out of `*x` which is behind a raw pointer
22
--> $DIR/borrowck-move-from-unsafe-ptr.rs:2:13
33
|
44
LL | let y = *x;
5-
| ^^
6-
| |
7-
| move occurs because `*x` has type `Box<isize>`, which does not implement the `Copy` trait
8-
| help: consider borrowing here: `&*x`
5+
| ^^ move occurs because `*x` has type `Box<isize>`, which does not implement the `Copy` trait
6+
|
7+
help: consider borrowing here
8+
|
9+
LL | let y = &*x;
10+
| +
911

1012
error: aborting due to previous error
1113

Diff for: src/test/ui/borrowck/borrowck-move-in-irrefut-pat.stderr

+28-13
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,45 @@ error[E0507]: cannot move out of a shared reference
33
|
44
LL | fn arg_item(&_x: &String) {}
55
| ^--
6-
| ||
7-
| |data moved here
8-
| |move occurs because `_x` has type `String`, which does not implement the `Copy` trait
9-
| help: consider removing the `&`: `_x`
6+
| |
7+
| data moved here
8+
| move occurs because `_x` has type `String`, which does not implement the `Copy` trait
9+
|
10+
help: consider removing the borrow
11+
|
12+
LL - fn arg_item(&_x: &String) {}
13+
LL + fn arg_item(_x: &String) {}
14+
|
1015

1116
error[E0507]: cannot move out of a shared reference
1217
--> $DIR/borrowck-move-in-irrefut-pat.rs:7:11
1318
|
1419
LL | with(|&_x| ())
1520
| ^--
16-
| ||
17-
| |data moved here
18-
| |move occurs because `_x` has type `String`, which does not implement the `Copy` trait
19-
| help: consider removing the `&`: `_x`
21+
| |
22+
| data moved here
23+
| move occurs because `_x` has type `String`, which does not implement the `Copy` trait
24+
|
25+
help: consider removing the borrow
26+
|
27+
LL - with(|&_x| ())
28+
LL + with(|_x| ())
29+
|
2030

2131
error[E0507]: cannot move out of a shared reference
2232
--> $DIR/borrowck-move-in-irrefut-pat.rs:12:15
2333
|
2434
LL | let &_x = &"hi".to_string();
25-
| --- ^^^^^^^^^^^^^^^^^
26-
| ||
27-
| |data moved here
28-
| |move occurs because `_x` has type `String`, which does not implement the `Copy` trait
29-
| help: consider removing the `&`: `_x`
35+
| -- ^^^^^^^^^^^^^^^^^
36+
| |
37+
| data moved here
38+
| move occurs because `_x` has type `String`, which does not implement the `Copy` trait
39+
|
40+
help: consider removing the borrow
41+
|
42+
LL - let &_x = &"hi".to_string();
43+
LL + let _x = &"hi".to_string();
44+
|
3045

3146
error: aborting due to 3 previous errors
3247

Diff for: src/test/ui/borrowck/borrowck-move-out-of-overloaded-deref.stderr

+6-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ error[E0507]: cannot move out of an `Rc`
22
--> $DIR/borrowck-move-out-of-overloaded-deref.rs:4:14
33
|
44
LL | let _x = *Rc::new("hi".to_string());
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
6-
| |
7-
| move occurs because value has type `String`, which does not implement the `Copy` trait
8-
| help: consider borrowing here: `&*Rc::new("hi".to_string())`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
6+
|
7+
help: consider borrowing here
8+
|
9+
LL | let _x = &*Rc::new("hi".to_string());
10+
| +
911

1012
error: aborting due to previous error
1113

Diff for: src/test/ui/borrowck/borrowck-move-out-of-vec-tail.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ LL | Foo { string: b }] => {
1010
| - ...and here
1111
|
1212
= note: move occurs because these variables have types that don't implement the `Copy` trait
13-
help: consider removing the `&`
13+
help: consider removing the borrow
1414
|
15-
LL ~ [Foo { string: a },
16-
LL ~ Foo { string: b }] => {
15+
LL - &[Foo { string: a },
16+
LL + [Foo { string: a },
1717
|
1818

1919
error: aborting due to previous error

Diff for: src/test/ui/borrowck/borrowck-overloaded-index-move-from-vec.stderr

+6-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ error[E0507]: cannot move out of index of `MyVec<Box<i32>>`
22
--> $DIR/borrowck-overloaded-index-move-from-vec.rs:20:15
33
|
44
LL | let bad = v[0];
5-
| ^^^^
6-
| |
7-
| move occurs because value has type `Box<i32>`, which does not implement the `Copy` trait
8-
| help: consider borrowing here: `&v[0]`
5+
| ^^^^ move occurs because value has type `Box<i32>`, which does not implement the `Copy` trait
6+
|
7+
help: consider borrowing here
8+
|
9+
LL | let bad = &v[0];
10+
| +
911

1012
error: aborting due to previous error
1113

0 commit comments

Comments
 (0)