Skip to content

Commit 498562d

Browse files
authored
Check MSRV before suggesting applying const to a function (#15080)
If a function environment contains trait bounds other than `Sized`, `const` cannot be used before Rust 1.61. changelog: [`missing_const_for_fn`]: check MSRV before emitting lint on function containing non-`Sized` trait bounds Fixes #15079 r? Jarcho
2 parents d8e9953 + 6524bf7 commit 498562d

File tree

5 files changed

+199
-1
lines changed

5 files changed

+199
-1
lines changed

clippy_utils/src/msrvs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ msrv_aliases! {
4242
1,65,0 { LET_ELSE, POINTER_CAST_CONSTNESS }
4343
1,63,0 { CLONE_INTO, CONST_SLICE_FROM_REF }
4444
1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE, CONST_EXTERN_C_FN }
45+
1,61,0 { CONST_FN_TRAIT_BOUND }
4546
1,60,0 { ABS_DIFF }
4647
1,59,0 { THREAD_LOCAL_CONST_INIT }
4748
1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY, CONST_RAW_PTR_DEREF }

clippy_utils/src/qualify_min_const_fn.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,19 @@ pub fn is_min_const_fn<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, msrv: Ms
3232
for local in &body.local_decls {
3333
check_ty(cx, local.ty, local.source_info.span, msrv)?;
3434
}
35+
if !msrv.meets(cx, msrvs::CONST_FN_TRAIT_BOUND)
36+
&& let Some(sized_did) = cx.tcx.lang_items().sized_trait()
37+
&& cx.tcx.param_env(def_id).caller_bounds().iter().any(|bound| {
38+
bound
39+
.as_trait_clause()
40+
.is_some_and(|clause| clause.def_id() != sized_did)
41+
})
42+
{
43+
return Err((
44+
body.span,
45+
"non-`Sized` trait clause before `const_fn_trait_bound` is stabilized".into(),
46+
));
47+
}
3548
// impl trait is gone in MIR, so check the return type manually
3649
check_ty(
3750
cx,

tests/ui/missing_const_for_fn/could_be_const.fixed

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,60 @@ const fn mut_add(x: &mut i32) {
221221
//~^ missing_const_for_fn
222222
*x += 1;
223223
}
224+
225+
mod issue_15079 {
226+
pub trait Trait {}
227+
228+
pub struct Struct<T: Trait> {
229+
_t: Option<T>,
230+
}
231+
232+
impl<T: Trait> Struct<T> {
233+
#[clippy::msrv = "1.60"]
234+
pub fn new_1_60() -> Self {
235+
Self { _t: None }
236+
}
237+
238+
#[clippy::msrv = "1.61"]
239+
pub const fn new_1_61() -> Self {
240+
//~^ missing_const_for_fn
241+
Self { _t: None }
242+
}
243+
}
244+
245+
pub struct S2<T> {
246+
_t: Option<T>,
247+
}
248+
249+
impl<T> S2<T> {
250+
#[clippy::msrv = "1.60"]
251+
pub const fn new_1_60() -> Self {
252+
//~^ missing_const_for_fn
253+
Self { _t: None }
254+
}
255+
256+
#[clippy::msrv = "1.61"]
257+
pub const fn new_1_61() -> Self {
258+
//~^ missing_const_for_fn
259+
Self { _t: None }
260+
}
261+
}
262+
263+
pub struct S3<T: ?Sized + 'static> {
264+
_t: Option<&'static T>,
265+
}
266+
267+
impl<T: ?Sized + 'static> S3<T> {
268+
#[clippy::msrv = "1.60"]
269+
pub const fn new_1_60() -> Self {
270+
//~^ missing_const_for_fn
271+
Self { _t: None }
272+
}
273+
274+
#[clippy::msrv = "1.61"]
275+
pub const fn new_1_61() -> Self {
276+
//~^ missing_const_for_fn
277+
Self { _t: None }
278+
}
279+
}
280+
}

