Skip to content

Commit 384cb5d

Browse files
committed
Add const blocks
1 parent 5181795 commit 384cb5d

File tree

4 files changed

+47
-1
lines changed

4 files changed

+47
-1
lines changed

src/const_eval.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ to be run.
2727
* [Tuple expressions].
2828
* [Array expressions].
2929
* [Struct] expressions.
30-
* [Block expressions], including `unsafe` blocks.
30+
* [Block expressions], including `unsafe` and `const` blocks.
3131
* [let statements] and thus irrefutable [patterns], including mutable bindings
3232
* [assignment expressions]
3333
* [compound assignment expressions]
@@ -59,6 +59,7 @@ A _const context_ is one of the following:
5959
* [statics]
6060
* [enum discriminants]
6161
* A [const generic argument]
62+
* A [const block]
6263

6364
## Const Functions
6465

@@ -106,6 +107,7 @@ Conversely, the following are possible in a const function, but not in a const c
106107
[cast]: expressions/operator-expr.md#type-cast-expressions
107108
[closure expressions]: expressions/closure-expr.md
108109
[comparison]: expressions/operator-expr.md#comparison-operators
110+
[const block]: expressions/block-expr.md#const-blocks
109111
[const functions]: items/functions.md#const-functions
110112
[const generic argument]: items/generics.md#const-generics
111113
[const generic parameters]: items/generics.md#const-generics

src/expressions.md

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup>[](#expression-attributes)\
3636
> &nbsp;&nbsp; (\
3737
> &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; [_BlockExpression_]\
38+
> &nbsp;&nbsp; &nbsp;&nbsp; | [_ConstBlockExpression_]\
3839
> &nbsp;&nbsp; &nbsp;&nbsp; | [_UnsafeBlockExpression_]\
3940
> &nbsp;&nbsp; &nbsp;&nbsp; | [_LoopExpression_]\
4041
> &nbsp;&nbsp; &nbsp;&nbsp; | [_IfExpression_]\
@@ -311,6 +312,7 @@ They are never allowed before:
311312
[_ClosureExpression_]: expressions/closure-expr.md
312313
[_ComparisonExpression_]: expressions/operator-expr.md#comparison-operators
313314
[_CompoundAssignmentExpression_]: expressions/operator-expr.md#compound-assignment-expressions
315+
[_ConstBlockExpression_]: expressions/block-expr.md#const-blocks
314316
[_ContinueExpression_]: expressions/loop-expr.md#continue-expressions
315317
[_FieldExpression_]: expressions/field-expr.md
316318
[_GroupedExpression_]: expressions/grouped-expr.md

src/expressions/block-expr.md

+40
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,44 @@ loop {
117117
}
118118
```
119119
120+
## `const` blocks
121+
122+
> **<sup>Syntax</sup>**\
123+
> _ConstBlockExpression_ :\
124+
> &nbsp;&nbsp; `const` _BlockExpression_
125+
126+
A *const block* is a variant of a block expression which evaluates in the compile time instead of in the run time.
127+
128+
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*.
129+
It also supports type inference so there is no need to specify the type, unlike [constant items].
130+
131+
Const blocks have 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.
133+
For example, this code:
134+
135+
```rust
136+
fn foo<T>() -> usize {
137+
const { std::mem::size_of::<T>() + 1 }
138+
}
139+
```
140+
141+
is equivalent to:
142+
143+
```rust
144+
fn foo<T>() -> usize {
145+
{
146+
struct Const<T>(T);
147+
impl<T> Const<T> {
148+
const CONST: usize = std::mem::size_of::<T>() + 1;
149+
}
150+
Const::<T>::CONST
151+
}
152+
}
153+
```
154+
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.
157+
120158
## `unsafe` blocks
121159

122160
> **<sup>Syntax</sup>**\
@@ -181,6 +219,8 @@ fn is_unix_platform() -> bool {
181219
[array expressions]: array-expr.md
182220
[call expressions]: call-expr.md
183221
[capture modes]: ../types/closure.md#capture-modes
222+
[constant items]: ../items/constant-items.md
223+
[free item]: ../glossory.md#free-item
184224
[function]: ../items/functions.md
185225
[inner attributes]: ../attributes.md
186226
[method]: ../items/associated-items.md#methods

src/macros-by-example.md

+2
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ For reasons of backwards compatibility, though `_` [is also an
146146
expression][_UnderscoreExpression_], a standalone underscore is not matched by
147147
the `expr` fragment specifier. However, `_` is matched by the `expr` fragment
148148
specifier when it appears as a subexpression.
149+
For the same reason, a standalone [const block] is not matched but it is matched when appearing as a subexpression.
149150

150151
> **Edition Differences**: Starting with the 2021 edition, `pat` fragment-specifiers match top-level or-patterns (that is, they accept [_Pattern_]).
151152
>
@@ -492,6 +493,7 @@ expansions, taking separators into account. This means:
492493

493494
For more detail, see the [formal specification].
494495

496+
[const block]: expressions/block-expr.md#const-blocks
495497
[Hygiene]: #hygiene
496498
[IDENTIFIER]: identifiers.md
497499
[IDENTIFIER_OR_KEYWORD]: identifiers.md

0 commit comments

Comments
 (0)