4
4
//! conflicts between multiple such attributes attached to the same
5
5
//! item.
6
6
7
- use std:: cell:: Cell ;
8
- use std:: collections:: hash_map:: Entry ;
9
-
10
7
use rustc_ast:: {
11
8
AttrKind , AttrStyle , Attribute , LitKind , MetaItemInner , MetaItemKind , MetaItemLit , ast,
9
+ token:: TokenKind , tokenstream:: TokenTree , AttrKind , AttrStyle , Attribute , LitKind ,
10
+ MetaItemKind , MetaItemLit , NestedMetaItem ,
12
11
} ;
13
12
use rustc_data_structures:: fx:: FxHashMap ;
14
13
use rustc_errors:: { Applicability , DiagCtxtHandle , IntoDiagArg , MultiSpan , StashKey } ;
@@ -39,6 +38,8 @@ use rustc_target::spec::abi::Abi;
39
38
use rustc_trait_selection:: error_reporting:: InferCtxtErrorExt ;
40
39
use rustc_trait_selection:: infer:: { TyCtxtInferExt , ValuePairs } ;
41
40
use rustc_trait_selection:: traits:: ObligationCtxt ;
41
+ use std:: cell:: Cell ;
42
+ use std:: collections:: hash_map:: Entry ;
42
43
use tracing:: debug;
43
44
44
45
use crate :: { errors, fluent_generated as fluent} ;
@@ -249,6 +250,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
249
250
}
250
251
[ sym:: linkage, ..] => self . check_linkage ( attr, span, target) ,
251
252
[ sym:: rustc_pub_transparent, ..] => self . check_rustc_pub_transparent ( attr. span , span, attrs) ,
253
+ [ sym:: instruction_set, ..] => {
254
+ self . check_instruction_set ( attr, item) ;
255
+ }
252
256
[
253
257
// ok
254
258
sym:: allow
@@ -264,7 +268,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
264
268
| sym:: omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
265
269
| sym:: used // handled elsewhere to restrict to static items
266
270
| sym:: repr // handled elsewhere to restrict to type decls items
267
- | sym:: instruction_set // broken on stable!!!
268
271
| sym:: windows_subsystem // broken on stable!!!
269
272
| sym:: patchable_function_entry // FIXME(patchable_function_entry)
270
273
| sym:: deprecated_safe // FIXME(deprecated_safe)
@@ -2375,6 +2378,37 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
2375
2378
_ => {
2376
2379
self . dcx ( ) . emit_err ( errors:: AutoDiffAttr { attr_span : span } ) ;
2377
2380
self . abort . set ( true ) ;
2381
+ }
2382
+ }
2383
+
2384
+ fn check_instruction_set ( & self , attr : & Attribute , _item : Option < ItemLike < ' _ > > ) {
2385
+ if let AttrKind :: Normal ( ref p) = attr. kind {
2386
+ let inner_tokens = p. item . args . inner_tokens ( ) ;
2387
+ let mut tokens = inner_tokens. trees ( ) ;
2388
+
2389
+ // Valid item for `instruction_set()` is:
2390
+ // - arm::a32
2391
+ // - arm::t32
2392
+ let valid_attribute = match ( tokens. next ( ) , tokens. next ( ) , tokens. next ( ) ) {
2393
+ (
2394
+ Some ( TokenTree :: Token ( first_token, _) ) ,
2395
+ Some ( TokenTree :: Token ( second_token, _) ) ,
2396
+ Some ( TokenTree :: Token ( third_token, _) ) ,
2397
+ ) => match ( first_token. ident ( ) , second_token. kind . clone ( ) , third_token. ident ( ) ) {
2398
+ ( Some ( first_ident) , TokenKind :: PathSep , Some ( third_ident) )
2399
+ if first_ident. 0 . name == sym:: arm =>
2400
+ {
2401
+ third_ident. 0 . name == sym:: a32 || third_ident. 0 . name == sym:: t32
2402
+ }
2403
+ _ => false ,
2404
+ } ,
2405
+ _ => false ,
2406
+ } ;
2407
+
2408
+ if !valid_attribute {
2409
+ self . dcx ( ) . emit_err ( errors:: InvalidInstructionSet { span : attr. span } ) ;
2410
+ } else {
2411
+ return ;
2378
2412
}
2379
2413
}
2380
2414
}
0 commit comments