Skip to content

Commit c883fa4

Browse files
committed
Allow multiple asm! options
1 parent 033013c commit c883fa4

File tree

1 file changed

+13
-16
lines changed
  • src/librustc_builtin_macros

1 file changed

+13
-16
lines changed

src/librustc_builtin_macros/asm.rs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ struct AsmArgs {
1616
named_args: FxHashMap<Symbol, usize>,
1717
reg_args: FxHashSet<usize>,
1818
options: ast::InlineAsmOptions,
19-
options_span: Option<Span>,
19+
options_spans: Option<Vec<Span>>,
2020
}
2121

2222
fn parse_args<'a>(
@@ -59,7 +59,7 @@ fn parse_args<'a>(
5959
named_args: FxHashMap::default(),
6060
reg_args: FxHashSet::default(),
6161
options: ast::InlineAsmOptions::empty(),
62-
options_span: None,
62+
options_spans: None,
6363
};
6464

6565
let mut allow_templates = true;
@@ -174,9 +174,9 @@ fn parse_args<'a>(
174174

175175
// Validate the order of named, positional & explicit register operands and options. We do
176176
// this at the end once we have the full span of the argument available.
177-
if let Some(options_span) = args.options_span {
177+
if let Some(ref options_spans) = args.options_spans {
178178
ecx.struct_span_err(span, "arguments are not allowed after options")
179-
.span_label(options_span, "previous options")
179+
.span_labels(options_spans.clone(), "previous options")
180180
.span_label(span, "argument")
181181
.emit();
182182
}
@@ -227,21 +227,21 @@ fn parse_args<'a>(
227227
if args.options.contains(ast::InlineAsmOptions::NOMEM)
228228
&& args.options.contains(ast::InlineAsmOptions::READONLY)
229229
{
230-
let span = args.options_span.unwrap();
231-
ecx.struct_span_err(span, "the `nomem` and `readonly` options are mutually exclusive")
230+
let spans = args.options_spans.clone().unwrap();
231+
ecx.struct_span_err(spans, "the `nomem` and `readonly` options are mutually exclusive")
232232
.emit();
233233
}
234234
if args.options.contains(ast::InlineAsmOptions::PURE)
235235
&& args.options.contains(ast::InlineAsmOptions::NORETURN)
236236
{
237-
let span = args.options_span.unwrap();
238-
ecx.struct_span_err(span, "the `pure` and `noreturn` options are mutually exclusive")
237+
let spans = args.options_spans.clone().unwrap();
238+
ecx.struct_span_err(spans, "the `pure` and `noreturn` options are mutually exclusive")
239239
.emit();
240240
}
241241
if args.options.contains(ast::InlineAsmOptions::PURE)
242242
&& !args.options.intersects(ast::InlineAsmOptions::NOMEM | ast::InlineAsmOptions::READONLY)
243243
{
244-
let span = args.options_span.unwrap();
244+
let span = args.options_spans.clone().unwrap();
245245
ecx.struct_span_err(
246246
span,
247247
"the `pure` option must be combined with either `nomem` or `readonly`",
@@ -267,7 +267,7 @@ fn parse_args<'a>(
267267
}
268268
if args.options.contains(ast::InlineAsmOptions::PURE) && !have_real_output {
269269
ecx.struct_span_err(
270-
args.options_span.unwrap(),
270+
args.options_spans.clone().unwrap(),
271271
"asm with `pure` option must have at least one output",
272272
)
273273
.emit();
@@ -314,13 +314,10 @@ fn parse_options<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> Result<(), Diagn
314314
}
315315

316316
let new_span = span_start.to(p.prev_token.span);
317-
if let Some(options_span) = args.options_span {
318-
p.struct_span_err(new_span, "asm options cannot be specified multiple times")
319-
.span_label(options_span, "previously here")
320-
.span_label(new_span, "duplicate options")
321-
.emit();
317+
if let Some(options_spans) = &mut args.options_spans {
318+
options_spans.push(new_span);
322319
} else {
323-
args.options_span = Some(new_span);
320+
args.options_spans = Some(vec![new_span]);
324321
}
325322

326323
Ok(())

0 commit comments

Comments
 (0)