Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rust 1.46 now allows more features in const fn #883

Merged
merged 3 commits into from
Sep 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion src/const_eval.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,24 @@ A _const context_ is one of the following:

A _const fn_ is a function that one is permitted to call from a const context. Declaring a function
`const` has no effect on any existing uses, it only restricts the types that arguments and the
return type may use, as well as prevent various expressions from being used within it.
return type may use, as well as prevent various expressions from being used within it. You can freely do anything with a const function that
you can do with a regular function.

When called from a const context, the function is interpreted by the
compiler at compile time. The interpretation happens in the
environment of the compilation target and not the host. So `usize` is
`32` bits if you are compiling against a `32` bit system, irrelevant
of whether you are building on a `64` bit or a `32` bit system.

Const functions have various restrictions to make sure that they can be
evaluated at compile-time. It is, for example, not possible to write a random
number generator as a const function. Calling a const function at compile-time
will always yield the same result as calling it at runtime, even when called
multiple times. There's one exception to this rule: if you are doing complex
floating point operations in extreme situations, then you might get (very
slightly) different results. It is advisable to not make array lengths and enum
discriminants depend on floating point computations.


Notable features that const contexts have, but const fn haven't are:

Expand Down
57 changes: 3 additions & 54 deletions src/items/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,58 +183,9 @@ aborts the process by executing an illegal instruction.

## Const functions

Functions qualified with the `const` keyword are const functions, as are
Functions qualified with the `const` keyword are [const functions], as are
[tuple struct] and [tuple variant] constructors. _Const functions_ can be
called from within [const context]s. When called from a const context, the
function is interpreted by the compiler at compile time. The interpretation
happens in the environment of the compilation target and not the host. So
`usize` is `32` bits if you are compiling against a `32` bit system, irrelevant
of whether you are building on a `64` bit or a `32` bit system.

If a const function is called outside a [const context], it is indistinguishable
from any other function. You can freely do anything with a const function that
you can do with a regular function.

Const functions have various restrictions to make sure that they can be
evaluated at compile-time. It is, for example, not possible to write a random
number generator as a const function. Calling a const function at compile-time
will always yield the same result as calling it at runtime, even when called
multiple times. There's one exception to this rule: if you are doing complex
floating point operations in extreme situations, then you might get (very
slightly) different results. It is advisable to not make array lengths and enum
discriminants depend on floating point computations.

Exhaustive list of permitted structures in const functions:

> **Note**: this list is more restrictive than what you can write in
> regular constants

* Type parameters where the parameters only have any [trait bounds]
of the following kind:
* lifetimes
* `Sized` or [`?Sized`]

This means that `<T: 'a + ?Sized>`, `<T: 'b + Sized>`, and `<T>`
are all permitted.

This rule also applies to type parameters of impl blocks that
contain const methods.

This does not apply to tuple struct and tuple variant constructors.

* Arithmetic and comparison operators on integers
* All boolean operators except for `&&` and `||` which are banned since
they are short-circuiting.
* Any kind of aggregate constructor (array, `struct`, `enum`, tuple, ...)
* Calls to other *safe* const functions (whether by function call or method call)
* Index expressions on arrays and slices
* Field accesses on structs and tuples
* Reading from constants (but not statics, not even taking a reference to a static)
* `&` and `*` (only dereferencing of references, not raw pointers)
* Casts except for raw pointer to integer casts
* `unsafe` blocks and `const unsafe fn` are allowed, but the body/block may only do
the following unsafe operations:
* calls to const unsafe functions
called from within [const context]s.

## Async functions

Expand Down Expand Up @@ -396,6 +347,7 @@ fn foo_oof(#[some_inert_attribute] arg: u8) {
[_WhereClause_]: generics.md#where-clauses
[_OuterAttribute_]: ../attributes.md
[const context]: ../const_eval.md#const-context
[const functions]: ../const_eval.md#const-functions
[tuple struct]: structs.md
[tuple variant]: enumerations.md
[external block]: external-blocks.md
Expand All @@ -416,10 +368,7 @@ fn foo_oof(#[some_inert_attribute] arg: u8) {
[`doc`]: ../../rustdoc/the-doc-attribute.html
[`must_use`]: ../attributes/diagnostics.md#the-must_use-attribute
[patterns]: ../patterns.md
[`?Sized`]: ../trait-bounds.md#sized
[trait bounds]: ../trait-bounds.md
[`export_name`]: ../abi.md#the-export_name-attribute
[`link_section`]: ../abi.md#the-link_section-attribute
[`no_mangle`]: ../abi.md#the-no_mangle-attribute
[external_block_abi]: external-blocks.md#abi
[built-in attributes]: ../attributes.html#built-in-attributes-index