Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -986,7 +986,7 @@ impl<'a, 'tcx> AssignmentResult<'a, 'tcx> {
// warn twice, for the unused local and for the unused assignment. Therefore, we remove
// from the list of assignments the ones that happen at the definition site.
statements.retain(|source_info, _| {
source_info.span.find_ancestor_inside(binding.pat_span).is_none()
!binding.introductions.iter().any(|intro| intro.span == source_info.span)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This additional filter against binding.introductions makes sense, especially for proc-macro generated bindings where spans don’t line up lexically. It avoids double warnings without weakening the lint.

});

// Extra assignments that we recognize thanks to the initialization span. We need to
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//@ run-pass
#![allow(unused_variables)]
#![warn(unused)]
#![deny(non_shorthand_field_patterns)]

pub struct Value<A> { pub value: A }
Expand All @@ -13,5 +13,5 @@ macro_rules! pat {

fn main() {
let pat!(value) = Value { value: () };
//~^ WARN value assigned to `value` is never read
//~^ WARN unused variable: `value`
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
warning: value assigned to `value` is never read
warning: unused variable: `value`
--> $DIR/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs:15:14
|
LL | let pat!(value) = Value { value: () };
| ^^^^^
| ^^^^^ help: if this is intentional, prefix it with an underscore: `_value`
|
= help: maybe it is overwritten before being read?
= note: `#[warn(unused_assignments)]` (part of `#[warn(unused)]`) on by default
note: the lint level is defined here
--> $DIR/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs:2:9
|
LL | #![warn(unused)]
| ^^^^^^
= note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`

warning: 1 warning emitted

23 changes: 23 additions & 0 deletions tests/ui/lint/unused/auxiliary/unused_assignment_proc_macro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#![feature(proc_macro_quote)]

extern crate proc_macro;
use proc_macro::*;

#[proc_macro_derive(Drop)]
pub fn generate(ts: TokenStream) -> TokenStream {
let mut ts = ts.into_iter();
let _pub = ts.next();
let _struct = ts.next();
let name = ts.next().unwrap();
let TokenTree::Group(fields) = ts.next().unwrap() else { panic!() };
let mut fields = fields.stream().into_iter();
let field = fields.next().unwrap();

quote! {
impl Drop for $name {
fn drop(&mut self) {
let Self { $field } = self;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without the fix, the compiler would incorrectly emit both unused_variables and unused_assignments. This test clearly asserts the intended behavior.

}
}
}
}
21 changes: 21 additions & 0 deletions tests/ui/lint/unused/unused_assignment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Unused assignments to an unused variable should trigger only the `unused_variables` lint and not
// also the `unused_assignments` lint. This test covers the situation where the span of the unused
// variable identifier comes from a different scope to the binding pattern - here, from a proc
// macro's input tokenstream (whereas the binding pattern is generated within the proc macro
// itself).
//
// Regression test for https://github.com/rust-lang/rust/issues/151514
//
//@ check-pass
//@ proc-macro: unused_assignment_proc_macro.rs
#![warn(unused)]

extern crate unused_assignment_proc_macro;
use unused_assignment_proc_macro::Drop;

#[derive(Drop)]
pub struct S {
a: (), //~ WARN unused variable: `a`
}

fn main() {}
15 changes: 15 additions & 0 deletions tests/ui/lint/unused/unused_assignment.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
warning: unused variable: `a`
--> $DIR/unused_assignment.rs:18:5
|
LL | a: (),
| ^ help: try ignoring the field: `a: _`
|
note: the lint level is defined here
--> $DIR/unused_assignment.rs:11:9
|
LL | #![warn(unused)]
| ^^^^^^
= note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`

warning: 1 warning emitted

1 change: 0 additions & 1 deletion tests/ui/pattern/bindings-after-at/bind-by-copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ pub fn main() {
}
match (E::E { a: 10, e: C { c: 20 } }) {
mut x @ E::E{ a, e: C { mut c } } => {
//~^ WARN value assigned to `a` is never read
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line does still trigger the unused_variables lint in respect of a, but that lint is allowed by the test and so is not shown here. I'd be happy to enable it, but there are a bunch of other occasions in the test that would then trigger it (if enabled test-wide; of course I could just enable it for this scope).

x = E::NotE;
//~^ WARN value assigned to `x` is never read
c += 30;
Expand Down
12 changes: 2 additions & 10 deletions tests/ui/pattern/bindings-after-at/bind-by-copy.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,12 @@ LL | y.d.c = 30;
= help: maybe it is overwritten before being read?

warning: value assigned to `x` is never read
--> $DIR/bind-by-copy.rs:57:13
--> $DIR/bind-by-copy.rs:56:13
|
LL | x = E::NotE;
| ^^^^^^^^^^^
|
= help: maybe it is overwritten before being read?

warning: value assigned to `a` is never read
--> $DIR/bind-by-copy.rs:55:23
|
LL | mut x @ E::E{ a, e: C { mut c } } => {
| ^
|
= help: maybe it is overwritten before being read?

warning: 4 warnings emitted
warning: 3 warnings emitted

Loading