Skip to content

Commit ee4bcfe

Browse files
Rollup merge of #154228 - folkertdev:mention-invalid-template-modifier, r=nnethercote
Improve inline assembly error messages by - using `DiagSymbolList` to get nicely formatted lists - mentioning the `modifier` when an invalid modifier is used. This is useful in case the span cannot be resolved (which I ran into).
2 parents 2d1fd85 + 6f08437 commit ee4bcfe

11 files changed

Lines changed: 74 additions & 79 deletions

File tree

compiler/rustc_ast_lowering/src/asm.rs

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::collections::hash_map::Entry;
2-
use std::fmt::Write;
32

43
use rustc_ast::*;
54
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
@@ -124,13 +123,9 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
124123
self.dcx().emit_err(ClobberAbiNotSupported { abi_span: *abi_span });
125124
}
126125
Err(supported_abis) => {
127-
let mut abis = format!("`{}`", supported_abis[0]);
128-
for m in &supported_abis[1..] {
129-
let _ = write!(abis, ", `{m}`");
130-
}
131126
self.dcx().emit_err(InvalidAbiClobberAbi {
132127
abi_span: *abi_span,
133-
supported_abis: abis,
128+
supported_abis: supported_abis.to_vec().into(),
134129
});
135130
}
136131
}
@@ -164,15 +159,12 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
164159
asm::InlineAsmRegOrRegClass::RegClass(if let Some(asm_arch) = asm_arch {
165160
asm::InlineAsmRegClass::parse(asm_arch, reg_class).unwrap_or_else(
166161
|supported_register_classes| {
167-
let mut register_classes =
168-
format!("`{}`", supported_register_classes[0]);
169-
for m in &supported_register_classes[1..] {
170-
let _ = write!(register_classes, ", `{m}`");
171-
}
172162
self.dcx().emit_err(InvalidRegisterClass {
173163
op_span: *op_sp,
174164
reg_class,
175-
supported_register_classes: register_classes,
165+
supported_register_classes: supported_register_classes
166+
.to_vec()
167+
.into(),
176168
});
177169
asm::InlineAsmRegClass::Err
178170
},
@@ -272,23 +264,20 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
272264
}
273265
let valid_modifiers = class.valid_modifiers(asm_arch.unwrap());
274266
if !valid_modifiers.contains(&modifier) {
275-
let sub = if !valid_modifiers.is_empty() {
276-
let mut mods = format!("`{}`", valid_modifiers[0]);
277-
for m in &valid_modifiers[1..] {
278-
let _ = write!(mods, ", `{m}`");
279-
}
280-
InvalidAsmTemplateModifierRegClassSub::SupportModifier {
267+
let sub = if valid_modifiers.is_empty() {
268+
InvalidAsmTemplateModifierRegClassSub::DoesNotSupportModifier {
281269
class_name: class.name(),
282-
modifiers: mods,
283270
}
284271
} else {
285-
InvalidAsmTemplateModifierRegClassSub::DoesNotSupportModifier {
272+
InvalidAsmTemplateModifierRegClassSub::SupportModifier {
286273
class_name: class.name(),
274+
modifiers: valid_modifiers.to_vec().into(),
287275
}
288276
};
289277
self.dcx().emit_err(InvalidAsmTemplateModifierRegClass {
290278
placeholder_span,
291279
op_span: op_sp,
280+
modifier: modifier.to_string(),
292281
sub,
293282
});
294283
}

compiler/rustc_ast_lowering/src/errors.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use rustc_errors::DiagArgFromDisplay;
21
use rustc_errors::codes::*;
2+
use rustc_errors::{DiagArgFromDisplay, DiagSymbolList};
33
use rustc_macros::{Diagnostic, Subdiagnostic};
44
use rustc_span::{Ident, Span, Symbol};
55

@@ -191,10 +191,10 @@ pub(crate) struct ClobberAbiNotSupported {
191191
#[derive(Diagnostic)]
192192
#[note("the following ABIs are supported on this target: {$supported_abis}")]
193193
#[diag("invalid ABI for `clobber_abi`")]
194-
pub(crate) struct InvalidAbiClobberAbi {
194+
pub(crate) struct InvalidAbiClobberAbi<'a> {
195195
#[primary_span]
196196
pub abi_span: Span,
197-
pub supported_abis: String,
197+
pub supported_abis: DiagSymbolList<&'a str>,
198198
}
199199

200200
#[derive(Diagnostic)]
@@ -215,17 +215,18 @@ pub(crate) struct InvalidRegisterClass {
215215
#[primary_span]
216216
pub op_span: Span,
217217
pub reg_class: Symbol,
218-
pub supported_register_classes: String,
218+
pub supported_register_classes: DiagSymbolList<Symbol>,
219219
}
220220

221221
#[derive(Diagnostic)]
222-
#[diag("invalid asm template modifier for this register class")]
222+
#[diag("invalid asm template modifier `{$modifier}` for this register class")]
223223
pub(crate) struct InvalidAsmTemplateModifierRegClass {
224224
#[primary_span]
225225
#[label("template modifier")]
226226
pub placeholder_span: Span,
227227
#[label("argument")]
228228
pub op_span: Span,
229+
pub modifier: String,
229230
#[subdiagnostic]
230231
pub sub: InvalidAsmTemplateModifierRegClassSub,
231232
}
@@ -235,7 +236,7 @@ pub(crate) enum InvalidAsmTemplateModifierRegClassSub {
235236
#[note(
236237
"the `{$class_name}` register class supports the following template modifiers: {$modifiers}"
237238
)]
238-
SupportModifier { class_name: Symbol, modifiers: String },
239+
SupportModifier { class_name: Symbol, modifiers: DiagSymbolList<char> },
239240
#[note("the `{$class_name}` register class does not support template modifiers")]
240241
DoesNotSupportModifier { class_name: Symbol },
241242
}

tests/ui/asm/aarch64/bad-options.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ error: invalid ABI for `clobber_abi`
7878
LL | asm!("", clobber_abi("foo"));
7979
| ^^^^^^^^^^^^^^^^^^
8080
|
81-
= note: the following ABIs are supported on this target: `C`, `system`, `efiapi`
81+
= note: the following ABIs are supported on this target: `C`, `system`, and `efiapi`
8282

8383
error: aborting due to 13 previous errors
8484

tests/ui/asm/aarch64/bad-reg.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
//@ add-minicore
12
//@ only-aarch64
23
//@ compile-flags: -C target-feature=+neon
4+
#![crate_type = "lib"]
5+
#![feature(no_core)]
6+
#![no_core]
37

4-
use std::arch::asm;
8+
extern crate minicore;
9+
use minicore::*;
510

611
fn main() {
712
let mut foo = 0;
@@ -14,11 +19,11 @@ fn main() {
1419
asm!("", in("foo") foo);
1520
//~^ ERROR invalid register `foo`: unknown register
1621
asm!("{:z}", in(reg) foo);
17-
//~^ ERROR invalid asm template modifier for this register class
22+
//~^ ERROR invalid asm template modifier `z` for this register class
1823
asm!("{:r}", in(vreg) foo);
19-
//~^ ERROR invalid asm template modifier for this register class
24+
//~^ ERROR invalid asm template modifier `r` for this register class
2025
asm!("{:r}", in(vreg_low16) foo);
21-
//~^ ERROR invalid asm template modifier for this register class
26+
//~^ ERROR invalid asm template modifier `r` for this register class
2227
asm!("{:a}", const 0);
2328
//~^ ERROR asm template modifiers are not allowed for `const` arguments
2429
asm!("{:a}", sym main);

tests/ui/asm/aarch64/bad-reg.stderr

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,159 +1,159 @@
11
error: invalid register class `foo`: unknown register class
2-
--> $DIR/bad-reg.rs:12:20
2+
--> $DIR/bad-reg.rs:17:20
33
|
44
LL | asm!("{}", in(foo) foo);
55
| ^^^^^^^^^^^
66
|
7-
= note: the following register classes are supported on this target: `reg`, `vreg`, `vreg_low16`, `preg`
7+
= note: the following register classes are supported on this target: `reg`, `vreg`, `vreg_low16`, and `preg`
88

99
error: invalid register `foo`: unknown register
10-
--> $DIR/bad-reg.rs:14:18
10+
--> $DIR/bad-reg.rs:19:18
1111
|
1212
LL | asm!("", in("foo") foo);
1313
| ^^^^^^^^^^^^^
1414

15-
error: invalid asm template modifier for this register class
16-
--> $DIR/bad-reg.rs:16:15
15+
error: invalid asm template modifier `z` for this register class
16+
--> $DIR/bad-reg.rs:21:15
1717
|
1818
LL | asm!("{:z}", in(reg) foo);
1919
| ^^^^ ----------- argument
2020
| |
2121
| template modifier
2222
|
23-
= note: the `reg` register class supports the following template modifiers: `w`, `x`
23+
= note: the `reg` register class supports the following template modifiers: `w` and `x`
2424

25-
error: invalid asm template modifier for this register class
26-
--> $DIR/bad-reg.rs:18:15
25+
error: invalid asm template modifier `r` for this register class
26+
--> $DIR/bad-reg.rs:23:15
2727
|
2828
LL | asm!("{:r}", in(vreg) foo);
2929
| ^^^^ ------------ argument
3030
| |
3131
| template modifier
3232
|
33-
= note: the `vreg` register class supports the following template modifiers: `b`, `h`, `s`, `d`, `q`, `v`
33+
= note: the `vreg` register class supports the following template modifiers: `b`, `h`, `s`, `d`, `q`, and `v`
3434

35-
error: invalid asm template modifier for this register class
36-
--> $DIR/bad-reg.rs:20:15
35+
error: invalid asm template modifier `r` for this register class
36+
--> $DIR/bad-reg.rs:25:15
3737
|
3838
LL | asm!("{:r}", in(vreg_low16) foo);
3939
| ^^^^ ------------------ argument
4040
| |
4141
| template modifier
4242
|
43-
= note: the `vreg_low16` register class supports the following template modifiers: `b`, `h`, `s`, `d`, `q`, `v`
43+
= note: the `vreg_low16` register class supports the following template modifiers: `b`, `h`, `s`, `d`, `q`, and `v`
4444

4545
error: asm template modifiers are not allowed for `const` arguments
46-
--> $DIR/bad-reg.rs:22:15
46+
--> $DIR/bad-reg.rs:27:15
4747
|
4848
LL | asm!("{:a}", const 0);
4949
| ^^^^ ------- argument
5050
| |
5151
| template modifier
5252

5353
error: asm template modifiers are not allowed for `sym` arguments
54-
--> $DIR/bad-reg.rs:24:15
54+
--> $DIR/bad-reg.rs:29:15
5555
|
5656
LL | asm!("{:a}", sym main);
5757
| ^^^^ -------- argument
5858
| |
5959
| template modifier
6060

6161
error: invalid register `x29`: the frame pointer cannot be used as an operand for inline asm
62-
--> $DIR/bad-reg.rs:26:18
62+
--> $DIR/bad-reg.rs:31:18
6363
|
6464
LL | asm!("", in("x29") foo);
6565
| ^^^^^^^^^^^^^
6666

6767
error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm
68-
--> $DIR/bad-reg.rs:28:18
68+
--> $DIR/bad-reg.rs:33:18
6969
|
7070
LL | asm!("", in("sp") foo);
7171
| ^^^^^^^^^^^^
7272

7373
error: invalid register `xzr`: the zero register cannot be used as an operand for inline asm
74-
--> $DIR/bad-reg.rs:30:18
74+
--> $DIR/bad-reg.rs:35:18
7575
|
7676
LL | asm!("", in("xzr") foo);
7777
| ^^^^^^^^^^^^^
7878

7979
error: invalid register `x19`: x19 is used internally by LLVM and cannot be used as an operand for inline asm
80-
--> $DIR/bad-reg.rs:32:18
80+
--> $DIR/bad-reg.rs:37:18
8181
|
8282
LL | asm!("", in("x19") foo);
8383
| ^^^^^^^^^^^^^
8484

8585
error: register class `preg` can only be used as a clobber, not as an input or output
86-
--> $DIR/bad-reg.rs:35:18
86+
--> $DIR/bad-reg.rs:40:18
8787
|
8888
LL | asm!("", in("p0") foo);
8989
| ^^^^^^^^^^^^
9090

9191
error: register class `preg` can only be used as a clobber, not as an input or output
92-
--> $DIR/bad-reg.rs:39:20
92+
--> $DIR/bad-reg.rs:44:20
9393
|
9494
LL | asm!("{}", in(preg) foo);
9595
| ^^^^^^^^^^^^
9696

9797
error: register class `preg` can only be used as a clobber, not as an input or output
98-
--> $DIR/bad-reg.rs:42:20
98+
--> $DIR/bad-reg.rs:47:20
9999
|
100100
LL | asm!("{}", out(preg) _);
101101
| ^^^^^^^^^^^
102102

103103
error: register `w0` conflicts with register `x0`
104-
--> $DIR/bad-reg.rs:48:32
104+
--> $DIR/bad-reg.rs:53:32
105105
|
106106
LL | asm!("", in("x0") foo, in("w0") bar);
107107
| ------------ ^^^^^^^^^^^^ register `w0`
108108
| |
109109
| register `x0`
110110

111111
error: register `x0` conflicts with register `x0`
112-
--> $DIR/bad-reg.rs:50:32
112+
--> $DIR/bad-reg.rs:55:32
113113
|
114114
LL | asm!("", in("x0") foo, out("x0") bar);
115115
| ------------ ^^^^^^^^^^^^^ register `x0`
116116
| |
117117
| register `x0`
118118
|
119119
help: use `lateout` instead of `out` to avoid conflict
120-
--> $DIR/bad-reg.rs:50:18
120+
--> $DIR/bad-reg.rs:55:18
121121
|
122122
LL | asm!("", in("x0") foo, out("x0") bar);
123123
| ^^^^^^^^^^^^
124124

125125
error: register `q0` conflicts with register `v0`
126-
--> $DIR/bad-reg.rs:53:32
126+
--> $DIR/bad-reg.rs:58:32
127127
|
128128
LL | asm!("", in("v0") foo, in("q0") bar);
129129
| ------------ ^^^^^^^^^^^^ register `q0`
130130
| |
131131
| register `v0`
132132

133133
error: register `q0` conflicts with register `v0`
134-
--> $DIR/bad-reg.rs:55:32
134+
--> $DIR/bad-reg.rs:60:32
135135
|
136136
LL | asm!("", in("v0") foo, out("q0") bar);
137137
| ------------ ^^^^^^^^^^^^^ register `q0`
138138
| |
139139
| register `v0`
140140
|
141141
help: use `lateout` instead of `out` to avoid conflict
142-
--> $DIR/bad-reg.rs:55:18
142+
--> $DIR/bad-reg.rs:60:18
143143
|
144144
LL | asm!("", in("v0") foo, out("q0") bar);
145145
| ^^^^^^^^^^^^
146146

147147
error: type `i32` cannot be used with this register class
148-
--> $DIR/bad-reg.rs:35:27
148+
--> $DIR/bad-reg.rs:40:27
149149
|
150150
LL | asm!("", in("p0") foo);
151151
| ^^^
152152
|
153153
= note: register class `preg` supports these types:
154154

155155
error: type `i32` cannot be used with this register class
156-
--> $DIR/bad-reg.rs:39:29
156+
--> $DIR/bad-reg.rs:44:29
157157
|
158158
LL | asm!("{}", in(preg) foo);
159159
| ^^^

tests/ui/asm/x86_64/bad-clobber-abi.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ error: invalid ABI for `clobber_abi`
44
LL | asm!("", clobber_abi("foo"));
55
| ^^^^^^^^^^^^^^^^^^
66
|
7-
= note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64`
7+
= note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, and `sysv64`
88

99
error: invalid ABI for `clobber_abi`
1010
--> $DIR/bad-clobber-abi.rs:13:35
1111
|
1212
LL | asm!("", clobber_abi("C", "foo"));
1313
| ^^^^^
1414
|
15-
= note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64`
15+
= note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, and `sysv64`
1616

1717
error: `C` ABI specified multiple times
1818
--> $DIR/bad-clobber-abi.rs:15:35
@@ -38,7 +38,7 @@ error: invalid ABI for `clobber_abi`
3838
LL | asm!("", clobber_abi("C", "foo", "C"));
3939
| ^^^^^
4040
|
41-
= note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64`
41+
= note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, and `sysv64`
4242

4343
error: `C` ABI specified multiple times
4444
--> $DIR/bad-clobber-abi.rs:20:42
@@ -54,7 +54,7 @@ error: invalid ABI for `clobber_abi`
5454
LL | asm!("", clobber_abi("win64", "foo", "efiapi"));
5555
| ^^^^^
5656
|
57-
= note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64`
57+
= note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, and `sysv64`
5858

5959
error: `win64` ABI specified multiple times
6060
--> $DIR/bad-clobber-abi.rs:23:46

tests/ui/asm/x86_64/bad-options.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ error: invalid ABI for `clobber_abi`
9393
LL | asm!("", clobber_abi("foo"));
9494
| ^^^^^^^^^^^^^^^^^^
9595
|
96-
= note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64`
96+
= note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, and `sysv64`
9797

9898
error: `C` ABI specified multiple times
9999
--> $DIR/bad-options.rs:28:52

0 commit comments

Comments
 (0)