diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index a9c0ff24fa60..477af3dbd12f 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -1685,12 +1685,7 @@ fn lint_or_fun_call<'a, 'tcx>( if path.ident.as_str() == "len" { let ty = walk_ptrs_ty(cx.tables.expr_ty(&args[0])); - match ty.kind { - ty::Slice(_) | ty::Array(_, _) => return, - _ => (), - } - - if match_type(cx, ty, &paths::VEC) { + if matches!(ty.kind, ty::Slice(_) | ty::Array(..)) || match_type(cx, ty, &paths::VEC) { return; } } diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 7e07e7751e34..d0acd2b56ccf 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -911,6 +911,7 @@ pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_, '_>, expr: &Exp if let ExprKind::Path(ref qp) = fun.kind { let res = cx.tables.qpath_res(qp, fun.hir_id); return match res { + def::Res::Def(DefKind::Fn, def_id) => rustc_mir::const_eval::is_const_fn(cx.tcx, def_id), def::Res::Def(DefKind::Variant | DefKind::Ctor(..), ..) => true, def::Res::Def(_, def_id) => cx.tcx.is_promotable_const_fn(def_id), _ => false, diff --git a/tests/ui/or_fun_call.fixed b/tests/ui/or_fun_call.fixed index 7bb08797ef39..576cd1803ec6 100644 --- a/tests/ui/or_fun_call.fixed +++ b/tests/ui/or_fun_call.fixed @@ -1,14 +1,13 @@ // run-rustfix #![warn(clippy::or_fun_call)] -#![allow(dead_code)] use std::collections::BTreeMap; use std::collections::HashMap; use std::time::Duration; /// Checks implementation of the `OR_FUN_CALL` lint. -fn or_fun_call() { +pub fn or_fun_call() { struct Foo; impl Foo { @@ -75,7 +74,7 @@ fn or_fun_call() { struct Foo(u8); struct Bar(String, Duration); #[rustfmt::skip] -fn test_or_with_ctors() { +pub fn test_or_with_ctors() { let opt = Some(1); let opt_opt = Some(Some(1)); // we also test for const promotion, this makes sure we don't hit that @@ -107,7 +106,7 @@ fn test_or_with_ctors() { } // Issue 4514 - early return -fn f() -> Option<()> { +pub fn f() -> Option<()> { let a = Some(1); let b = 1i32; @@ -116,4 +115,11 @@ fn f() -> Option<()> { Some(()) } +pub fn skip_const_fn() { + const fn foo(v: i32) -> Option { + Some(v) + } + let _ = None.or(foo(42)); +} + fn main() {} diff --git a/tests/ui/or_fun_call.rs b/tests/ui/or_fun_call.rs index 522f31b72d01..69a262fee472 100644 --- a/tests/ui/or_fun_call.rs +++ b/tests/ui/or_fun_call.rs @@ -1,14 +1,13 @@ // run-rustfix #![warn(clippy::or_fun_call)] -#![allow(dead_code)] use std::collections::BTreeMap; use std::collections::HashMap; use std::time::Duration; /// Checks implementation of the `OR_FUN_CALL` lint. -fn or_fun_call() { +pub fn or_fun_call() { struct Foo; impl Foo { @@ -75,7 +74,7 @@ fn or_fun_call() { struct Foo(u8); struct Bar(String, Duration); #[rustfmt::skip] -fn test_or_with_ctors() { +pub fn test_or_with_ctors() { let opt = Some(1); let opt_opt = Some(Some(1)); // we also test for const promotion, this makes sure we don't hit that @@ -107,7 +106,7 @@ fn test_or_with_ctors() { } // Issue 4514 - early return -fn f() -> Option<()> { +pub fn f() -> Option<()> { let a = Some(1); let b = 1i32; @@ -116,4 +115,11 @@ fn f() -> Option<()> { Some(()) } +pub fn skip_const_fn() { + const fn foo(v: i32) -> Option { + Some(v) + } + let _ = None.or(foo(42)); +} + fn main() {} diff --git a/tests/ui/or_fun_call.stderr b/tests/ui/or_fun_call.stderr index 96d55771e6ce..16755502cd2c 100644 --- a/tests/ui/or_fun_call.stderr +++ b/tests/ui/or_fun_call.stderr @@ -1,5 +1,5 @@ error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:35:22 + --> $DIR/or_fun_call.rs:34:22 | LL | with_constructor.unwrap_or(make()); | ^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(make)` @@ -7,73 +7,73 @@ LL | with_constructor.unwrap_or(make()); = note: `-D clippy::or-fun-call` implied by `-D warnings` error: use of `unwrap_or` followed by a call to `new` - --> $DIR/or_fun_call.rs:38:5 + --> $DIR/or_fun_call.rs:37:5 | LL | with_new.unwrap_or(Vec::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_new.unwrap_or_default()` error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:41:21 + --> $DIR/or_fun_call.rs:40:21 | LL | with_const_args.unwrap_or(Vec::with_capacity(12)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| Vec::with_capacity(12))` error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:44:14 + --> $DIR/or_fun_call.rs:43:14 | LL | with_err.unwrap_or(make()); | ^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|_| make())` error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:47:19 + --> $DIR/or_fun_call.rs:46:19 | LL | with_err_args.unwrap_or(Vec::with_capacity(12)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|_| Vec::with_capacity(12))` error: use of `unwrap_or` followed by a call to `default` - --> $DIR/or_fun_call.rs:50:5 + --> $DIR/or_fun_call.rs:49:5 | LL | with_default_trait.unwrap_or(Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_default_trait.unwrap_or_default()` error: use of `unwrap_or` followed by a call to `default` - --> $DIR/or_fun_call.rs:53:5 + --> $DIR/or_fun_call.rs:52:5 | LL | with_default_type.unwrap_or(u64::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_default_type.unwrap_or_default()` error: use of `unwrap_or` followed by a call to `new` - --> $DIR/or_fun_call.rs:56:5 + --> $DIR/or_fun_call.rs:55:5 | LL | with_vec.unwrap_or(vec![]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_vec.unwrap_or_default()` error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:59:21 + --> $DIR/or_fun_call.rs:58:21 | LL | without_default.unwrap_or(Foo::new()); | ^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(Foo::new)` error: use of `or_insert` followed by a function call - --> $DIR/or_fun_call.rs:62:19 + --> $DIR/or_fun_call.rs:61:19 | LL | map.entry(42).or_insert(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_insert_with(String::new)` error: use of `or_insert` followed by a function call - --> $DIR/or_fun_call.rs:65:21 + --> $DIR/or_fun_call.rs:64:21 | LL | btree.entry(42).or_insert(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_insert_with(String::new)` error: use of `unwrap_or` followed by a function call - --> $DIR/or_fun_call.rs:68:21 + --> $DIR/or_fun_call.rs:67:21 | LL | let _ = stringy.unwrap_or("".to_owned()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| "".to_owned())` error: use of `or` followed by a function call - --> $DIR/or_fun_call.rs:93:35 + --> $DIR/or_fun_call.rs:92:35 | LL | let _ = Some("a".to_string()).or(Some("b".to_string())); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_else(|| Some("b".to_string()))`