@@ -12,13 +12,16 @@ use rustc_middle::ty::TyCtxt;
12
12
use rustc_session:: parse:: feature_err;
13
13
use rustc_span:: symbol:: { sym, Symbol } ;
14
14
use rustc_span:: Span ;
15
+ use rustc_target:: target_features:: { self , Stability } ;
15
16
16
17
use crate :: errors;
17
18
18
- pub fn from_target_feature (
19
+ /// Compute the enabled target features from the `#[target_feature]` function attribute.
20
+ /// Enabled target features are added to `target_features`.
21
+ pub fn from_target_feature_attr (
19
22
tcx : TyCtxt < ' _ > ,
20
23
attr : & ast:: Attribute ,
21
- supported_target_features : & UnordMap < String , Option < Symbol > > ,
24
+ known_target_features : & UnordMap < String , target_features :: Stability > ,
22
25
target_features : & mut Vec < TargetFeature > ,
23
26
) {
24
27
let Some ( list) = attr. meta_item_list ( ) else { return } ;
@@ -47,12 +50,12 @@ pub fn from_target_feature(
47
50
48
51
// We allow comma separation to enable multiple features.
49
52
added_target_features. extend ( value. as_str ( ) . split ( ',' ) . filter_map ( |feature| {
50
- let Some ( feature_gate ) = supported_target_features . get ( feature) else {
53
+ let Some ( stability ) = known_target_features . get ( feature) else {
51
54
let msg = format ! ( "the feature named `{feature}` is not valid for this target" ) ;
52
55
let mut err = tcx. dcx ( ) . struct_span_err ( item. span ( ) , msg) ;
53
56
err. span_label ( item. span ( ) , format ! ( "`{feature}` is not valid for this target" ) ) ;
54
57
if let Some ( stripped) = feature. strip_prefix ( '+' ) {
55
- let valid = supported_target_features . contains_key ( stripped) ;
58
+ let valid = known_target_features . contains_key ( stripped) ;
56
59
if valid {
57
60
err. help ( "consider removing the leading `+` in the feature name" ) ;
58
61
}
@@ -62,39 +65,73 @@ pub fn from_target_feature(
62
65
} ;
63
66
64
67
// Only allow features whose feature gates have been enabled.
65
- let allowed = match feature_gate. as_ref ( ) . copied ( ) {
66
- Some ( sym:: arm_target_feature) => rust_features. arm_target_feature ,
67
- Some ( sym:: hexagon_target_feature) => rust_features. hexagon_target_feature ,
68
- Some ( sym:: powerpc_target_feature) => rust_features. powerpc_target_feature ,
69
- Some ( sym:: mips_target_feature) => rust_features. mips_target_feature ,
70
- Some ( sym:: riscv_target_feature) => rust_features. riscv_target_feature ,
71
- Some ( sym:: avx512_target_feature) => rust_features. avx512_target_feature ,
72
- Some ( sym:: sse4a_target_feature) => rust_features. sse4a_target_feature ,
73
- Some ( sym:: tbm_target_feature) => rust_features. tbm_target_feature ,
74
- Some ( sym:: wasm_target_feature) => rust_features. wasm_target_feature ,
75
- Some ( sym:: rtm_target_feature) => rust_features. rtm_target_feature ,
76
- Some ( sym:: ermsb_target_feature) => rust_features. ermsb_target_feature ,
77
- Some ( sym:: bpf_target_feature) => rust_features. bpf_target_feature ,
78
- Some ( sym:: aarch64_ver_target_feature) => rust_features. aarch64_ver_target_feature ,
79
- Some ( sym:: csky_target_feature) => rust_features. csky_target_feature ,
80
- Some ( sym:: loongarch_target_feature) => rust_features. loongarch_target_feature ,
81
- Some ( sym:: lahfsahf_target_feature) => rust_features. lahfsahf_target_feature ,
82
- Some ( sym:: prfchw_target_feature) => rust_features. prfchw_target_feature ,
83
- Some ( sym:: sha512_sm_x86) => rust_features. sha512_sm_x86 ,
84
- Some ( sym:: x86_amx_intrinsics) => rust_features. x86_amx_intrinsics ,
85
- Some ( sym:: xop_target_feature) => rust_features. xop_target_feature ,
86
- Some ( sym:: s390x_target_feature) => rust_features. s390x_target_feature ,
87
- Some ( name) => bug ! ( "unknown target feature gate {}" , name) ,
88
- None => true ,
68
+ let allowed = match stability {
69
+ Stability :: Forbidden => false ,
70
+ Stability :: Stable => true ,
71
+ Stability :: Unstable ( sym:: arm_target_feature) => rust_features. arm_target_feature ,
72
+ Stability :: Unstable ( sym:: hexagon_target_feature) => {
73
+ rust_features. hexagon_target_feature
74
+ }
75
+ Stability :: Unstable ( sym:: powerpc_target_feature) => {
76
+ rust_features. powerpc_target_feature
77
+ }
78
+ Stability :: Unstable ( sym:: mips_target_feature) => rust_features. mips_target_feature ,
79
+ Stability :: Unstable ( sym:: riscv_target_feature) => {
80
+ rust_features. riscv_target_feature
81
+ }
82
+ Stability :: Unstable ( sym:: avx512_target_feature) => {
83
+ rust_features. avx512_target_feature
84
+ }
85
+ Stability :: Unstable ( sym:: sse4a_target_feature) => {
86
+ rust_features. sse4a_target_feature
87
+ }
88
+ Stability :: Unstable ( sym:: tbm_target_feature) => rust_features. tbm_target_feature ,
89
+ Stability :: Unstable ( sym:: wasm_target_feature) => rust_features. wasm_target_feature ,
90
+ Stability :: Unstable ( sym:: rtm_target_feature) => rust_features. rtm_target_feature ,
91
+ Stability :: Unstable ( sym:: ermsb_target_feature) => {
92
+ rust_features. ermsb_target_feature
93
+ }
94
+ Stability :: Unstable ( sym:: bpf_target_feature) => rust_features. bpf_target_feature ,
95
+ Stability :: Unstable ( sym:: aarch64_ver_target_feature) => {
96
+ rust_features. aarch64_ver_target_feature
97
+ }
98
+ Stability :: Unstable ( sym:: csky_target_feature) => rust_features. csky_target_feature ,
99
+ Stability :: Unstable ( sym:: loongarch_target_feature) => {
100
+ rust_features. loongarch_target_feature
101
+ }
102
+ Stability :: Unstable ( sym:: lahfsahf_target_feature) => {
103
+ rust_features. lahfsahf_target_feature
104
+ }
105
+ Stability :: Unstable ( sym:: prfchw_target_feature) => {
106
+ rust_features. prfchw_target_feature
107
+ }
108
+ Stability :: Unstable ( sym:: sha512_sm_x86) => rust_features. sha512_sm_x86 ,
109
+ Stability :: Unstable ( sym:: x86_amx_intrinsics) => rust_features. x86_amx_intrinsics ,
110
+ Stability :: Unstable ( sym:: xop_target_feature) => rust_features. xop_target_feature ,
111
+ Stability :: Unstable ( sym:: s390x_target_feature) => {
112
+ rust_features. s390x_target_feature
113
+ }
114
+ Stability :: Unstable ( name) => bug ! ( "unknown target feature gate {}" , name) ,
89
115
} ;
90
116
if !allowed {
91
- feature_err (
92
- & tcx. sess ,
93
- feature_gate. unwrap ( ) ,
94
- item. span ( ) ,
95
- format ! ( "the target feature `{feature}` is currently unstable" ) ,
96
- )
97
- . emit ( ) ;
117
+ match stability {
118
+ Stability :: Stable => unreachable ! ( ) ,
119
+ & Stability :: Unstable ( lang_feature_name) => {
120
+ feature_err (
121
+ & tcx. sess ,
122
+ lang_feature_name,
123
+ item. span ( ) ,
124
+ format ! ( "the target feature `{feature}` is currently unstable" ) ,
125
+ )
126
+ . emit ( ) ;
127
+ }
128
+ Stability :: Forbidden => {
129
+ tcx. dcx ( ) . emit_err ( errors:: ForbiddenTargetFeature {
130
+ span : item. span ( ) ,
131
+ feature,
132
+ } ) ;
133
+ }
134
+ }
98
135
}
99
136
Some ( Symbol :: intern ( feature) )
100
137
} ) ) ;
@@ -160,20 +197,20 @@ pub fn check_target_feature_trait_unsafe(tcx: TyCtxt<'_>, id: LocalDefId, attr_s
160
197
161
198
pub ( crate ) fn provide ( providers : & mut Providers ) {
162
199
* providers = Providers {
163
- supported_target_features : |tcx, cnum| {
200
+ known_target_features : |tcx, cnum| {
164
201
assert_eq ! ( cnum, LOCAL_CRATE ) ;
165
202
if tcx. sess . opts . actually_rustdoc {
166
203
// rustdoc needs to be able to document functions that use all the features, so
167
204
// whitelist them all
168
205
rustc_target:: target_features:: all_known_features ( )
169
- . map ( |( a, b) | ( a. to_string ( ) , b. as_feature_name ( ) ) )
206
+ . map ( |( a, b) | ( a. to_string ( ) , b) )
170
207
. collect ( )
171
208
} else {
172
209
tcx. sess
173
210
. target
174
- . supported_target_features ( )
211
+ . known_target_features ( )
175
212
. iter ( )
176
- . map ( |& ( a, b, _) | ( a. to_string ( ) , b. as_feature_name ( ) ) )
213
+ . map ( |& ( a, b, _) | ( a. to_string ( ) , b) )
177
214
. collect ( )
178
215
}
179
216
} ,
0 commit comments