Skip to content

Commit dc075b4

Browse files
committed
Change redundant_pattern_matching to also lint std::net::IpAddr
Suggest using utility methods `is_ipv4` and `is_ipv6`.
1 parent f897d27 commit dc075b4

11 files changed

+341
-36
lines changed

clippy_lints/src/matches.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,8 @@ declare_clippy_lint! {
411411
}
412412

413413
declare_clippy_lint! {
414-
/// **What it does:** Lint for redundant pattern matching over `Result`, `Option` or
415-
/// `std::task::Poll`
414+
/// **What it does:** Lint for redundant pattern matching over `Result`, `Option`,
415+
/// `std::task::Poll` or `std::net::IpAddr`
416416
///
417417
/// **Why is this bad?** It's more concise and clear to just use the proper
418418
/// utility function
@@ -423,12 +423,15 @@ declare_clippy_lint! {
423423
///
424424
/// ```rust
425425
/// # use std::task::Poll;
426+
/// # use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
426427
/// if let Ok(_) = Ok::<i32, i32>(42) {}
427428
/// if let Err(_) = Err::<i32, i32>(42) {}
428429
/// if let None = None::<()> {}
429430
/// if let Some(_) = Some(42) {}
430431
/// if let Poll::Pending = Poll::Pending::<()> {}
431432
/// if let Poll::Ready(_) = Poll::Ready(42) {}
433+
/// if let IpAddr::V4(_) = IpAddr::V4(Ipv4Addr::LOCALHOST) {}
434+
/// if let IpAddr::V6(_) = IpAddr::V6(Ipv6Addr::LOCALHOST) {}
432435
/// match Ok::<i32, i32>(42) {
433436
/// Ok(_) => true,
434437
/// Err(_) => false,
@@ -439,12 +442,15 @@ declare_clippy_lint! {
439442
///
440443
/// ```rust
441444
/// # use std::task::Poll;
445+
/// # use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
442446
/// if Ok::<i32, i32>(42).is_ok() {}
443447
/// if Err::<i32, i32>(42).is_err() {}
444448
/// if None::<()>.is_none() {}
445449
/// if Some(42).is_some() {}
446450
/// if Poll::Pending::<()>.is_pending() {}
447451
/// if Poll::Ready(42).is_ready() {}
452+
/// if IpAddr::V4(Ipv4Addr::LOCALHOST).is_ipv4() {}
453+
/// if IpAddr::V6(Ipv6Addr::LOCALHOST).is_ipv6() {}
448454
/// Ok::<i32, i32>(42).is_ok();
449455
/// ```
450456
pub REDUNDANT_PATTERN_MATCHING,
@@ -1546,6 +1552,10 @@ mod redundant_pattern_match {
15461552
"is_some()"
15471553
} else if match_qpath(path, &paths::POLL_READY) {
15481554
"is_ready()"
1555+
} else if match_qpath(path, &paths::IPADDR_V4) {
1556+
"is_ipv4()"
1557+
} else if match_qpath(path, &paths::IPADDR_V6) {
1558+
"is_ipv6()"
15491559
} else {
15501560
return;
15511561
}
@@ -1626,6 +1636,17 @@ mod redundant_pattern_match {
16261636
"is_ok()",
16271637
"is_err()",
16281638
)
1639+
.or_else(|| {
1640+
find_good_method_for_match(
1641+
arms,
1642+
path_left,
1643+
path_right,
1644+
&paths::IPADDR_V4,
1645+
&paths::IPADDR_V6,
1646+
"is_ipv4()",
1647+
"is_ipv6()",
1648+
)
1649+
})
16291650
} else {
16301651
None
16311652
}

clippy_lints/src/utils/paths.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ pub const INTO: [&str; 3] = ["core", "convert", "Into"];
5858
pub const INTO_ITERATOR: [&str; 5] = ["core", "iter", "traits", "collect", "IntoIterator"];
5959
pub const IO_READ: [&str; 3] = ["std", "io", "Read"];
6060
pub const IO_WRITE: [&str; 3] = ["std", "io", "Write"];
61+
pub const IPADDR_V4: [&str; 4] = ["std", "net", "IpAddr", "V4"];
62+
pub const IPADDR_V6: [&str; 4] = ["std", "net", "IpAddr", "V6"];
6163
pub const ITERATOR: [&str; 5] = ["core", "iter", "traits", "iterator", "Iterator"];
6264
pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"];
6365
pub const LINKED_LIST: [&str; 4] = ["alloc", "collections", "linked_list", "LinkedList"];
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// run-rustfix
2+
3+
#![warn(clippy::all)]
4+
#![warn(clippy::redundant_pattern_matching)]
5+
#![allow(unused_must_use, clippy::needless_bool, clippy::match_like_matches_macro)]
6+
7+
use std::net::{
8+
IpAddr::{self, V4, V6},
9+
Ipv4Addr, Ipv6Addr,
10+
};
11+
12+
fn main() {
13+
let ipaddr: IpAddr = V4(Ipv4Addr::LOCALHOST);
14+
if ipaddr.is_ipv4() {}
15+
16+
if V4(Ipv4Addr::LOCALHOST).is_ipv4() {}
17+
18+
if V6(Ipv6Addr::LOCALHOST).is_ipv6() {}
19+
20+
while V4(Ipv4Addr::LOCALHOST).is_ipv4() {}
21+
22+
while V6(Ipv6Addr::LOCALHOST).is_ipv6() {}
23+
24+
if V4(Ipv4Addr::LOCALHOST).is_ipv4() {}
25+
26+
if V6(Ipv6Addr::LOCALHOST).is_ipv6() {}
27+
28+
if let V4(ipaddr) = V4(Ipv4Addr::LOCALHOST) {
29+
println!("{}", ipaddr);
30+
}
31+
32+
V4(Ipv4Addr::LOCALHOST).is_ipv4();
33+
34+
V4(Ipv4Addr::LOCALHOST).is_ipv6();
35+
36+
V6(Ipv6Addr::LOCALHOST).is_ipv6();
37+
38+
V6(Ipv6Addr::LOCALHOST).is_ipv4();
39+
40+
let _ = if V4(Ipv4Addr::LOCALHOST).is_ipv4() {
41+
true
42+
} else {
43+
false
44+
};
45+
46+
ipaddr_const();
47+
48+
let _ = if gen_ipaddr().is_ipv4() {
49+
1
50+
} else if gen_ipaddr().is_ipv6() {
51+
2
52+
} else {
53+
3
54+
};
55+
}
56+
57+
fn gen_ipaddr() -> IpAddr {
58+
V4(Ipv4Addr::LOCALHOST)
59+
}
60+
61+
const fn ipaddr_const() {
62+
if V4(Ipv4Addr::LOCALHOST).is_ipv4() {}
63+
64+
if V6(Ipv6Addr::LOCALHOST).is_ipv6() {}
65+
66+
while V4(Ipv4Addr::LOCALHOST).is_ipv4() {}
67+
68+
while V6(Ipv6Addr::LOCALHOST).is_ipv6() {}
69+
70+
V4(Ipv4Addr::LOCALHOST).is_ipv4();
71+
72+
V6(Ipv6Addr::LOCALHOST).is_ipv6();
73+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// run-rustfix
2+
3+
#![warn(clippy::all)]
4+
#![warn(clippy::redundant_pattern_matching)]
5+
#![allow(unused_must_use, clippy::needless_bool, clippy::match_like_matches_macro)]
6+
7+
use std::net::{
8+
IpAddr::{self, V4, V6},
9+
Ipv4Addr, Ipv6Addr,
10+
};
11+
12+
fn main() {
13+
let ipaddr: IpAddr = V4(Ipv4Addr::LOCALHOST);
14+
if let V4(_) = &ipaddr {}
15+
16+
if let V4(_) = V4(Ipv4Addr::LOCALHOST) {}
17+
18+
if let V6(_) = V6(Ipv6Addr::LOCALHOST) {}
19+
20+
while let V4(_) = V4(Ipv4Addr::LOCALHOST) {}
21+
22+
while let V6(_) = V6(Ipv6Addr::LOCALHOST) {}
23+
24+
if V4(Ipv4Addr::LOCALHOST).is_ipv4() {}
25+
26+
if V6(Ipv6Addr::LOCALHOST).is_ipv6() {}
27+
28+
if let V4(ipaddr) = V4(Ipv4Addr::LOCALHOST) {
29+
println!("{}", ipaddr);
30+
}
31+
32+
match V4(Ipv4Addr::LOCALHOST) {
33+
V4(_) => true,
34+
V6(_) => false,
35+
};
36+
37+
match V4(Ipv4Addr::LOCALHOST) {
38+
V4(_) => false,
39+
V6(_) => true,
40+
};
41+
42+
match V6(Ipv6Addr::LOCALHOST) {
43+
V4(_) => false,
44+
V6(_) => true,
45+
};
46+
47+
match V6(Ipv6Addr::LOCALHOST) {
48+
V4(_) => true,
49+
V6(_) => false,
50+
};
51+
52+
let _ = if let V4(_) = V4(Ipv4Addr::LOCALHOST) {
53+
true
54+
} else {
55+
false
56+
};
57+
58+
ipaddr_const();
59+
60+
let _ = if let V4(_) = gen_ipaddr() {
61+
1
62+
} else if let V6(_) = gen_ipaddr() {
63+
2
64+
} else {
65+
3
66+
};
67+
}
68+
69+
fn gen_ipaddr() -> IpAddr {
70+
V4(Ipv4Addr::LOCALHOST)
71+
}
72+
73+
const fn ipaddr_const() {
74+
if let V4(_) = V4(Ipv4Addr::LOCALHOST) {}
75+
76+
if let V6(_) = V6(Ipv6Addr::LOCALHOST) {}
77+
78+
while let V4(_) = V4(Ipv4Addr::LOCALHOST) {}
79+
80+
while let V6(_) = V6(Ipv6Addr::LOCALHOST) {}
81+
82+
match V4(Ipv4Addr::LOCALHOST) {
83+
V4(_) => true,
84+
V6(_) => false,
85+
};
86+
87+
match V6(Ipv6Addr::LOCALHOST) {
88+
V4(_) => false,
89+
V6(_) => true,
90+
};
91+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
error: redundant pattern matching, consider using `is_ipv4()`
2+
--> $DIR/redundant_pattern_matching_ipaddr.rs:14:12
3+
|
4+
LL | if let V4(_) = &ipaddr {}
5+
| -------^^^^^---------- help: try this: `if ipaddr.is_ipv4()`
6+
|
7+
= note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
8+
9+
error: redundant pattern matching, consider using `is_ipv4()`
10+
--> $DIR/redundant_pattern_matching_ipaddr.rs:16:12
11+
|
12+
LL | if let V4(_) = V4(Ipv4Addr::LOCALHOST) {}
13+
| -------^^^^^-------------------------- help: try this: `if V4(Ipv4Addr::LOCALHOST).is_ipv4()`
14+
15+
error: redundant pattern matching, consider using `is_ipv6()`
16+
--> $DIR/redundant_pattern_matching_ipaddr.rs:18:12
17+
|
18+
LL | if let V6(_) = V6(Ipv6Addr::LOCALHOST) {}
19+
| -------^^^^^-------------------------- help: try this: `if V6(Ipv6Addr::LOCALHOST).is_ipv6()`
20+
21+
error: redundant pattern matching, consider using `is_ipv4()`
22+
--> $DIR/redundant_pattern_matching_ipaddr.rs:20:15
23+
|
24+
LL | while let V4(_) = V4(Ipv4Addr::LOCALHOST) {}
25+
| ----------^^^^^-------------------------- help: try this: `while V4(Ipv4Addr::LOCALHOST).is_ipv4()`
26+
27+
error: redundant pattern matching, consider using `is_ipv6()`
28+
--> $DIR/redundant_pattern_matching_ipaddr.rs:22:15
29+
|
30+
LL | while let V6(_) = V6(Ipv6Addr::LOCALHOST) {}
31+
| ----------^^^^^-------------------------- help: try this: `while V6(Ipv6Addr::LOCALHOST).is_ipv6()`
32+
33+
error: redundant pattern matching, consider using `is_ipv4()`
34+
--> $DIR/redundant_pattern_matching_ipaddr.rs:32:5
35+
|
36+
LL | / match V4(Ipv4Addr::LOCALHOST) {
37+
LL | | V4(_) => true,
38+
LL | | V6(_) => false,
39+
LL | | };
40+
| |_____^ help: try this: `V4(Ipv4Addr::LOCALHOST).is_ipv4()`
41+
42+
error: redundant pattern matching, consider using `is_ipv6()`
43+
--> $DIR/redundant_pattern_matching_ipaddr.rs:37:5
44+
|
45+
LL | / match V4(Ipv4Addr::LOCALHOST) {
46+
LL | | V4(_) => false,
47+
LL | | V6(_) => true,
48+
LL | | };
49+
| |_____^ help: try this: `V4(Ipv4Addr::LOCALHOST).is_ipv6()`
50+
51+
error: redundant pattern matching, consider using `is_ipv6()`
52+
--> $DIR/redundant_pattern_matching_ipaddr.rs:42:5
53+
|
54+
LL | / match V6(Ipv6Addr::LOCALHOST) {
55+
LL | | V4(_) => false,
56+
LL | | V6(_) => true,
57+
LL | | };
58+
| |_____^ help: try this: `V6(Ipv6Addr::LOCALHOST).is_ipv6()`
59+
60+
error: redundant pattern matching, consider using `is_ipv4()`
61+
--> $DIR/redundant_pattern_matching_ipaddr.rs:47:5
62+
|
63+
LL | / match V6(Ipv6Addr::LOCALHOST) {
64+
LL | | V4(_) => true,
65+
LL | | V6(_) => false,
66+
LL | | };
67+
| |_____^ help: try this: `V6(Ipv6Addr::LOCALHOST).is_ipv4()`
68+
69+
error: redundant pattern matching, consider using `is_ipv4()`
70+
--> $DIR/redundant_pattern_matching_ipaddr.rs:52:20
71+
|
72+
LL | let _ = if let V4(_) = V4(Ipv4Addr::LOCALHOST) {
73+
| -------^^^^^-------------------------- help: try this: `if V4(Ipv4Addr::LOCALHOST).is_ipv4()`
74+
75+
error: redundant pattern matching, consider using `is_ipv4()`
76+
--> $DIR/redundant_pattern_matching_ipaddr.rs:60:20
77+
|
78+
LL | let _ = if let V4(_) = gen_ipaddr() {
79+
| -------^^^^^--------------- help: try this: `if gen_ipaddr().is_ipv4()`
80+
81+
error: redundant pattern matching, consider using `is_ipv6()`
82+
--> $DIR/redundant_pattern_matching_ipaddr.rs:62:19
83+
|
84+
LL | } else if let V6(_) = gen_ipaddr() {
85+
| -------^^^^^--------------- help: try this: `if gen_ipaddr().is_ipv6()`
86+
87+
error: redundant pattern matching, consider using `is_ipv4()`
88+
--> $DIR/redundant_pattern_matching_ipaddr.rs:74:12
89+
|
90+
LL | if let V4(_) = V4(Ipv4Addr::LOCALHOST) {}
91+
| -------^^^^^-------------------------- help: try this: `if V4(Ipv4Addr::LOCALHOST).is_ipv4()`
92+
93+
error: redundant pattern matching, consider using `is_ipv6()`
94+
--> $DIR/redundant_pattern_matching_ipaddr.rs:76:12
95+
|
96+
LL | if let V6(_) = V6(Ipv6Addr::LOCALHOST) {}
97+
| -------^^^^^-------------------------- help: try this: `if V6(Ipv6Addr::LOCALHOST).is_ipv6()`
98+
99+
error: redundant pattern matching, consider using `is_ipv4()`
100+
--> $DIR/redundant_pattern_matching_ipaddr.rs:78:15
101+
|
102+
LL | while let V4(_) = V4(Ipv4Addr::LOCALHOST) {}
103+
| ----------^^^^^-------------------------- help: try this: `while V4(Ipv4Addr::LOCALHOST).is_ipv4()`
104+
105+
error: redundant pattern matching, consider using `is_ipv6()`
106+
--> $DIR/redundant_pattern_matching_ipaddr.rs:80:15
107+
|
108+
LL | while let V6(_) = V6(Ipv6Addr::LOCALHOST) {}
109+
| ----------^^^^^-------------------------- help: try this: `while V6(Ipv6Addr::LOCALHOST).is_ipv6()`
110+
111+
error: redundant pattern matching, consider using `is_ipv4()`
112+
--> $DIR/redundant_pattern_matching_ipaddr.rs:82:5
113+
|
114+
LL | / match V4(Ipv4Addr::LOCALHOST) {
115+
LL | | V4(_) => true,
116+
LL | | V6(_) => false,
117+
LL | | };
118+
| |_____^ help: try this: `V4(Ipv4Addr::LOCALHOST).is_ipv4()`
119+
120+
error: redundant pattern matching, consider using `is_ipv6()`
121+
--> $DIR/redundant_pattern_matching_ipaddr.rs:87:5
122+
|
123+
LL | / match V6(Ipv6Addr::LOCALHOST) {
124+
LL | | V4(_) => false,
125+
LL | | V6(_) => true,
126+
LL | | };
127+
| |_____^ help: try this: `V6(Ipv6Addr::LOCALHOST).is_ipv6()`
128+
129+
error: aborting due to 18 previous errors
130+

tests/ui/redundant_pattern_matching_option.fixed

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ fn main() {
3737
let _ = None::<()>.is_none();
3838

3939
let opt = Some(false);
40-
let x = if opt.is_some() { true } else { false };
41-
takes_bool(x);
40+
let _ = if opt.is_some() { true } else { false };
4241

4342
issue6067();
4443

@@ -55,8 +54,6 @@ fn gen_opt() -> Option<()> {
5554
None
5655
}
5756

58-
fn takes_bool(_: bool) {}
59-
6057
fn foo() {}
6158

6259
fn bar() {}

0 commit comments

Comments
 (0)