Skip to content

Commit 2eb8343

Browse files
committed
Correct unused field warning on struct match container patterns
1 parent 8e8fe90 commit 2eb8343

File tree

3 files changed

+77
-13
lines changed

3 files changed

+77
-13
lines changed

src/librustc/middle/liveness.rs

+22-7
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ use ty::{self, TyCtxt};
111111
use lint;
112112
use util::nodemap::{NodeMap, NodeSet};
113113

114+
use std::collections::VecDeque;
114115
use std::{fmt, usize};
115116
use std::io::prelude::*;
116117
use std::io;
@@ -420,21 +421,35 @@ fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) {
420421
// phased out in favor of `HirId`s; however, we need to match the signature of
421422
// `each_binding`, which uses `NodeIds`.
422423
let mut shorthand_field_ids = NodeSet();
423-
loop {
424+
let mut pats = VecDeque::new();
425+
pats.push_back(pat);
426+
while let Some(pat) = pats.pop_front() {
427+
use hir::PatKind::*;
424428
match pat.node {
425-
hir::PatKind::Struct(_, ref fields, _) => {
429+
Binding(_, _, _, ref inner_pat) => {
430+
pats.extend(inner_pat.iter());
431+
}
432+
Struct(_, ref fields, _) => {
426433
for field in fields {
427434
if field.node.is_shorthand {
428435
shorthand_field_ids.insert(field.node.pat.id);
429436
}
430437
}
431-
break;
432438
}
433-
hir::PatKind::Ref(ref inner_pat, _) |
434-
hir::PatKind::Box(ref inner_pat) => {
435-
pat = inner_pat;
439+
Ref(ref inner_pat, _) |
440+
Box(ref inner_pat) => {
441+
pats.push_back(inner_pat);
442+
}
443+
TupleStruct(_, ref inner_pats, _) |
444+
Tuple(ref inner_pats, _) => {
445+
pats.extend(inner_pats.iter());
446+
}
447+
Slice(ref pre_pats, ref inner_pat, ref post_pats) => {
448+
pats.extend(pre_pats.iter());
449+
pats.extend(inner_pat.iter());
450+
pats.extend(post_pats.iter());
436451
}
437-
_ => break
452+
_ => {}
438453
}
439454
}
440455

src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs

+25
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,13 @@ struct SoulHistory {
2020
endless_and_singing: bool
2121
}
2222

23+
#[derive(Clone, Copy)]
2324
enum Large {
2425
Suit { case: () }
2526
}
2627

28+
struct Tuple(Large, ());
29+
2730
fn main() {
2831
let i_think_continually = 2;
2932
let who_from_the_womb_remembered = SoulHistory {
@@ -42,11 +45,33 @@ fn main() {
4245
case: ()
4346
};
4447

48+
// Plain struct
49+
match bag {
50+
Large::Suit { case } => {}
51+
};
52+
53+
// Referenced struct
4554
match &bag {
4655
&Large::Suit { case } => {}
4756
};
4857

58+
// Boxed struct
4959
match box bag {
5060
box Large::Suit { case } => {}
5161
};
62+
63+
// Tuple with struct
64+
match (bag,) {
65+
(Large::Suit { case },) => {}
66+
};
67+
68+
// Slice with struct
69+
match [bag] {
70+
[Large::Suit { case }] => {}
71+
};
72+
73+
// Tuple struct with struct
74+
match Tuple(bag, ()) {
75+
Tuple(Large::Suit { case }, ()) => {}
76+
};
5277
}

src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr

+30-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
warning: unused variable: `i_think_continually`
2-
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:28:9
2+
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:31:9
33
|
44
LL | let i_think_continually = 2;
55
| ^^^^^^^^^^^^^^^^^^^ help: consider using `_i_think_continually` instead
@@ -12,21 +12,21 @@ LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
1212
= note: #[warn(unused_variables)] implied by #[warn(unused)]
1313

1414
warning: unused variable: `corridors_of_light`
15-
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:35:26
15+
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:38:26
1616
|
1717
LL | if let SoulHistory { corridors_of_light,
1818
| ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _`
1919

2020
warning: variable `hours_are_suns` is assigned to, but never used
21-
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:36:26
21+
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:39:26
2222
|
2323
LL | mut hours_are_suns,
2424
| ^^^^^^^^^^^^^^^^^^
2525
|
2626
= note: consider using `_hours_are_suns` instead
2727

2828
warning: value assigned to `hours_are_suns` is never read
29-
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:38:9
29+
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:41:9
3030
|
3131
LL | hours_are_suns = false;
3232
| ^^^^^^^^^^^^^^
@@ -39,14 +39,38 @@ LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
3939
= note: #[warn(unused_assignments)] implied by #[warn(unused)]
4040

4141
warning: unused variable: `case`
42-
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:46:24
42+
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:50:23
43+
|
44+
LL | Large::Suit { case } => {}
45+
| ^^^^ help: try ignoring the field: `case: _`
46+
47+
warning: unused variable: `case`
48+
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:55:24
4349
|
4450
LL | &Large::Suit { case } => {}
4551
| ^^^^ help: try ignoring the field: `case: _`
4652

4753
warning: unused variable: `case`
48-
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:50:27
54+
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:60:27
4955
|
5056
LL | box Large::Suit { case } => {}
5157
| ^^^^ help: try ignoring the field: `case: _`
5258

59+
warning: unused variable: `case`
60+
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:65:24
61+
|
62+
LL | (Large::Suit { case },) => {}
63+
| ^^^^ help: try ignoring the field: `case: _`
64+
65+
warning: unused variable: `case`
66+
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:70:24
67+
|
68+
LL | [Large::Suit { case }] => {}
69+
| ^^^^ help: try ignoring the field: `case: _`
70+
71+
warning: unused variable: `case`
72+
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:75:29
73+
|
74+
LL | Tuple(Large::Suit { case }, ()) => {}
75+
| ^^^^ help: try ignoring the field: `case: _`
76+

0 commit comments

Comments
 (0)