From a9549b0c613442f3269c68be96bc4a703de79d65 Mon Sep 17 00:00:00 2001 From: "Joshua J. Cogliati" Date: Thu, 3 Sep 2020 20:05:54 -0600 Subject: [PATCH 1/3] Rust 1.46 now allows more features in const fn --- src/items/functions.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/items/functions.md b/src/items/functions.md index 138f1169e..855b77b62 100644 --- a/src/items/functions.md +++ b/src/items/functions.md @@ -223,15 +223,16 @@ Exhaustive list of permitted structures in const functions: 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. +* All boolean operators including `&&` and `||` * 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 +* `if`, `if let`, and `match` +* `while`, `while let`, and `loop` +* Casts except for raw pointer to integer casts and cast to slice * `unsafe` blocks and `const unsafe fn` are allowed, but the body/block may only do the following unsafe operations: * calls to const unsafe functions From 7ad799da00dd162638999e38dad10905bf6c7ec6 Mon Sep 17 00:00:00 2001 From: "Joshua J. Cogliati" Date: Mon, 7 Sep 2020 11:13:55 -0600 Subject: [PATCH 2/3] Moving text to const_eval from functions. --- src/const_eval.md | 19 ++++++++++++++- src/items/functions.md | 55 +++--------------------------------------- 2 files changed, 21 insertions(+), 53 deletions(-) diff --git a/src/const_eval.md b/src/const_eval.md index 2c4fbe9ba..b3d087f32 100644 --- a/src/const_eval.md +++ b/src/const_eval.md @@ -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: diff --git a/src/items/functions.md b/src/items/functions.md index 855b77b62..1df72d2b8 100644 --- a/src/items/functions.md +++ b/src/items/functions.md @@ -183,59 +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 ``, ``, and `` - 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 including `&&` and `||` -* 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) -* `if`, `if let`, and `match` -* `while`, `while let`, and `loop` -* Casts except for raw pointer to integer casts and cast to slice -* `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 @@ -397,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 From 6dceee14cd895247c3a272086798083e35b31d06 Mon Sep 17 00:00:00 2001 From: "Joshua J. Cogliati" Date: Wed, 9 Sep 2020 18:32:09 -0600 Subject: [PATCH 3/3] Removing dangling references. --- src/items/functions.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/items/functions.md b/src/items/functions.md index 1df72d2b8..15b8cc10b 100644 --- a/src/items/functions.md +++ b/src/items/functions.md @@ -368,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