From fea824e740ab7997de4795e66eb7947c47bedb93 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 21 Mar 2022 20:08:20 +0100 Subject: [PATCH 1/2] update section for type system constants --- src/constants.md | 48 ++++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/src/constants.md b/src/constants.md index 30c0da736..af8e863ad 100644 --- a/src/constants.md +++ b/src/constants.md @@ -16,6 +16,32 @@ or a generic parameter, e.g. `[u8; N]`, converting a constant to its [`ty::Const returns an unevaluated constant. Even fully concrete constants which do not depend on generic parameters are not evaluated right away. +Anonymous constants are typechecked separately from their containing item, e.g. +```rust +fn foo() -> [u8; N + 1] { + [0; N + 1] +} +``` +is treated as +```rust +const ANON_CONST_1 = N + 1; +const ANON_CONST_2 = N + 1; +fn foo() -> [u8; ANON_CONST_1::] { + [0; ANON_CONST_2::] +} +``` + +### Unifying constants + +For the compiler, `ANON_CONST_1` and `ANON_CONST_2` are completely different, so +we have to somehow look into unevaluated constants to check whether they should +unify. + +For this we use [InferCtxt::try_unify_abstract_consts](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html#method.try_unify_abstract_consts). This builds a custom AST for the two inputs from their THIR. Thish is then used for +the actual comparison. + +### Lazy normalization for constants + We do not eagerly evaluate constant as they can be used in the `where`-clauses of their parent item, for example: @@ -32,7 +58,7 @@ its parents caller bounds, but is also part of another bound itself. If we were to eagerly evaluate this constant while computing its parents bounds this would cause a query cycle. -### Generic arguments of anonymous constants +### Unused generic arguments of anonymous constants Anonymous constants inherit the generic parameters of their parent, which is why the array length in `foo() -> [u8; N + 1]` can use `N`. @@ -41,25 +67,7 @@ Without any manual adjustments, this causes us to include parameters even if the constant doesn't use them in any way. This can cause [some interesting errors][pcg-unused-substs] and breaks some already stable code. -To deal with this, we intend to look at the generic parameters explicitly mentioned -by the constants and then search the predicates of its parents to figure out which -of the other generic parameters are reachable by our constant. - -**TODO**: Expand this section once the parameter filtering is implemented. - -As constants can be part of their parents `where`-clauses, we mention unevaluated -constants in their parents predicates. It is therefore necessary to mention unevaluated -constants before we have computed the generic parameters -available to these constants. - -To do this unevaluated constants start out with [`substs_`] being `None` while assuming -that their generic arguments could be arbitrary generic parameters. -When first accessing the generic arguments of an unevaluated constants, we then replace -`substs_` with the actual default arguments of a constants, which are the generic parameters -of their parent we assume to be used by this constant. - [`ty::Const`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Const.html [`ty::ConstKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.ConstKind.html [`ty::TyKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html -[pcg-unused-substs]: https://github.com/rust-lang/project-const-generics/blob/master/design-docs/anon-const-substs.md#unused-substs -[`substs_`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/consts/kind/struct.Unevaluated.html#structfield.substs_ \ No newline at end of file +[pcg-unused-substs]: https://github.com/rust-lang/project-const-generics/blob/master/design-docs/anon-const-substs.md#unused-substs \ No newline at end of file From c487fc9eba0ad7448b454a8a4ea190d550fa4b5c Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 22 Mar 2022 14:33:12 +0100 Subject: [PATCH 2/2] Update src/constants.md --- src/constants.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/constants.md b/src/constants.md index af8e863ad..0b3becec3 100644 --- a/src/constants.md +++ b/src/constants.md @@ -37,7 +37,8 @@ For the compiler, `ANON_CONST_1` and `ANON_CONST_2` are completely different, so we have to somehow look into unevaluated constants to check whether they should unify. -For this we use [InferCtxt::try_unify_abstract_consts](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html#method.try_unify_abstract_consts). This builds a custom AST for the two inputs from their THIR. Thish is then used for +For this we use [InferCtxt::try_unify_abstract_consts](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html#method.try_unify_abstract_consts). +This builds a custom AST for the two inputs from their THIR. This is then used for the actual comparison. ### Lazy normalization for constants