Skip to content

Commit c943f4c

Browse files
authored
or_fun_call: also lint and method for Option/Result (#15073)
<strike>build on top of #15071</strike> This also adds ability to lint Option/Result::and method. Yes, this is not `or` method, but uses the same eager/lazy linting logic. Should i update lint description to list all checked structs/methods? changelog: [`or_fun_call`]: lint Option/Result::and
2 parents cc7b2f5 + a82c142 commit c943f4c

File tree

4 files changed

+56
-2
lines changed

4 files changed

+56
-2
lines changed

clippy_lints/src/methods/or_fun_call.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ pub(super) fn check<'tcx>(
136136
fun_span: Option<Span>,
137137
) -> bool {
138138
// (path, fn_has_argument, methods, suffix)
139-
const KNOW_TYPES: [(Symbol, bool, &[Symbol], &str); 5] = [
139+
const KNOW_TYPES: [(Symbol, bool, &[Symbol], &str); 7] = [
140140
(sym::BTreeEntry, false, &[sym::or_insert], "with"),
141141
(sym::HashMapEntry, false, &[sym::or_insert], "with"),
142142
(
@@ -146,7 +146,9 @@ pub(super) fn check<'tcx>(
146146
"else",
147147
),
148148
(sym::Option, false, &[sym::get_or_insert], "with"),
149+
(sym::Option, true, &[sym::and], "then"),
149150
(sym::Result, true, &[sym::map_or, sym::or, sym::unwrap_or], "else"),
151+
(sym::Result, true, &[sym::and], "then"),
150152
];
151153

152154
if KNOW_TYPES.iter().any(|k| k.2.contains(&name))

tests/ui/or_fun_call.fixed

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,4 +439,24 @@ fn test_option_get_or_insert() {
439439
//~^ or_fun_call
440440
}
441441

442+
fn test_option_and() {
443+
// assume that this is slow call
444+
fn g() -> Option<u8> {
445+
Some(99)
446+
}
447+
let mut x = Some(42_u8);
448+
let _ = x.and_then(|_| g());
449+
//~^ or_fun_call
450+
}
451+
452+
fn test_result_and() {
453+
// assume that this is slow call
454+
fn g() -> Result<u8, ()> {
455+
Ok(99)
456+
}
457+
let mut x: Result<u8, ()> = Ok(42);
458+
let _ = x.and_then(|_| g());
459+
//~^ or_fun_call
460+
}
461+
442462
fn main() {}

tests/ui/or_fun_call.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,4 +439,24 @@ fn test_option_get_or_insert() {
439439
//~^ or_fun_call
440440
}
441441

442+
fn test_option_and() {
443+
// assume that this is slow call
444+
fn g() -> Option<u8> {
445+
Some(99)
446+
}
447+
let mut x = Some(42_u8);
448+
let _ = x.and(g());
449+
//~^ or_fun_call
450+
}
451+
452+
fn test_result_and() {
453+
// assume that this is slow call
454+
fn g() -> Result<u8, ()> {
455+
Ok(99)
456+
}
457+
let mut x: Result<u8, ()> = Ok(42);
458+
let _ = x.and(g());
459+
//~^ or_fun_call
460+
}
461+
442462
fn main() {}

tests/ui/or_fun_call.stderr

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,5 +264,17 @@ error: function call inside of `get_or_insert`
264264
LL | let _ = x.get_or_insert(g());
265265
| ^^^^^^^^^^^^^^^^^^ help: try: `get_or_insert_with(g)`
266266

267-
error: aborting due to 41 previous errors
267+
error: function call inside of `and`
268+
--> tests/ui/or_fun_call.rs:448:15
269+
|
270+
LL | let _ = x.and(g());
271+
| ^^^^^^^^ help: try: `and_then(|_| g())`
272+
273+
error: function call inside of `and`
274+
--> tests/ui/or_fun_call.rs:458:15
275+
|
276+
LL | let _ = x.and(g());
277+
| ^^^^^^^^ help: try: `and_then(|_| g())`
278+
279+
error: aborting due to 43 previous errors
268280

0 commit comments

Comments
 (0)