tests/ui/missing_const_for_fn/could_be_const.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,60 @@ fn mut_add(x: &mut i32) {
221221
//~^ missing_const_for_fn
222222
*x += 1;
223223
}
224+
225+
mod issue_15079 {
226+
pub trait Trait {}
227+
228+
pub struct Struct<T: Trait> {
229+
_t: Option<T>,
230+
}
231+
232+
impl<T: Trait> Struct<T> {
233+
#[clippy::msrv = "1.60"]
234+
pub fn new_1_60() -> Self {
235+
Self { _t: None }
236+
}
237+
238+
#[clippy::msrv = "1.61"]
239+
pub fn new_1_61() -> Self {
240+
//~^ missing_const_for_fn
241+
Self { _t: None }
242+
}
243+
}
244+
245+
pub struct S2<T> {
246+
_t: Option<T>,
247+
}
248+
249+
impl<T> S2<T> {
250+
#[clippy::msrv = "1.60"]
251+
pub fn new_1_60() -> Self {
252+
//~^ missing_const_for_fn
253+
Self { _t: None }
254+
}
255+
256+
#[clippy::msrv = "1.61"]
257+
pub fn new_1_61() -> Self {
258+
//~^ missing_const_for_fn
259+
Self { _t: None }
260+
}
261+
}
262+
263+
pub struct S3<T: ?Sized + 'static> {
264+
_t: Option<&'static T>,
265+
}
266+
267+
impl<T: ?Sized + 'static> S3<T> {
268+
#[clippy::msrv = "1.60"]
269+
pub fn new_1_60() -> Self {
270+
//~^ missing_const_for_fn
271+
Self { _t: None }
272+
}
273+
274+
#[clippy::msrv = "1.61"]
275+
pub fn new_1_61() -> Self {
276+
//~^ missing_const_for_fn
277+
Self { _t: None }
278+
}
279+
}
280+
}

tests/ui/missing_const_for_fn/could_be_const.stderr

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,5 +332,75 @@ help: make the function `const`
332332
LL | const fn mut_add(x: &mut i32) {
333333
| +++++
334334

335-
error: aborting due to 25 previous errors
335+
error: this could be a `const fn`
336+
--> tests/ui/missing_const_for_fn/could_be_const.rs:239:9
337+
|
338+
LL | / pub fn new_1_61() -> Self {
339+
LL | |
340+
LL | | Self { _t: None }
341+
LL | | }
342+
| |_________^
343+
|
344+
help: make the function `const`
345+
|
346+
LL | pub const fn new_1_61() -> Self {
347+
| +++++
348+
349+
error: this could be a `const fn`
350+
--> tests/ui/missing_const_for_fn/could_be_const.rs:251:9
351+
|
352+
LL | / pub fn new_1_60() -> Self {
353+
LL | |
354+
LL | | Self { _t: None }
355+
LL | | }
356+
| |_________^
357+
|
358+
help: make the function `const`
359+
|
360+
LL | pub const fn new_1_60() -> Self {
361+
| +++++
362+
363+
error: this could be a `const fn`
364+
--> tests/ui/missing_const_for_fn/could_be_const.rs:257:9
365+
|
366+
LL | / pub fn new_1_61() -> Self {
367+
LL | |
368+
LL | | Self { _t: None }
369+
LL | | }
370+
| |_________^
371+
|
372+
help: make the function `const`
373+
|
374+
LL | pub const fn new_1_61() -> Self {
375+
| +++++
376+
377+
error: this could be a `const fn`
378+
--> tests/ui/missing_const_for_fn/could_be_const.rs:269:9
379+
|
380+
LL | / pub fn new_1_60() -> Self {
381+
LL | |
382+
LL | | Self { _t: None }
383+
LL | | }
384+
| |_________^
385+
|
386+
help: make the function `const`
387+
|
388+
LL | pub const fn new_1_60() -> Self {
389+
| +++++
390+
391+
error: this could be a `const fn`
392+
--> tests/ui/missing_const_for_fn/could_be_const.rs:275:9
393+
|
394+
LL | / pub fn new_1_61() -> Self {
395+
LL | |
396+
LL | | Self { _t: None }
397+
LL | | }
398+
| |_________^
399+
|
400+
help: make the function `const`
401+
|
402+
LL | pub const fn new_1_61() -> Self {
403+
| +++++
404+
405+
error: aborting due to 30 previous errors
336406

0 commit comments

Comments
 (0)