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 } ;
66use rustc_infer:: infer:: TyCtxtInferExt ;
77use rustc_middle:: mir:: visit:: { MutatingUseContext , NonMutatingUseContext , PlaceContext , Visitor } ;
88use rustc_middle:: mir:: * ;
@@ -25,6 +25,34 @@ use crate::const_eval::is_unstable_const_fn;
2525use crate :: dataflow:: impls:: MaybeMutBorrowedLocals ;
2626use 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