1
- use crate :: hir:: map:: blocks:: FnLikeNode ;
2
- use crate :: ty:: query:: Providers ;
3
- use crate :: ty:: TyCtxt ;
1
+ use rustc :: hir:: map:: blocks:: FnLikeNode ;
2
+ use rustc :: ty:: query:: Providers ;
3
+ use rustc :: ty:: TyCtxt ;
4
4
use rustc_hir as hir;
5
5
use rustc_hir:: def_id:: DefId ;
6
6
use rustc_span:: symbol:: Symbol ;
7
7
use rustc_target:: spec:: abi:: Abi ;
8
8
use syntax:: attr;
9
9
10
- impl < ' tcx > TyCtxt < ' tcx > {
11
- /// Whether the `def_id` counts as const fn in your current crate, considering all active
12
- /// feature gates
13
- pub fn is_const_fn ( self , def_id : DefId ) -> bool {
14
- self . is_const_fn_raw ( def_id)
15
- && match self . is_unstable_const_fn ( def_id) {
16
- Some ( feature_name) => {
17
- // has a `rustc_const_unstable` attribute, check whether the user enabled the
18
- // corresponding feature gate.
19
- self . features ( )
20
- . declared_lib_features
21
- . iter ( )
22
- . any ( |& ( sym, _) | sym == feature_name)
23
- }
24
- // functions without const stability are either stable user written
25
- // const fn or the user is using feature gates and we thus don't
26
- // care what they do
27
- None => true ,
10
+ /// Whether the `def_id` counts as const fn in your current crate, considering all active
11
+ /// feature gates
12
+ pub fn is_const_fn ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> bool {
13
+ tcx. is_const_fn_raw ( def_id)
14
+ && match is_unstable_const_fn ( tcx, def_id) {
15
+ Some ( feature_name) => {
16
+ // has a `rustc_const_unstable` attribute, check whether the user enabled the
17
+ // corresponding feature gate.
18
+ tcx. features ( ) . declared_lib_features . iter ( ) . any ( |& ( sym, _) | sym == feature_name)
28
19
}
29
- }
30
-
31
- /// Whether the `def_id` is an unstable const fn and what feature gate is necessary to enable it
32
- pub fn is_unstable_const_fn ( self , def_id : DefId ) -> Option < Symbol > {
33
- if self . is_const_fn_raw ( def_id) {
34
- let const_stab = self . lookup_const_stability ( def_id) ?;
35
- if const_stab. level . is_unstable ( ) { Some ( const_stab. feature ) } else { None }
36
- } else {
37
- None
20
+ // functions without const stability are either stable user written
21
+ // const fn or the user is using feature gates and we thus don't
22
+ // care what they do
23
+ None => true ,
38
24
}
25
+ }
26
+
27
+ /// Whether the `def_id` is an unstable const fn and what feature gate is necessary to enable it
28
+ pub fn is_unstable_const_fn ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> Option < Symbol > {
29
+ if tcx. is_const_fn_raw ( def_id) {
30
+ let const_stab = tcx. lookup_const_stability ( def_id) ?;
31
+ if const_stab. level . is_unstable ( ) { Some ( const_stab. feature ) } else { None }
32
+ } else {
33
+ None
39
34
}
35
+ }
40
36
41
- /// Returns `true` if this function must conform to `min_const_fn`
42
- pub fn is_min_const_fn ( self , def_id : DefId ) -> bool {
43
- // Bail out if the signature doesn't contain `const`
44
- if !self . is_const_fn_raw ( def_id) {
45
- return false ;
46
- }
37
+ /// Returns `true` if this function must conform to `min_const_fn`
38
+ pub fn is_min_const_fn ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> bool {
39
+ // Bail out if the signature doesn't contain `const`
40
+ if !tcx . is_const_fn_raw ( def_id) {
41
+ return false ;
42
+ }
47
43
48
- if self . features ( ) . staged_api {
49
- // In order for a libstd function to be considered min_const_fn
50
- // it needs to be stable and have no `rustc_const_unstable` attribute.
51
- match self . lookup_const_stability ( def_id) {
52
- // `rustc_const_unstable` functions don't need to conform.
53
- Some ( & attr:: ConstStability { ref level, .. } ) if level. is_unstable ( ) => false ,
54
- None => {
55
- if let Some ( stab) = self . lookup_stability ( def_id) {
56
- if stab. level . is_stable ( ) {
57
- self . sess . span_err (
58
- self . def_span ( def_id) ,
59
- "stable const functions must have either `rustc_const_stable` or \
60
- `rustc_const_unstable` attribute",
61
- ) ;
62
- // While we errored above, because we don't know if we need to conform, we
63
- // err on the "safe" side and require min_const_fn.
64
- true
65
- } else {
66
- // Unstable functions need not conform to min_const_fn.
67
- false
68
- }
69
- } else {
70
- // Internal functions are forced to conform to min_const_fn.
71
- // Annotate the internal function with a const stability attribute if
72
- // you need to use unstable features.
73
- // Note: this is an arbitrary choice that does not affect stability or const
74
- // safety or anything, it just changes whether we need to annotate some
75
- // internal functions with `rustc_const_stable` or with `rustc_const_unstable`
44
+ if tcx. features ( ) . staged_api {
45
+ // In order for a libstd function to be considered min_const_fn
46
+ // it needs to be stable and have no `rustc_const_unstable` attribute.
47
+ match tcx. lookup_const_stability ( def_id) {
48
+ // `rustc_const_unstable` functions don't need to conform.
49
+ Some ( & attr:: ConstStability { ref level, .. } ) if level. is_unstable ( ) => false ,
50
+ None => {
51
+ if let Some ( stab) = tcx. lookup_stability ( def_id) {
52
+ if stab. level . is_stable ( ) {
53
+ tcx. sess . span_err (
54
+ tcx. def_span ( def_id) ,
55
+ "stable const functions must have either `rustc_const_stable` or \
56
+ `rustc_const_unstable` attribute",
57
+ ) ;
58
+ // While we errored above, because we don't know if we need to conform, we
59
+ // err on the "safe" side and require min_const_fn.
76
60
true
61
+ } else {
62
+ // Unstable functions need not conform to min_const_fn.
63
+ false
77
64
}
65
+ } else {
66
+ // Internal functions are forced to conform to min_const_fn.
67
+ // Annotate the internal function with a const stability attribute if
68
+ // you need to use unstable features.
69
+ // Note: this is an arbitrary choice that does not affect stability or const
70
+ // safety or anything, it just changes whether we need to annotate some
71
+ // internal functions with `rustc_const_stable` or with `rustc_const_unstable`
72
+ true
78
73
}
79
- // Everything else needs to conform, because it would be callable from
80
- // other `min_const_fn` functions.
81
- _ => true ,
82
74
}
83
- } else {
84
- // users enabling the `const_fn` feature gate can do what they want
85
- ! self . features ( ) . const_fn
75
+ // Everything else needs to conform, because it would be callable from
76
+ // other `min_const_fn` functions.
77
+ _ => true ,
86
78
}
79
+ } else {
80
+ // users enabling the `const_fn` feature gate can do what they want
81
+ !tcx. features ( ) . const_fn
87
82
}
88
83
}
89
84
@@ -121,7 +116,7 @@ pub fn provide(providers: &mut Providers<'_>) {
121
116
}
122
117
123
118
fn is_promotable_const_fn ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> bool {
124
- tcx . is_const_fn ( def_id)
119
+ is_const_fn ( tcx , def_id)
125
120
&& match tcx. lookup_const_stability ( def_id) {
126
121
Some ( stab) => {
127
122
if cfg ! ( debug_assertions) && stab. promotable {
@@ -140,7 +135,7 @@ pub fn provide(providers: &mut Providers<'_>) {
140
135
}
141
136
142
137
fn const_fn_is_allowed_fn_ptr ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> bool {
143
- tcx . is_const_fn ( def_id)
138
+ is_const_fn ( tcx , def_id)
144
139
&& tcx
145
140
. lookup_const_stability ( def_id)
146
141
. map ( |stab| stab. allow_const_fn_ptr )
0 commit comments