Skip to content

Commit 4d548f0

Browse files
authored
Rollup merge of rust-lang#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 104f430 + 52f7a21 commit 4d548f0

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

0 commit comments

Comments
 (0)