Skip to content

Commit cb0fb24

Browse files
authoredMar 10, 2023
Rollup merge of #105798 - Amanieu:relax-asm, r=joshtriplett
Relax ordering rules for `asm!` operands The `asm!` and `global_asm!` macros require their operands to appear strictly in the following order: - Template strings - Positional operands - Named operands - Explicit register operands - `clobber_abi` - `options` This is overly strict and can be inconvienent when building complex `asm!` statements with macros. This PR relaxes the ordering requirements as follows: - Template strings must still come before all other operands. - Positional operands must still come before named and explicit register operands. - Named and explicit register operands can be freely mixed. - `options` and `clobber_abi` can appear in any position after the template strings. r? ```````@joshtriplett```````
2 parents 35a0961 + 52f7a21 commit cb0fb24

9 files changed

+152
-291
lines changed
 

‎compiler/rustc_builtin_macros/src/asm.rs

+4-31
Original file line numberDiff line numberDiff line change
@@ -203,17 +203,6 @@ pub fn parse_asm_args<'a>(
203203
// Validate the order of named, positional & explicit register operands and
204204
// clobber_abi/options. We do this at the end once we have the full span
205205
// of the argument available.
206-
if !args.options_spans.is_empty() {
207-
diag.struct_span_err(span, "arguments are not allowed after options")
208-
.span_labels(args.options_spans.clone(), "previous options")
209-
.span_label(span, "argument")
210-
.emit();
211-
} else if let Some((_, abi_span)) = args.clobber_abis.last() {
212-
diag.struct_span_err(span, "arguments are not allowed after clobber_abi")
213-
.span_label(*abi_span, "clobber_abi")
214-
.span_label(span, "argument")
215-
.emit();
216-
}
217206
if explicit_reg {
218207
if name.is_some() {
219208
diag.struct_span_err(span, "explicit register arguments cannot have names").emit();
@@ -227,17 +216,6 @@ pub fn parse_asm_args<'a>(
227216
.emit();
228217
continue;
229218
}
230-
if !args.reg_args.is_empty() {
231-
let mut err = diag.struct_span_err(
232-
span,
233-
"named arguments cannot follow explicit register arguments",
234-
);
235-
err.span_label(span, "named argument");
236-
for pos in &args.reg_args {
237-
err.span_label(args.operands[*pos].1, "explicit register argument");
238-
}
239-
err.emit();
240-
}
241219
args.named_args.insert(name, slot);
242220
} else {
243221
if !args.named_args.is_empty() || !args.reg_args.is_empty() {
@@ -478,15 +456,6 @@ fn parse_clobber_abi<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> PResult<'a,
478456

479457
let full_span = span_start.to(p.prev_token.span);
480458

481-
if !args.options_spans.is_empty() {
482-
let mut err = p
483-
.sess
484-
.span_diagnostic
485-
.struct_span_err(full_span, "clobber_abi is not allowed after options");
486-
err.span_labels(args.options_spans.clone(), "options");
487-
return Err(err);
488-
}
489-
490459
match &new_abis[..] {
491460
// should have errored above during parsing
492461
[] => unreachable!(),
@@ -699,6 +668,10 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
699668
args.operands[idx].1,
700669
"explicit register arguments cannot be used in the asm template",
701670
);
671+
err.span_help(
672+
args.operands[idx].1,
673+
"use the register name directly in the assembly code",
674+
);
702675
}
703676
err.emit();
704677
None

‎tests/ui/asm/aarch64/parse-error.rs

+8-15
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,18 @@ fn main() {
3737
asm!("", options(nomem, foo));
3838
//~^ ERROR expected one of
3939
asm!("{}", options(), const foo);
40-
//~^ ERROR arguments are not allowed after options
41-
//~^^ ERROR attempt to use a non-constant value in a constant
40+
//~^ ERROR attempt to use a non-constant value in a constant
4241
asm!("", clobber_abi(foo));
4342
//~^ ERROR expected string literal
4443
asm!("", clobber_abi("C" foo));
4544
//~^ ERROR expected one of `)` or `,`, found `foo`
4645
asm!("", clobber_abi("C", foo));
4746
//~^ ERROR expected string literal
4847
asm!("{}", clobber_abi("C"), const foo);
49-
//~^ ERROR arguments are not allowed after clobber_abi
50-
//~^^ ERROR attempt to use a non-constant value in a constant
48+
//~^ ERROR attempt to use a non-constant value in a constant
5149
asm!("", options(), clobber_abi("C"));
52-
//~^ ERROR clobber_abi is not allowed after options
5350
asm!("{}", options(), clobber_abi("C"), const foo);
54-
//~^ ERROR clobber_abi is not allowed after options
51+
//~^ ERROR attempt to use a non-constant value in a constant
5552
asm!("{a}", a = const foo, a = const bar);
5653
//~^ ERROR duplicate argument named `a`
5754
//~^^ ERROR argument never used
@@ -60,11 +57,9 @@ fn main() {
6057
asm!("", a = in("x0") foo);
6158
//~^ ERROR explicit register arguments cannot have names
6259
asm!("{a}", in("x0") foo, a = const bar);
63-
//~^ ERROR named arguments cannot follow explicit register arguments
64-
//~^^ ERROR attempt to use a non-constant value in a constant
60+
//~^ ERROR attempt to use a non-constant value in a constant
6561
asm!("{a}", in("x0") foo, a = const bar);
66-
//~^ ERROR named arguments cannot follow explicit register arguments
67-
//~^^ ERROR attempt to use a non-constant value in a constant
62+
//~^ ERROR attempt to use a non-constant value in a constant
6863
asm!("{1}", in("x0") foo, const bar);
6964
//~^ ERROR positional arguments cannot follow named arguments or explicit register arguments
7065
//~^^ ERROR attempt to use a non-constant value in a constant
@@ -106,20 +101,18 @@ global_asm!("", options(nomem FOO));
106101
global_asm!("", options(nomem, FOO));
107102
//~^ ERROR expected one of
108103
global_asm!("{}", options(), const FOO);
109-
//~^ ERROR arguments are not allowed after options
110104
global_asm!("", clobber_abi(FOO));
111105
//~^ ERROR expected string literal
112106
global_asm!("", clobber_abi("C" FOO));
113107
//~^ ERROR expected one of `)` or `,`, found `FOO`
114108
global_asm!("", clobber_abi("C", FOO));
115109
//~^ ERROR expected string literal
116110
global_asm!("{}", clobber_abi("C"), const FOO);
117-
//~^ ERROR arguments are not allowed after clobber_abi
118-
//~^^ ERROR `clobber_abi` cannot be used with `global_asm!`
111+
//~^ ERROR `clobber_abi` cannot be used with `global_asm!`
119112
global_asm!("", options(), clobber_abi("C"));
120-
//~^ ERROR clobber_abi is not allowed after options
113+
//~^ ERROR `clobber_abi` cannot be used with `global_asm!`
121114
global_asm!("{}", options(), clobber_abi("C"), const FOO);
122-
//~^ ERROR clobber_abi is not allowed after options
115+
//~^ ERROR `clobber_abi` cannot be used with `global_asm!`
123116
global_asm!("{a}", a = const FOO, a = const BAR);
124117
//~^ ERROR duplicate argument named `a`
125118
//~^^ ERROR argument never used

‎tests/ui/asm/aarch64/parse-error.stderr

+55-114
Large diffs are not rendered by default.

‎tests/ui/asm/bad-template.aarch64_mirunsafeck.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ note: explicit register arguments cannot be used in the asm template
8181
|
8282
LL | asm!("{}", in("x0") foo);
8383
| ^^^^^^^^^^^^
84+
help: use the register name directly in the assembly code
85+
--> $DIR/bad-template.rs:48:20
86+
|
87+
LL | asm!("{}", in("x0") foo);
88+
| ^^^^^^^^^^^^
8489

8590
error: asm template modifier must be a single character
8691
--> $DIR/bad-template.rs:50:17

‎tests/ui/asm/bad-template.aarch64_thirunsafeck.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ note: explicit register arguments cannot be used in the asm template
8181
|
8282
LL | asm!("{}", in("x0") foo);
8383
| ^^^^^^^^^^^^
84+
help: use the register name directly in the assembly code
85+
--> $DIR/bad-template.rs:48:20
86+
|
87+
LL | asm!("{}", in("x0") foo);
88+
| ^^^^^^^^^^^^
8489

8590
error: asm template modifier must be a single character
8691
--> $DIR/bad-template.rs:50:17

‎tests/ui/asm/bad-template.x86_64_mirunsafeck.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ note: explicit register arguments cannot be used in the asm template
8181
|
8282
LL | asm!("{}", in("eax") foo);
8383
| ^^^^^^^^^^^^^
84+
help: use the register name directly in the assembly code
85+
--> $DIR/bad-template.rs:45:20
86+
|
87+
LL | asm!("{}", in("eax") foo);
88+
| ^^^^^^^^^^^^^
8489

8590
error: asm template modifier must be a single character
8691
--> $DIR/bad-template.rs:50:17

‎tests/ui/asm/bad-template.x86_64_thirunsafeck.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ note: explicit register arguments cannot be used in the asm template
8181
|
8282
LL | asm!("{}", in("eax") foo);
8383
| ^^^^^^^^^^^^^
84+
help: use the register name directly in the assembly code
85+
--> $DIR/bad-template.rs:45:20
86+
|
87+
LL | asm!("{}", in("eax") foo);
88+
| ^^^^^^^^^^^^^
8489

8590
error: asm template modifier must be a single character
8691
--> $DIR/bad-template.rs:50:17

‎tests/ui/asm/x86_64/parse-error.rs

+8-15
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ fn main() {
3737
asm!("", options(nomem, foo));
3838
//~^ ERROR expected one of
3939
asm!("{}", options(), const foo);
40-
//~^ ERROR arguments are not allowed after options
41-
//~^^ ERROR attempt to use a non-constant value in a constant
40+
//~^ ERROR attempt to use a non-constant value in a constant
4241
asm!("", clobber_abi());
4342
//~^ ERROR at least one abi must be provided
4443
asm!("", clobber_abi(foo));
@@ -48,12 +47,10 @@ fn main() {
4847
asm!("", clobber_abi("C", foo));
4948
//~^ ERROR expected string literal
5049
asm!("{}", clobber_abi("C"), const foo);
51-
//~^ ERROR arguments are not allowed after clobber_abi
52-
//~^^ ERROR attempt to use a non-constant value in a constant
50+
//~^ ERROR attempt to use a non-constant value in a constant
5351
asm!("", options(), clobber_abi("C"));
54-
//~^ ERROR clobber_abi is not allowed after options
5552
asm!("{}", options(), clobber_abi("C"), const foo);
56-
//~^ ERROR clobber_abi is not allowed after options
53+
//~^ ERROR attempt to use a non-constant value in a constant
5754
asm!("{a}", a = const foo, a = const bar);
5855
//~^ ERROR duplicate argument named `a`
5956
//~^^ ERROR argument never used
@@ -62,11 +59,9 @@ fn main() {
6259
asm!("", a = in("eax") foo);
6360
//~^ ERROR explicit register arguments cannot have names
6461
asm!("{a}", in("eax") foo, a = const bar);
65-
//~^ ERROR named arguments cannot follow explicit register arguments
66-
//~^^ ERROR attempt to use a non-constant value in a constant
62+
//~^ ERROR attempt to use a non-constant value in a constant
6763
asm!("{a}", in("eax") foo, a = const bar);
68-
//~^ ERROR named arguments cannot follow explicit register arguments
69-
//~^^ ERROR attempt to use a non-constant value in a constant
64+
//~^ ERROR attempt to use a non-constant value in a constant
7065
asm!("{1}", in("eax") foo, const bar);
7166
//~^ ERROR positional arguments cannot follow named arguments or explicit register arguments
7267
//~^^ ERROR attempt to use a non-constant value in a constant
@@ -108,20 +103,18 @@ global_asm!("", options(nomem FOO));
108103
global_asm!("", options(nomem, FOO));
109104
//~^ ERROR expected one of
110105
global_asm!("{}", options(), const FOO);
111-
//~^ ERROR arguments are not allowed after options
112106
global_asm!("", clobber_abi(FOO));
113107
//~^ ERROR expected string literal
114108
global_asm!("", clobber_abi("C" FOO));
115109
//~^ ERROR expected one of `)` or `,`, found `FOO`
116110
global_asm!("", clobber_abi("C", FOO));
117111
//~^ ERROR expected string literal
118112
global_asm!("{}", clobber_abi("C"), const FOO);
119-
//~^ ERROR arguments are not allowed after clobber_abi
120-
//~^^ ERROR `clobber_abi` cannot be used with `global_asm!`
113+
//~^ ERROR `clobber_abi` cannot be used with `global_asm!`
121114
global_asm!("", options(), clobber_abi("C"));
122-
//~^ ERROR clobber_abi is not allowed after options
115+
//~^ ERROR `clobber_abi` cannot be used with `global_asm!`
123116
global_asm!("{}", options(), clobber_abi("C"), const FOO);
124-
//~^ ERROR clobber_abi is not allowed after options
117+
//~^ ERROR `clobber_abi` cannot be used with `global_asm!`
125118
global_asm!("", clobber_abi("C"), clobber_abi("C"));
126119
//~^ ERROR `clobber_abi` cannot be used with `global_asm!`
127120
global_asm!("{a}", a = const FOO, a = const BAR);

‎tests/ui/asm/x86_64/parse-error.stderr

+57-116
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.