Skip to content

Commit 3dd583d

Browse files
committed
Fix error span when arg to asm!() is a macro call
When the template string passed to asm!() is produced by a macro call like concat!() we were producing wrong error spans. Now in the case of a macro call we just use the entire arg to asm!(), macro call and all, as the error span.
1 parent 2b11f26 commit 3dd583d

File tree

4 files changed

+63
-8
lines changed

4 files changed

+63
-8
lines changed

compiler/rustc_builtin_macros/src/asm.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,7 @@ fn expand_preparsed_asm(
507507

508508
let msg = "asm template must be a string literal";
509509
let template_sp = template_expr.span;
510+
let template_is_mac_call = matches!(template_expr.kind, ast::ExprKind::MacCall(_));
510511
let (template_str, template_style, template_span) = {
511512
let ExpandResult::Ready(mac) = expr_to_spanned_string(ecx, template_expr, msg) else {
512513
return ExpandResult::Retry(());
@@ -596,7 +597,14 @@ fn expand_preparsed_asm(
596597

597598
if !parser.errors.is_empty() {
598599
let err = parser.errors.remove(0);
599-
let err_sp = template_span.from_inner(InnerSpan::new(err.span.start, err.span.end));
600+
let err_sp = if template_is_mac_call {
601+
// If the template is a macro call we can't reliably point to the error's
602+
// span so just use the template's span as the error span (fixes #129503)
603+
template_span
604+
} else {
605+
template_span.from_inner(InnerSpan::new(err.span.start, err.span.end))
606+
};
607+
600608
let msg = format!("invalid asm template string: {}", err.description);
601609
let mut e = ecx.dcx().struct_span_err(err_sp, msg);
602610
e.span_label(err_sp, err.label + " in asm template string");

tests/crashes/129503.rs

-7
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Regression test for ICE #129503
2+
3+
4+
// Tests that we come up with decent error spans
5+
// when the template fed to `asm!()` is itself a
6+
// macro call like `concat!()` and should not ICE
7+
8+
use std::arch::asm;
9+
10+
fn main() {
11+
// Should not ICE
12+
asm!(concat!(r#"lJ𐏿Æ�.𐏿�"#, "r} {}"));
13+
//~^ ERROR invalid asm template string: unmatched `}` found
14+
15+
16+
// Macro call template: should point to
17+
// everything within `asm!()` as error span
18+
asm!(concat!("abc", "r} {}"));
19+
//~^ ERROR invalid asm template string: unmatched `}` found
20+
21+
22+
// Literal template: should point precisely to
23+
// just the `}` as error span
24+
asm!("abc", "r} {}");
25+
//~^ ERROR invalid asm template string: unmatched `}` found
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
error: invalid asm template string: unmatched `}` found
2+
--> $DIR/ice-bad-err-span-in-template-129503.rs:12:10
3+
|
4+
LL | asm!(concat!(r#"lJ𐏿Æ�.𐏿�"#, "r} {}"));
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unmatched `}` in asm template string
6+
|
7+
= note: if you intended to print `}`, you can escape it using `}}`
8+
= note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info)
9+
10+
error: invalid asm template string: unmatched `}` found
11+
--> $DIR/ice-bad-err-span-in-template-129503.rs:18:10
12+
|
13+
LL | asm!(concat!("abc", "r} {}"));
14+
| ^^^^^^^^^^^^^^^^^^^^^^^ unmatched `}` in asm template string
15+
|
16+
= note: if you intended to print `}`, you can escape it using `}}`
17+
= note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info)
18+
19+
error: invalid asm template string: unmatched `}` found
20+
--> $DIR/ice-bad-err-span-in-template-129503.rs:24:19
21+
|
22+
LL | asm!("abc", "r} {}");
23+
| ^ unmatched `}` in asm template string
24+
|
25+
= note: if you intended to print `}`, you can escape it using `}}`
26+
27+
error: aborting due to 3 previous errors
28+

0 commit comments

Comments
 (0)