Skip to content

Commit 8095303

Browse files
Expose speculative const-checking for clippy
1 parent 2ca256a commit 8095303

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

compiler/rustc_mir/src/transform/check_consts/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rustc_middle::ty::{self, TyCtxt};
1212
use rustc_span::Symbol;
1313

1414
pub use self::qualifs::Qualif;
15+
pub use self::validation::non_const_fn_could_be_made_stable_const_fn;
1516

1617
mod ops;
1718
pub mod post_drop_elaboration;

compiler/rustc_mir/src/transform/check_consts/validation.rs

+31-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations.
22
3-
use rustc_errors::{Applicability, struct_span_err};
4-
use rustc_hir::{self as hir, LangItem};
5-
use rustc_hir::{def_id::DefId, HirId};
3+
use rustc_errors::{struct_span_err, Applicability};
4+
use rustc_hir::def_id::{DefId, LocalDefId};
5+
use rustc_hir::{self as hir, HirId, LangItem};
66
use rustc_infer::infer::TyCtxtInferExt;
77
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
88
use rustc_middle::mir::*;
@@ -25,6 +25,34 @@ use crate::const_eval::is_unstable_const_fn;
2525
use crate::dataflow::impls::MaybeMutBorrowedLocals;
2626
use crate::dataflow::{self, Analysis};
2727

28+
/// Returns `true` if the given `fn` could be made into a `const fn` without depending on any
29+
/// unstable features.
30+
///
31+
/// This is used by clippy. Do not use it for const-checking.
32+
pub fn non_const_fn_could_be_made_stable_const_fn(
33+
tcx: TyCtxt<'tcx>,
34+
def_id: LocalDefId,
35+
body: &Body<'tcx>,
36+
) -> bool {
37+
let const_kind = tcx.hir().body_const_context(def_id);
38+
39+
// Only run this on non-const `fn`s.
40+
assert!(const_kind.is_none());
41+
42+
let ccx = ConstCx {
43+
body,
44+
tcx,
45+
def_id,
46+
const_kind: Some(hir::ConstContext::ConstFn),
47+
param_env: tcx.param_env(def_id),
48+
};
49+
50+
let mut checker = Validator::new(&ccx);
51+
checker.silence_errors = true;
52+
checker.check_body();
53+
checker.passes_checks_without_unstable_features
54+
}
55+
2856
// We are using `MaybeMutBorrowedLocals` as a proxy for whether an item may have been mutated
2957
// through a pointer prior to the given point. This is okay even though `MaybeMutBorrowedLocals`
3058
// kills locals upon `StorageDead` because a local will never be used after a `StorageDead`.

0 commit comments

Comments
 (0)