Skip to content

Compile error when directly using &mut in explicity const context #140126

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
RedRam567 opened this issue Apr 21, 2025 · 5 comments
Open

Compile error when directly using &mut in explicity const context #140126

RedRam567 opened this issue Apr 21, 2025 · 5 comments
Labels
A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@RedRam567
Copy link

RedRam567 commented Apr 21, 2025

I tried this code:

const OKAY_SOMEHOW: &mut [f32] = std::convert::identity(&mut []);

// error[E0764]: mutable references are not allowed in the final value of constants
const BAD: &mut [f32] = &mut [];

I expected to see this happen: Both constants compile or both fail to compile.

Instead, this happened: BAD failed to compile.

I'm not sure which is the intended behavior or if it is UB. I don't know the rules around constants that hold mutable references.

This fails to compile in constants, statics and const {} blocks. This succeeds when using const functions to wrap the expressions, even in constants, statics, and const {} blocks.

Additional examples: https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=7b7a327957429e5706e520755d9cd467

See also an ICE related to this "ICE error performing operation: fully_perform" #140123

Meta

rustc --version --verbose:

rustc 1.88.0-nightly (b8c54d635 2025-04-20)
binary: rustc
commit-hash: b8c54d6358926028ac2fab1ec2b8665c70edb1c0
commit-date: 2025-04-20
host: x86_64-unknown-linux-gnu
release: 1.88.0-nightly
LLVM version: 20.1.2
Backtrace

RUST_BACKTRACE=1 cargo +nightly build

   Compiling rust_playground3 v0.1.0 (/tmp/rust_playground3)
error[E0764]: mutable references are not allowed in the final value of constants
 --> src/lib.rs:4:25
  |
4 | const BAD: &mut [f32] = &mut [];
  |                         ^^^^^^^

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

@RedRam567 RedRam567 added the C-bug Category: This is a bug. label Apr 21, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Apr 21, 2025
@RedRam567 RedRam567 changed the title Compile error when using &mut in explicity const context directly Compile error when directly using &mut in explicity const context Apr 21, 2025
@theemathas
Copy link
Contributor

This seems to happen only with empty arrays. It is perfectly fine to have two &mut references pointing to the same place if the references refer only to a zero-sized type (such as empty arrays). Therefore, I don't think this can lead to UB.

I'm guessing that this probably isn't intended though.

@theemathas
Copy link
Contributor

It appears that constant promotion, for some reason, works on &mut references to specifically empty arrays (and not to other kinds of zero-sized types).

fn require_static<T>(_: &'static mut T) {}

fn works() {
    require_static::<[i32; 0]>(&mut []);
}

fn fails() {
    // error[E0716]: temporary value dropped while borrowed
    require_static::<()>(&mut ());
}

@theemathas
Copy link
Contributor

Relevant past discussion: #110288 (comment)

@theemathas
Copy link
Contributor

From #103821 (comment):

That [constant promotion] works for empty arrays is maintained for backwards compatibility, since this was allowed in some very early version of promotion.

@theemathas
Copy link
Contributor

theemathas commented Apr 22, 2025

From #76411:

Promote &mut [] everywhere, not just in non-const functions, for consistency.

And:

// In theory, any zero-sized value could be borrowed
// mutably without consequences. However, only &mut []
// is allowed right now.

Based on this, I believe that the BAD const should compile.

Note that this also compiles fine.

const ALSO_COMPILES: &mut [f32] = {
    let x = &mut [];
    x
};

@jieyouxu jieyouxu added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) labels Apr 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants