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
- ast, AttrKind , AttrStyle , Attribute , LitKind , MetaItemKind , MetaItemLit , NestedMetaItem ,
8
+ ast, token:: TokenKind , tokenstream:: TokenTree , AttrKind , AttrStyle , Attribute , LitKind ,
9
+ MetaItemKind , MetaItemLit , NestedMetaItem ,
12
10
} ;
13
11
use rustc_data_structures:: fx:: FxHashMap ;
14
12
use rustc_errors:: { Applicability , DiagCtxtHandle , IntoDiagArg , MultiSpan , StashKey } ;
@@ -38,6 +36,8 @@ use rustc_target::spec::abi::Abi;
38
36
use rustc_trait_selection:: error_reporting:: InferCtxtErrorExt ;
39
37
use rustc_trait_selection:: infer:: { TyCtxtInferExt , ValuePairs } ;
40
38
use rustc_trait_selection:: traits:: ObligationCtxt ;
39
+ use std:: cell:: Cell ;
40
+ use std:: collections:: hash_map:: Entry ;
41
41
use tracing:: debug;
42
42
43
43
use crate :: { errors, fluent_generated as fluent} ;
@@ -243,6 +243,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
243
243
[ sym:: coroutine, ..] => {
244
244
self . check_coroutine ( attr, target) ;
245
245
}
246
+ [ sym:: instruction_set, ..] => {
247
+ self . check_instruction_set ( attr, item) ;
248
+ }
246
249
[
247
250
// ok
248
251
sym:: allow
@@ -260,7 +263,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
260
263
| sym:: omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
261
264
| sym:: used // handled elsewhere to restrict to static items
262
265
| sym:: repr // handled elsewhere to restrict to type decls items
263
- | sym:: instruction_set // broken on stable!!!
264
266
| sym:: windows_subsystem // broken on stable!!!
265
267
| sym:: patchable_function_entry // FIXME(patchable_function_entry)
266
268
| sym:: deprecated_safe // FIXME(deprecated_safe)
@@ -2349,6 +2351,38 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
2349
2351
}
2350
2352
}
2351
2353
}
2354
+
2355
+ fn check_instruction_set ( & self , attr : & Attribute , _item : Option < ItemLike < ' _ > > ) {
2356
+ if let AttrKind :: Normal ( ref p) = attr. kind {
2357
+ let inner_tokens = p. item . args . inner_tokens ( ) ;
2358
+ let mut tokens = inner_tokens. trees ( ) ;
2359
+
2360
+ // Valid item for `instruction_set()` is:
2361
+ // - arm::a32
2362
+ // - arm::t32
2363
+ let valid_attribute = match ( tokens. next ( ) , tokens. next ( ) , tokens. next ( ) ) {
2364
+ (
2365
+ Some ( TokenTree :: Token ( first_token, _) ) ,
2366
+ Some ( TokenTree :: Token ( second_token, _) ) ,
2367
+ Some ( TokenTree :: Token ( third_token, _) ) ,
2368
+ ) => match ( first_token. ident ( ) , second_token. kind . clone ( ) , third_token. ident ( ) ) {
2369
+ ( Some ( first_ident) , TokenKind :: PathSep , Some ( third_ident) )
2370
+ if first_ident. 0 . name == sym:: arm =>
2371
+ {
2372
+ third_ident. 0 . name == sym:: a32 || third_ident. 0 . name == sym:: t32
2373
+ }
2374
+ _ => false ,
2375
+ } ,
2376
+ _ => false ,
2377
+ } ;
2378
+
2379
+ if !valid_attribute {
2380
+ self . dcx ( ) . emit_err ( errors:: InvalidInstructionSet { span : attr. span } ) ;
2381
+ } else {
2382
+ return ;
2383
+ }
2384
+ }
2385
+ }
2352
2386
}
2353
2387
2354
2388
impl < ' tcx > Visitor < ' tcx > for CheckAttrVisitor < ' tcx > {
0 commit comments