Skip to content

allow constants to refer to mutable/external memory, but reject such constants as patterns #1859

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
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

RalfJung
Copy link
Member

Reference update for rust-lang/rust#140942.

@ehuss
Copy link
Contributor

ehuss commented Jun 15, 2025

I'm trying to figure out, which reference rule rejects the following?

static mut S: i32 = 1;
const C: &mut i32 = unsafe { &mut S }; // ERROR: constructing invalid value

What I'm getting at, is that it seems like despite removing items.const.final-value-immutable, it seems like there is still some restriction somewhere. What I'm thinking:

  • final value of &mut — never ok?
  • final value of & of a static mut — now ok
  • final value of & of something with interior mutability — sometimes ok?

Is there maybe still some "final value must not have mutable references" restriction?


Is there some rule in the reference that would explain the following?

const C: &AtomicU32 = &AtomicU32::new(1);  // ERROR: constants cannot refer to interior mutable data

It seems like a pretty strong blanket statement that "constants cannot refer to interior mutable data", but the AtomicU32 example from rust-lang/rust#140942 seems like you can refer to interior mutable data. What exactly is the difference between a reference to a static versus a reference to a value created in the initializer?


Similarly, I'm trying to understand E0764. Is the description of E0764 out of date?

const C: &mut i32 = &mut 1; // ERROR: mutable references are not allowed in the final value of constants

Questions:

  • Is there a rule in the reference that explains this error?
  • "Mutable references (&mut) can only be used in constant functions, not statics or constants." seems to be wrong now, as you can use mutable references in statics or constants (with some limitations), right?
  • "Remember: you cannot use a function call inside a constant or static"... I...don't understand this at all. The example below it clearly shows using a function call inside a constant. I can't even guess what this is trying to say.

@RalfJung
Copy link
Member Author

RalfJung commented Jun 17, 2025

So, I can't always tell you where any of that is in the reference, I had a hard time even find the things I am editing here.^^

But I can tell you what the compiler does:

static mut S: i32 = 1;
const C: &mut i32 = unsafe { &mut S }; // ERROR: constructing invalid value

We do a type-directed pass over the final value of the constant, mostly to check e.g. that every bool we find is 0 or 1 and things like that. As part of that pass, we just throw an error if we find any mutable reference in a const. We also error if

  • we find an UnsafeCell in memory that is immutable (see tests tests/ui/statics/mutable_memory_validation.rs and tests/ui/consts/interior-mut-const-via-union.rs) in either const or static
  • or if we find an &mut pointing to immutable memory (that last case might be just UB due to an aliasing violation, or it might be const being extra paranoid, that depends on the details of the aliasing model).
const C: &AtomicU32 = &AtomicU32::new(1);  // ERROR: constants cannot refer to interior mutable data

That falls out of the following two things which are in the reference:

  • "shared borrows to values with interior mutability are only allowed to refer to transient places"
  • and lifetime extension, which says that the AtomicU32 constructed here is not transient

Similarly, I'm trying to understand E0764. Is the description of E0764 out of date?

Oh yeah, that is very outdated. And I don't understand that "remember" thing either. (I worry this might be true for many of our error descriptions -- at least I don't ever seem them so I wouldn't even notice them being outdated. Multiple of our Exxxx tests don't even emit the right error code any more...)

const C: &mut i32 = &mut 1; // ERROR: mutable references are not allowed in the final value of constants

This is the exact same as "constants cannot refer to interior mutable data", but for a mutable reference rather than an interior mutable shared ref. I don't know why the error messages are worded so differently...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: The marked PR is awaiting review from a maintainer
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants