From 3dd583d5407c1d459c6539a4673e6d329903da66 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Fri, 27 Sep 2024 09:49:15 +0530 Subject: [PATCH] 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. --- compiler/rustc_builtin_macros/src/asm.rs | 10 ++++++- tests/crashes/129503.rs | 7 ----- .../ice-bad-err-span-in-template-129503.rs | 26 +++++++++++++++++ ...ice-bad-err-span-in-template-129503.stderr | 28 +++++++++++++++++++ 4 files changed, 63 insertions(+), 8 deletions(-) delete mode 100644 tests/crashes/129503.rs create mode 100644 tests/ui/asm/ice-bad-err-span-in-template-129503.rs create mode 100644 tests/ui/asm/ice-bad-err-span-in-template-129503.stderr diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 0e1ec3b3cad..486d1dada84 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -507,6 +507,7 @@ fn expand_preparsed_asm( let msg = "asm template must be a string literal"; 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 ExpandResult::Ready(mac) = expr_to_spanned_string(ecx, template_expr, msg) else { return ExpandResult::Retry(()); @@ -596,7 +597,14 @@ fn expand_preparsed_asm( if !parser.errors.is_empty() { 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 mut e = ecx.dcx().struct_span_err(err_sp, msg); e.span_label(err_sp, err.label + " in asm template string"); diff --git a/tests/crashes/129503.rs b/tests/crashes/129503.rs deleted file mode 100644 index c1ed46e5955..00000000000 --- a/tests/crashes/129503.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ known-bug: rust-lang/rust#129503 - -use std::arch::asm; - -unsafe fn f6() { - asm!(concat!(r#"lJ𐏿Æ�.𐏿�"#, "r} {}")); -} diff --git a/tests/ui/asm/ice-bad-err-span-in-template-129503.rs b/tests/ui/asm/ice-bad-err-span-in-template-129503.rs new file mode 100644 index 00000000000..3b4390f881a --- /dev/null +++ b/tests/ui/asm/ice-bad-err-span-in-template-129503.rs @@ -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𐏿Æ�.𐏿�"#, "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 +} diff --git a/tests/ui/asm/ice-bad-err-span-in-template-129503.stderr b/tests/ui/asm/ice-bad-err-span-in-template-129503.stderr new file mode 100644 index 00000000000..ffa9362ed95 --- /dev/null +++ b/tests/ui/asm/ice-bad-err-span-in-template-129503.stderr @@ -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𐏿Æ�.𐏿�"#, "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 +