1
1
use rustc_hir as hir;
2
+ use rustc_hir:: def:: DefKind ;
2
3
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
3
4
use rustc_middle:: ty:: query:: Providers ;
4
- use rustc_middle:: ty:: TyCtxt ;
5
+ use rustc_middle:: ty:: { DefIdTree , TyCtxt } ;
5
6
use rustc_span:: symbol:: Symbol ;
6
7
use rustc_target:: spec:: abi:: Abi ;
7
8
@@ -16,44 +17,47 @@ pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Symbol> {
16
17
}
17
18
18
19
pub 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
28
23
}
29
24
30
25
/// Checks whether the function has a `const` modifier or, in case it is an intrinsic, whether
31
26
/// 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 {
33
28
let def_id = def_id. expect_local ( ) ;
34
29
let node = tcx. hir ( ) . get_by_def_id ( def_id) ;
35
30
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 }
50
46
}
47
+ _ => {
48
+ if let Some ( fn_kind) = node. fn_kind ( ) {
49
+ if fn_kind. constness ( ) == hir:: Constness :: Const {
50
+ return hir:: Constness :: Const ;
51
+ }
51
52
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
+ }
57
61
}
58
62
}
59
63
@@ -77,5 +81,5 @@ fn is_promotable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
77
81
}
78
82
79
83
pub 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 } ;
81
85
}
0 commit comments