11use crate :: { ImplTraitContext , ImplTraitPosition , ParamMode , ResolverAstLoweringExt } ;
22
3+ use super :: errors:: {
4+ AbiSpecifiedMultipleTimes , AttSyntaxOnlyX86 , ClobberAbiNotSupported ,
5+ InlineAsmUnsupportedTarget , InvalidAbiClobberAbi , InvalidAsmTemplateModifierConst ,
6+ InvalidAsmTemplateModifierRegClass , InvalidAsmTemplateModifierRegClassSub ,
7+ InvalidAsmTemplateModifierSym , InvalidRegister , InvalidRegisterClass , RegisterClassOnlyClobber ,
8+ RegisterConflict ,
9+ } ;
310use super :: LoweringContext ;
411
512use rustc_ast:: ptr:: P ;
613use rustc_ast:: * ;
714use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
8- use rustc_errors:: struct_span_err;
915use rustc_hir as hir;
1016use rustc_hir:: def:: { DefKind , Res } ;
1117use rustc_hir:: definitions:: DefPathData ;
@@ -26,13 +32,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2632 let asm_arch =
2733 if self . tcx . sess . opts . actually_rustdoc { None } else { self . tcx . sess . asm_arch } ;
2834 if asm_arch. is_none ( ) && !self . tcx . sess . opts . actually_rustdoc {
29- struct_span_err ! (
30- self . tcx. sess,
31- sp,
32- E0472 ,
33- "inline assembly is unsupported on this target"
34- )
35- . emit ( ) ;
35+ self . tcx . sess . emit_err ( InlineAsmUnsupportedTarget { span : sp } ) ;
3636 }
3737 if let Some ( asm_arch) = asm_arch {
3838 // Inline assembly is currently only stable for these architectures.
@@ -59,10 +59,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
5959 && !matches ! ( asm_arch, Some ( asm:: InlineAsmArch :: X86 | asm:: InlineAsmArch :: X86_64 ) )
6060 && !self . tcx . sess . opts . actually_rustdoc
6161 {
62- self . tcx
63- . sess
64- . struct_span_err ( sp, "the `att_syntax` option is only supported on x86" )
65- . emit ( ) ;
62+ self . tcx . sess . emit_err ( AttSyntaxOnlyX86 { span : sp } ) ;
6663 }
6764 if asm. options . contains ( InlineAsmOptions :: MAY_UNWIND ) && !self . tcx . features ( ) . asm_unwind {
6865 feature_err (
@@ -82,51 +79,37 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
8279 // If the abi was already in the list, emit an error
8380 match clobber_abis. get ( & abi) {
8481 Some ( ( prev_name, prev_sp) ) => {
85- let mut err = self . tcx . sess . struct_span_err (
86- * abi_span,
87- & format ! ( "`{}` ABI specified multiple times" , prev_name) ,
88- ) ;
89- err. span_label ( * prev_sp, "previously specified here" ) ;
90-
9182 // Multiple different abi names may actually be the same ABI
9283 // If the specified ABIs are not the same name, alert the user that they resolve to the same ABI
9384 let source_map = self . tcx . sess . source_map ( ) ;
94- if source_map. span_to_snippet ( * prev_sp)
95- != source_map. span_to_snippet ( * abi_span)
96- {
97- err. note ( "these ABIs are equivalent on the current target" ) ;
98- }
85+ let equivalent = ( source_map. span_to_snippet ( * prev_sp)
86+ != source_map. span_to_snippet ( * abi_span) )
87+ . then_some ( ( ) ) ;
9988
100- err. emit ( ) ;
89+ self . tcx . sess . emit_err ( AbiSpecifiedMultipleTimes {
90+ abi_span : * abi_span,
91+ prev_name : * prev_name,
92+ prev_span : * prev_sp,
93+ equivalent,
94+ } ) ;
10195 }
10296 None => {
103- clobber_abis. insert ( abi, ( abi_name, * abi_span) ) ;
97+ clobber_abis. insert ( abi, ( * abi_name, * abi_span) ) ;
10498 }
10599 }
106100 }
107101 Err ( & [ ] ) => {
108- self . tcx
109- . sess
110- . struct_span_err (
111- * abi_span,
112- "`clobber_abi` is not supported on this target" ,
113- )
114- . emit ( ) ;
102+ self . tcx . sess . emit_err ( ClobberAbiNotSupported { abi_span : * abi_span } ) ;
115103 }
116104 Err ( supported_abis) => {
117- let mut err = self
118- . tcx
119- . sess
120- . struct_span_err ( * abi_span, "invalid ABI for `clobber_abi`" ) ;
121105 let mut abis = format ! ( "`{}`" , supported_abis[ 0 ] ) ;
122106 for m in & supported_abis[ 1 ..] {
123107 let _ = write ! ( abis, ", `{}`" , m) ;
124108 }
125- err. note ( & format ! (
126- "the following ABIs are supported on this target: {}" ,
127- abis
128- ) ) ;
129- err. emit ( ) ;
109+ self . tcx . sess . emit_err ( InvalidAbiClobberAbi {
110+ abi_span : * abi_span,
111+ supported_abis : abis,
112+ } ) ;
130113 }
131114 }
132115 }
@@ -141,24 +124,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
141124 . iter ( )
142125 . map ( |( op, op_sp) | {
143126 let lower_reg = |reg| match reg {
144- InlineAsmRegOrRegClass :: Reg ( s ) => {
127+ InlineAsmRegOrRegClass :: Reg ( reg ) => {
145128 asm:: InlineAsmRegOrRegClass :: Reg ( if let Some ( asm_arch) = asm_arch {
146- asm:: InlineAsmReg :: parse ( asm_arch, s) . unwrap_or_else ( |e| {
147- let msg = format ! ( "invalid register `{}`: {}" , s, e) ;
148- sess. struct_span_err ( * op_sp, & msg) . emit ( ) ;
129+ asm:: InlineAsmReg :: parse ( asm_arch, reg) . unwrap_or_else ( |error| {
130+ sess. emit_err ( InvalidRegister { op_span : * op_sp, reg, error } ) ;
149131 asm:: InlineAsmReg :: Err
150132 } )
151133 } else {
152134 asm:: InlineAsmReg :: Err
153135 } )
154136 }
155- InlineAsmRegOrRegClass :: RegClass ( s ) => {
137+ InlineAsmRegOrRegClass :: RegClass ( reg_class ) => {
156138 asm:: InlineAsmRegOrRegClass :: RegClass ( if let Some ( asm_arch) = asm_arch {
157- asm:: InlineAsmRegClass :: parse ( asm_arch, s) . unwrap_or_else ( |e| {
158- let msg = format ! ( "invalid register class `{}`: {}" , s, e) ;
159- sess. struct_span_err ( * op_sp, & msg) . emit ( ) ;
160- asm:: InlineAsmRegClass :: Err
161- } )
139+ asm:: InlineAsmRegClass :: parse ( asm_arch, reg_class) . unwrap_or_else (
140+ |error| {
141+ sess. emit_err ( InvalidRegisterClass {
142+ op_span : * op_sp,
143+ reg_class,
144+ error,
145+ } ) ;
146+ asm:: InlineAsmRegClass :: Err
147+ } ,
148+ )
162149 } else {
163150 asm:: InlineAsmRegClass :: Err
164151 } )
@@ -282,50 +269,39 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
282269 }
283270 let valid_modifiers = class. valid_modifiers ( asm_arch. unwrap ( ) ) ;
284271 if !valid_modifiers. contains ( & modifier) {
285- let mut err = sess. struct_span_err (
286- placeholder_span,
287- "invalid asm template modifier for this register class" ,
288- ) ;
289- err. span_label ( placeholder_span, "template modifier" ) ;
290- err. span_label ( op_sp, "argument" ) ;
291- if !valid_modifiers. is_empty ( ) {
272+ let sub = if !valid_modifiers. is_empty ( ) {
292273 let mut mods = format ! ( "`{}`" , valid_modifiers[ 0 ] ) ;
293274 for m in & valid_modifiers[ 1 ..] {
294275 let _ = write ! ( mods, ", `{}`" , m) ;
295276 }
296- err. note ( & format ! (
297- "the `{}` register class supports \
298- the following template modifiers: {}",
299- class. name( ) ,
300- mods
301- ) ) ;
277+ InvalidAsmTemplateModifierRegClassSub :: SupportModifier {
278+ class_name : class. name ( ) ,
279+ modifiers : mods,
280+ }
302281 } else {
303- err. note ( & format ! (
304- "the `{}` register class does not support template modifiers" ,
305- class. name( )
306- ) ) ;
307- }
308- err. emit ( ) ;
282+ InvalidAsmTemplateModifierRegClassSub :: DoesNotSupportModifier {
283+ class_name : class. name ( ) ,
284+ }
285+ } ;
286+ sess. emit_err ( InvalidAsmTemplateModifierRegClass {
287+ placeholder_span,
288+ op_span : op_sp,
289+ sub,
290+ } ) ;
309291 }
310292 }
311293 hir:: InlineAsmOperand :: Const { .. } => {
312- let mut err = sess. struct_span_err (
294+ sess. emit_err ( InvalidAsmTemplateModifierConst {
313295 placeholder_span,
314- "asm template modifiers are not allowed for `const` arguments" ,
315- ) ;
316- err. span_label ( placeholder_span, "template modifier" ) ;
317- err. span_label ( op_sp, "argument" ) ;
318- err. emit ( ) ;
296+ op_span : op_sp,
297+ } ) ;
319298 }
320299 hir:: InlineAsmOperand :: SymFn { .. }
321300 | hir:: InlineAsmOperand :: SymStatic { .. } => {
322- let mut err = sess. struct_span_err (
301+ sess. emit_err ( InvalidAsmTemplateModifierSym {
323302 placeholder_span,
324- "asm template modifiers are not allowed for `sym` arguments" ,
325- ) ;
326- err. span_label ( placeholder_span, "template modifier" ) ;
327- err. span_label ( op_sp, "argument" ) ;
328- err. emit ( ) ;
303+ op_span : op_sp,
304+ } ) ;
329305 }
330306 }
331307 }
@@ -346,12 +322,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
346322 // require that the operand name an explicit register, not a
347323 // register class.
348324 if reg_class. is_clobber_only ( asm_arch. unwrap ( ) ) && !op. is_clobber ( ) {
349- let msg = format ! (
350- "register class `{}` can only be used as a clobber, \
351- not as an input or output",
352- reg_class. name( )
353- ) ;
354- sess. struct_span_err ( op_sp, & msg) . emit ( ) ;
325+ sess. emit_err ( RegisterClassOnlyClobber {
326+ op_span : op_sp,
327+ reg_class_name : reg_class. name ( ) ,
328+ } ) ;
355329 continue ;
356330 }
357331
@@ -391,16 +365,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
391365 unreachable ! ( ) ;
392366 } ;
393367
394- let msg = format ! (
395- "register `{}` conflicts with register `{}`" ,
396- reg. name( ) ,
397- reg2. name( )
398- ) ;
399- let mut err = sess. struct_span_err ( op_sp, & msg) ;
400- err. span_label ( op_sp, & format ! ( "register `{}`" , reg. name( ) ) ) ;
401- err. span_label ( op_sp2, & format ! ( "register `{}`" , reg2. name( ) ) ) ;
402-
403- match ( op, op2) {
368+ let in_out = match ( op, op2) {
404369 (
405370 hir:: InlineAsmOperand :: In { .. } ,
406371 hir:: InlineAsmOperand :: Out { late, .. } ,
@@ -411,14 +376,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
411376 ) => {
412377 assert ! ( !* late) ;
413378 let out_op_sp = if input { op_sp2 } else { op_sp } ;
414- let msg = "use `lateout` instead of \
415- `out` to avoid conflict";
416- err. span_help ( out_op_sp, msg) ;
417- }
418- _ => { }
419- }
379+ Some ( out_op_sp)
380+ } ,
381+ _ => None ,
382+ } ;
420383
421- err. emit ( ) ;
384+ sess. emit_err ( RegisterConflict {
385+ op_span1 : op_sp,
386+ op_span2 : op_sp2,
387+ reg1_name : reg. name ( ) ,
388+ reg2_name : reg2. name ( ) ,
389+ in_out
390+ } ) ;
422391 }
423392 Entry :: Vacant ( v) => {
424393 if r == reg {
0 commit comments