Skip to content
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

const expression can borrow static items #1610

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
4 changes: 3 additions & 1 deletion src/const_eval.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ r[const-eval.const-expr.path-item]
Recursively defining constants is not allowed.

r[const-eval.const-expr.path-static]
* Paths to [statics]. These are only allowed within the initializer of a static.
* Paths to [statics] with these restrictions and observations.
* In particular, reads and writes to any `static mut` or [`extern` statics] is not allowed.
Copy link
Contributor

@traviscross traviscross Nov 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So over in #1657, there is proposed language:

Static initializers may refer to and even read from other statics.
When reading from mutable statics, they read the initial value of that static.

The language in this PR seems contradictory to the language in that one, no? Or is there a subtle distinction we're making? Do we need some carve-out here?

(We talked this through on the lang-docs call and couldn't immediately work it out.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RalfJung Can you write down exactly what we should say here? It would be helpful since we don't know exactly what the rules are. From looking at the implementation, I'm guessing, is it the CanAccessMutGlobal setting, which appears to be set only when in a static initializer? Does this need to say that you cannot read from static mut unless inside a static initializer, and that you can never write to a static mut, and that reading and writing extern statics always disallowed?

Copy link
Member

@RalfJung RalfJung Nov 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes:

  • reads from mutable statics (static mut, and interior mutable static) are forbidden except when evaluating the initializer expression of a static/static mut (so to be clear, the read can be syntactically inside a const fn or not, what matters is the const context, i.e. whether this is computing the initial value of a static or not)
  • writes to mutable statics are forbidden everywhere
  • reads from and writes to extern static are forbidden everywhere


r[const-eval.const-expr.tuple]
* [Tuple expressions].
Expand Down Expand Up @@ -177,6 +178,7 @@ of whether you are building on a `64` bit or a `32` bit system.
[enum discriminants]: items/enumerations.md#discriminants
[expression statements]: statements.md#expression-statements
[expressions]: expressions.md
[`extern` statics]: items/external-blocks.md#statics
[field]: expressions/field-expr.md
[functions]: items/functions.md
[grouped]: expressions/grouped-expr.md
Expand Down
2 changes: 2 additions & 0 deletions src/items/constant-items.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ const BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings {
};
```

The final value of a `const` item cannot contain references to anything mutable.

r[items.const.expr-omission]
The constant expression may only be omitted in a [trait definition].

Expand Down
7 changes: 2 additions & 5 deletions src/items/static-items.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,7 @@ All access to a static is safe, but there are a number of restrictions on
statics:

r[items.static.sync]
* The type must have the `Sync` trait bound to allow thread-safe access.

r[items.static.const]
* Constants cannot refer to statics.
* The type must have the [`Sync`](std::marker::Sync) trait bound to allow thread-safe access.

r[items.static.init.omission]
The initializer expression must be omitted in an [external block], and must be
Expand Down Expand Up @@ -159,7 +156,7 @@ It can be confusing whether or not you should use a constant item or a static
item. Constants should, in general, be preferred over statics unless one of the
following are true:

* Large amounts of data are being stored
* Large amounts of data are being stored.
* The single-address property of statics is required.
* Interior mutability is required.

Expand Down