@@ -28,6 +28,29 @@ pub struct AsmArgs {
2828 pub options_spans : Vec < Span > ,
2929}
3030
31+ /// Used for better error messages when operand types are used that are not
32+ /// supported by the current macro (e.g. `in` or `out` for `global_asm!`)
33+ ///
34+ /// returns
35+ ///
36+ /// - `Ok(true)` if the current token matches the keyword, and was expected
37+ /// - `Ok(false)` if the current token does not match the keyword
38+ /// - `Err(_)` if the current token matches the keyword, but was not expected
39+ fn eat_operand_keyword < ' a > ( p : & mut Parser < ' a > , symbol : Symbol , expect : bool ) -> PResult < ' a , bool > {
40+ if expect {
41+ Ok ( p. eat_keyword ( symbol) )
42+ } else {
43+ let span = p. token . span ;
44+ if p. eat_keyword_noexpect ( symbol) {
45+ // in gets printed as `r#in` otherwise
46+ let symbol = if symbol == kw:: In { "in" } else { symbol. as_str ( ) } ;
47+ Err ( p. dcx ( ) . create_err ( errors:: GlobalAsmUnsupportedOperand { span, symbol } ) )
48+ } else {
49+ Ok ( false )
50+ }
51+ }
52+ }
53+
3154fn parse_args < ' a > (
3255 ecx : & ExtCtxt < ' a > ,
3356 sp : Span ,
@@ -105,23 +128,23 @@ pub fn parse_asm_args<'a>(
105128 } ;
106129
107130 let mut explicit_reg = false ;
108- let op = if !is_global_asm && p . eat_keyword ( kw:: In ) {
131+ let op = if eat_operand_keyword ( p , kw:: In , !is_global_asm ) ? {
109132 let reg = parse_reg ( p, & mut explicit_reg) ?;
110133 if p. eat_keyword ( kw:: Underscore ) {
111134 let err = dcx. create_err ( errors:: AsmUnderscoreInput { span : p. token . span } ) ;
112135 return Err ( err) ;
113136 }
114137 let expr = p. parse_expr ( ) ?;
115138 ast:: InlineAsmOperand :: In { reg, expr }
116- } else if !is_global_asm && p . eat_keyword ( sym:: out) {
139+ } else if eat_operand_keyword ( p , sym:: out, !is_global_asm ) ? {
117140 let reg = parse_reg ( p, & mut explicit_reg) ?;
118141 let expr = if p. eat_keyword ( kw:: Underscore ) { None } else { Some ( p. parse_expr ( ) ?) } ;
119142 ast:: InlineAsmOperand :: Out { reg, expr, late : false }
120- } else if !is_global_asm && p . eat_keyword ( sym:: lateout) {
143+ } else if eat_operand_keyword ( p , sym:: lateout, !is_global_asm ) ? {
121144 let reg = parse_reg ( p, & mut explicit_reg) ?;
122145 let expr = if p. eat_keyword ( kw:: Underscore ) { None } else { Some ( p. parse_expr ( ) ?) } ;
123146 ast:: InlineAsmOperand :: Out { reg, expr, late : true }
124- } else if !is_global_asm && p . eat_keyword ( sym:: inout) {
147+ } else if eat_operand_keyword ( p , sym:: inout, !is_global_asm ) ? {
125148 let reg = parse_reg ( p, & mut explicit_reg) ?;
126149 if p. eat_keyword ( kw:: Underscore ) {
127150 let err = dcx. create_err ( errors:: AsmUnderscoreInput { span : p. token . span } ) ;
@@ -135,7 +158,7 @@ pub fn parse_asm_args<'a>(
135158 } else {
136159 ast:: InlineAsmOperand :: InOut { reg, expr, late : false }
137160 }
138- } else if !is_global_asm && p . eat_keyword ( sym:: inlateout) {
161+ } else if eat_operand_keyword ( p , sym:: inlateout, !is_global_asm ) ? {
139162 let reg = parse_reg ( p, & mut explicit_reg) ?;
140163 if p. eat_keyword ( kw:: Underscore ) {
141164 let err = dcx. create_err ( errors:: AsmUnderscoreInput { span : p. token . span } ) ;
@@ -149,6 +172,9 @@ pub fn parse_asm_args<'a>(
149172 } else {
150173 ast:: InlineAsmOperand :: InOut { reg, expr, late : true }
151174 }
175+ } else if eat_operand_keyword ( p, sym:: label, !is_global_asm) ? {
176+ let block = p. parse_block ( ) ?;
177+ ast:: InlineAsmOperand :: Label { block }
152178 } else if p. eat_keyword ( kw:: Const ) {
153179 let anon_const = p. parse_expr_anon_const ( ) ?;
154180 ast:: InlineAsmOperand :: Const { anon_const }
@@ -164,9 +190,6 @@ pub fn parse_asm_args<'a>(
164190 path : path. clone ( ) ,
165191 } ;
166192 ast:: InlineAsmOperand :: Sym { sym }
167- } else if !is_global_asm && p. eat_keyword ( sym:: label) {
168- let block = p. parse_block ( ) ?;
169- ast:: InlineAsmOperand :: Label { block }
170193 } else if allow_templates {
171194 let template = p. parse_expr ( ) ?;
172195 // If it can't possibly expand to a string, provide diagnostics here to include other
0 commit comments