Skip to content

Commit

Permalink
Add const blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
nbdd0121 committed Apr 29, 2024
1 parent 5181795 commit 01c8196
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/const_eval.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ to be run.
* [Tuple expressions].
* [Array expressions].
* [Struct] expressions.
* [Block expressions], including `unsafe` blocks.
* [Block expressions], including `unsafe` and `const` blocks.
* [let statements] and thus irrefutable [patterns], including mutable bindings
* [assignment expressions]
* [compound assignment expressions]
Expand Down Expand Up @@ -59,6 +59,7 @@ A _const context_ is one of the following:
* [statics]
* [enum discriminants]
* A [const generic argument]
* A [const block]

## Const Functions

Expand Down Expand Up @@ -106,6 +107,7 @@ Conversely, the following are possible in a const function, but not in a const c
[cast]: expressions/operator-expr.md#type-cast-expressions
[closure expressions]: expressions/closure-expr.md
[comparison]: expressions/operator-expr.md#comparison-operators
[const block]: expressions/block-expr.md#const-blocks
[const functions]: items/functions.md#const-functions
[const generic argument]: items/generics.md#const-generics
[const generic parameters]: items/generics.md#const-generics
Expand Down
2 changes: 2 additions & 0 deletions src/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup>[](#expression-attributes)\
> &nbsp;&nbsp; (\
> &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; [_BlockExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_ConstBlockExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_UnsafeBlockExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_LoopExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_IfExpression_]\
Expand Down Expand Up @@ -311,6 +312,7 @@ They are never allowed before:
[_ClosureExpression_]: expressions/closure-expr.md
[_ComparisonExpression_]: expressions/operator-expr.md#comparison-operators
[_CompoundAssignmentExpression_]: expressions/operator-expr.md#compound-assignment-expressions
[_ConstBlockExpression_]: expressions/block-expr.md#const-blocks
[_ContinueExpression_]: expressions/loop-expr.md#continue-expressions
[_FieldExpression_]: expressions/field-expr.md
[_GroupedExpression_]: expressions/grouped-expr.md
Expand Down
40 changes: 40 additions & 0 deletions src/expressions/block-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,44 @@ loop {
}
```

## `const` blocks

> **<sup>Syntax</sup>**\
> _ConstBlockExpression_ :\
> &nbsp;&nbsp; `const` _BlockExpression_
A *const block* is a variant of a block expression which evaluates in the compile time instead of in the run time.

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 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.
For example, this code:

```rust
fn foo<T>() -> usize {
const { std::mem::size_of::<T>() + 1 }
}
```

is equivalent to:

```rust
fn foo<T>() -> usize {
{
struct Const<T>(T);
impl<T> Const<T> {
const CONST: usize = std::mem::size_of::<T>() + 1;
}
Const::<T>::CONST
}
}
```

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.

## `unsafe` blocks

> **<sup>Syntax</sup>**\
Expand Down Expand Up @@ -181,6 +219,8 @@ fn is_unix_platform() -> bool {
[array expressions]: array-expr.md
[call expressions]: call-expr.md
[capture modes]: ../types/closure.md#capture-modes
[constant items]: ../items/constant-items.md
[free item]: ../glossary.md#free-item
[function]: ../items/functions.md
[inner attributes]: ../attributes.md
[method]: ../items/associated-items.md#methods
Expand Down
2 changes: 2 additions & 0 deletions src/macros-by-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ For reasons of backwards compatibility, though `_` [is also an
expression][_UnderscoreExpression_], a standalone underscore is not matched by
the `expr` fragment specifier. However, `_` is matched by the `expr` fragment
specifier when it appears as a subexpression.
For the same reason, a standalone [const block] is not matched but it is matched when appearing as a subexpression.

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

For more detail, see the [formal specification].

[const block]: expressions/block-expr.md#const-blocks
[Hygiene]: #hygiene
[IDENTIFIER]: identifiers.md
[IDENTIFIER_OR_KEYWORD]: identifiers.md
Expand Down

0 comments on commit 01c8196

Please sign in to comment.