Skip to content

Commit 673ef58

Browse files
committed
document guarantee about evaluation of associated consts and const blocks
1 parent e356977 commit 673ef58

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

src/expressions/block-expr.md

+21-4
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,13 @@ loop {
123123
> _ConstBlockExpression_ :\
124124
>    `const` _BlockExpression_
125125
126-
A *const block* is a variant of a block expression which evaluates at compile-time instead of at runtime.
126+
A *const block* is a variant of a block expression whose body evaluates at compile-time instead of at runtime.
127127

128128
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*.
129129
It also supports type inference so there is no need to specify the type, unlike [constant items].
130130

131131
Const blocks have the ability to reference generic parameters in scope, unlike [free][free item] constant items.
132-
They are desugared to associated constant items with generic parameters in scope.
132+
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).
133133
For example, this code:
134134

135135
```rust
@@ -152,8 +152,25 @@ fn foo<T>() -> usize {
152152
}
153153
```
154154

155-
This also means that const blocks are treated similarly to associated constants.
156-
For example, they are not guaranteed to be evaluated when the enclosing function is unused.
155+
If the const block expression is executed at runtime, then the constant is guaranteed to be evaluated, even if its return value is ignored:
156+
157+
```rust
158+
fn foo<T>() -> usize {
159+
// If this code ever gets executed, then the assertion has definitely
160+
// been evaluated at compile-time.
161+
const { assert!(std::mem::size_of::<T>() > 0); }
162+
// Here we can have unsafe code relying on the type being non-zero-sized.
163+
/* ... */
164+
}
165+
```
166+
167+
If the const block expression is not executed at runtime, it may or may not be evaluated:
168+
```rust,compile_fail
169+
if false {
170+
// The panic may or may not occur when the program is built.
171+
const { panic!(); }
172+
}
173+
```
157174

158175
## `unsafe` blocks
159176

src/expressions/path-expr.md

+3
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@ let push_integer = Vec::<i32>::push;
2323
let slice_reverse = <[i32]>::reverse;
2424
```
2525

26+
Evaluation of associated constants is handled the same way as [`const` blocks].
27+
2628
[_PathInExpression_]: ../paths.md#paths-in-expressions
2729
[_QualifiedPathInExpression_]: ../paths.md#qualified-paths
2830
[place expressions]: ../expressions.md#place-expressions-and-value-expressions
2931
[value expressions]: ../expressions.md#place-expressions-and-value-expressions
3032
[path]: ../paths.md
3133
[`static mut`]: ../items/static-items.md#mutable-statics
3234
[`unsafe` block]: block-expr.md#unsafe-blocks
35+
[`const` blocks]: block-expr.md#const-blocks

0 commit comments

Comments
 (0)