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)
@@ -2398,6 +2401,37 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
23982401 _ => {
23992402 self . dcx ( ) . emit_err ( errors:: AutoDiffAttr { attr_span : span } ) ;
24002403 self . abort . set ( true ) ;
2404+ }
2405+ }
2406+
2407+ fn check_instruction_set ( & self , attr : & Attribute , _item : Option < ItemLike < ' _ > > ) {
2408+ if let AttrKind :: Normal ( ref p) = attr. kind {
2409+ let inner_tokens = p. item . args . inner_tokens ( ) ;
2410+ let mut tokens = inner_tokens. trees ( ) ;
2411+
2412+ // Valid item for `instruction_set()` is:
2413+ // - arm::a32
2414+ // - arm::t32
2415+ let valid_attribute = match ( tokens. next ( ) , tokens. next ( ) , tokens. next ( ) ) {
2416+ (
2417+ Some ( TokenTree :: Token ( first_token, _) ) ,
2418+ Some ( TokenTree :: Token ( second_token, _) ) ,
2419+ Some ( TokenTree :: Token ( third_token, _) ) ,
2420+ ) => match ( first_token. ident ( ) , second_token. kind . clone ( ) , third_token. ident ( ) ) {
2421+ ( Some ( first_ident) , TokenKind :: PathSep , Some ( third_ident) )
2422+ if first_ident. 0 . name == sym:: arm =>
2423+ {
2424+ third_ident. 0 . name == sym:: a32 || third_ident. 0 . name == sym:: t32
2425+ }
2426+ _ => false ,
2427+ } ,
2428+ _ => false ,
2429+ } ;
2430+
2431+ if !valid_attribute {
2432+ self . dcx ( ) . emit_err ( errors:: InvalidInstructionSet { span : attr. span } ) ;
2433+ } else {
2434+ return ;
24012435 }
24022436 }
24032437 }
0 commit comments