@@ -29,6 +29,29 @@ pub struct AsmArgs {
2929 pub options_spans : Vec < Span > ,
3030}
3131
32+ /// Used for better error messages when operand types are used that are not
33+ /// supported by the current macro (e.g. `in` or `out` for `global_asm!`)
34+ ///
35+ /// returns
36+ ///
37+ /// - `Ok(true)` if the current token matches the keyword, and was expected
38+ /// - `Ok(false)` if the current token does not match the keyword
39+ /// - `Err(_)` if the current token matches the keyword, but was not expected
40+ fn eat_operand_keyword < ' a > ( p : & mut Parser < ' a > , symbol : Symbol , expect : bool ) -> PResult < ' a , bool > {
41+ if expect {
42+ Ok ( p. eat_keyword ( symbol) )
43+ } else {
44+ let span = p. token . span ;
45+ if p. eat_keyword_noexpect ( symbol) {
46+ // in gets printed as `r#in` otherwise
47+ let symbol = if symbol == kw:: In { "in" } else { symbol. as_str ( ) } ;
48+ Err ( p. dcx ( ) . create_err ( errors:: GlobalAsmUnsupportedOperand { span, symbol } ) )
49+ } else {
50+ Ok ( false )
51+ }
52+ }
53+ }
54+
3255fn parse_args < ' a > (
3356 ecx : & ExtCtxt < ' a > ,
3457 sp : Span ,
@@ -106,23 +129,23 @@ pub fn parse_asm_args<'a>(
106129 } ;
107130
108131 let mut explicit_reg = false ;
109- let op = if !is_global_asm && p . eat_keyword ( kw:: In ) {
132+ let op = if eat_operand_keyword ( p , kw:: In , !is_global_asm ) ? {
110133 let reg = parse_reg ( p, & mut explicit_reg) ?;
111134 if p. eat_keyword ( kw:: Underscore ) {
112135 let err = dcx. create_err ( errors:: AsmUnderscoreInput { span : p. token . span } ) ;
113136 return Err ( err) ;
114137 }
115138 let expr = p. parse_expr ( ) ?;
116139 ast:: InlineAsmOperand :: In { reg, expr }
117- } else if !is_global_asm && p . eat_keyword ( sym:: out) {
140+ } else if eat_operand_keyword ( p , sym:: out, !is_global_asm ) ? {
118141 let reg = parse_reg ( p, & mut explicit_reg) ?;
119142 let expr = if p. eat_keyword ( kw:: Underscore ) { None } else { Some ( p. parse_expr ( ) ?) } ;
120143 ast:: InlineAsmOperand :: Out { reg, expr, late : false }
121- } else if !is_global_asm && p . eat_keyword ( sym:: lateout) {
144+ } else if eat_operand_keyword ( p , sym:: lateout, !is_global_asm ) ? {
122145 let reg = parse_reg ( p, & mut explicit_reg) ?;
123146 let expr = if p. eat_keyword ( kw:: Underscore ) { None } else { Some ( p. parse_expr ( ) ?) } ;
124147 ast:: InlineAsmOperand :: Out { reg, expr, late : true }
125- } else if !is_global_asm && p . eat_keyword ( sym:: inout) {
148+ } else if eat_operand_keyword ( p , sym:: inout, !is_global_asm ) ? {
126149 let reg = parse_reg ( p, & mut explicit_reg) ?;
127150 if p. eat_keyword ( kw:: Underscore ) {
128151 let err = dcx. create_err ( errors:: AsmUnderscoreInput { span : p. token . span } ) ;
@@ -136,7 +159,7 @@ pub fn parse_asm_args<'a>(
136159 } else {
137160 ast:: InlineAsmOperand :: InOut { reg, expr, late : false }
138161 }
139- } else if !is_global_asm && p . eat_keyword ( sym:: inlateout) {
162+ } else if eat_operand_keyword ( p , sym:: inlateout, !is_global_asm ) ? {
140163 let reg = parse_reg ( p, & mut explicit_reg) ?;
141164 if p. eat_keyword ( kw:: Underscore ) {
142165 let err = dcx. create_err ( errors:: AsmUnderscoreInput { span : p. token . span } ) ;
@@ -150,6 +173,9 @@ pub fn parse_asm_args<'a>(
150173 } else {
151174 ast:: InlineAsmOperand :: InOut { reg, expr, late : true }
152175 }
176+ } else if eat_operand_keyword ( p, sym:: label, !is_global_asm) ? {
177+ let block = p. parse_block ( ) ?;
178+ ast:: InlineAsmOperand :: Label { block }
153179 } else if p. eat_keyword ( kw:: Const ) {
154180 let anon_const = p. parse_expr_anon_const ( ) ?;
155181 ast:: InlineAsmOperand :: Const { anon_const }
@@ -165,9 +191,6 @@ pub fn parse_asm_args<'a>(
165191 path : path. clone ( ) ,
166192 } ;
167193 ast:: InlineAsmOperand :: Sym { sym }
168- } else if !is_global_asm && p. eat_keyword ( sym:: label) {
169- let block = p. parse_block ( ) ?;
170- ast:: InlineAsmOperand :: Label { block }
171194 } else if allow_templates {
172195 let template = p. parse_expr ( ) ?;
173196 // If it can't possibly expand to a string, provide diagnostics here to include other
0 commit comments