44//! conflicts between multiple such attributes attached to the same
55//! item.
66
7- use std:: cell:: Cell ;
8- use std:: collections:: hash_map:: Entry ;
9-
107use 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 ,
1210} ;
1311use rustc_data_structures:: fx:: FxHashMap ;
1412use rustc_errors:: { Applicability , DiagCtxtHandle , IntoDiagArg , MultiSpan , StashKey } ;
@@ -38,6 +36,8 @@ use rustc_target::spec::abi::Abi;
3836use rustc_trait_selection:: error_reporting:: InferCtxtErrorExt ;
3937use rustc_trait_selection:: infer:: { TyCtxtInferExt , ValuePairs } ;
4038use rustc_trait_selection:: traits:: ObligationCtxt ;
39+ use std:: cell:: Cell ;
40+ use std:: collections:: hash_map:: Entry ;
4141use tracing:: debug;
4242
4343use crate :: { errors, fluent_generated as fluent} ;
@@ -243,6 +243,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
243243 [ sym:: coroutine, ..] => {
244244 self . check_coroutine ( attr, target) ;
245245 }
246+ [ sym:: instruction_set, ..] => {
247+ self . check_instruction_set ( attr, item) ;
248+ }
246249 [
247250 // ok
248251 sym:: allow
@@ -260,7 +263,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
260263 | sym:: omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
261264 | sym:: used // handled elsewhere to restrict to static items
262265 | sym:: repr // handled elsewhere to restrict to type decls items
263- | sym:: instruction_set // broken on stable!!!
264266 | sym:: windows_subsystem // broken on stable!!!
265267 | sym:: patchable_function_entry // FIXME(patchable_function_entry)
266268 | sym:: deprecated_safe // FIXME(deprecated_safe)
@@ -2349,6 +2351,38 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
23492351 }
23502352 }
23512353 }
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+ }
23522386}
23532387
23542388impl < ' tcx > Visitor < ' tcx > for CheckAttrVisitor < ' tcx > {
0 commit comments