@@ -310,6 +310,16 @@ fn err_duplicate_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
310310 p. dcx ( ) . emit_err ( errors:: AsmOptAlreadyprovided { span, symbol, full_span } ) ;
311311}
312312
313+ /// Report an invalid option error.
314+ ///
315+ /// This function must be called immediately after the option token is parsed.
316+ /// Otherwise, the suggestion will be incorrect.
317+ fn err_unsupported_option ( p : & Parser < ' _ > , symbol : Symbol , span : Span ) {
318+ // Tool-only output
319+ let full_span = if p. token . kind == token:: Comma { span. to ( p. token . span ) } else { span } ;
320+ p. dcx ( ) . emit_err ( errors:: GlobalAsmUnsupportedOption { span, symbol, full_span } ) ;
321+ }
322+
313323/// Try to set the provided option in the provided `AsmArgs`.
314324/// If it is already set, report a duplicate option error.
315325///
@@ -318,13 +328,16 @@ fn err_duplicate_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
318328fn try_set_option < ' a > (
319329 p : & Parser < ' a > ,
320330 args : & mut AsmArgs ,
331+ is_global_asm : bool ,
321332 symbol : Symbol ,
322333 option : ast:: InlineAsmOptions ,
323334) {
324- if !args . options . contains ( option) {
325- args . options |= option ;
326- } else {
335+ if is_global_asm && !ast :: InlineAsmOptions :: GLOBAL_OPTIONS . contains ( option) {
336+ err_unsupported_option ( p , symbol , p . prev_token . span ) ;
337+ } else if args . options . contains ( option ) {
327338 err_duplicate_option ( p, symbol, p. prev_token . span ) ;
339+ } else {
340+ args. options |= option;
328341 }
329342}
330343
@@ -338,25 +351,33 @@ fn parse_options<'a>(
338351 p. expect ( & token:: OpenDelim ( Delimiter :: Parenthesis ) ) ?;
339352
340353 while !p. eat ( & token:: CloseDelim ( Delimiter :: Parenthesis ) ) {
341- if !is_global_asm && p. eat_keyword ( sym:: pure) {
342- try_set_option ( p, args, sym:: pure, ast:: InlineAsmOptions :: PURE ) ;
343- } else if !is_global_asm && p. eat_keyword ( sym:: nomem) {
344- try_set_option ( p, args, sym:: nomem, ast:: InlineAsmOptions :: NOMEM ) ;
345- } else if !is_global_asm && p. eat_keyword ( sym:: readonly) {
346- try_set_option ( p, args, sym:: readonly, ast:: InlineAsmOptions :: READONLY ) ;
347- } else if !is_global_asm && p. eat_keyword ( sym:: preserves_flags) {
348- try_set_option ( p, args, sym:: preserves_flags, ast:: InlineAsmOptions :: PRESERVES_FLAGS ) ;
349- } else if !is_global_asm && p. eat_keyword ( sym:: noreturn) {
350- try_set_option ( p, args, sym:: noreturn, ast:: InlineAsmOptions :: NORETURN ) ;
351- } else if !is_global_asm && p. eat_keyword ( sym:: nostack) {
352- try_set_option ( p, args, sym:: nostack, ast:: InlineAsmOptions :: NOSTACK ) ;
353- } else if !is_global_asm && p. eat_keyword ( sym:: may_unwind) {
354- try_set_option ( p, args, kw:: Raw , ast:: InlineAsmOptions :: MAY_UNWIND ) ;
355- } else if p. eat_keyword ( sym:: att_syntax) {
356- try_set_option ( p, args, sym:: att_syntax, ast:: InlineAsmOptions :: ATT_SYNTAX ) ;
357- } else if p. eat_keyword ( kw:: Raw ) {
358- try_set_option ( p, args, kw:: Raw , ast:: InlineAsmOptions :: RAW ) ;
359- } else {
354+ const OPTIONS : [ ( Symbol , ast:: InlineAsmOptions ) ; ast:: InlineAsmOptions :: COUNT ] = [
355+ ( sym:: pure, ast:: InlineAsmOptions :: PURE ) ,
356+ ( sym:: nomem, ast:: InlineAsmOptions :: NOMEM ) ,
357+ ( sym:: readonly, ast:: InlineAsmOptions :: READONLY ) ,
358+ ( sym:: preserves_flags, ast:: InlineAsmOptions :: PRESERVES_FLAGS ) ,
359+ ( sym:: noreturn, ast:: InlineAsmOptions :: NORETURN ) ,
360+ ( sym:: nostack, ast:: InlineAsmOptions :: NOSTACK ) ,
361+ ( sym:: may_unwind, ast:: InlineAsmOptions :: MAY_UNWIND ) ,
362+ ( sym:: att_syntax, ast:: InlineAsmOptions :: ATT_SYNTAX ) ,
363+ ( kw:: Raw , ast:: InlineAsmOptions :: RAW ) ,
364+ ] ;
365+
366+ ' blk: {
367+ for ( symbol, option) in OPTIONS {
368+ let kw_matched =
369+ if !is_global_asm || ast:: InlineAsmOptions :: GLOBAL_OPTIONS . contains ( option) {
370+ p. eat_keyword ( symbol)
371+ } else {
372+ p. eat_keyword_noexpect ( symbol)
373+ } ;
374+
375+ if kw_matched {
376+ try_set_option ( p, args, is_global_asm, symbol, option) ;
377+ break ' blk;
378+ }
379+ }
380+
360381 return p. unexpected ( ) ;
361382 }
362383
0 commit comments