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} ;
@@ -249,6 +250,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
249250 }
250251 [ sym:: linkage, ..] => self . check_linkage ( attr, span, target) ,
251252 [ 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+ }
252256 [
253257 // ok
254258 sym:: allow
@@ -264,7 +268,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
264268 | sym:: omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
265269 | sym:: used // handled elsewhere to restrict to static items
266270 | sym:: repr // handled elsewhere to restrict to type decls items
267- | sym:: instruction_set // broken on stable!!!
268271 | sym:: windows_subsystem // broken on stable!!!
269272 | sym:: patchable_function_entry // FIXME(patchable_function_entry)
270273 | sym:: deprecated_safe // FIXME(deprecated_safe)
@@ -2375,6 +2378,37 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
23752378 _ => {
23762379 self . dcx ( ) . emit_err ( errors:: AutoDiffAttr { attr_span : span } ) ;
23772380 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 ;
23782412 }
23792413 }
23802414 }
0 commit comments