mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Label overwritten assignments for never read assignments
This commit is contained in:
@@ -218,11 +218,29 @@ pub(crate) struct UnusedVarAssignedOnly {
|
||||
pub(crate) struct UnusedAssign {
|
||||
pub name: Symbol,
|
||||
#[subdiagnostic]
|
||||
pub overwrite: Option<UnusedAssignOverwrite>,
|
||||
#[subdiagnostic]
|
||||
pub suggestion: Option<UnusedAssignSuggestion>,
|
||||
#[help("maybe it is overwritten before being read?")]
|
||||
pub help: bool,
|
||||
}
|
||||
|
||||
pub(crate) struct UnusedAssignOverwrite {
|
||||
pub assigned_span: Span,
|
||||
pub overwrite_span: Span,
|
||||
pub name: Symbol,
|
||||
}
|
||||
|
||||
impl Subdiagnostic for UnusedAssignOverwrite {
|
||||
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
|
||||
diag.span_label(self.assigned_span, "this value is reassigned later and never used");
|
||||
diag.span_label(
|
||||
self.overwrite_span,
|
||||
format!("`{}` is overwritten here before the previous value is read", self.name),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(
|
||||
"you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding",
|
||||
|
||||
@@ -1094,29 +1094,49 @@ fn report_unused_assignments(self) {
|
||||
self.body,
|
||||
);
|
||||
|
||||
// We probed MIR in reverse order for dataflow.
|
||||
// We revert the vector to give a consistent order to the user.
|
||||
for (source_info, Access { live, kind, is_direct }) in statements.into_iter().rev() {
|
||||
// By convention, underscore-prefixed bindings are allowed to be unused explicitly.
|
||||
if name.as_str().starts_with('_') {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut next_direct_assign = None;
|
||||
let mut dead_statements = Vec::with_capacity(statements.len());
|
||||
|
||||
for (source_info, Access { live, kind, is_direct }) in statements.into_iter() {
|
||||
let overwrite = match (kind, is_direct, next_direct_assign) {
|
||||
(AccessKind::Assign, true, Some(overwrite_span)) => {
|
||||
Some(errors::UnusedAssignOverwrite {
|
||||
assigned_span: source_info.span,
|
||||
overwrite_span,
|
||||
name,
|
||||
})
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if kind == AccessKind::Assign && is_direct {
|
||||
next_direct_assign = Some(source_info.span);
|
||||
}
|
||||
|
||||
if live {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this place was dropped and has non-trivial drop,
|
||||
// skip reporting field assignments.
|
||||
if !is_direct && is_maybe_drop_guard {
|
||||
continue;
|
||||
}
|
||||
dead_statements.push((source_info, kind, is_direct, overwrite));
|
||||
}
|
||||
|
||||
// We probed MIR in reverse order for dataflow.
|
||||
// Emit diagnostics in source order instead.
|
||||
for (source_info, kind, is_direct, overwrite) in dead_statements.into_iter().rev() {
|
||||
// Report the dead assignment.
|
||||
let Some(hir_id) = source_info.scope.lint_root(&self.body.source_scopes) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// By convention, underscore-prefixed bindings are allowed to be unused explicitly
|
||||
if name.as_str().starts_with('_') {
|
||||
break;
|
||||
}
|
||||
|
||||
match kind {
|
||||
AccessKind::Assign => {
|
||||
let suggestion = annotate_mut_binding_to_immutable_binding(
|
||||
@@ -1126,11 +1146,14 @@ fn report_unused_assignments(self) {
|
||||
source_info.span,
|
||||
self.body,
|
||||
);
|
||||
let overwrite =
|
||||
if suggestion.is_none() && is_direct { overwrite } else { None };
|
||||
let help = suggestion.is_none() && overwrite.is_none();
|
||||
tcx.emit_node_span_lint(
|
||||
lint::builtin::UNUSED_ASSIGNMENTS,
|
||||
hir_id,
|
||||
source_info.span,
|
||||
errors::UnusedAssign { name, help: suggestion.is_none(), suggestion },
|
||||
errors::UnusedAssign { name, overwrite, help, suggestion },
|
||||
)
|
||||
}
|
||||
AccessKind::Param => tcx.emit_node_span_lint(
|
||||
|
||||
@@ -80,9 +80,10 @@ warning: value assigned to `e.x` is never read
|
||||
--> $DIR/liveness.rs:74:13
|
||||
|
|
||||
LL | e.x = Some("e1");
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^^^^^^^^^^^ this value is reassigned later and never used
|
||||
LL |
|
||||
LL | e.x = Some("e2");
|
||||
| ---------------- `e.x` is overwritten here before the previous value is read
|
||||
|
||||
warning: value assigned to `e.x` is never read
|
||||
--> $DIR/liveness.rs:76:13
|
||||
@@ -104,9 +105,10 @@ warning: value assigned to `b` is never read
|
||||
--> $DIR/liveness.rs:77:13
|
||||
|
|
||||
LL | b = Some("e1");
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^^^^^^^^^ this value is reassigned later and never used
|
||||
LL |
|
||||
LL | b = Some("e2");
|
||||
| -------------- `b` is overwritten here before the previous value is read
|
||||
|
||||
warning: value assigned to `b` is never read
|
||||
--> $DIR/liveness.rs:79:13
|
||||
@@ -120,17 +122,17 @@ warning: value assigned to `d.x` is never read
|
||||
--> $DIR/liveness.rs:68:13
|
||||
|
|
||||
LL | d.x = Some("d1");
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^^^^^^^^^^^ this value is reassigned later and never used
|
||||
LL | d.x = Some("d2");
|
||||
| ---------------- `d.x` is overwritten here before the previous value is read
|
||||
|
||||
warning: value assigned to `a` is never read
|
||||
--> $DIR/liveness.rs:70:13
|
||||
|
|
||||
LL | a = Some("d1");
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^^^^^^^^^ this value is reassigned later and never used
|
||||
LL | a = Some("d2");
|
||||
| -------------- `a` is overwritten here before the previous value is read
|
||||
|
||||
warning: 16 warnings emitted
|
||||
|
||||
|
||||
@@ -2,9 +2,10 @@ warning: value assigned to `a` is never read
|
||||
--> $DIR/warn-unused-duplication.rs:9:6
|
||||
|
|
||||
LL | (a, a) = (0, 1);
|
||||
| ^
|
||||
| ^ - `a` is overwritten here before the previous value is read
|
||||
| |
|
||||
| this value is reassigned later and never used
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
note: the lint level is defined here
|
||||
--> $DIR/warn-unused-duplication.rs:3:9
|
||||
|
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
//@ check-pass
|
||||
//@ compile-flags: -W unused-assignments
|
||||
|
||||
fn main() {
|
||||
let mut d = String::from("hello"); //~ WARN value assigned to `d` is never read
|
||||
d = String::from("ahoy");
|
||||
|
||||
println!("{d}, world!");
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
warning: value assigned to `d` is never read
|
||||
--> $DIR/overwritten-before-read-note-issue-154434.rs:5:17
|
||||
|
|
||||
LL | let mut d = String::from("hello");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ this value is reassigned later and never used
|
||||
LL | d = String::from("ahoy");
|
||||
| - `d` is overwritten here before the previous value is read
|
||||
|
|
||||
= note: requested on the command line with `-W unused-assignments`
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
@@ -2,9 +2,10 @@ error: value assigned to `value` is never read
|
||||
--> $DIR/unused-assign-148960.rs:6:21
|
||||
|
|
||||
LL | let mut value = b"0".to_vec();
|
||||
| ^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^ this value is reassigned later and never used
|
||||
LL | value = b"1".to_vec();
|
||||
| ----- `value` is overwritten here before the previous value is read
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
note: the lint level is defined here
|
||||
--> $DIR/unused-assign-148960.rs:2:9
|
||||
|
|
||||
@@ -16,25 +17,25 @@ error: value assigned to `x` is never read
|
||||
--> $DIR/unused-assign-148960.rs:12:17
|
||||
|
|
||||
LL | let mut x = 1;
|
||||
| ^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^ this value is reassigned later and never used
|
||||
LL | x = 2;
|
||||
| ----- `x` is overwritten here before the previous value is read
|
||||
|
||||
error: value assigned to `x` is never read
|
||||
--> $DIR/unused-assign-148960.rs:13:5
|
||||
|
|
||||
LL | x = 2;
|
||||
| ^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^ this value is reassigned later and never used
|
||||
LL | x = 3;
|
||||
| ----- `x` is overwritten here before the previous value is read
|
||||
|
||||
error: value assigned to `p` is never read
|
||||
--> $DIR/unused-assign-148960.rs:24:17
|
||||
|
|
||||
LL | let mut p = Point { x: 1, y: 1 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^^^^^^^^^^^^^^^ this value is reassigned later and never used
|
||||
LL | p = Point { x: 2, y: 2 };
|
||||
| ------------------------ `p` is overwritten here before the previous value is read
|
||||
|
||||
error: variable `foo` is assigned to, but never used
|
||||
--> $DIR/unused-assign-148960.rs:38:9
|
||||
|
||||
@@ -44,17 +44,17 @@ warning: value assigned to `b` is never read
|
||||
--> $DIR/liveness-consts.rs:18:17
|
||||
|
|
||||
LL | let mut b = 1;
|
||||
| ^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^ this value is reassigned later and never used
|
||||
LL | b += 1;
|
||||
| ------ `b` is overwritten here before the previous value is read
|
||||
|
||||
warning: value assigned to `b` is never read
|
||||
--> $DIR/liveness-consts.rs:19:5
|
||||
|
|
||||
LL | b += 1;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^ this value is reassigned later and never used
|
||||
LL | b = 42;
|
||||
| ------ `b` is overwritten here before the previous value is read
|
||||
|
||||
warning: unused variable: `z`
|
||||
--> $DIR/liveness-consts.rs:62:13
|
||||
|
||||
@@ -2,9 +2,10 @@ error: value assigned to `x` is never read
|
||||
--> $DIR/liveness-dead.rs:9:24
|
||||
|
|
||||
LL | let mut x: isize = 3;
|
||||
| ^
|
||||
| ^ this value is reassigned later and never used
|
||||
LL | x = 4;
|
||||
| ----- `x` is overwritten here before the previous value is read
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
note: the lint level is defined here
|
||||
--> $DIR/liveness-dead.rs:2:9
|
||||
|
|
||||
|
||||
@@ -167,49 +167,55 @@ error: value assigned to `a` is never read
|
||||
--> $DIR/liveness-unused.rs:183:5
|
||||
|
|
||||
LL | a += b;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^ this value is reassigned later and never used
|
||||
LL |
|
||||
LL | a -= c;
|
||||
| ------ `a` is overwritten here before the previous value is read
|
||||
|
||||
error: value assigned to `a` is never read
|
||||
--> $DIR/liveness-unused.rs:185:5
|
||||
|
|
||||
LL | a -= c;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^ this value is reassigned later and never used
|
||||
LL |
|
||||
LL | a *= d;
|
||||
| ------ `a` is overwritten here before the previous value is read
|
||||
|
||||
error: value assigned to `a` is never read
|
||||
--> $DIR/liveness-unused.rs:187:5
|
||||
|
|
||||
LL | a *= d;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^ this value is reassigned later and never used
|
||||
LL |
|
||||
LL | a /= e;
|
||||
| ------ `a` is overwritten here before the previous value is read
|
||||
|
||||
error: value assigned to `a` is never read
|
||||
--> $DIR/liveness-unused.rs:189:5
|
||||
|
|
||||
LL | a /= e;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^ this value is reassigned later and never used
|
||||
LL |
|
||||
LL | a |= f;
|
||||
| ------ `a` is overwritten here before the previous value is read
|
||||
|
||||
error: value assigned to `a` is never read
|
||||
--> $DIR/liveness-unused.rs:191:5
|
||||
|
|
||||
LL | a |= f;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^ this value is reassigned later and never used
|
||||
LL |
|
||||
LL | a &= g;
|
||||
| ------ `a` is overwritten here before the previous value is read
|
||||
|
||||
error: value assigned to `a` is never read
|
||||
--> $DIR/liveness-unused.rs:193:5
|
||||
|
|
||||
LL | a &= g;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^ this value is reassigned later and never used
|
||||
LL |
|
||||
LL | a %= h;
|
||||
| ------ `a` is overwritten here before the previous value is read
|
||||
|
||||
error: value assigned to `a` is never read
|
||||
--> $DIR/liveness-unused.rs:195:5
|
||||
@@ -231,33 +237,37 @@ error: value assigned to `a` is never read
|
||||
--> $DIR/liveness-unused.rs:229:5
|
||||
|
|
||||
LL | a += b;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^ this value is reassigned later and never used
|
||||
LL |
|
||||
LL | a -= c;
|
||||
| ------ `a` is overwritten here before the previous value is read
|
||||
|
||||
error: value assigned to `a` is never read
|
||||
--> $DIR/liveness-unused.rs:231:5
|
||||
|
|
||||
LL | a -= c;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^ this value is reassigned later and never used
|
||||
LL |
|
||||
LL | a *= d;
|
||||
| ------ `a` is overwritten here before the previous value is read
|
||||
|
||||
error: value assigned to `a` is never read
|
||||
--> $DIR/liveness-unused.rs:233:5
|
||||
|
|
||||
LL | a *= d;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^ this value is reassigned later and never used
|
||||
LL |
|
||||
LL | a /= e;
|
||||
| ------ `a` is overwritten here before the previous value is read
|
||||
|
||||
error: value assigned to `a` is never read
|
||||
--> $DIR/liveness-unused.rs:235:5
|
||||
|
|
||||
LL | a /= e;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^ this value is reassigned later and never used
|
||||
LL |
|
||||
LL | a %= f;
|
||||
| ------ `a` is overwritten here before the previous value is read
|
||||
|
||||
error: value assigned to `a` is never read
|
||||
--> $DIR/liveness-unused.rs:237:5
|
||||
|
||||
@@ -112,9 +112,10 @@ warning: value assigned to `e` is never read
|
||||
--> $DIR/liveness-upvars.rs:82:13
|
||||
|
|
||||
LL | e = Some("e1");
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^^^^^^^^^ this value is reassigned later and never used
|
||||
LL |
|
||||
LL | e = Some("e2");
|
||||
| -------------- `e` is overwritten here before the previous value is read
|
||||
|
||||
warning: value assigned to `e` is never read
|
||||
--> $DIR/liveness-upvars.rs:84:13
|
||||
@@ -128,9 +129,9 @@ warning: value assigned to `d` is never read
|
||||
--> $DIR/liveness-upvars.rs:78:13
|
||||
|
|
||||
LL | d = Some("d1");
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^^^^^^^^^ this value is reassigned later and never used
|
||||
LL | d = Some("d2");
|
||||
| -------------- `d` is overwritten here before the previous value is read
|
||||
|
||||
warning: value assigned to `v` is never read
|
||||
--> $DIR/liveness-upvars.rs:92:13
|
||||
@@ -176,9 +177,10 @@ warning: value assigned to `state` is never read
|
||||
--> $DIR/liveness-upvars.rs:131:9
|
||||
|
|
||||
LL | state = 4;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^^^^ this value is reassigned later and never used
|
||||
...
|
||||
LL | state = 5;
|
||||
| --------- `state` is overwritten here before the previous value is read
|
||||
|
||||
warning: value assigned to `state` is never read
|
||||
--> $DIR/liveness-upvars.rs:134:9
|
||||
@@ -192,17 +194,17 @@ warning: value assigned to `s` is never read
|
||||
--> $DIR/liveness-upvars.rs:143:9
|
||||
|
|
||||
LL | s = 1;
|
||||
| ^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^ this value is reassigned later and never used
|
||||
LL | yield (s = 2);
|
||||
| ------- `s` is overwritten here before the previous value is read
|
||||
|
||||
warning: value assigned to `s` is never read
|
||||
--> $DIR/liveness-upvars.rs:145:9
|
||||
|
|
||||
LL | s = yield ();
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
| ^^^^^^^^^^^^ this value is reassigned later and never used
|
||||
LL | s = 3;
|
||||
| ----- `s` is overwritten here before the previous value is read
|
||||
|
||||
warning: 25 warnings emitted
|
||||
|
||||
|
||||
@@ -2,9 +2,11 @@ warning: value assigned to `b` is never read
|
||||
--> $DIR/general.rs:60:25
|
||||
|
|
||||
LL | (Some(a), &Some(mut b)) => {
|
||||
| ^^^^^
|
||||
| ^^^^^ this value is reassigned later and never used
|
||||
...
|
||||
LL | b = 7;
|
||||
| ----- `b` is overwritten here before the previous value is read
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
= note: `#[warn(unused_assignments)]` (part of `#[warn(unused)]`) on by default
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
Reference in New Issue
Block a user