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.
This commit is contained in:
Gurinder Singh 2024-09-27 09:49:15 +05:30
parent 2b11f265b6
commit 3dd583d540
4 changed files with 63 additions and 8 deletions

View File

@ -507,6 +507,7 @@ fn expand_preparsed_asm(
let msg = "asm template must be a string literal"; let msg = "asm template must be a string literal";
let template_sp = template_expr.span; let template_sp = template_expr.span;
let template_is_mac_call = matches!(template_expr.kind, ast::ExprKind::MacCall(_));
let (template_str, template_style, template_span) = { let (template_str, template_style, template_span) = {
let ExpandResult::Ready(mac) = expr_to_spanned_string(ecx, template_expr, msg) else { let ExpandResult::Ready(mac) = expr_to_spanned_string(ecx, template_expr, msg) else {
return ExpandResult::Retry(()); return ExpandResult::Retry(());
@ -596,7 +597,14 @@ fn expand_preparsed_asm(
if !parser.errors.is_empty() { if !parser.errors.is_empty() {
let err = parser.errors.remove(0); let err = parser.errors.remove(0);
let err_sp = template_span.from_inner(InnerSpan::new(err.span.start, err.span.end)); let err_sp = if template_is_mac_call {
// If the template is a macro call we can't reliably point to the error's
// span so just use the template's span as the error span (fixes #129503)
template_span
} else {
template_span.from_inner(InnerSpan::new(err.span.start, err.span.end))
};
let msg = format!("invalid asm template string: {}", err.description); let msg = format!("invalid asm template string: {}", err.description);
let mut e = ecx.dcx().struct_span_err(err_sp, msg); let mut e = ecx.dcx().struct_span_err(err_sp, msg);
e.span_label(err_sp, err.label + " in asm template string"); e.span_label(err_sp, err.label + " in asm template string");

View File

@ -1,7 +0,0 @@
//@ known-bug: rust-lang/rust#129503
use std::arch::asm;
unsafe fn f6() {
asm!(concat!(r#"lJ𐏿Æ<F0908FBF>.𐏿<>"#, "r} {}"));
}

View File

@ -0,0 +1,26 @@
// Regression test for ICE #129503
// Tests that we come up with decent error spans
// when the template fed to `asm!()` is itself a
// macro call like `concat!()` and should not ICE
use std::arch::asm;
fn main() {
// Should not ICE
asm!(concat!(r#"lJ𐏿Æ<F0908FBF>.𐏿<>"#, "r} {}"));
//~^ ERROR invalid asm template string: unmatched `}` found
// Macro call template: should point to
// everything within `asm!()` as error span
asm!(concat!("abc", "r} {}"));
//~^ ERROR invalid asm template string: unmatched `}` found
// Literal template: should point precisely to
// just the `}` as error span
asm!("abc", "r} {}");
//~^ ERROR invalid asm template string: unmatched `}` found
}

View File

@ -0,0 +1,28 @@
error: invalid asm template string: unmatched `}` found
--> $DIR/ice-bad-err-span-in-template-129503.rs:12:10
|
LL | asm!(concat!(r#"lJ𐏿Æ<F0908FBF>.𐏿<>"#, "r} {}"));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unmatched `}` in asm template string
|
= note: if you intended to print `}`, you can escape it using `}}`
= note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: invalid asm template string: unmatched `}` found
--> $DIR/ice-bad-err-span-in-template-129503.rs:18:10
|
LL | asm!(concat!("abc", "r} {}"));
| ^^^^^^^^^^^^^^^^^^^^^^^ unmatched `}` in asm template string
|
= note: if you intended to print `}`, you can escape it using `}}`
= note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: invalid asm template string: unmatched `}` found
--> $DIR/ice-bad-err-span-in-template-129503.rs:24:19
|
LL | asm!("abc", "r} {}");
| ^ unmatched `}` in asm template string
|
= note: if you intended to print `}`, you can escape it using `}}`
error: aborting due to 3 previous errors