Skip to content

Commit

Permalink
Merge pull request #1497 from RalfJung/const-eval-guarantee
Browse files Browse the repository at this point in the history
document guarantee about evaluation of associated consts and const blocks
  • Loading branch information
ehuss authored May 25, 2024
2 parents e356977 + d33e4b0 commit 1bf2cdc
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 4 deletions.
26 changes: 22 additions & 4 deletions src/expressions/block-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,13 @@ loop {
> _ConstBlockExpression_ :\
>    `const` _BlockExpression_
A *const block* is a variant of a block expression which evaluates at compile-time instead of at runtime.
A *const block* is a variant of a block expression whose body evaluates at compile-time instead of at runtime.

Const blocks allows you to define a constant value without having to define new [constant items], and thus they are also sometimes referred as *inline consts*.
It also supports type inference so there is no need to specify the type, unlike [constant items].

Const blocks have the ability to reference generic parameters in scope, unlike [free][free item] constant items.
They are desugared to associated constant items with generic parameters in scope.
They are desugared to constant items with generic parameters in scope (similar to associated constants, but without a trait or type they are associated with).
For example, this code:

```rust
Expand All @@ -152,8 +152,26 @@ fn foo<T>() -> usize {
}
```

This also means that const blocks are treated similarly to associated constants.
For example, they are not guaranteed to be evaluated when the enclosing function is unused.
If the const block expression is executed at runtime, then the constant is guaranteed to be evaluated, even if its return value is ignored:

```rust
fn foo<T>() -> usize {
// If this code ever gets executed, then the assertion has definitely
// been evaluated at compile-time.
const { assert!(std::mem::size_of::<T>() > 0); }
// Here we can have unsafe code relying on the type being non-zero-sized.
/* ... */
42
}
```

If the const block expression is not executed at runtime, it may or may not be evaluated:
```rust,compile_fail
if false {
// The panic may or may not occur when the program is built.
const { panic!(); }
}
```

## `unsafe` blocks

Expand Down
3 changes: 3 additions & 0 deletions src/expressions/path-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@ let push_integer = Vec::<i32>::push;
let slice_reverse = <[i32]>::reverse;
```

Evaluation of associated constants is handled the same way as [`const` blocks].

[_PathInExpression_]: ../paths.md#paths-in-expressions
[_QualifiedPathInExpression_]: ../paths.md#qualified-paths
[place expressions]: ../expressions.md#place-expressions-and-value-expressions
[value expressions]: ../expressions.md#place-expressions-and-value-expressions
[path]: ../paths.md
[`static mut`]: ../items/static-items.md#mutable-statics
[`unsafe` block]: block-expr.md#unsafe-blocks
[`const` blocks]: block-expr.md#const-blocks

0 comments on commit 1bf2cdc

Please sign in to comment.