@@ -28,6 +28,29 @@ pub struct AsmArgs {
28
28
pub options_spans : Vec < Span > ,
29
29
}
30
30
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
+
31
54
fn parse_args < ' a > (
32
55
ecx : & ExtCtxt < ' a > ,
33
56
sp : Span ,
@@ -105,23 +128,23 @@ pub fn parse_asm_args<'a>(
105
128
} ;
106
129
107
130
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 ) ? {
109
132
let reg = parse_reg ( p, & mut explicit_reg) ?;
110
133
if p. eat_keyword ( kw:: Underscore ) {
111
134
let err = dcx. create_err ( errors:: AsmUnderscoreInput { span : p. token . span } ) ;
112
135
return Err ( err) ;
113
136
}
114
137
let expr = p. parse_expr ( ) ?;
115
138
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 ) ? {
117
140
let reg = parse_reg ( p, & mut explicit_reg) ?;
118
141
let expr = if p. eat_keyword ( kw:: Underscore ) { None } else { Some ( p. parse_expr ( ) ?) } ;
119
142
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 ) ? {
121
144
let reg = parse_reg ( p, & mut explicit_reg) ?;
122
145
let expr = if p. eat_keyword ( kw:: Underscore ) { None } else { Some ( p. parse_expr ( ) ?) } ;
123
146
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 ) ? {
125
148
let reg = parse_reg ( p, & mut explicit_reg) ?;
126
149
if p. eat_keyword ( kw:: Underscore ) {
127
150
let err = dcx. create_err ( errors:: AsmUnderscoreInput { span : p. token . span } ) ;
@@ -135,7 +158,7 @@ pub fn parse_asm_args<'a>(
135
158
} else {
136
159
ast:: InlineAsmOperand :: InOut { reg, expr, late : false }
137
160
}
138
- } else if !is_global_asm && p . eat_keyword ( sym:: inlateout) {
161
+ } else if eat_operand_keyword ( p , sym:: inlateout, !is_global_asm ) ? {
139
162
let reg = parse_reg ( p, & mut explicit_reg) ?;
140
163
if p. eat_keyword ( kw:: Underscore ) {
141
164
let err = dcx. create_err ( errors:: AsmUnderscoreInput { span : p. token . span } ) ;
@@ -149,6 +172,9 @@ pub fn parse_asm_args<'a>(
149
172
} else {
150
173
ast:: InlineAsmOperand :: InOut { reg, expr, late : true }
151
174
}
175
+ } else if eat_operand_keyword ( p, sym:: label, !is_global_asm) ? {
176
+ let block = p. parse_block ( ) ?;
177
+ ast:: InlineAsmOperand :: Label { block }
152
178
} else if p. eat_keyword ( kw:: Const ) {
153
179
let anon_const = p. parse_expr_anon_const ( ) ?;
154
180
ast:: InlineAsmOperand :: Const { anon_const }
@@ -164,9 +190,6 @@ pub fn parse_asm_args<'a>(
164
190
path : path. clone ( ) ,
165
191
} ;
166
192
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 }
170
193
} else if allow_templates {
171
194
let template = p. parse_expr ( ) ?;
172
195
// If it can't possibly expand to a string, provide diagnostics here to include other
0 commit comments