Skip to content

Commit 12a2d73

Browse files
committed
Improve mutable-binding suggestion to include name
1 parent 5dbf406 commit 12a2d73

File tree

3 files changed

+52
-13
lines changed

3 files changed

+52
-13
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3940,21 +3940,33 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
39403940
if let Some(decl) = local_decl
39413941
&& decl.can_be_made_mutable()
39423942
{
3943-
err.span_suggestion_verbose(
3944-
decl.source_info.span.shrink_to_lo(),
3945-
"consider making this binding mutable",
3946-
"mut ".to_string(),
3947-
Applicability::MachineApplicable,
3943+
let is_destructuring_pattern = matches!(
3944+
decl.local_info(),
3945+
LocalInfo::User(BindingForm::Var(VarBindingForm {
3946+
opt_match_place: Some((Some(_), _)),
3947+
..
3948+
}))
39483949
);
3949-
if !from_arg
3950-
&& matches!(
3951-
decl.local_info(),
3952-
LocalInfo::User(BindingForm::Var(VarBindingForm {
3953-
opt_match_place: Some((Some(_), _)),
3954-
..
3955-
}))
3956-
)
3950+
if is_destructuring_pattern
3951+
&& matches!(decl.source_info.span.desugaring_kind(), Some(DesugaringKind::ForLoop))
3952+
&& let Ok(binding_name) =
3953+
self.infcx.tcx.sess.source_map().span_to_snippet(decl.source_info.span)
39573954
{
3955+
err.span_suggestion_verbose(
3956+
decl.source_info.span.shrink_to_lo(),
3957+
"consider making this binding mutable",
3958+
format!("(mut {}) ", binding_name),
3959+
Applicability::MachineApplicable,
3960+
);
3961+
} else {
3962+
err.span_suggestion_verbose(
3963+
decl.source_info.span.shrink_to_lo(),
3964+
"consider making this binding mutable",
3965+
"mut ".to_string(),
3966+
Applicability::MachineApplicable,
3967+
);
3968+
}
3969+
if !from_arg && is_destructuring_pattern {
39583970
err.span_suggestion_verbose(
39593971
decl.source_info.span.shrink_to_lo(),
39603972
"to modify the original value, take a borrow instead",
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn main() {
2+
let nums: &[u32] = &[1, 2, 3];
3+
for &num in nums {
4+
num *= 2; //~ ERROR cannot assign twice to immutable variable `num`
5+
println!("{num}");
6+
}
7+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0384]: cannot assign twice to immutable variable `num`
2+
--> $DIR/borrowck-for-loop-deref-pattern-assignment.rs:4:9
3+
|
4+
LL | for &num in nums {
5+
| --- first assignment to `num`
6+
LL | num *= 2;
7+
| ^^^^^^^^ cannot assign twice to immutable variable
8+
|
9+
help: consider making this binding mutable
10+
|
11+
LL | for &(mut num) num in nums {
12+
| +++++++++
13+
help: to modify the original value, take a borrow instead
14+
|
15+
LL | for &ref mut num in nums {
16+
| +++++++
17+
18+
error: aborting due to 1 previous error
19+
20+
For more information about this error, try `rustc --explain E0384`.

0 commit comments

Comments
 (0)