Skip to content

Commit 12ab1cf

Browse files
committed
Auto merge of rust-lang#154456 - chenyukang:yukang-fix-154434-unused-assignments, r=estebank
Label overwritten for never read assignments Fixes rust-lang#154434 Closes rust-lang#144079
2 parents 700cfa8 + ebf22f8 commit 12ab1cf

11 files changed

Lines changed: 154 additions & 92 deletions

File tree

compiler/rustc_mir_transform/src/errors.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,29 @@ pub(crate) struct UnusedVarAssignedOnly {
218218
pub(crate) struct UnusedAssign {
219219
pub name: Symbol,
220220
#[subdiagnostic]
221+
pub overwrite: Option<UnusedAssignOverwrite>,
222+
#[subdiagnostic]
221223
pub suggestion: Option<UnusedAssignSuggestion>,
222224
#[help("maybe it is overwritten before being read?")]
223225
pub help: bool,
224226
}
225227

228+
pub(crate) struct UnusedAssignOverwrite {
229+
pub assigned_span: Span,
230+
pub overwrite_span: Span,
231+
pub name: Symbol,
232+
}
233+
234+
impl Subdiagnostic for UnusedAssignOverwrite {
235+
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
236+
diag.span_label(self.assigned_span, "this value is reassigned later and never used");
237+
diag.span_label(
238+
self.overwrite_span,
239+
format!("`{}` is overwritten here before the previous value is read", self.name),
240+
);
241+
}
242+
}
243+
226244
#[derive(Subdiagnostic)]
227245
#[multipart_suggestion(
228246
"you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding",

compiler/rustc_mir_transform/src/liveness.rs

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,29 +1094,49 @@ impl<'a, 'tcx> AssignmentResult<'a, 'tcx> {
10941094
self.body,
10951095
);
10961096

