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:: {
118 AttrKind , AttrStyle , Attribute , LitKind , MetaItemInner , MetaItemKind , MetaItemLit , ast,
9+ token:: TokenKind , tokenstream:: TokenTree , AttrKind , AttrStyle , Attribute , LitKind ,
10+ MetaItemKind , MetaItemLit , NestedMetaItem ,
1211} ;
1312use rustc_data_structures:: fx:: FxHashMap ;
1413use rustc_errors:: { Applicability , DiagCtxtHandle , IntoDiagArg , MultiSpan , StashKey } ;
@@ -39,6 +38,8 @@ use rustc_target::spec::abi::Abi;
3938use rustc_trait_selection:: error_reporting:: InferCtxtErrorExt ;
4039use rustc_trait_selection:: infer:: { TyCtxtInferExt , ValuePairs } ;
4140use rustc_trait_selection:: traits:: ObligationCtxt ;
41+ use std:: cell:: Cell ;
42+ use std:: collections:: hash_map:: Entry ;
4243use tracing:: debug;
4344
4445use crate :: { errors, fluent_generated as fluent} ;
@@ -252,6 +253,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
252253 }
253254 [ sym:: linkage, ..] => self . check_linkage ( attr, span, target) ,
254255 [ sym:: rustc_pub_transparent, ..] => self . check_rustc_pub_transparent ( attr. span , span, attrs) ,
256+ [ sym:: instruction_set, ..] => {
257+ self . check_instruction_set ( attr, item) ;
258+ }
255259 [
256260 // ok
257261 sym:: allow
@@ -267,7 +271,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
267271 | sym:: omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
268272 | sym:: used // handled elsewhere to restrict to static items
269273 | sym:: repr // handled elsewhere to restrict to type decls items
270- | sym:: instruction_set // broken on stable!!!
271274 | sym:: windows_subsystem // broken on stable!!!
272275 | sym:: patchable_function_entry // FIXME(patchable_function_entry)
273276 | sym:: deprecated_safe // FIXME(deprecated_safe)
@@ -2401,6 +2404,37 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
24012404 _ => {
24022405 self . dcx ( ) . emit_err ( errors:: AutoDiffAttr { attr_span : span } ) ;
24032406 self . abort . set ( true ) ;
2407+ }
2408+ }
2409+
2410+ fn check_instruction_set ( & self , attr : & Attribute , _item : Option < ItemLike < ' _ > > ) {
2411+ if let AttrKind :: Normal ( ref p) = attr. kind {
2412+ let inner_tokens = p. item . args . inner_tokens ( ) ;
2413+ let mut tokens = inner_tokens. trees ( ) ;
2414+
2415+ // Valid item for `instruction_set()` is:
2416+ // - arm::a32
2417+ // - arm::t32
2418+ let valid_attribute = match ( tokens. next ( ) , tokens. next ( ) , tokens. next ( ) ) {
2419+ (
2420+ Some ( TokenTree :: Token ( first_token, _) ) ,
2421+ Some ( TokenTree :: Token ( second_token, _) ) ,
2422+ Some ( TokenTree :: Token ( third_token, _) ) ,
2423+ ) => match ( first_token. ident ( ) , second_token. kind . clone ( ) , third_token. ident ( ) ) {
2424+ ( Some ( first_ident) , TokenKind :: PathSep , Some ( third_ident) )
2425+ if first_ident. 0 . name == sym:: arm =>
2426+ {
2427+ third_ident. 0 . name == sym:: a32 || third_ident. 0 . name == sym:: t32
2428+ }
2429+ _ => false ,
2430+ } ,
2431+ _ => false ,
2432+ } ;
2433+
2434+ if !valid_attribute {
2435+ self . dcx ( ) . emit_err ( errors:: InvalidInstructionSet { span : attr. span } ) ;
2436+ } else {
2437+ return ;
24042438 }
24052439 }
24062440 }
0 commit comments