Skip to content

Commit

Permalink
Rollup merge of rust-lang#50327 - varkor:match-unused-struct-field, r…
Browse files Browse the repository at this point in the history
…=estebank

Display correct unused field suggestion for nested struct patterns

Extends rust-lang#47922 by checking more sophisticated patterns (e.g. references, slices, etc.).
Before:
```
warning: unused variable: `bar`
  --> src/main.rs:37:21
   |
37 |         &Foo::Bar { bar } => true,
   |                     ^^^ help: consider using `_bar` instead
   |
   = note: #[warn(unused_variables)] on by default
```
After:
```
warning: unused variable: `bar`
  --> src/main.rs:37:21
   |
37 |         &Foo::Bar { bar } => true,
   |                     ^^^ help: try ignoring the field: `bar: _`
   |
   = note: #[warn(unused_variables)] on by default
```

Fixes rust-lang#50303.

r? @estebank
  • Loading branch information
kennytm committed Apr 30, 2018
2 parents 30c990b + 2eb8343 commit cbbdf99
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 15 deletions.
44 changes: 35 additions & 9 deletions src/librustc/middle/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ use ty::{self, TyCtxt};
use lint;
use util::nodemap::{NodeMap, NodeSet};

use std::collections::VecDeque;
use std::{fmt, usize};
use std::io::prelude::*;
use std::io;
Expand Down Expand Up @@ -412,18 +413,43 @@ fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) {
}

fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) {
for pat in &arm.pats {
// for struct patterns, take note of which fields used shorthand (`x` rather than `x: x`)
for mut pat in &arm.pats {
// For struct patterns, take note of which fields used shorthand
// (`x` rather than `x: x`).
//
// FIXME: according to the rust-lang-nursery/rustc-guide book, `NodeId`s are to be phased
// out in favor of `HirId`s; however, we need to match the signature of `each_binding`,
// which uses `NodeIds`.
// FIXME: according to the rust-lang-nursery/rustc-guide book, `NodeId`s are to be
// phased out in favor of `HirId`s; however, we need to match the signature of
// `each_binding`, which uses `NodeIds`.
let mut shorthand_field_ids = NodeSet();
if let hir::PatKind::Struct(_, ref fields, _) = pat.node {
for field in fields {
if field.node.is_shorthand {
shorthand_field_ids.insert(field.node.pat.id);
let mut pats = VecDeque::new();
pats.push_back(pat);
while let Some(pat) = pats.pop_front() {
use hir::PatKind::*;
match pat.node {
Binding(_, _, _, ref inner_pat) => {
pats.extend(inner_pat.iter());
}
Struct(_, ref fields, _) => {
for field in fields {
if field.node.is_shorthand {
shorthand_field_ids.insert(field.node.pat.id);
}
}
}
Ref(ref inner_pat, _) |
Box(ref inner_pat) => {
pats.push_back(inner_pat);
}
TupleStruct(_, ref inner_pats, _) |
Tuple(ref inner_pats, _) => {
pats.extend(inner_pats.iter());
}
Slice(ref pre_pats, ref inner_pat, ref post_pats) => {
pats.extend(pre_pats.iter());
pats.extend(inner_pat.iter());
pats.extend(post_pats.iter());
}
_ => {}
}
}

Expand Down
43 changes: 43 additions & 0 deletions src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

// compile-pass

#![feature(box_syntax)]
#![feature(box_patterns)]
#![warn(unused)] // UI tests pass `-A unused` (#43896)

struct SoulHistory {
Expand All @@ -18,6 +20,13 @@ struct SoulHistory {
endless_and_singing: bool
}

#[derive(Clone, Copy)]
enum Large {
Suit { case: () }
}

struct Tuple(Large, ());

fn main() {
let i_think_continually = 2;
let who_from_the_womb_remembered = SoulHistory {
Expand All @@ -31,4 +40,38 @@ fn main() {
endless_and_singing: true } = who_from_the_womb_remembered {
hours_are_suns = false;
}

let bag = Large::Suit {
case: ()
};

// Plain struct
match bag {
Large::Suit { case } => {}
};

// Referenced struct
match &bag {
&Large::Suit { case } => {}
};

// Boxed struct
match box bag {
box Large::Suit { case } => {}
};

// Tuple with struct
match (bag,) {
(Large::Suit { case },) => {}
};

// Slice with struct
match [bag] {
[Large::Suit { case }] => {}
};

// Tuple struct with struct
match Tuple(bag, ()) {
Tuple(Large::Suit { case }, ()) => {}
};
}
Original file line number Diff line number Diff line change
@@ -1,40 +1,76 @@
warning: unused variable: `i_think_continually`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:22:9
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:31:9
|
LL | let i_think_continually = 2;
| ^^^^^^^^^^^^^^^^^^^ help: consider using `_i_think_continually` instead
|
note: lint level defined here
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:13:9
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:15:9
|
LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
| ^^^^^^
= note: #[warn(unused_variables)] implied by #[warn(unused)]

warning: unused variable: `corridors_of_light`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:29:26
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:38:26
|
LL | if let SoulHistory { corridors_of_light,
| ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _`

warning: variable `hours_are_suns` is assigned to, but never used
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:30:26
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:39:26
|
LL | mut hours_are_suns,
| ^^^^^^^^^^^^^^^^^^
|
= note: consider using `_hours_are_suns` instead

warning: value assigned to `hours_are_suns` is never read
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:32:9
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:41:9
|
LL | hours_are_suns = false;
| ^^^^^^^^^^^^^^
|
note: lint level defined here
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:13:9
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:15:9
|
LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
| ^^^^^^
= note: #[warn(unused_assignments)] implied by #[warn(unused)]

warning: unused variable: `case`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:50:23
|
LL | Large::Suit { case } => {}
| ^^^^ help: try ignoring the field: `case: _`

warning: unused variable: `case`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:55:24
|
LL | &Large::Suit { case } => {}
| ^^^^ help: try ignoring the field: `case: _`

warning: unused variable: `case`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:60:27
|
LL | box Large::Suit { case } => {}
| ^^^^ help: try ignoring the field: `case: _`

warning: unused variable: `case`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:65:24
|
LL | (Large::Suit { case },) => {}
| ^^^^ help: try ignoring the field: `case: _`

warning: unused variable: `case`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:70:24
|
LL | [Large::Suit { case }] => {}
| ^^^^ help: try ignoring the field: `case: _`

warning: unused variable: `case`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:75:29
|
LL | Tuple(Large::Suit { case }, ()) => {}
| ^^^^ help: try ignoring the field: `case: _`

0 comments on commit cbbdf99

Please sign in to comment.