diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 56cc432758511..a5c9bad3ac2db 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -840,14 +840,22 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } else { bug!("not an upvar") }; - err.span_label( - *span, - format!( - "calling `{}` requires mutable binding due to {}", - self.describe_place(the_place_err).unwrap(), - reason - ), - ); + // sometimes we deliberately don't store the name of a place when coming from a macro in + // another crate. We generally want to limit those diagnostics a little, to hide + // implementation details (such as those from pin!() or format!()). In that case show a + // slightly different error message, or none at all if something else happened. In other + // cases the message is likely not useful. + if let Some(place_name) = self.describe_place(the_place_err) { + err.span_label( + *span, + format!("calling `{place_name}` requires mutable binding due to {reason}"), + ); + } else if span.from_expansion() { + err.span_label( + *span, + format!("a call in this macro requires a mutable binding due to {reason}",), + ); + } } } diff --git a/tests/ui/macros/auxiliary/borrowck-error-in-macro.rs b/tests/ui/macros/auxiliary/borrowck-error-in-macro.rs new file mode 100644 index 0000000000000..2d5f2bda2edfe --- /dev/null +++ b/tests/ui/macros/auxiliary/borrowck-error-in-macro.rs @@ -0,0 +1,10 @@ +#[macro_export] +macro_rules! ice { + () => { + fn main() { + let d = &mut 0; + let c = || *d += 1; + c(); + } + }; +} diff --git a/tests/ui/macros/borrowck-error-in-macro.rs b/tests/ui/macros/borrowck-error-in-macro.rs new file mode 100644 index 0000000000000..fe75188efd203 --- /dev/null +++ b/tests/ui/macros/borrowck-error-in-macro.rs @@ -0,0 +1,8 @@ +//@ aux-build: borrowck-error-in-macro.rs +//@ error-pattern: a call in this macro requires a mutable binding due to mutable borrow of `d` +//FIXME: remove error-pattern (see #141896) + +extern crate borrowck_error_in_macro as a; + +a::ice! {} +//~^ ERROR cannot borrow value as mutable, as it is not declared as mutable diff --git a/tests/ui/macros/borrowck-error-in-macro.stderr b/tests/ui/macros/borrowck-error-in-macro.stderr new file mode 100644 index 0000000000000..ec0302ee287ec --- /dev/null +++ b/tests/ui/macros/borrowck-error-in-macro.stderr @@ -0,0 +1,19 @@ +error[E0596]: cannot borrow value as mutable, as it is not declared as mutable + --> $DIR/borrowck-error-in-macro.rs:7:1 + | +LL | a::ice! {} + | ^^^^^^^^^^ + | | + | cannot borrow as mutable + | a call in this macro requires a mutable binding due to mutable borrow of `d` + | + = note: this error originates in the macro `a::ice` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider changing this to be mutable + --> $DIR/auxiliary/borrowck-error-in-macro.rs:6:17 + | +LL | let mut c = || *d += 1; + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0596`.