Skip to content

pin!() macro no longer constant-promotes &mut references to empty arrays #142345

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

Open
theemathas opened this issue Jun 11, 2025 · 3 comments
Open
Labels
A-pin Area: Pin C-bug Category: This is a bug. F-super_let it's super, let's go! I-prioritize Issue: Indicates that prioritization has been requested for this issue. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. regression-from-stable-to-beta Performance or correctness regression from stable to beta.

Comments

@theemathas
Copy link
Contributor

Code

I tried this code:

use std::pin::{pin, Pin};

fn require_static(_: Pin<&'static mut [i32; 0]>) {}

pub fn weird() {
    require_static(pin!([]));
}

I expected to see this happen: The code compiles

Instead, this happened (when compiled with beta rust):

error[E0716]: temporary value dropped while borrowed
 --> src/lib.rs:6:20
  |
6 |     require_static(pin!([]));
  |     ---------------^^^^^^^^-- temporary value is freed at the end of this statement
  |     |              |
  |     |              creates a temporary value which is freed while still in use
  |     argument requires that borrow lasts for `'static`
  |
  = note: this error originates in the macro `pin` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0716`.
error: could not compile `playground` (lib) due to 1 previous error

See also #140126, which is about the fact that &mut references to empty arrays are, for some reason, sometimes allowed in const contexts.

This was found while messing around. I don't know if any code relies on this.

Version it worked on

It most recently worked on: stable Rust 1.87.0

Version with regression

The error is reproducible on the playground with 1.88.0-beta.5 (2025-06-01 645b44edd3717f02838d)

The regression presumably happened due to #139114. cc @m-ou-se

@rustbot modify labels: +regression-from-stable-to-beta -regression-untriaged A-pin F-super_let

@theemathas theemathas added C-bug Category: This is a bug. regression-untriaged Untriaged performance or correctness regression. labels Jun 11, 2025
@rustbot rustbot added needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. I-prioritize Issue: Indicates that prioritization has been requested for this issue. A-pin Area: Pin F-super_let it's super, let's go! regression-from-stable-to-beta Performance or correctness regression from stable to beta. and removed regression-untriaged Untriaged performance or correctness regression. labels Jun 11, 2025
@m-ou-se
Copy link
Member

m-ou-se commented Jun 11, 2025

Did you come across this in a real world use case? A pinned static mutable reference to a zero sized type seems like a bit of a wild concept to me. ^^'

@theemathas
Copy link
Contributor Author

I was just messing around, because I felt like something with this combination of stuff had to be broken somehow 😅

@theemathas
Copy link
Contributor Author

Another variant:

use std::pin::{pin, Pin};

const fn identity<T>(x: T) -> T { x }

pub const X: Pin<&'static mut [i32; 0]> = identity(pin!([]));

This compiles on stable, but gives the following error on beta:

error[E0716]: temporary value dropped while borrowed
 --> src/lib.rs:5:52
  |
5 | pub const X: Pin<&'static mut [i32; 0]> = identity(pin!([]));
  |                                           ---------^^^^^^^^-
  |                                           |        |       |
  |                                           |        |       temporary value is freed at the end of this statement
  |                                           |        creates a temporary value which is freed while still in use
  |                                           using this value as a constant requires that borrow lasts for `'static`
  |
  = note: this error originates in the macro `pin` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0716`.
error: could not compile `playground` (lib) due to 1 previous error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-pin Area: Pin C-bug Category: This is a bug. F-super_let it's super, let's go! I-prioritize Issue: Indicates that prioritization has been requested for this issue. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. regression-from-stable-to-beta Performance or correctness regression from stable to beta.
Projects
None yet
Development

No branches or pull requests

3 participants