11use rustc_hir as hir;
2+ use rustc_hir:: def:: DefKind ;
23use rustc_hir:: def_id:: { DefId , LocalDefId } ;
34use rustc_middle:: ty:: query:: Providers ;
4- use rustc_middle:: ty:: TyCtxt ;
5+ use rustc_middle:: ty:: { DefIdTree , TyCtxt } ;
56use rustc_span:: symbol:: Symbol ;
67use rustc_target:: spec:: abi:: Abi ;
78
@@ -16,44 +17,47 @@ pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Symbol> {
1617}
1718
1819pub fn is_parent_const_impl_raw ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> bool {
19- let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( def_id) ;
20- let parent_id = tcx. hir ( ) . get_parent_node ( hir_id) ;
21- matches ! (
22- tcx. hir( ) . get( parent_id) ,
23- hir:: Node :: Item ( hir:: Item {
24- kind: hir:: ItemKind :: Impl ( hir:: Impl { constness: hir:: Constness :: Const , .. } ) ,
25- ..
26- } )
27- )
20+ let parent_id = tcx. local_parent ( def_id) . unwrap ( ) ;
21+ tcx. def_kind ( parent_id) == DefKind :: Impl
22+ && tcx. impl_constness ( parent_id) == hir:: Constness :: Const
2823}
2924
3025/// Checks whether the function has a `const` modifier or, in case it is an intrinsic, whether
3126/// said intrinsic has a `rustc_const_{un,}stable` attribute.
32- fn is_const_fn_raw ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> bool {
27+ fn impl_constness ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> hir :: Constness {
3328 let def_id = def_id. expect_local ( ) ;
3429 let node = tcx. hir ( ) . get_by_def_id ( def_id) ;
3530
36- if let hir:: Node :: ForeignItem ( hir:: ForeignItem { kind : hir:: ForeignItemKind :: Fn ( ..) , .. } ) =
37- node
38- {
39- // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
40- // foreign items cannot be evaluated at compile-time.
41- let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( def_id) ;
42- if let Abi :: RustIntrinsic | Abi :: PlatformIntrinsic = tcx. hir ( ) . get_foreign_abi ( hir_id) {
43- tcx. lookup_const_stability ( def_id) . is_some ( )
44- } else {
45- false
46- }
47- } else if let Some ( fn_kind) = node. fn_kind ( ) {
48- if fn_kind. constness ( ) == hir:: Constness :: Const {
49- return true ;
31+ match node {
32+ hir:: Node :: Ctor ( _) => hir:: Constness :: Const ,
33+ hir:: Node :: Item ( hir:: Item { kind : hir:: ItemKind :: Impl ( impl_) , .. } ) => impl_. constness ,
34+ hir:: Node :: ForeignItem ( hir:: ForeignItem { kind : hir:: ForeignItemKind :: Fn ( ..) , .. } ) => {
35+ // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
36+ // foreign items cannot be evaluated at compile-time.
37+ let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( def_id) ;
38+ let is_const = if let Abi :: RustIntrinsic | Abi :: PlatformIntrinsic =
39+ tcx. hir ( ) . get_foreign_abi ( hir_id)
40+ {
41+ tcx. lookup_const_stability ( def_id) . is_some ( )
42+ } else {
43+ false
44+ } ;
45+ if is_const { hir:: Constness :: Const } else { hir:: Constness :: NotConst }
5046 }
47+ _ => {
48+ if let Some ( fn_kind) = node. fn_kind ( ) {
49+ if fn_kind. constness ( ) == hir:: Constness :: Const {
50+ return hir:: Constness :: Const ;
51+ }
5152
52- // If the function itself is not annotated with `const`, it may still be a `const fn`
53- // if it resides in a const trait impl.
54- is_parent_const_impl_raw ( tcx, def_id)
55- } else {
56- matches ! ( node, hir:: Node :: Ctor ( _) )
53+ // If the function itself is not annotated with `const`, it may still be a `const fn`
54+ // if it resides in a const trait impl.
55+ let is_const = is_parent_const_impl_raw ( tcx, def_id) ;
56+ if is_const { hir:: Constness :: Const } else { hir:: Constness :: NotConst }
57+ } else {
58+ hir:: Constness :: NotConst
59+ }
60+ }
5761 }
5862}
5963
@@ -77,5 +81,5 @@ fn is_promotable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
7781}
7882
7983pub fn provide ( providers : & mut Providers ) {
80- * providers = Providers { is_const_fn_raw , is_promotable_const_fn, ..* providers } ;
84+ * providers = Providers { impl_constness , is_promotable_const_fn, ..* providers } ;
8185}
0 commit comments