1097-
// We probed MIR in reverse order for dataflow.
1098-
// We revert the vector to give a consistent order to the user.
1099-
for (source_info, Access { live, kind, is_direct }) in statements.into_iter().rev() {
1097+
// By convention, underscore-prefixed bindings are allowed to be unused explicitly.
1098+
if name.as_str().starts_with('_') {
1099+
continue;
1100+
}
1101+
1102+
let mut next_direct_assign = None;
1103+
let mut dead_statements = Vec::with_capacity(statements.len());
1104+
1105+
for (source_info, Access { live, kind, is_direct }) in statements.into_iter() {
1106+
let overwrite = match (kind, is_direct, next_direct_assign) {
1107+
(AccessKind::Assign, true, Some(overwrite_span)) => {
1108+
Some(errors::UnusedAssignOverwrite {
1109+
assigned_span: source_info.span,
1110+
overwrite_span,
1111+
name,
1112+
})
1113+
}
1114+
_ => None,
1115+
};
1116+
1117+
if kind == AccessKind::Assign && is_direct {
1118+
next_direct_assign = Some(source_info.span);
1119+
}
1120+
11001121
if live {
11011122
continue;
11021123
}
1103-
11041124
// If this place was dropped and has non-trivial drop,
11051125
// skip reporting field assignments.
11061126
if !is_direct && is_maybe_drop_guard {
11071127
continue;
11081128
}
1129+
dead_statements.push((source_info, kind, is_direct, overwrite));
1130+
}
11091131

1132+
// We probed MIR in reverse order for dataflow.
1133+
// Emit diagnostics in source order instead.
1134+
for (source_info, kind, is_direct, overwrite) in dead_statements.into_iter().rev() {
11101135
// Report the dead assignment.
11111136
let Some(hir_id) = source_info.scope.lint_root(&self.body.source_scopes) else {
11121137
continue;
11131138
};
11141139

1115-
// By convention, underscore-prefixed bindings are allowed to be unused explicitly
1116-
if name.as_str().starts_with('_') {
1117-
break;
1118-
}
1119-
11201140
match kind {
11211141
AccessKind::Assign => {
11221142
let suggestion = annotate_mut_binding_to_immutable_binding(
@@ -1126,11 +1146,14 @@ impl<'a, 'tcx> AssignmentResult<'a, 'tcx> {
11261146
source_info.span,
11271147
self.body,
11281148
);
1149+
let overwrite =
1150+
if suggestion.is_none() && is_direct { overwrite } else { None };
1151+
let help = suggestion.is_none() && overwrite.is_none();
11291152
tcx.emit_node_span_lint(
11301153
lint::builtin::UNUSED_ASSIGNMENTS,
11311154
hir_id,
11321155
source_info.span,
1133-
errors::UnusedAssign { name, help: suggestion.is_none(), suggestion },
1156+
errors::UnusedAssign { name, overwrite, help, suggestion },
11341157
)
11351158
}
11361159
AccessKind::Param => tcx.emit_node_span_lint(

tests/ui/asm/x86_64/goto.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ warning: value assigned to `value` is never read
2222
--> $DIR/goto.rs:71:25
2323
|
2424
LL | let mut value = false;
25-
| ^^^^^
25+
| ^^^^^ this value is reassigned later and never used
26+
...
27+
LL | value = true;
28+
| ------------ `value` is overwritten here before the previous value is read
2629
|
27-
= help: maybe it is overwritten before being read?
2830
= note: `#[warn(unused_assignments)]` (part of `#[warn(unused)]`) on by default
2931

3032
warning: 2 warnings emitted

tests/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,10 @@ warning: value assigned to `e.x` is never read
8080
--> $DIR/liveness.rs:74:13
8181
|
8282
LL | e.x = Some("e1");
83-
| ^^^^^^^^^^^^^^^^
84-
|
85-
= help: maybe it is overwritten before being read?
83+
| ^^^^^^^^^^^^^^^^ this value is reassigned later and never used
84+
LL |
85+
LL | e.x = Some("e2");
86+
| ---------------- `e.x` is overwritten here before the previous value is read
8687

8788
warning: value assigned to `e.x` is never read
8889
--> $DIR/liveness.rs:76:13
@@ -104,9 +105,10 @@ warning: value assigned to `b` is never read
104105
--> $DIR/liveness.rs:77:13
105106
|
106107
LL | b = Some("e1");
107-
| ^^^^^^^^^^^^^^
108-
|
109-
= help: maybe it is overwritten before being read?
108+
| ^^^^^^^^^^^^^^ this value is reassigned later and never used
109+
LL |
110+
LL | b = Some("e2");
111+
| -------------- `b` is overwritten here before the previous value is read
110112

111113
warning: value assigned to `b` is never read
112114
--> $DIR/liveness.rs:79:13
@@ -120,17 +122,17 @@ warning: value assigned to `d.x` is never read
120122
--> $DIR/liveness.rs:68:13
121123
|
122124
LL | d.x = Some("d1");
123-
| ^^^^^^^^^^^^^^^^
124-
|
125-
= help: maybe it is overwritten before being read?
125+
| ^^^^^^^^^^^^^^^^ this value is reassigned later and never used
126+
LL | d.x = Some("d2");
127+
| ---------------- `d.x` is overwritten here before the previous value is read
126128

127129
warning: value assigned to `a` is never read
128130
--> $DIR/liveness.rs:70:13
129131
|
130132
LL | a = Some("d1");
131-
| ^^^^^^^^^^^^^^
132-
|
133-
= help: maybe it is overwritten before being read?
133+
| ^^^^^^^^^^^^^^ this value is reassigned later and never used
134+
LL | a = Some("d2");
135+
| -------------- `a` is overwritten here before the previous value is read
134136

135137
warning: 16 warnings emitted
136138

tests/ui/destructuring-assignment/warn-unused-duplication.stderr

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ warning: value assigned to `a` is never read
22
--> $DIR/warn-unused-duplication.rs:9:6
33
|
44
LL | (a, a) = (0, 1);
5-
| ^
5+
| ^ - `a` is overwritten here before the previous value is read
6+
| |
7+
| this value is reassigned later and never used
68
|
7-
= help: maybe it is overwritten before being read?
89
note: the lint level is defined here
910
--> $DIR/warn-unused-duplication.rs:3:9
1011
|

tests/ui/lint/unused/unused-assign-148960.stderr

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ error: value assigned to `value` is never read
22
--> $DIR/unused-assign-148960.rs:6:21
33
|
44
LL | let mut value = b"0".to_vec();
5-
| ^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^ this value is reassigned later and never used
6+
LL | value = b"1".to_vec();
7+
| ----- `value` is overwritten here before the previous value is read
68
|
7-
= help: maybe it is overwritten before being read?
89
note: the lint level is defined here
910
--> $DIR/unused-assign-148960.rs:2:9
1011
|
@@ -16,25 +17,25 @@ error: value assigned to `x` is never read
1617
--> $DIR/unused-assign-148960.rs:12:17
1718
|
1819
LL | let mut x = 1;
19-
| ^
20-
|
21-
= help: maybe it is overwritten before being read?
20+
| ^ this value is reassigned later and never used
21+
LL | x = 2;
22+
| ----- `x` is overwritten here before the previous value is read
2223

2324
error: value assigned to `x` is never read
2425
--> $DIR/unused-assign-148960.rs:13:5
2526
|
2627
LL | x = 2;
27-
| ^^^^^
28-
|
29-
= help: maybe it is overwritten before being read?
28+
| ^^^^^ this value is reassigned later and never used
29+
LL | x = 3;
30+
| ----- `x` is overwritten here before the previous value is read
3031

3132
error: value assigned to `p` is never read
3233
--> $DIR/unused-assign-148960.rs:24:17
3334
|
3435
LL | let mut p = Point { x: 1, y: 1 };
35-
| ^^^^^^^^^^^^^^^^^^^^
36-
|
37-
= help: maybe it is overwritten before being read?
36+
| ^^^^^^^^^^^^^^^^^^^^ this value is reassigned later and never used
37+
LL | p = Point { x: 2, y: 2 };
38+
| ------------------------ `p` is overwritten here before the previous value is read
3839

3940
error: variable `foo` is assigned to, but never used
4041
--> $DIR/unused-assign-148960.rs:38:9

tests/ui/liveness/liveness-consts.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,17 @@ warning: value assigned to `b` is never read
4444
--> $DIR/liveness-consts.rs:18:17
4545
|
4646
LL | let mut b = 1;
47-
| ^
48-
|
49-
= help: maybe it is overwritten before being read?
47+
| ^ this value is reassigned later and never used
48+
LL | b += 1;
49+
| ------ `b` is overwritten here before the previous value is read
5050

5151
warning: value assigned to `b` is never read
5252
--> $DIR/liveness-consts.rs:19:5
5353
|
5454
LL | b += 1;
55-
| ^^^^^^
56-
|
57-
= help: maybe it is overwritten before being read?
55+
| ^^^^^^ this value is reassigned later and never used
56+
LL | b = 42;
57+
| ------ `b` is overwritten here before the previous value is read
5858

5959
warning: unused variable: `z`
6060
--> $DIR/liveness-consts.rs:62:13

tests/ui/liveness/liveness-dead.stderr

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ error: value assigned to `x` is never read
22
--> $DIR/liveness-dead.rs:9:24
33
|
44
LL | let mut x: isize = 3;
5-
| ^
5+
| ^ this value is reassigned later and never used
6+
LL | x = 4;
7+
| ----- `x` is overwritten here before the previous value is read
68
|
7-
= help: maybe it is overwritten before being read?
89
note: the lint level is defined here
910
--> $DIR/liveness-dead.rs:2:9
1011
|

tests/ui/liveness/liveness-unused.stderr

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -167,49 +167,55 @@ error: value assigned to `a` is never read
167167
--> $DIR/liveness-unused.rs:183:5
168168
|
169169
LL | a += b;
170-
| ^^^^^^
171-
|
172-
= help: maybe it is overwritten before being read?
170+
| ^^^^^^ this value is reassigned later and never used
171+
LL |
172+
LL | a -= c;
173+
| ------ `a` is overwritten here before the previous value is read
173174

174175
error: value assigned to `a` is never read
175176
--> $DIR/liveness-unused.rs:185:5
176177
|
177178
LL | a -= c;
178-
| ^^^^^^
179-
|
180-
= help: maybe it is overwritten before being read?
179+
| ^^^^^^ this value is reassigned later and never used
180+
LL |
181+
LL | a *= d;
182+
| ------ `a` is overwritten here before the previous value is read
181183

182184
error: value assigned to `a` is never read
183185
--> $DIR/liveness-unused.rs:187:5
184186
|
185187
LL | a *= d;
186-
| ^^^^^^
187-
|
188-
= help: maybe it is overwritten before being read?
188+
| ^^^^^^ this value is reassigned later and never used
189+
LL |
190+
LL | a /= e;
191+
| ------ `a` is overwritten here before the previous value is read
189192

190193
error: value assigned to `a` is never read
191194
--> $DIR/liveness-unused.rs:189:5
192195
|
193196
LL | a /= e;
194-
| ^^^^^^
195-
|
196-
= help: maybe it is overwritten before being read?
197+
| ^^^^^^ this value is reassigned later and never used
198+
LL |
199+
LL | a |= f;
200+
| ------ `a` is overwritten here before the previous value is read
197201

198202
error: value assigned to `a` is never read
199203
--> $DIR/liveness-unused.rs:191:5
200204
|
201205
LL | a |= f;
202-
| ^^^^^^
203-
|
204-
= help: maybe it is overwritten before being read?
206+
| ^^^^^^ this value is reassigned later and never used
207+
LL |
208+
LL | a &= g;
209+
| ------ `a` is overwritten here before the previous value is read
205210

206211
error: value assigned to `a` is never read
207212
--> $DIR/liveness-unused.rs:193:5
208213
|
209214
LL | a &= g;
210-
| ^^^^^^
211-
|
212-
= help: maybe it is overwritten before being read?
215+
| ^^^^^^ this value is reassigned later and never used
216+
LL |
217+
LL | a %= h;
218+
| ------ `a` is overwritten here before the previous value is read
213219

214220
error: value assigned to `a` is never read
215221
--> $DIR/liveness-unused.rs:195:5
@@ -231,33 +237,37 @@ error: value assigned to `a` is never read
231237
--> $DIR/liveness-unused.rs:229:5
232238
|
233239
LL | a += b;
234-
| ^^^^^^
235-
|
236-
= help: maybe it is overwritten before being read?
240+
| ^^^^^^ this value is reassigned later and never used
241+
LL |
242+
LL | a -= c;
243+
| ------ `a` is overwritten here before the previous value is read
237244

238245
error: value assigned to `a` is never read
239246
--> $DIR/liveness-unused.rs:231:5
240247
|
241248
LL | a -= c;
242-
| ^^^^^^
243-
|
244-
= help: maybe it is overwritten before being read?
249+
| ^^^^^^ this value is reassigned later and never used
250+
LL |
251+
LL | a *= d;
252+
| ------ `a` is overwritten here before the previous value is read
245253

246254
error: value assigned to `a` is never read
247255
--> $DIR/liveness-unused.rs:233:5
248256
|
249257
LL | a *= d;
250-
| ^^^^^^
251-
|
252-
= help: maybe it is overwritten before being read?
258+
| ^^^^^^ this value is reassigned later and never used
259+
LL |
260+
LL | a /= e;
261+
| ------ `a` is overwritten here before the previous value is read
253262

254263
error: value assigned to `a` is never read
255264
--> $DIR/liveness-unused.rs:235:5
256265
|
257266
LL | a /= e;
258-
| ^^^^^^
259-
|
260-
= help: maybe it is overwritten before being read?
267+
| ^^^^^^ this value is reassigned later and never used
268+
LL |
269+
LL | a %= f;
270+
| ------ `a` is overwritten here before the previous value is read
261271

262272
error: value assigned to `a` is never read
263273
--> $DIR/liveness-unused.rs:237:5

0 commit comments

Comments
 (0)