Skip to content

Commit

Permalink
Simplify const_refs_to_static
Browse files Browse the repository at this point in the history
This removes some content for const_refs_to_static which seems to
duplicate content elsewhere. In particular:

* Remove the examples of allowed use of `static` in `const_eval.md`. We
  don't show examples for any of the other permitted uses. Additionally,
  I believe the other points in the list already cover concerns such as
  interior mutability (and possibly more precise way, since the existing
  content mentions things like transient places).
* I think a single statement that reads of `extern` statics is
  sufficient to follow the pattern of all the other allowed behaviors.
* Removed the examples from the `constant-items.md` chapter about
  allowing use of `static`s. Again, we generally don't duplicate what
  is allowed unless there is some explicit statement indicating that
  it is not. Also, I am reluctant to duplicate what is allowed between
  `const_eval.md` and `constant-items.md`.
  • Loading branch information
ehuss committed Oct 9, 2024
1 parent 9af6601 commit 97abd04
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 63 deletions.
38 changes: 2 additions & 36 deletions src/const_eval.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ to be run.
* [Paths] to [functions] and [constants].
Recursively defining constants is not allowed.
* Paths to immutable [statics].
* Reads of [`extern` statics] are not allowed.
* [Tuple expressions].
* [Array expressions].
* [Struct] expressions.
Expand Down Expand Up @@ -71,41 +72,6 @@ surrounding generic parameters: such an expression must either be a single bare
const generic parameter, or an arbitrary expression not making use of any
generics.

## Permitted use of `static`s

Within the constant evaluation context, items that ultimately contain no mutable memory or data that is
capable of interior mutability can be used, borrowed or taken address of.
Among those are the `static` items as long as they are not actually `mut` items.

```rust
const fn allowed() -> &'static u32 {
static VALUE: u32 = 0;
&VALUE
}
const A_CONST: &'static u32 = allowed();
```

On the contrary, for example, `static mut` and types embedding an `UnsafeCell` is not allowed.

```rust,edition2021,compile_fail,E0080
const fn not_allowed() -> &'static u32 {
static mut VALUE: u32 = 0;
&VALUE
}
const WILL_FAIL: &'static u32 = not_allowed();
```

One other instance that the constant evaluation will reject is any attempt to read values behind a `static` item declared in an [`extern`] block, even though the item is not marked as `mut`.
Computing the address to the `static` item is still permitted. However, as soon as a use or dereferencing of the whole or a part of the `static` item is performed, it constitutes a read access which will fail the constant evaluation.

```rust,edition2021,compile_fail,E0080
extern {
static S: u32;
}
const C: u32 = unsafe { S };
```

## Const Functions

A _const fn_ is a function that one is permitted to call from a const context. Declaring a function
Expand Down Expand Up @@ -141,7 +107,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`]: items/external-blocks.md#statics
[`extern` statics]: items/external-blocks.md#statics
[field]: expressions/field-expr.md
[functions]: items/functions.md
[grouped]: expressions/grouped-expr.md
Expand Down
27 changes: 0 additions & 27 deletions src/items/constant-items.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,32 +90,6 @@ m!(const _: () = (););
// const _: () = ();
```

## Use and reference to `static` items

When a constant item or constant block is defined, [`static` items] can be used, borrowed or taken address of.
By extension, you are allowed to call methods that immutably borrows the `static` items as receivers.

```rust
static A: u32 = 32;
const ANOTHER_A: u32 = A;
const BORROW_A: &'static u32 = &A;
const POINTER_TO_A: *const u32 = &A as _;

struct MyStruct {
inner: u32,
}
impl MyStruct {
const fn get(&self) -> u32 {
self.inner + 1
}
}
static MYSTRUCT: MyStruct = MyStruct {
inner: 0
};
const BORROW_STATIC_INNER: &'static u32 = &MYSTRUCT.inner;
const CALL_CONST_STATIC_ASSOCIATED_METHOD: u32 = MYSTRUCT.get();
```

## Evaluation

[Free][free] constants are always [evaluated][const_eval] at compile-time to surface
Expand All @@ -136,7 +110,6 @@ fn unused_generic_function<T>() {
[constant value]: ../const_eval.md#constant-expressions
[free]: ../glossary.md#free-item
[static lifetime elision]: ../lifetime-elision.md#static-lifetime-elision
[`static` items]: ./static-items.md
[trait definition]: traits.md
[IDENTIFIER]: ../identifiers.md
[underscore imports]: use-declarations.md#underscore-imports
Expand Down

0 comments on commit 97abd04

Please sign in to comment.