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.
This commit is contained in:
parent
db137ba7d4
commit
52f7a218fb
9 changed files with 155 additions and 294 deletions
|
@ -203,17 +203,6 @@ pub fn parse_asm_args<'a>(
|
|||
// Validate the order of named, positional & explicit register operands and
|
||||
// clobber_abi/options. We do this at the end once we have the full span
|
||||
// of the argument available.
|
||||
if !args.options_spans.is_empty() {
|
||||
diag.struct_span_err(span, "arguments are not allowed after options")
|
||||
.span_labels(args.options_spans.clone(), "previous options")
|
||||
.span_label(span, "argument")
|
||||
.emit();
|
||||
} else if let Some((_, abi_span)) = args.clobber_abis.last() {
|
||||
diag.struct_span_err(span, "arguments are not allowed after clobber_abi")
|
||||
.span_label(*abi_span, "clobber_abi")
|
||||
.span_label(span, "argument")
|
||||
.emit();
|
||||
}
|
||||
if explicit_reg {
|
||||
if name.is_some() {
|
||||
diag.struct_span_err(span, "explicit register arguments cannot have names").emit();
|
||||
|
@ -227,17 +216,6 @@ pub fn parse_asm_args<'a>(
|
|||
.emit();
|
||||
continue;
|
||||
}
|
||||
if !args.reg_args.is_empty() {
|
||||
let mut err = diag.struct_span_err(
|
||||
span,
|
||||
"named arguments cannot follow explicit register arguments",
|
||||
);
|
||||
err.span_label(span, "named argument");
|
||||
for pos in &args.reg_args {
|
||||
err.span_label(args.operands[*pos].1, "explicit register argument");
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
args.named_args.insert(name, slot);
|
||||
} else {
|
||||
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,
|
|||
|
||||
let full_span = span_start.to(p.prev_token.span);
|
||||
|
||||
if !args.options_spans.is_empty() {
|
||||
let mut err = p
|
||||
.sess
|
||||
.span_diagnostic
|
||||
.struct_span_err(full_span, "clobber_abi is not allowed after options");
|
||||
err.span_labels(args.options_spans.clone(), "options");
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
match &new_abis[..] {
|
||||
// should have errored above during parsing
|
||||
[] => unreachable!(),
|
||||
|
@ -699,6 +668,10 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
|
|||
args.operands[idx].1,
|
||||
"explicit register arguments cannot be used in the asm template",
|
||||
);
|
||||
err.span_help(
|
||||
args.operands[idx].1,
|
||||
"use the register name directly in the assembly code",
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
None
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue