Skip to content

Commit

Permalink
Emit missing_const_for_fn for CONST_MUT_REFS (#13839)
Browse files Browse the repository at this point in the history
1.83 stabilized `CONST_MUT_REFS`, also allowing for `const fn` to mutate
through mutable references. This ensures `missing_const_for_fn` is
emitted for those cases.

changelog: [`missing_const_for_fn`]: Now suggests marking some functions
taking mutable references `const`
  • Loading branch information
Alexendoo authored Jan 18, 2025
2 parents 38828bf + f327640 commit 2220806
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 5 deletions.
2 changes: 1 addition & 1 deletion clippy_utils/src/msrvs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ macro_rules! msrv_aliases {

// names may refer to stabilized feature flags or library items
msrv_aliases! {
1,83,0 { CONST_EXTERN_FN, CONST_FLOAT_BITS_CONV, CONST_FLOAT_CLASSIFY, CONST_UNWRAP }
1,83,0 { CONST_EXTERN_FN, CONST_FLOAT_BITS_CONV, CONST_FLOAT_CLASSIFY, CONST_MUT_REFS, CONST_UNWRAP }
1,82,0 { IS_NONE_OR, REPEAT_N, RAW_REF_OP }
1,81,0 { LINT_REASONS_STABILIZATION, ERROR_IN_CORE, EXPLICIT_SELF_TYPE_ELISION }
1,80,0 { BOX_INTO_ITER }
Expand Down
7 changes: 4 additions & 3 deletions clippy_utils/src/qualify_min_const_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv)
let def_id = body.source.def_id();

for local in &body.local_decls {
check_ty(tcx, local.ty, local.source_info.span)?;
check_ty(tcx, local.ty, local.source_info.span, msrv)?;
}
// impl trait is gone in MIR, so check the return type manually
check_ty(
tcx,
tcx.fn_sig(def_id).instantiate_identity().output().skip_binder(),
body.local_decls.iter().next().unwrap().source_info.span,
msrv,
)?;

for bb in &*body.basic_blocks {
Expand All @@ -51,7 +52,7 @@ pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv)
Ok(())
}

fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult {
fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span, msrv: &Msrv) -> McfResult {
for arg in ty.walk() {
let ty = match arg.unpack() {
GenericArgKind::Type(ty) => ty,
Expand All @@ -62,7 +63,7 @@ fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult {
};

match ty.kind() {
ty::Ref(_, _, hir::Mutability::Mut) => {
ty::Ref(_, _, hir::Mutability::Mut) if !msrv.meets(msrvs::CONST_MUT_REFS) => {
return Err((span, "mutable references in const fn are unstable".into()));
},
ty::Alias(ty::Opaque, ..) => return Err((span, "`impl Trait` in const fn is unstable".into())),
Expand Down
6 changes: 6 additions & 0 deletions tests/ui/missing_const_for_fn/cant_be_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,9 @@ mod with_ty_alias {
let _: Foo = 1;
}
}

// Do not lint because mutable references in const functions are unstable in 1.82
#[clippy::msrv = "1.82"]
fn mut_add(x: &mut i32) {
*x += 1;
}
5 changes: 5 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 @@ -212,3 +212,8 @@ mod extern_fn {
const extern "system-unwind" fn system_unwind() {}
//~^ ERROR: this could be a `const fn`
}

const fn mut_add(x: &mut i32) {
//~^ ERROR: this could be a `const fn`
*x += 1;
}
5 changes: 5 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 @@ -212,3 +212,8 @@ mod extern_fn {
extern "system-unwind" fn system_unwind() {}
//~^ ERROR: this could be a `const fn`
}

fn mut_add(x: &mut i32) {
//~^ ERROR: this could be a `const fn`
*x += 1;
}
16 changes: 15 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 @@ -316,5 +316,19 @@ help: make the function `const`
LL | const extern "system-unwind" fn system_unwind() {}
| +++++

error: aborting due to 24 previous errors
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:216:1
|
LL | / fn mut_add(x: &mut i32) {
LL | |
LL | | *x += 1;
LL | | }
| |_^
|
help: make the function `const`
|
LL | const fn mut_add(x: &mut i32) {
| +++++

error: aborting due to 25 previous errors

0 comments on commit 2220806

Please sign in to comment.