mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-16 01:38:09 +00:00
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 https://github.com/rust-lang/rust-clippy/pull/5682#issuecomment-638681210. So this does *not* solve #5658 changelog: Avoid triggering [`or_fun_call`] with `const fn`s that take no arguments. Fixes #5886
This commit is contained in:
commit
16831891da
3 changed files with 25 additions and 0 deletions
|
@ -43,6 +43,7 @@ use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_lint::{LateContext, Level, Lint, LintContext};
|
use rustc_lint::{LateContext, Level, Lint, LintContext};
|
||||||
use rustc_middle::hir::map::Map;
|
use rustc_middle::hir::map::Map;
|
||||||
use rustc_middle::ty::{self, layout::IntegerExt, subst::GenericArg, Ty, TyCtxt, TypeFoldable};
|
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::hygiene::{ExpnKind, MacroKind};
|
||||||
use rustc_span::source_map::original_sp;
|
use rustc_span::source_map::original_sp;
|
||||||
use rustc_span::symbol::{self, kw, Symbol};
|
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
|
/// 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 {
|
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::Call(ref fun, _) = expr.kind {
|
||||||
if let ExprKind::Path(ref qp) = fun.kind {
|
if let ExprKind::Path(ref qp) = fun.kind {
|
||||||
let res = cx.qpath_res(qp, fun.hir_id);
|
let res = cx.qpath_res(qp, fun.hir_id);
|
||||||
return match res {
|
return match res {
|
||||||
def::Res::Def(DefKind::Variant | DefKind::Ctor(..), ..) => true,
|
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),
|
def::Res::Def(_, def_id) => cx.tcx.is_promotable_const_fn(def_id),
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
|
@ -116,4 +116,12 @@ fn f() -> Option<()> {
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue 5886 - const fn (with no arguments)
|
||||||
|
pub fn skip_const_fn_with_no_args() {
|
||||||
|
const fn foo() -> Option<i32> {
|
||||||
|
Some(42)
|
||||||
|
}
|
||||||
|
let _ = None.or(foo());
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -116,4 +116,12 @@ fn f() -> Option<()> {
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue 5886 - const fn (with no arguments)
|
||||||
|
pub fn skip_const_fn_with_no_args() {
|
||||||
|
const fn foo() -> Option<i32> {
|
||||||
|
Some(42)
|
||||||
|
}
|
||||||
|
let _ = None.or(foo());
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
Loading…
Reference in a new issue