named_args: FxHashMap<Symbol, usize>,
reg_args: FxHashSet<usize>,
options: ast::InlineAsmOptions,
- options_span: Option<Span>,
+ options_spans: Option<Vec<Span>>,
}
fn parse_args<'a>(
named_args: FxHashMap::default(),
reg_args: FxHashSet::default(),
options: ast::InlineAsmOptions::empty(),
- options_span: None,
+ options_spans: None,
};
let mut allow_templates = true;
// Validate the order of named, positional & explicit register operands and options. We do
// this at the end once we have the full span of the argument available.
- if let Some(options_span) = args.options_span {
+ if let Some(ref options_spans) = args.options_spans {
ecx.struct_span_err(span, "arguments are not allowed after options")
- .span_label(options_span, "previous options")
+ .span_labels(options_spans.clone(), "previous options")
.span_label(span, "argument")
.emit();
}
if args.options.contains(ast::InlineAsmOptions::NOMEM)
&& args.options.contains(ast::InlineAsmOptions::READONLY)
{
- let span = args.options_span.unwrap();
- ecx.struct_span_err(span, "the `nomem` and `readonly` options are mutually exclusive")
+ let spans = args.options_spans.clone().unwrap();
+ ecx.struct_span_err(spans, "the `nomem` and `readonly` options are mutually exclusive")
.emit();
}
if args.options.contains(ast::InlineAsmOptions::PURE)
&& args.options.contains(ast::InlineAsmOptions::NORETURN)
{
- let span = args.options_span.unwrap();
- ecx.struct_span_err(span, "the `pure` and `noreturn` options are mutually exclusive")
+ let spans = args.options_spans.clone().unwrap();
+ ecx.struct_span_err(spans, "the `pure` and `noreturn` options are mutually exclusive")
.emit();
}
if args.options.contains(ast::InlineAsmOptions::PURE)
&& !args.options.intersects(ast::InlineAsmOptions::NOMEM | ast::InlineAsmOptions::READONLY)
{
- let span = args.options_span.unwrap();
+ let span = args.options_spans.clone().unwrap();
ecx.struct_span_err(
span,
"the `pure` option must be combined with either `nomem` or `readonly`",
}
if args.options.contains(ast::InlineAsmOptions::PURE) && !have_real_output {
ecx.struct_span_err(
- args.options_span.unwrap(),
+ args.options_spans.clone().unwrap(),
"asm with `pure` option must have at least one output",
)
.emit();
}
let new_span = span_start.to(p.prev_token.span);
- if let Some(options_span) = args.options_span {
- p.struct_span_err(new_span, "asm options cannot be specified multiple times")
- .span_label(options_span, "previously here")
- .span_label(new_span, "duplicate options")
- .emit();
+ if let Some(options_spans) = &mut args.options_spans {
+ options_spans.push(new_span);
} else {
- args.options_span = Some(new_span);
+ args.options_spans = Some(vec![new_span]);
}
Ok(())