Skip to content

Commit 7c828e6

Browse files
or_fun_call: lint more methods (#15071)
Extend `or_fun_call` lint with new checks for Option::get_or_insert, Result::map_or. changelog: [`or_fun_call`]: lint more methods
2 parents 4ead403 + ea72620 commit 7c828e6

File tree

10 files changed

+136
-54
lines changed

10 files changed

+136
-54
lines changed

clippy_dev/src/lint.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub fn run<'a>(path: &str, edition: &str, args: impl Iterator<Item = &'a String>
1313

1414
if is_file {
1515
exit_if_err(
16-
Command::new(env::var("CARGO").unwrap_or("cargo".into()))
16+
Command::new(env::var("CARGO").unwrap_or_else(|_| "cargo".into()))
1717
.args(["run", "--bin", "clippy-driver", "--"])
1818
.args(["-L", "./target/debug"])
1919
.args(["-Z", "no-codegen"])
@@ -26,7 +26,7 @@ pub fn run<'a>(path: &str, edition: &str, args: impl Iterator<Item = &'a String>
2626
);
2727
} else {
2828
exit_if_err(
29-
Command::new(env::var("CARGO").unwrap_or("cargo".into()))
29+
Command::new(env::var("CARGO").unwrap_or_else(|_| "cargo".into()))
3030
.arg("build")
3131
.status(),
3232
);

clippy_dev/src/serve.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub fn run(port: u16, lint: Option<String>) -> ! {
2828
.map(mtime);
2929

3030
if times.iter().any(|&time| index_time < time) {
31-
Command::new(env::var("CARGO").unwrap_or("cargo".into()))
31+
Command::new(env::var("CARGO").unwrap_or_else(|_| "cargo".into()))
3232
.arg("collect-metadata")
3333
.spawn()
3434
.unwrap()

clippy_lints/src/attrs/utils.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,13 @@ pub(super) fn is_relevant_trait(cx: &LateContext<'_>, item: &TraitItem<'_>) -> b
4646
}
4747

4848
fn is_relevant_block(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_>, block: &Block<'_>) -> bool {
49-
block.stmts.first().map_or(
50-
block
51-
.expr
52-
.as_ref()
53-
.is_some_and(|e| is_relevant_expr(cx, typeck_results, e)),
49+
block.stmts.first().map_or_else(
50+
|| {
51+
block
52+
.expr
53+
.as_ref()
54+
.is_some_and(|e| is_relevant_expr(cx, typeck_results, e))
55+
},
5456
|stmt| match &stmt.kind {
5557
StmtKind::Let(_) => true,
5658
StmtKind::Expr(expr) | StmtKind::Semi(expr) => is_relevant_expr(cx, typeck_results, expr),

clippy_lints/src/methods/or_fun_call.rs

Lines changed: 6 additions & 5 deletions
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); 4] = [
139+
const KNOW_TYPES: [(Symbol, bool, &[Symbol], &str); 5] = [
140140
(sym::BTreeEntry, false, &[sym::or_insert], "with"),
141141
(sym::HashMapEntry, false, &[sym::or_insert], "with"),
142142
(
@@ -145,16 +145,17 @@ pub(super) fn check<'tcx>(
145145
&[sym::map_or, sym::ok_or, sym::or, sym::unwrap_or],
146146
"else",
147147
),
148-
(sym::Result, true, &[sym::or, sym::unwrap_or], "else"),
148+
(sym::Option, false, &[sym::get_or_insert], "with"),
149+
(sym::Result, true, &[sym::map_or, sym::or, sym::unwrap_or], "else"),
149150
];
150151

151152
if KNOW_TYPES.iter().any(|k| k.2.contains(&name))
152153
&& switch_to_lazy_eval(cx, arg)
153154
&& !contains_return(arg)
154155
&& let self_ty = cx.typeck_results().expr_ty(self_expr)
155-
&& let Some(&(_, fn_has_arguments, poss, suffix)) =
156-
KNOW_TYPES.iter().find(|&&i| is_type_diagnostic_item(cx, self_ty, i.0))
157-
&& poss.contains(&name)
156+
&& let Some(&(_, fn_has_arguments, _, suffix)) = KNOW_TYPES
157+
.iter()
158+
.find(|&&i| is_type_diagnostic_item(cx, self_ty, i.0) && i.2.contains(&name))
158159
{
159160
let ctxt = span.ctxt();
160161
let mut app = Applicability::HasPlaceholders;

clippy_utils/src/sym.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ generate! {
167167
futures_util,
168168
get,
169169
get_mut,
170+
get_or_insert,
170171
get_or_insert_with,
171172
get_unchecked,
172173
get_unchecked_mut,

lintcheck/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use rayon::prelude::*;
4545

4646
#[must_use]
4747
pub fn target_dir() -> String {
48-
env::var("CARGO_TARGET_DIR").unwrap_or("target".to_owned())
48+
env::var("CARGO_TARGET_DIR").unwrap_or_else(|_| "target".to_owned())
4949
}
5050

5151
fn lintcheck_sources() -> String {

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl ClippyCmd {
107107
}
108108

109109
fn into_std_cmd(self) -> Command {
110-
let mut cmd = Command::new(env::var("CARGO").unwrap_or("cargo".into()));
110+
let mut cmd = Command::new(env::var("CARGO").unwrap_or_else(|_| "cargo".into()));
111111
let clippy_args: String = self
112112
.clippy_args
113113
.iter()

tests/ui/or_fun_call.fixed

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
clippy::uninlined_format_args,
66
clippy::unnecessary_wraps,
77
clippy::unnecessary_literal_unwrap,
8+
clippy::unnecessary_result_map_or_else,
89
clippy::useless_vec
910
)]
1011

@@ -409,4 +410,33 @@ fn fn_call_in_nested_expr() {
409410
//~^ or_fun_call
410411
}
411412

413+
mod result_map_or {
414+
fn g() -> i32 {
415+
3
416+
}
417+
418+
fn f(n: i32) -> i32 {
419+
n
420+
}
421+
422+
fn test_map_or() {
423+
let x: Result<i32, ()> = Ok(4);
424+
let _ = x.map_or_else(|_| g(), |v| v);
425+
//~^ or_fun_call
426+
let _ = x.map_or_else(|_| g(), f);
427+
//~^ or_fun_call
428+
let _ = x.map_or(0, f);
429+
}
430+
}
431+
432+
fn test_option_get_or_insert() {
433+
// assume that this is slow call
434+
fn g() -> u8 {
435+
99
436+
}
437+
let mut x = Some(42_u8);
438+
let _ = x.get_or_insert_with(g);
439+
//~^ or_fun_call
440+
}
441+
412442
fn main() {}

tests/ui/or_fun_call.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
clippy::uninlined_format_args,
66
clippy::unnecessary_wraps,
77
clippy::unnecessary_literal_unwrap,
8+
clippy::unnecessary_result_map_or_else,
89
clippy::useless_vec
910
)]
1011

@@ -409,4 +410,33 @@ fn fn_call_in_nested_expr() {
409410
//~^ or_fun_call
410411
}
411412

413+
mod result_map_or {
414+
fn g() -> i32 {
415+
3
416+
}
417+
418+
fn f(n: i32) -> i32 {
419+
n
420+
}
421+
422+
fn test_map_or() {
423+
let x: Result<i32, ()> = Ok(4);
424+
let _ = x.map_or(g(), |v| v);
425+
//~^ or_fun_call
426+
let _ = x.map_or(g(), f);
427+
//~^ or_fun_call
428+
let _ = x.map_or(0, f);
429+
}
430+
}
431+
432+
fn test_option_get_or_insert() {
433+
// assume that this is slow call
434+
fn g() -> u8 {
435+
99
436+
}
437+
let mut x = Some(42_u8);
438+
let _ = x.get_or_insert(g());
439+
//~^ or_fun_call
440+
}
441+
412442
fn main() {}

0 commit comments

Comments
 (0)