Skip to content

Commit dcdbbd0

Browse files
authoredDec 13, 2022
Rollup merge of #105476 - estebank:moves-n-borrows, r=compiler-errors
Change pattern borrowing suggestions to be verbose and remove invalid suggestion Synthesize a more accurate span and use verbose suggestion output to make the message clearer. Do not suggest borrowing binding in pattern in let else. Fix #104838.
·
1.88.01.68.0
2 parents 5e38e70 + cf0b6b9 commit dcdbbd0

File tree

73 files changed

+1842
-816
lines changed

Some content is hidden

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

73 files changed

+1842
-816
lines changed
 

‎compiler/rustc_borrowck/src/diagnostics/move_errors.rs

Lines changed: 64 additions & 36 deletions
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,15 +410,7 @@ 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-
}
421-
413+
self.add_borrow_suggestions(err, span);
422414
if binds_to.is_empty() {
423415
let place_ty = move_from.ty(self.body, self.infcx.tcx).ty;
424416
let place_desc = match self.describe_place(move_from.as_ref()) {
@@ -461,39 +453,75 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
461453
}
462454
}
463455

456+
fn add_borrow_suggestions(&self, err: &mut Diagnostic, span: Span) {
457+
match self.infcx.tcx.sess.source_map().span_to_snippet(span) {
458+
Ok(snippet) if snippet.starts_with('*') => {
459+
err.span_suggestion_verbose(
460+
span.with_hi(span.lo() + BytePos(1)),
461+
"consider removing the dereference here",
462+
String::new(),
463+
Applicability::MaybeIncorrect,
464+
);
465+
}
466+
_ => {
467+
err.span_suggestion_verbose(
468+
span.shrink_to_lo(),
469+
"consider borrowing here",
470+
"&".to_string(),
471+
Applicability::MaybeIncorrect,
472+
);
473+
}
474+
}
475+
}
476+
464477
fn add_move_error_suggestions(&self, err: &mut Diagnostic, binds_to: &[Local]) {
465-
let mut suggestions: Vec<(Span, &str, String)> = Vec::new();
478+
let mut suggestions: Vec<(Span, String, String)> = Vec::new();
466479
for local in binds_to {
467480
let bind_to = &self.body.local_decls[*local];
468481
if let Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
469482
VarBindingForm { pat_span, .. },
470483
)))) = bind_to.local_info
471484
{
472-
if let Ok(pat_snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(pat_span)
485+
let Ok(pat_snippet) =
486+
self.infcx.tcx.sess.source_map().span_to_snippet(pat_span) else { continue; };
487+
let Some(stripped) = pat_snippet.strip_prefix('&') else {
488+
suggestions.push((
489+
bind_to.source_info.span.shrink_to_lo(),
490+
"consider borrowing the pattern binding".to_string(),
491+
"ref ".to_string(),
492+
));
493+
continue;
494+
};
495+
let inner_pat_snippet = stripped.trim_start();
496+
let (pat_span, suggestion, to_remove) = if inner_pat_snippet.starts_with("mut")
497+
&& inner_pat_snippet["mut".len()..].starts_with(rustc_lexer::is_whitespace)
473498
{
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-
}
499+
let inner_pat_snippet = inner_pat_snippet["mut".len()..].trim_start();
500+
let pat_span = pat_span.with_hi(
501+
pat_span.lo()
502+
+ BytePos((pat_snippet.len() - inner_pat_snippet.len()) as u32),
503+
);
504+
(pat_span, String::new(), "mutable borrow")
505+
} else {
506+
let pat_span = pat_span.with_hi(
507+
pat_span.lo()
508+
+ BytePos(
509+
(pat_snippet.len() - inner_pat_snippet.trim_start().len()) as u32,
510+
),
511+
);
512+
(pat_span, String::new(), "borrow")
513+
};
514+
suggestions.push((
515+
pat_span,
516+
format!("consider removing the {to_remove}"),
517+
suggestion.to_string(),
518+
));
486519
}
487520
}
488521
suggestions.sort_unstable_by_key(|&(span, _, _)| span);
489522
suggestions.dedup_by_key(|&mut (span, _, _)| span);
490-
for (span, to_remove, suggestion) in suggestions {
491-
err.span_suggestion(
492-
span,
493-
&format!("consider removing the `{to_remove}`"),
494-
suggestion,
495-
Applicability::MachineApplicable,
496-
);
523+
for (span, msg, suggestion) in suggestions {
524+
err.span_suggestion_verbose(span, &msg, suggestion, Applicability::MachineApplicable);
497525
}
498526
}
499527

@@ -521,8 +549,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
521549

522550
if binds_to.len() > 1 {
523551
err.note(
524-
"move occurs because these variables have types that \
525-
don't implement the `Copy` trait",
552+
"move occurs because these variables have types that don't implement the `Copy` \
553+
trait",
526554
);
527555
}
528556
}

‎compiler/rustc_mir_build/src/build/block.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
231231
remainder_span,
232232
pattern,
233233
None,
234-
Some((None, initializer_span)),
234+
Some((Some(&destination), initializer_span)),
235235
);
236236
this.visit_primary_bindings(
237237
pattern,

0 commit comments

Comments
 (0)
Please sign in to comment.