Skip to content

Don't name variables from external macros in borrow errors. #140580

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2954,12 +2954,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
}
}

let name = if borrow_span.in_external_macro(self.infcx.tcx.sess.source_map()) {
// Don't name local variables in external macros.
"value".to_string()
} else {
format!("`{name}`")
};
let name = format!("`{name}`");

let mut err = self.path_does_not_live_long_enough(borrow_span, &name);

Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_borrowck/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,14 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
opt: DescribePlaceOpt,
) -> Option<String> {
let local = place.local;
if self.body.local_decls[local]
.source_info
.span
.in_external_macro(self.infcx.tcx.sess.source_map())
{
return None;
}

let mut autoderef_index = None;
let mut buf = String::new();
let mut ok = self.append_local_to_string(local, &mut buf);
Expand Down
18 changes: 9 additions & 9 deletions tests/ui/derives/deriving-with-repr-packed-move-errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ use std::cmp::Ordering;
#[repr(packed)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
struct StructA(String);
//~^ ERROR: cannot move out of `self` which is behind a shared reference
//~| ERROR: cannot move out of `self` which is behind a shared reference
//~| ERROR: cannot move out of `other` which is behind a shared reference
//~| ERROR: cannot move out of `self` which is behind a shared reference
//~| ERROR: cannot move out of `other` which is behind a shared reference
//~| ERROR: cannot move out of `self` which is behind a shared reference
//~| ERROR: cannot move out of `other` which is behind a shared reference
//~| ERROR: cannot move out of `self` which is behind a shared reference
//~| ERROR: cannot move out of `self` which is behind a shared reference
//~^ ERROR: cannot move out of a shared reference [E0507]
//~| ERROR: cannot move out of a shared reference [E0507]
//~| ERROR: cannot move out of a shared reference [E0507]
//~| ERROR: cannot move out of a shared reference [E0507]
//~| ERROR: cannot move out of a shared reference [E0507]
//~| ERROR: cannot move out of a shared reference [E0507]
//~| ERROR: cannot move out of a shared reference [E0507]
//~| ERROR: cannot move out of a shared reference [E0507]
//~| ERROR: cannot move out of a shared reference [E0507]


// Unrelated impl: additinal diagnostic should NOT be emitted
Expand Down
39 changes: 21 additions & 18 deletions tests/ui/derives/deriving-with-repr-packed-move-errors.stderr
Original file line number Diff line number Diff line change
@@ -1,122 +1,125 @@
error[E0507]: cannot move out of `self` which is behind a shared reference
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
|
LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
| ----- in this derive macro expansion
LL | struct StructA(String);
| ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
help: consider cloning the value if the performance cost is acceptable
|
LL | struct StructA(String.clone());
| ++++++++

error[E0507]: cannot move out of `self` which is behind a shared reference
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
|
LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
| --------- in this derive macro expansion
LL | struct StructA(String);
| ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(PartialEq)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
help: consider cloning the value if the performance cost is acceptable
|
LL | struct StructA(String.clone());
| ++++++++

error[E0507]: cannot move out of `other` which is behind a shared reference
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
|
LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
| --------- in this derive macro expansion
LL | struct StructA(String);
| ^^^^^^ move occurs because `other.0` has type `String`, which does not implement the `Copy` trait
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(PartialEq)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: consider cloning the value if the performance cost is acceptable
|
LL | struct StructA(String.clone());
| ++++++++

error[E0507]: cannot move out of `self` which is behind a shared reference
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
|
LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
| ---------- in this derive macro expansion
LL | struct StructA(String);
| ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(PartialOrd)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
help: consider cloning the value if the performance cost is acceptable
|
LL | struct StructA(String.clone());
| ++++++++

error[E0507]: cannot move out of `other` which is behind a shared reference
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
|
LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
| ---------- in this derive macro expansion
LL | struct StructA(String);
| ^^^^^^ move occurs because `other.0` has type `String`, which does not implement the `Copy` trait
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(PartialOrd)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: consider cloning the value if the performance cost is acceptable
|
LL | struct StructA(String.clone());
| ++++++++

error[E0507]: cannot move out of `self` which is behind a shared reference
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
|
LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
| --- in this derive macro expansion
LL | struct StructA(String);
| ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(Ord)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
help: consider cloning the value if the performance cost is acceptable
|
LL | struct StructA(String.clone());
| ++++++++

error[E0507]: cannot move out of `other` which is behind a shared reference
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
|
LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
| --- in this derive macro expansion
LL | struct StructA(String);
| ^^^^^^ move occurs because `other.0` has type `String`, which does not implement the `Copy` trait
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(Ord)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: consider cloning the value if the performance cost is acceptable
|
LL | struct StructA(String.clone());
| ++++++++

error[E0507]: cannot move out of `self` which is behind a shared reference
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
|
LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
| ---- in this derive macro expansion
LL | struct StructA(String);
| ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(Hash)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
help: consider cloning the value if the performance cost is acceptable
|
LL | struct StructA(String.clone());
| ++++++++

error[E0507]: cannot move out of `self` which is behind a shared reference
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
|
LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
| ----- in this derive macro expansion
LL | struct StructA(String);
| ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(Clone)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
help: consider cloning the value if the performance cost is acceptable
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/derives/deriving-with-repr-packed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ struct Y(usize);
#[derive(Debug, Default)]
#[repr(packed)]
struct X(Y);
//~^ ERROR cannot move out of `self` which is behind a shared reference
//~^ ERROR cannot move out of a shared reference [E0507]

#[derive(Debug)]
#[repr(packed)]
Expand Down
12 changes: 6 additions & 6 deletions tests/ui/derives/deriving-with-repr-packed.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0507]: cannot move out of `self` which is behind a shared reference
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed.rs:22:10
|
LL | #[derive(Debug, Default)]
| ----- in this derive macro expansion
LL | #[repr(packed)]
LL | struct X(Y);
| ^ move occurs because `self.0` has type `Y`, which does not implement the `Copy` trait
| ^ move occurs because value has type `Y`, which does not implement the `Copy` trait
|
note: if `Y` implemented `Clone`, you could clone the value
--> $DIR/deriving-with-repr-packed.rs:16:1
Expand All @@ -23,14 +23,14 @@ error[E0161]: cannot move a value of type `[u8]`
LL | data: [u8],
| ^^^^^^^^^^ the size of `[u8]` cannot be statically determined

