diff --git a/clippy_lints/src/missing_const_for_fn.rs b/clippy_lints/src/missing_const_for_fn.rs index bad9e0be82e61..ecc9acf4445d0 100644 --- a/clippy_lints/src/missing_const_for_fn.rs +++ b/clippy_lints/src/missing_const_for_fn.rs @@ -3,6 +3,7 @@ use clippy_utils::qualify_min_const_fn::is_min_const_fn; use clippy_utils::ty::has_drop; use clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, meets_msrv, msrvs, trait_ref_of_method}; use rustc_hir as hir; +use rustc_hir::def_id::CRATE_DEF_ID; use rustc_hir::intravisit::FnKind; use rustc_hir::{Body, Constness, FnDecl, GenericParamKind, HirId}; use rustc_lint::{LateContext, LateLintPass}; @@ -131,6 +132,18 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { FnKind::Closure => return, } + // Const fns are not allowed as methods in a trait. + { + let parent = cx.tcx.hir().get_parent_item(hir_id); + if parent != CRATE_DEF_ID { + if let hir::Node::Item(item) = cx.tcx.hir().get_by_def_id(parent) { + if let hir::ItemKind::Trait(..) = &item.kind { + return; + } + } + } + } + let mir = cx.tcx.optimized_mir(def_id); if let Err((span, err)) = is_min_const_fn(cx.tcx, mir, self.msrv.as_ref()) { diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index c039fec955db9..891531951c1a0 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -32,32 +32,12 @@ pub fn is_min_const_fn<'a, 'tcx>(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, msrv: | ty::PredicateKind::Projection(_) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Trait(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => continue, ty::PredicateKind::ObjectSafe(_) => panic!("object safe predicate on function: {:#?}", predicate), ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {:#?}", predicate), ty::PredicateKind::Subtype(_) => panic!("subtype predicate on function: {:#?}", predicate), ty::PredicateKind::Coerce(_) => panic!("coerce predicate on function: {:#?}", predicate), - ty::PredicateKind::Trait(pred) => { - if Some(pred.def_id()) == tcx.lang_items().sized_trait() { - continue; - } - match pred.self_ty().kind() { - ty::Param(ref p) => { - let generics = tcx.generics_of(current); - let def = generics.type_param(p, tcx); - let span = tcx.def_span(def.def_id); - return Err(( - span, - "trait bounds other than `Sized` \ - on const fn parameters are unstable" - .into(), - )); - }, - // other kinds of bounds are either tautologies - // or cause errors in other passes - _ => continue, - } - }, } } match predicates.parent { diff --git a/tests/ui/missing_const_for_fn/could_be_const.rs b/tests/ui/missing_const_for_fn/could_be_const.rs index baa7eec05462e..88f6935d224ae 100644 --- a/tests/ui/missing_const_for_fn/could_be_const.rs +++ b/tests/ui/missing_const_for_fn/could_be_const.rs @@ -49,8 +49,6 @@ fn sub(x: u32) -> usize { unsafe { transmute(&x) } } -// NOTE: This is currently not yet allowed to be const -// Once implemented, Clippy should be able to suggest this as const, too. fn generic_arr(t: [T; 1]) -> T { t[0] } diff --git a/tests/ui/missing_const_for_fn/could_be_const.stderr b/tests/ui/missing_const_for_fn/could_be_const.stderr index b89cc6451bb59..3eb52b6827475 100644 --- a/tests/ui/missing_const_for_fn/could_be_const.stderr +++ b/tests/ui/missing_const_for_fn/could_be_const.stderr @@ -58,7 +58,15 @@ LL | | } | |_^ error: this could be a `const fn` - --> $DIR/could_be_const.rs:67:9 + --> $DIR/could_be_const.rs:52:1 + | +LL | / fn generic_arr(t: [T; 1]) -> T { +LL | | t[0] +LL | | } + | |_^ + +error: this could be a `const fn` + --> $DIR/could_be_const.rs:65:9 | LL | / pub fn b(self, a: &A) -> B { LL | | B @@ -66,12 +74,12 @@ LL | | } | |_________^ error: this could be a `const fn` - --> $DIR/could_be_const.rs:77:5 + --> $DIR/could_be_const.rs:75:5 | LL | / fn const_fn_stabilized_before_msrv(byte: u8) { LL | | byte.is_ascii_digit(); LL | | } | |_____^ -error: aborting due to 9 previous errors +error: aborting due to 10 previous errors