@@ -3,7 +3,7 @@ use rustc_ast::ptr::P;
33use rustc_ast:: token:: { self , Delimiter } ;
44use rustc_ast:: tokenstream:: TokenStream ;
55use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
6- use rustc_errors:: { Applicability , PResult } ;
6+ use rustc_errors:: PResult ;
77use rustc_expand:: base:: { self , * } ;
88use rustc_parse:: parser:: Parser ;
99use rustc_parse_format as parse;
@@ -49,7 +49,7 @@ pub fn parse_asm_args<'a>(
4949 let diag = & sess. span_diagnostic ;
5050
5151 if p. token == token:: Eof {
52- return Err ( diag. struct_span_err ( sp , "requires at least a template string argument" ) ) ;
52+ return Err ( diag. create_err ( errors :: AsmRequiresTemplate { span : sp } ) ) ;
5353 }
5454
5555 let first_template = p. parse_expr ( ) ?;
@@ -68,8 +68,7 @@ pub fn parse_asm_args<'a>(
6868 if !p. eat ( & token:: Comma ) {
6969 if allow_templates {
7070 // After a template string, we always expect *only* a comma...
71- let mut err = diag. struct_span_err ( p. token . span , "expected token: `,`" ) ;
72- err. span_label ( p. token . span , "expected `,`" ) ;
71+ let mut err = diag. create_err ( errors:: AsmExpectedComma { span : p. token . span } ) ;
7372 p. maybe_annotate_with_ascription ( & mut err, false ) ;
7473 return Err ( err) ;
7574 } else {
@@ -112,7 +111,7 @@ pub fn parse_asm_args<'a>(
112111 let op = if !is_global_asm && p. eat_keyword ( kw:: In ) {
113112 let reg = parse_reg ( p, & mut explicit_reg) ?;
114113 if p. eat_keyword ( kw:: Underscore ) {
115- let err = diag. struct_span_err ( p. token . span , "_ cannot be used for input operands" ) ;
114+ let err = diag. create_err ( errors :: AsmUnderscoreInput { span : p. token . span } ) ;
116115 return Err ( err) ;
117116 }
118117 let expr = p. parse_expr ( ) ?;
@@ -128,7 +127,7 @@ pub fn parse_asm_args<'a>(
128127 } else if !is_global_asm && p. eat_keyword ( sym:: inout) {
129128 let reg = parse_reg ( p, & mut explicit_reg) ?;
130129 if p. eat_keyword ( kw:: Underscore ) {
131- let err = diag. struct_span_err ( p. token . span , "_ cannot be used for input operands" ) ;
130+ let err = diag. create_err ( errors :: AsmUnderscoreInput { span : p. token . span } ) ;
132131 return Err ( err) ;
133132 }
134133 let expr = p. parse_expr ( ) ?;
@@ -142,7 +141,7 @@ pub fn parse_asm_args<'a>(
142141 } else if !is_global_asm && p. eat_keyword ( sym:: inlateout) {
143142 let reg = parse_reg ( p, & mut explicit_reg) ?;
144143 if p. eat_keyword ( kw:: Underscore ) {
145- let err = diag. struct_span_err ( p. token . span , "_ cannot be used for input operands" ) ;
144+ let err = diag. create_err ( errors :: AsmUnderscoreInput { span : p. token . span } ) ;
146145 return Err ( err) ;
147146 }
148147 let expr = p. parse_expr ( ) ?;
@@ -160,7 +159,7 @@ pub fn parse_asm_args<'a>(
160159 let expr = p. parse_expr ( ) ?;
161160 let ast:: ExprKind :: Path ( qself, path) = & expr. kind else {
162161 let err = diag
163- . struct_span_err ( expr. span , "expected a path for argument to `sym`" ) ;
162+ . create_err ( errors :: AsmSymNoPath { span : expr. span } ) ;
164163 return Err ( err) ;
165164 } ;
166165 let sym = ast:: InlineAsmSym {
@@ -181,13 +180,10 @@ pub fn parse_asm_args<'a>(
181180 ) => { }
182181 ast:: ExprKind :: MacCall ( ..) => { }
183182 _ => {
184- let errstr = if is_global_asm {
185- "expected operand, options, or additional template string"
186- } else {
187- "expected operand, clobber_abi, options, or additional template string"
188- } ;
189- let mut err = diag. struct_span_err ( template. span , errstr) ;
190- err. span_label ( template. span , errstr) ;
183+ let err = diag. create_err ( errors:: AsmExpectedOther {
184+ span : template. span ,
185+ is_global_asm,
186+ } ) ;
191187 return Err ( err) ;
192188 }
193189 }
@@ -212,28 +208,16 @@ pub fn parse_asm_args<'a>(
212208 args. reg_args . insert ( slot) ;
213209 } else if let Some ( name) = name {
214210 if let Some ( & prev) = args. named_args . get ( & name) {
215- diag. struct_span_err ( span, & format ! ( "duplicate argument named `{}`" , name) )
216- . span_label ( args. operands [ prev] . 1 , "previously here" )
217- . span_label ( span, "duplicate argument" )
218- . emit ( ) ;
211+ diag. emit_err ( errors:: AsmDuplicateArg { span, name, prev : args. operands [ prev] . 1 } ) ;
219212 continue ;
220213 }
221214 args. named_args . insert ( name, slot) ;
222215 } else {
223216 if !args. named_args . is_empty ( ) || !args. reg_args . is_empty ( ) {
224- let mut err = diag. struct_span_err (
225- span,
226- "positional arguments cannot follow named arguments \
227- or explicit register arguments",
228- ) ;
229- err. span_label ( span, "positional argument" ) ;
230- for pos in args. named_args . values ( ) {
231- err. span_label ( args. operands [ * pos] . 1 , "named argument" ) ;
232- }
233- for pos in & args. reg_args {
234- err. span_label ( args. operands [ * pos] . 1 , "explicit register argument" ) ;
235- }
236- err. emit ( ) ;
217+ let named = args. named_args . values ( ) . map ( |p| args. operands [ * p] . 1 ) . collect ( ) ;
218+ let explicit = args. reg_args . iter ( ) . map ( |p| args. operands [ * p] . 1 ) . collect ( ) ;
219+
220+ diag. emit_err ( errors:: AsmPositionalAfter { span, named, explicit } ) ;
237221 }
238222 }
239223 }
@@ -284,34 +268,25 @@ pub fn parse_asm_args<'a>(
284268 diag. emit_err ( errors:: AsmPureNoOutput { spans : args. options_spans . clone ( ) } ) ;
285269 }
286270 if args. options . contains ( ast:: InlineAsmOptions :: NORETURN ) && !outputs_sp. is_empty ( ) {
287- let err = diag
288- . struct_span_err ( outputs_sp, "asm outputs are not allowed with the `noreturn` option" ) ;
289-
271+ let err = diag. create_err ( errors:: AsmNoReturn { outputs_sp } ) ;
290272 // Bail out now since this is likely to confuse MIR
291273 return Err ( err) ;
292274 }
293275
294276 if args. clobber_abis . len ( ) > 0 {
295277 if is_global_asm {
296- let err = diag. struct_span_err (
297- args. clobber_abis . iter ( ) . map ( |( _, span) | * span) . collect :: < Vec < Span > > ( ) ,
298- "`clobber_abi` cannot be used with `global_asm!`" ,
299- ) ;
278+ let err = diag. create_err ( errors:: GlobalAsmClobberAbi {
279+ spans : args. clobber_abis . iter ( ) . map ( |( _, span) | * span) . collect ( ) ,
280+ } ) ;
300281
301282 // Bail out now since this is likely to confuse later stages
302283 return Err ( err) ;
303284 }
304285 if !regclass_outputs. is_empty ( ) {
305- diag. struct_span_err (
306- regclass_outputs. clone ( ) ,
307- "asm with `clobber_abi` must specify explicit registers for outputs" ,
308- )
309- . span_labels (
310- args. clobber_abis . iter ( ) . map ( |( _, span) | * span) . collect :: < Vec < Span > > ( ) ,
311- "clobber_abi" ,
312- )
313- . span_labels ( regclass_outputs, "generic outputs" )
314- . emit ( ) ;
286+ diag. emit_err ( errors:: AsmClobberNoReg {
287+ spans : regclass_outputs,
288+ clobbers : args. clobber_abis . iter ( ) . map ( |( _, span) | * span) . collect ( ) ,
289+ } ) ;
315290 }
316291 }
317292
@@ -323,25 +298,9 @@ pub fn parse_asm_args<'a>(
323298/// This function must be called immediately after the option token is parsed.
324299/// Otherwise, the suggestion will be incorrect.
325300fn err_duplicate_option ( p : & mut Parser < ' _ > , symbol : Symbol , span : Span ) {
326- let mut err = p
327- . sess
328- . span_diagnostic
329- . struct_span_err ( span, & format ! ( "the `{}` option was already provided" , symbol) ) ;
330- err. span_label ( span, "this option was already provided" ) ;
331-
332301 // Tool-only output
333- let mut full_span = span;
334- if p. token . kind == token:: Comma {
335- full_span = full_span. to ( p. token . span ) ;
336- }
337- err. tool_only_span_suggestion (
338- full_span,
339- "remove this option" ,
340- "" ,
341- Applicability :: MachineApplicable ,
342- ) ;
343-
344- err. emit ( ) ;
302+ let full_span = if p. token . kind == token:: Comma { span. to ( p. token . span ) } else { span } ;
303+ p. sess . span_diagnostic . emit_err ( errors:: AsmOptAlreadyprovided { span, symbol, full_span } ) ;
345304}
346305
347306/// Try to set the provided option in the provided `AsmArgs`.
0 commit comments