Skip to content

Check MSRV before suggesting applying const to a function #15080

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clippy_utils/src/msrvs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ msrv_aliases! {
1,65,0 { LET_ELSE, POINTER_CAST_CONSTNESS }
1,63,0 { CLONE_INTO, CONST_SLICE_FROM_REF }
1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE, CONST_EXTERN_C_FN }
1,61,0 { CONST_FN_TRAIT_BOUND }
1,60,0 { ABS_DIFF }
1,59,0 { THREAD_LOCAL_CONST_INIT }
1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY, CONST_RAW_PTR_DEREF }
Expand Down
13 changes: 13 additions & 0 deletions clippy_utils/src/qualify_min_const_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,19 @@ pub fn is_min_const_fn<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, msrv: Ms
for local in &body.local_decls {
check_ty(cx, local.ty, local.source_info.span, msrv)?;
}
if !msrv.meets(cx, msrvs::CONST_FN_TRAIT_BOUND)
&& let Some(sized_did) = cx.tcx.lang_items().sized_trait()
&& cx.tcx.param_env(def_id).caller_bounds().iter().any(|bound| {
bound
.as_trait_clause()
.is_some_and(|clause| clause.def_id() != sized_did)
})
{
return Err((
body.span,
"non-`Sized` trait clause before `const_fn_trait_bound` is stabilized".into(),
));
}
// impl trait is gone in MIR, so check the return type manually
check_ty(
cx,
Expand Down
57 changes: 57 additions & 0 deletions tests/ui/missing_const_for_fn/could_be_const.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,60 @@ const fn mut_add(x: &mut i32) {
//~^ missing_const_for_fn
*x += 1;
}

mod issue_15079 {
pub trait Trait {}

pub struct Struct<T: Trait> {
_t: Option<T>,
}

impl<T: Trait> Struct<T> {
#[clippy::msrv = "1.60"]
pub fn new_1_60() -> Self {
Self { _t: None }
}

#[clippy::msrv = "1.61"]
pub const fn new_1_61() -> Self {
//~^ missing_const_for_fn
Self { _t: None }
}
}

pub struct S2<T> {
_t: Option<T>,
}

impl<T> S2<T> {
#[clippy::msrv = "1.60"]
pub const fn new_1_60() -> Self {
//~^ missing_const_for_fn
Self { _t: None }
}

#[clippy::msrv = "1.61"]
pub const fn new_1_61() -> Self {
//~^ missing_const_for_fn
Self { _t: None }
}
}

pub struct S3<T: ?Sized + 'static> {
_t: Option<&'static T>,
}

impl<T: ?Sized + 'static> S3<T> {
#[clippy::msrv = "1.60"]
pub const fn new_1_60() -> Self {
//~^ missing_const_for_fn
Self { _t: None }
}

#[clippy::msrv = "1.61"]
pub const fn new_1_61() -> Self {
//~^ missing_const_for_fn
Self { _t: None }
}
}
}
57 changes: 57 additions & 0 deletions tests/ui/missing_const_for_fn/could_be_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,60 @@ fn mut_add(x: &mut i32) {
//~^ missing_const_for_fn
*x += 1;
}

mod issue_15079 {
pub trait Trait {}

pub struct Struct<T: Trait> {
_t: Option<T>,
}

impl<T: Trait> Struct<T> {
#[clippy::msrv = "1.60"]
pub fn new_1_60() -> Self {
Self { _t: None }
}

#[clippy::msrv = "1.61"]
pub fn new_1_61() -> Self {
//~^ missing_const_for_fn
Self { _t: None }
}
}

pub struct S2<T> {
_t: Option<T>,
}

impl<T> S2<T> {
#[clippy::msrv = "1.60"]
pub fn new_1_60() -> Self {
//~^ missing_const_for_fn
Self { _t: None }
}

#[clippy::msrv = "1.61"]
pub fn new_1_61() -> Self {
//~^ missing_const_for_fn
Self { _t: None }
}
}

pub struct S3<T: ?Sized + 'static> {
_t: Option<&'static T>,
}

impl<T: ?Sized + 'static> S3<T> {
#[clippy::msrv = "1.60"]
pub fn new_1_60() -> Self {
//~^ missing_const_for_fn
Self { _t: None }
}

#[clippy::msrv = "1.61"]
pub fn new_1_61() -> Self {
//~^ missing_const_for_fn
Self { _t: None }
}
}
}
72 changes: 71 additions & 1 deletion tests/ui/missing_const_for_fn/could_be_const.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -332,5 +332,75 @@ help: make the function `const`
LL | const fn mut_add(x: &mut i32) {
| +++++

error: aborting due to 25 previous errors
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:239:9
|
LL | / pub fn new_1_61() -> Self {
LL | |
LL | | Self { _t: None }
LL | | }
| |_________^
|
help: make the function `const`
|
LL | pub const fn new_1_61() -> Self {
| +++++

error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:251:9
|
LL | / pub fn new_1_60() -> Self {
LL | |
LL | | Self { _t: None }
LL | | }
| |_________^
|
help: make the function `const`
|
LL | pub const fn new_1_60() -> Self {
| +++++

error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:257:9
|
LL | / pub fn new_1_61() -> Self {
LL | |
LL | | Self { _t: None }
LL | | }
| |_________^
|
help: make the function `const`
|
LL | pub const fn new_1_61() -> Self {
| +++++

error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:269:9
|
LL | / pub fn new_1_60() -> Self {
LL | |
LL | | Self { _t: None }
LL | | }
| |_________^
|
help: make the function `const`
|
LL | pub const fn new_1_60() -> Self {
| +++++

error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:275:9
|
LL | / pub fn new_1_61() -> Self {
LL | |
LL | | Self { _t: None }
LL | | }
| |_________^
|
help: make the function `const`
|
LL | pub const fn new_1_61() -> Self {
| +++++

error: aborting due to 30 previous errors

Loading