Skip to content

Commit 1683189

Browse files
committed
Auto merge of #5889 - ebroto:5886_or_fun_call_const_0_args, r=Manishearth
Avoid or_fun_call for const_fn with no args Based on #5682 by @lzutao This avoids a subset of false positives, specifically those related to `const fn`s that take no arguments. For the rest, a much more involved fix would be needed, see #5682 (comment). So this does *not* solve #5658 changelog: Avoid triggering [`or_fun_call`] with `const fn`s that take no arguments. Fixes #5886
2 parents 4113453 + 5d66bd7 commit 1683189

File tree

3 files changed

+25
-0
lines changed

3 files changed

+25
-0
lines changed

clippy_lints/src/utils/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ use rustc_infer::infer::TyCtxtInferExt;
4343
use rustc_lint::{LateContext, Level, Lint, LintContext};
4444
use rustc_middle::hir::map::Map;
4545
use rustc_middle::ty::{self, layout::IntegerExt, subst::GenericArg, Ty, TyCtxt, TypeFoldable};
46+
use rustc_mir::const_eval;
4647
use rustc_span::hygiene::{ExpnKind, MacroKind};
4748
use rustc_span::source_map::original_sp;
4849
use rustc_span::symbol::{self, kw, Symbol};
@@ -868,11 +869,19 @@ pub fn is_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
868869

869870
/// Checks if an expression is constructing a tuple-like enum variant or struct
870871
pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
872+
fn has_no_arguments(cx: &LateContext<'_>, def_id: DefId) -> bool {
873+
cx.tcx.fn_sig(def_id).skip_binder().inputs().is_empty()
874+
}
875+
871876
if let ExprKind::Call(ref fun, _) = expr.kind {
872877
if let ExprKind::Path(ref qp) = fun.kind {
873878
let res = cx.qpath_res(qp, fun.hir_id);
874879
return match res {
875880
def::Res::Def(DefKind::Variant | DefKind::Ctor(..), ..) => true,
881+
// FIXME: check the constness of the arguments, see https://github.com/rust-lang/rust-clippy/pull/5682#issuecomment-638681210
882+
def::Res::Def(DefKind::Fn, def_id) if has_no_arguments(cx, def_id) => {
883+
const_eval::is_const_fn(cx.tcx, def_id)
884+
},
876885
def::Res::Def(_, def_id) => cx.tcx.is_promotable_const_fn(def_id),
877886
_ => false,
878887
};

tests/ui/or_fun_call.fixed

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,12 @@ fn f() -> Option<()> {
116116
Some(())
117117
}
118118

119+
// Issue 5886 - const fn (with no arguments)
120+
pub fn skip_const_fn_with_no_args() {
121+
const fn foo() -> Option<i32> {
122+
Some(42)
123+
}
124+
let _ = None.or(foo());
125+
}
126+
119127
fn main() {}

tests/ui/or_fun_call.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,12 @@ fn f() -> Option<()> {
116116
Some(())
117117
}
118118

119+
// Issue 5886 - const fn (with no arguments)
120+
pub fn skip_const_fn_with_no_args() {
121+
const fn foo() -> Option<i32> {
122+
Some(42)
123+
}
124+
let _ = None.or(foo());
125+
}
126+
119127
fn main() {}

0 commit comments

Comments
 (0)