1
1
use crate :: { ImplTraitContext , ImplTraitPosition , ParamMode , ResolverAstLoweringExt } ;
2
2
3
+ use super :: errors:: {
4
+ AbiSpecifiedMultipleTimes , AttSyntaxOnlyX86 , ClobberAbiNotSupported ,
5
+ InlineAsmUnsupportedTarget , InvalidAbiClobberAbi , InvalidAsmTemplateModifierConst ,
6
+ InvalidAsmTemplateModifierRegClass , InvalidAsmTemplateModifierRegClassSub ,
7
+ InvalidAsmTemplateModifierSym , InvalidRegister , InvalidRegisterClass , RegisterClassOnlyClobber ,
8
+ RegisterConflict ,
9
+ } ;
3
10
use super :: LoweringContext ;
4
11
5
12
use rustc_ast:: ptr:: P ;
6
13
use rustc_ast:: * ;
7
14
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
8
- use rustc_errors:: struct_span_err;
9
15
use rustc_hir as hir;
10
16
use rustc_hir:: def:: { DefKind , Res } ;
11
17
use rustc_hir:: definitions:: DefPathData ;
@@ -26,13 +32,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
26
32
let asm_arch =
27
33
if self . tcx . sess . opts . actually_rustdoc { None } else { self . tcx . sess . asm_arch } ;
28
34
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 } ) ;
36
36
}
37
37
if let Some ( asm_arch) = asm_arch {
38
38
// Inline assembly is currently only stable for these architectures.
@@ -59,10 +59,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
59
59
&& !matches ! ( asm_arch, Some ( asm:: InlineAsmArch :: X86 | asm:: InlineAsmArch :: X86_64 ) )
60
60
&& !self . tcx . sess . opts . actually_rustdoc
61
61
{
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 } ) ;
66
63
}
67
64
if asm. options . contains ( InlineAsmOptions :: MAY_UNWIND ) && !self . tcx . features ( ) . asm_unwind {
68
65
feature_err (
@@ -82,51 +79,37 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
82
79
// If the abi was already in the list, emit an error
83
80
match clobber_abis. get ( & abi) {
84
81
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
-
91
82
// Multiple different abi names may actually be the same ABI
92
83
// If the specified ABIs are not the same name, alert the user that they resolve to the same ABI
93
84
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 ( ( ) ) ;
99
88
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
+ } ) ;
101
95
}
102
96
None => {
103
- clobber_abis. insert ( abi, ( abi_name, * abi_span) ) ;
97
+ clobber_abis. insert ( abi, ( * abi_name, * abi_span) ) ;
104
98
}
105
99
}
106
100
}
107
101
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 } ) ;
115
103
}
116
104
Err ( supported_abis) => {
117
- let mut err = self
118
- . tcx
119
- . sess
120
- . struct_span_err ( * abi_span, "invalid ABI for `clobber_abi`" ) ;
121
105
let mut abis = format ! ( "`{}`" , supported_abis[ 0 ] ) ;
122
106
for m in & supported_abis[ 1 ..] {
123
107
let _ = write ! ( abis, ", `{}`" , m) ;
124
108
}
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
+ } ) ;
130
113
}
131
114
}
132
115
}
@@ -141,24 +124,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
141
124
. iter ( )
142
125
. map ( |( op, op_sp) | {
143
126
let lower_reg = |reg| match reg {
144
- InlineAsmRegOrRegClass :: Reg ( s ) => {
127
+ InlineAsmRegOrRegClass :: Reg ( reg ) => {
145
128
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 } ) ;
149
131
asm:: InlineAsmReg :: Err
150
132
} )
151
133
} else {
152
134
asm:: InlineAsmReg :: Err
153
135
} )
154
136
}
155
- InlineAsmRegOrRegClass :: RegClass ( s ) => {
137
+ InlineAsmRegOrRegClass :: RegClass ( reg_class ) => {
156
138
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
+ )
162
149
} else {
163
150
asm:: InlineAsmRegClass :: Err
164
151
} )
@@ -282,50 +269,39 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
282
269
}
283
270
let valid_modifiers = class. valid_modifiers ( asm_arch. unwrap ( ) ) ;
284
271
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 ( ) {
292
273
let mut mods = format ! ( "`{}`" , valid_modifiers[ 0 ] ) ;
293
274
for m in & valid_modifiers[ 1 ..] {
294
275
let _ = write ! ( mods, ", `{}`" , m) ;
295
276
}
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
+ }
302
281
} 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
+ } ) ;
309
291
}
310
292
}
311
293
hir:: InlineAsmOperand :: Const { .. } => {
312
- let mut err = sess. struct_span_err (
294
+ sess. emit_err ( InvalidAsmTemplateModifierConst {
313
295
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
+ } ) ;
319
298
}
320
299
hir:: InlineAsmOperand :: SymFn { .. }
321
300
| hir:: InlineAsmOperand :: SymStatic { .. } => {
322
- let mut err = sess. struct_span_err (
301
+ sess. emit_err ( InvalidAsmTemplateModifierSym {
323
302
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
+ } ) ;
329
305
}
330
306
}
331
307
}
@@ -346,12 +322,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
346
322
// require that the operand name an explicit register, not a
347
323
// register class.
348
324
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
+ } ) ;
355
329
continue ;
356
330
}
357
331
@@ -391,16 +365,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
391
365
unreachable ! ( ) ;
392
366
} ;
393
367
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) {
404
369
(
405
370
hir:: InlineAsmOperand :: In { .. } ,
406
371
hir:: InlineAsmOperand :: Out { late, .. } ,
@@ -411,14 +376,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
411
376
) => {
412
377
assert ! ( !* late) ;
413
378
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
+ } ;
420
383
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
+ } ) ;
422
391
}
423
392
Entry :: Vacant ( v) => {
424
393
if r == reg {
0 commit comments