From 5d66bd7bb3fd701d70ec11217e3f89fabe5cb0a7 Mon Sep 17 00:00:00 2001 From: Eduardo Broto Date: Mon, 10 Aug 2020 23:38:58 +0200 Subject: [PATCH] Avoid or_fun_call for const_fn with no args --- clippy_lints/src/utils/mod.rs | 9 +++++++++ tests/ui/or_fun_call.fixed | 8 ++++++++ tests/ui/or_fun_call.rs | 8 ++++++++ 3 files changed, 25 insertions(+) diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 9f967d59c8b..223628cc610 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -43,6 +43,7 @@ use rustc_lint::{LateContext, Level, Lint, LintContext}; use rustc_middle::hir::map::Map; use rustc_middle::ty::{self, layout::IntegerExt, subst::GenericArg, Ty, TyCtxt, TypeFoldable}; +use rustc_mir::const_eval; use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::source_map::original_sp; use rustc_span::symbol::{self, kw, Symbol}; @@ -868,11 +869,19 @@ pub fn is_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { /// Checks if an expression is constructing a tuple-like enum variant or struct pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { + fn has_no_arguments(cx: &LateContext<'_>, def_id: DefId) -> bool { + cx.tcx.fn_sig(def_id).skip_binder().inputs().is_empty() + } + if let ExprKind::Call(ref fun, _) = expr.kind { if let ExprKind::Path(ref qp) = fun.kind { let res = cx.qpath_res(qp, fun.hir_id); return match res { def::Res::Def(DefKind::Variant | DefKind::Ctor(..), ..) => true, + // FIXME: check the constness of the arguments, see https://github.com/rust-lang/rust-clippy/pull/5682#issuecomment-638681210 + def::Res::Def(DefKind::Fn, def_id) if has_no_arguments(cx, def_id) => { + const_eval::is_const_fn(cx.tcx, def_id) + }, 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 2045ffdb5f0..67faa8bd4a0 100644 --- a/tests/ui/or_fun_call.fixed +++ b/tests/ui/or_fun_call.fixed @@ -116,4 +116,12 @@ fn f() -> Option<()> { Some(()) } +// Issue 5886 - const fn (with no arguments) +pub fn skip_const_fn_with_no_args() { + const fn foo() -> Option { + Some(42) + } + let _ = None.or(foo()); +} + fn main() {} diff --git a/tests/ui/or_fun_call.rs b/tests/ui/or_fun_call.rs index 522f31b72d0..9867e2eedcf 100644 --- a/tests/ui/or_fun_call.rs +++ b/tests/ui/or_fun_call.rs @@ -116,4 +116,12 @@ fn f() -> Option<()> { Some(()) } +// Issue 5886 - const fn (with no arguments) +pub fn skip_const_fn_with_no_args() { + const fn foo() -> Option { + Some(42) + } + let _ = None.or(foo()); +} + fn main() {} -- 2.44.0