From cf06f4a7e30381c5426e537673d6232c042da049 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Thu, 27 Jan 2022 15:00:27 -0500 Subject: [PATCH 1/3] Don't implicitly talk about free constant CTFE timing @RalfJung pointed out in a [comment] that the previous phrasing of the sentence can read like it is giving guarantees about free constant definitions always undergoing CTFE, even when unused. That seems to be how the compiler behaves right now, but it's unclear whether it's intentional. Be more precise and don't talk about free constants at all. [comment]: https://github.com/rust-lang/reference/pull/1120#discussion_r791928575 --- src/items/associated-items.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/items/associated-items.md b/src/items/associated-items.md index 68e5de163..eab9aee56 100644 --- a/src/items/associated-items.md +++ b/src/items/associated-items.md @@ -293,8 +293,8 @@ type that the definition has to implement. An *associated constant definition* defines a constant associated with a type. It is written the same as a [constant item]. -Unlike [free] constants, associated constant definitions undergo -[constant evaluation] only when referenced. +Associated constant definitions undergo [constant evaluation] only when +referenced. ```rust struct Struct; @@ -381,5 +381,4 @@ fn main() { [regular function parameters]: functions.md#attributes-on-function-parameters [generic parameters]: generics.md [where clauses]: generics.md#where-clauses -[free]: ../glossary.md#free-item [constant evaluation]: ../const_eval.md From d0b33a2990c305e8793a2e53dbc77b6edec1b018 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Sat, 5 Feb 2022 10:10:47 -0500 Subject: [PATCH 2/3] Mention associated const CTFE interactions with generics --- src/items/associated-items.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/items/associated-items.md b/src/items/associated-items.md index eab9aee56..4552b5491 100644 --- a/src/items/associated-items.md +++ b/src/items/associated-items.md @@ -294,7 +294,8 @@ An *associated constant definition* defines a constant associated with a type. It is written the same as a [constant item]. Associated constant definitions undergo [constant evaluation] only when -referenced. +referenced. Further, definitions that include [generic parameters] are +evaluated after monomorphization. ```rust struct Struct; From 37e3c15c52b31f3cda9fd359d3bb66a3e69bb5ff Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Sat, 5 Feb 2022 10:14:42 -0500 Subject: [PATCH 3/3] Use generics in associated const CTFE timing example This makes the example a bit bigger, but makes the reason why constants don't immediately undergo CTFE more conspicuous. When there is computation in the definition that use generic parameters, there is not enough information to fully evaluate the definition eagerly. I made it a `compile_fail` example so the run button on the page gives reader useful outputs. --- src/items/associated-items.md | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/items/associated-items.md b/src/items/associated-items.md index 4552b5491..f5dc31aae 100644 --- a/src/items/associated-items.md +++ b/src/items/associated-items.md @@ -297,19 +297,31 @@ Associated constant definitions undergo [constant evaluation] only when referenced. Further, definitions that include [generic parameters] are evaluated after monomorphization. -```rust +```rust,compile_fail struct Struct; +struct GenericStruct; impl Struct { - const ID: i32 = 1; // Definition not immediately evaluated const PANIC: () = panic!("compile-time panic"); } +impl GenericStruct { + // Definition not immediately evaluated + const NON_ZERO: () = if ID == 0 { + panic!("contradiction") + }; +} + fn main() { - assert_eq!(1, Struct::ID); // Referencing Struct::PANIC causes compilation error - // let _ = Struct::PANIC; + let _ = Struct::PANIC; + + // Fine, ID is not 0 + let _ = GenericStruct::<1>::NON_ZERO; + + // Compilation error from evaluating NON_ZERO with ID=0 + let _ = GenericStruct::<0>::NON_ZERO; } ```