Skip to content

Commit

Permalink
make sure the msrv for const_ptr_deref is met when linting [`missin…
Browse files Browse the repository at this point in the history
…g_const_for_fn`]
  • Loading branch information
J-ZhengLi committed Apr 25, 2024
1 parent b2a7371 commit d86cbc3
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 3 deletions.
2 changes: 1 addition & 1 deletion clippy_config/src/msrvs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ msrv_aliases! {
1,63,0 { ASSIGNING_CLONES }
1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE }
1,59,0 { THREAD_LOCAL_INITIALIZER_CAN_BE_MADE_CONST }
1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY }
1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY, CONST_RAW_PTR_DEREF }
1,55,0 { SEEK_REWIND }
1,54,0 { INTO_KEYS }
1,53,0 { OR_PATTERNS, MANUAL_BITS, BTREE_MAP_RETAIN, BTREE_SET_RETAIN, ARRAY_INTO_ITERATOR }
Expand Down
22 changes: 21 additions & 1 deletion clippy_lints/src/missing_const_for_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@ use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint;
use clippy_utils::qualify_min_const_fn::is_min_const_fn;
use clippy_utils::ty::has_drop;
use clippy_utils::visitors::for_each_expr;
use clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, is_from_proc_macro, 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};
use rustc_hir::{Body, Constness, ExprKind, FnDecl, GenericParamKind, UnOp};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
use rustc_session::impl_lint_pass;
use rustc_span::def_id::LocalDefId;
use rustc_span::Span;
use std::ops::ControlFlow;

declare_clippy_lint! {
/// ### What it does
Expand Down Expand Up @@ -149,6 +151,11 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
return;
}

// Skip if there is any pointer deref ops in the body, and the msrv of that feature does not meet.
if !self.msrv.meets(msrvs::CONST_RAW_PTR_DEREF) && has_raw_ptr_deref_in_body(cx, body) {
return;
}

let mir = cx.tcx.optimized_mir(def_id);

if let Err((span, err)) = is_min_const_fn(cx.tcx, mir, &self.msrv) {
Expand Down Expand Up @@ -176,3 +183,16 @@ fn method_accepts_droppable(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {
fn already_const(header: hir::FnHeader) -> bool {
header.constness == Constness::Const
}

fn has_raw_ptr_deref_in_body(cx: &LateContext<'_>, body: &Body<'_>) -> bool {
for_each_expr(body.value, |expr| {
if let ExprKind::Unary(UnOp::Deref, oprand) = expr.kind
&& cx.typeck_results().expr_ty(oprand).is_unsafe_ptr()
{
ControlFlow::Break(())
} else {
ControlFlow::Continue(())
}
})
.is_some()
}
21 changes: 21 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 @@ -113,3 +113,24 @@ impl const Drop for D {
// Lint this, since it can be dropped in const contexts
// FIXME(effects)
fn d(this: D) {}

#[clippy::msrv = "1.58"]
mod const_ptr_deref_supported {
struct Foo(*const u8);
impl Foo {
fn can_be_const(self) -> usize {
//~^ ERROR: this could be a `const fn`
unsafe { *self.0 as usize }
}
}
}

#[clippy::msrv = "1.57"]
mod const_ptr_deref_not_supported {
struct Foo(*const u8);
impl Foo {
fn cannot_be_const(self) -> usize {
unsafe { *self.0 as usize }
}
}
}
11 changes: 10 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 @@ -102,5 +102,14 @@ LL | | 46
LL | | }
| |_^

error: aborting due to 11 previous errors
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:121:9
|
LL | / fn can_be_const(self) -> usize {
LL | |
LL | | unsafe { *self.0 as usize }
LL | | }
| |_________^

error: aborting due to 12 previous errors

0 comments on commit d86cbc3

Please sign in to comment.