error[E0507]: cannot move out of `self.data` which is behind a shared reference
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed.rs:29:5
|
LL | #[derive(Debug)]
| ----- in this derive macro expansion
...
LL | data: [u8],
| ^^^^^^^^^^ move occurs because `self.data` has type `[u8]`, which does not implement the `Copy` trait
| ^^^^^^^^^^ move occurs because value has type `[u8]`, which does not implement the `Copy` trait
|
= note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour

Expand All @@ -40,14 +40,14 @@ error[E0161]: cannot move a value of type `str`
LL | data: str,
| ^^^^^^^^^ the size of `str` cannot be statically determined

error[E0507]: cannot move out of `self.data` which is behind a shared reference
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed.rs:38:5
|
LL | #[derive(Debug)]
| ----- in this derive macro expansion
...
LL | data: str,
| ^^^^^^^^^ move occurs because `self.data` has type `str`, which does not implement the `Copy` trait
| ^^^^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait
|
= note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour

Expand Down
11 changes: 11 additions & 0 deletions tests/ui/macros/auxiliary/return_from_external_macro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#![feature(super_let)]

#[macro_export]
macro_rules! foo {
() => {
{
super let args = 1;
&args
}
};
}
17 changes: 17 additions & 0 deletions tests/ui/macros/return_from_external_macro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//@ aux-crate: ret_from_ext=return_from_external_macro.rs

#![feature(super_let)]
extern crate ret_from_ext;

fn foo() -> impl Sized {
drop(|| ret_from_ext::foo!());
//~^ ERROR cannot return reference to local binding

ret_from_ext::foo!()
//~^ ERROR temporary value dropped while borrowed
}
//~^ NOTE temporary value is freed at the end of this statement

fn main() {
foo();
}
29 changes: 29 additions & 0 deletions tests/ui/macros/return_from_external_macro.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
error[E0515]: cannot return reference to local binding
--> $DIR/return_from_external_macro.rs:7:13
|
LL | drop(|| ret_from_ext::foo!());
| ^^^^^^^^^^^^^^^^^^^^
| |
| returns a reference to data owned by the current function
| local binding introduced here
|
= note: this error originates in the macro `ret_from_ext::foo` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0716]: temporary value dropped while borrowed
--> $DIR/return_from_external_macro.rs:10:5
|
LL | ret_from_ext::foo!()
| ^^^^^^^^^^^^^^^^^^^^
| |
| creates a temporary value which is freed while still in use
| opaque type requires that borrow lasts for `'static`
LL |
LL | }
| - temporary value is freed at the end of this statement
|
= note: this error originates in the macro `ret_from_ext::foo` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0515, E0716.
For more information about an error, try `rustc --explain E0515`.
4 changes: 2 additions & 2 deletions tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ use core::{

fn function_call_stops_borrow_extension() {
let phantom_pinned = identity(pin!(PhantomPinned));
//~^ ERROR does not live long enough
//~^ ERROR temporary value dropped while borrowed [E0716]
stuff(phantom_pinned)
}

fn promotion_only_works_for_the_innermost_block() {
let phantom_pinned = {
let phantom_pinned = pin!(PhantomPinned);
//~^ ERROR does not live long enough
//~^ ERROR temporary value dropped while borrowed [E0716]
phantom_pinned
};
stuff(phantom_pinned)
Expand Down
16 changes: 9 additions & 7 deletions tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
error[E0597]: value does not live long enough
error[E0716]: temporary value dropped while borrowed
--> $DIR/lifetime_errors_on_promotion_misusage.rs:11:35
|
LL | let phantom_pinned = identity(pin!(PhantomPinned));
| ^^^^^^^^^^^^^^^^^^^ - value dropped here while still borrowed
| ^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
| borrowed value does not live long enough
| creates a temporary value which is freed while still in use
LL |
LL | stuff(phantom_pinned)
| -------------- borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
= note: this error originates in the macro `pin` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0597]: value does not live long enough
error[E0716]: temporary value dropped while borrowed
--> $DIR/lifetime_errors_on_promotion_misusage.rs:18:30
|
LL | let phantom_pinned = {
| -------------- borrow later stored here
LL | let phantom_pinned = pin!(PhantomPinned);
| ^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
| ^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
...
LL | };
| - value dropped here while still borrowed
| - temporary value is freed at the end of this statement
|
= note: consider using a `let` binding to create a longer lived value
= note: this error originates in the macro `pin` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0597`.
For more information about this error, try `rustc --explain E0716`.
Loading