From 5e401daf2c62a6dd2153bcd6d07d536ce00318ea Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 21 Mar 2022 18:35:00 +0100 Subject: [PATCH] uwu a list of all the issues --- SUMMARY.md | 13 +- design-docs/README.md | 3 - design-docs/anon-const-substs.md | 113 ------------------ design-docs/const-eval-requirements.md | 14 --- design/README.md | 86 +++++++++++++ design/const-eval-requirements.md | 22 ++++ design/constraining-generic-parameters.md | 27 +++++ design/exhaustiveness.md | 15 +++ design/functions-as-const-parameters.md | 17 +++ .../generic-const-param-types.md | 8 +- design/structural-equality.md | 7 ++ design/valid-const-parameter-types.md | 9 ++ design/valtrees.md | 11 ++ 13 files changed, 209 insertions(+), 136 deletions(-) delete mode 100644 design-docs/README.md delete mode 100644 design-docs/anon-const-substs.md delete mode 100644 design-docs/const-eval-requirements.md create mode 100644 design/README.md create mode 100644 design/const-eval-requirements.md create mode 100644 design/constraining-generic-parameters.md create mode 100644 design/exhaustiveness.md create mode 100644 design/functions-as-const-parameters.md rename {design-docs => design}/generic-const-param-types.md (86%) create mode 100644 design/structural-equality.md create mode 100644 design/valid-const-parameter-types.md create mode 100644 design/valtrees.md diff --git a/SUMMARY.md b/SUMMARY.md index e8c28eb..a2d5de4 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -17,9 +17,14 @@ - [📅 Roadmap for 2021](./vision/roadmap.md) - [❓How to vision doc](./vision/how_to_vision_doc.md) - [🔍 Meetings](./meetings/README.md) -- [📚 Design Documents](./design-docs/README.md) - - [Anon const substs](./design-docs/anon-const-substs.md) - - [Const eval requirements](./design-docs/const-eval-requirements.md) - - [Generic const param types](./design-docs/generic-const-param-types.md) +- [📚 Design](./design/README.md) + - [❗ Constraining generic parameters](./design/constraining-generic-parameters.md) + - [❗⚖️🔄 Generic const parameter types](./design/generic-const-param-types.md) + - [❗🔙 Restrictions on const evaluation](./design/const-eval-requirements.md) + - [❗🔙 ⚖️ Structural equality](./design/structural-equality.md) + - [❗⚖️ Valid const parameter types](./design/valid-const-parameter-types.md) + - [❗ Valtrees](./design/valtrees.md) + - [❔ Exhaustiveness](./design/exhaustiveness.md) + - [❔🔙 Functions as const parameters](./design/functions-as-const-parameters.md) - [✏️ Draft RFCs](./draft-rfcs/README.md) s \ No newline at end of file diff --git a/design-docs/README.md b/design-docs/README.md deleted file mode 100644 index c024cfc..0000000 --- a/design-docs/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Design documents - -This folder contains implementation and design considerations about const generics. \ No newline at end of file diff --git a/design-docs/anon-const-substs.md b/design-docs/anon-const-substs.md deleted file mode 100644 index 77785cc..0000000 --- a/design-docs/anon-const-substs.md +++ /dev/null @@ -1,113 +0,0 @@ -# Anon consts substs - -Currently locked behind `feature(generic_const_exprs)`, we do not supply anonymous constants -with their parents generics. - -Doing so is needed if we want to ever support more complex generic expressions in anonymous constants. - -## Known blockers - -Unless said otherwise, "currently" means "with `feature(generic_const_exprs)` enabled" for the rest of this document. - -### Unused substs - -Anon consts currently inherit all of their parents generic parameters. This breaks code already compiling on stable and causes unexpected compilation failures: - -[#78369](https://github.com/rust-lang/rust/issues/78369) -```rust -#![feature(generic_const_exprs)] -struct P([u8; 1 + 4], T); - -fn main() { - let x: Box> = Box::new(P(Default::default(), [0; 0])); - let _: Box> = x; //~ ERROR mismatched types -} -``` -const occurs check (with [#81351](https://github.com/rust-lang/rust/pull/81351)): -```rust -#![feature(lazy_normalization_consts)] - -fn bind(value: [u8; N]) -> [u8; 3 + 4] { - todo!() -} - -fn main() { - let mut arr = Default::default(); - arr = bind(arr); //~ ERROR mismatched type -} -``` - -#### Status - -Discussed in the following meetings: [2021.02.09](../meetings/2021.02.09-lazy-norm.md), [2021.02.16](../meetings/2021.02.16-lazy-norm.md), [2021.03.09](../meetings/2021.03.09-unused-substs-impl.md) - -A potential solution has been merged with [#87280](https://github.com/rust-lang/rust/pull/87280) and reverted in [#92805](https://github.com/rust-lang/rust/pull/92805) as the required changes negatively impacted large parts of the compiler, even these unrelated to const generics. A potentially nicer solution would be to forbid all parameters which aren't explicitly mentioned by anonymous constants. It isn't yet clear how to best implement this. - -### Consts in where bounds can reference themselves - -This causes query cycles for code that should compile and already compiles on stable - -[#79356](https://github.com/rust-lang/rust/issues/79356) -```rust -#![feature(generic_const_exprs)] - -struct Foo(T); - -fn test() where [u8; { - let _: Foo<[u8; 3 + 4]>; - 3 -}]: Sized {} -``` -#### Status - -Discussed in the following meetings: [2021.02.23](../meetings/2021.02.23-ct-in-where-bounds.md) - -Not yet solved, potentially fixed by improving the query/trait system to deal with cycles. Maybe blocked on *chalk*. - -### Consts in where clauses are executed with inconsistent substs - -We evaluate consts in where clauses without first proving the where clauses of the const itself, potentially causing ICE. - -```rust -#![feature(generic_const_exprs)] - -trait Foo { - type Assoc; - const ASSOC: ::Assoc; -} - -impl Foo for i32 { - type Assoc = i64; - const ASSOC: i64 = 3; -} - -const fn bar(x: T) -> usize { - std::mem::forget(x); - 3 -} - -fn foo() where - T: Foo, - [u8; bar::(::ASSOC)]: Sized, -{} - -fn main() { - foo::(); -} -``` - -#### Status - -Discussed in the following meetings: [2021.03.23](../meetings/2021.03.23-ct-in-where-bounds.md) - -Probably solved by retypechecking the MIR of anonymous constants before const evaluating them. -Therefore waiting on implementation work. - - - - - - - - - diff --git a/design-docs/const-eval-requirements.md b/design-docs/const-eval-requirements.md deleted file mode 100644 index 7a357a2..0000000 --- a/design-docs/const-eval-requirements.md +++ /dev/null @@ -1,14 +0,0 @@ -# Const eval requirements - -For this to work, const operations have to be deterministic and -must not depend on any external state, -at least when they are used in the type system. - -Using floats during CTFE is fully determinstic. So using -them inside of the type system is fine. CTFE can however -produce different results than what would happen on real hardware, -but this is not a concern for const generics. - -Other sources of non-determinism are allocations. This non-determinism -must however not be observed during const-evaluation (TODO: link to const-eval). -Any references used in a constant are considered equal if their targets are equal, which is also determistic. (ref [val-trees](https://github.com/rust-lang/rust/issues/72396)) \ No newline at end of file diff --git a/design/README.md b/design/README.md new file mode 100644 index 0000000..c46c3f7 --- /dev/null +++ b/design/README.md @@ -0,0 +1,86 @@ +# 📚 Design + +For an explanation of how const generics currently works in the compiler, +also check out the [rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/constants.html). + + +Const generics has quite a few deep rooted issues and design challenges. +In this document we try to highlight some specific topics which are fairly +pervasive while working on this feature. + +### 🔙 Backwards compatability + +Rust was not design with const generics in mind, and we've also made +some unfortunate decisions even after work on const generics started. + +Future extensions of const generics must not cause substantial breakage +to existing code, or if they do, this breakage has to be contained somehow. +A possible solution to many such changes are editions. + +### ⚖️ No perfect solution + +There isn't just one *perfect* version of const generics we are working towards. +Instead there are a lot of major and minor tradeoffs between learnability, expressiveness, +implementation complexity and many other factors. As we can't perfectly tell how +const generics will be used in the future, making these decisions can be especially +hard. For any such issues we should try to reach out to the wider community before +coming to a final conclusion. + +### 🔄 The query system + +Const generics mixes evaluation with typechecking which very quickly reaches the edge +of what is possible with the query system. It might make sense to look at these issues in +unison and consider whether there are some more fundamental changes to the compiler which +provide a better solution to them instead of [adding more hacks](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.WithOptConstParam.html). + +### ❔ Optional extensions + +There are a lot of things which are nice to have but not strictly necessary or maybe not even +desirable. This means that decisions which prevents them may still be the correct ones, +i.e. these are not strictly a blocking concern. +We should still try to find alternatives before blocking these though. + +## Const parameter types ([`adt_const_params`](https://github.com/rust-lang/rust/issues/95174)) + +On stable, only integers, `bool`, and `char` is allowed as the type of const parameters. +We want to extend this to more types in the future. +```rust +struct NamedType { ... } +``` + +Additionally, we want to support generic const parameter types and must not stabilize anything +which prevents the addition of that in the future. +```rust +struct WithGenericArray { ... } +``` + +This feature interacts with the following topics: + +- [❗ Constraining generic parameters](./design/constraining-generic-parameters.html) +- [❗🔙 ⚖️ Structural equality](./design/structural-equality.html) +- [❗⚖️ Valid const parameter types](./design/valid-const-parameter-types.html) +- [❗ Valtrees](./design/valtrees.html) +- [❗⚖️🔄 Generic const parameter types](./design/generic-const-param-types.html) +- [❔ Exhaustiveness](./design/exhaustiveness.html) +- [❔🔙 Functions as const parameters](./design/functions-as-const-parameters.html) + +## Generic constants in the type system ([`generic_const_exprs`](https://github.com/rust-lang/rust/issues/76560)) + +- ❗🔙 🔄 Unused substs +- ❗🔄 Self referential where clauses +- ❗🔄 Evaluation without first checking where-clauses +### Unifying generic constants + +- [❗🔙 Restrictions on const evaluation](./design/const-eval-requirements.html) +- ❗ Do not leak implementation details +- ❗ Splitting constants during unification +- [❗ Constraining generic parameters](./design/constraining-generic-parameters.html) +- ❔⚖️ Extending unification logic + +### Const evaluatable bounds + +ALL OF THIS + +## Repeat length backcompatability lint ([`const_evaluatable_unchecked`](https://github.com/rust-lang/rust/issues/76200)) + +close this or wait until it's possible on stable. diff --git a/design/const-eval-requirements.md b/design/const-eval-requirements.md new file mode 100644 index 0000000..781e203 --- /dev/null +++ b/design/const-eval-requirements.md @@ -0,0 +1,22 @@ +# ❗🔙 Restrictions on const evaluation + +For generic constants in the type system to be sound, const evaluation must +not be able to differentiate between values considered equal by the type system. +Const evaluation must also be fully deterministic and must not depend on any external state +when used in the type system. + +## Floats + +Using floats during CTFE is fully determinstic. So using +them inside of the type system is fine. CTFE can however +produce different results than what would happen on real hardware, +but this is not a concern for const generics. + +## Dealing with references and allocations + +Other sources of non-determinism are allocations. This non-determinism +must however not be observed during const-evaluation (TODO: link to const-eval). + +Any references used in a constant are considered equal if their targets are equal, which is also determistic. +This is needed by [valtrees](./design/valtrees.html). The specific design of valtrees also adds some other +additional constraints to const evaluation which are listed on its page. diff --git a/design/constraining-generic-parameters.md b/design/constraining-generic-parameters.md new file mode 100644 index 0000000..a203770 --- /dev/null +++ b/design/constraining-generic-parameters.md @@ -0,0 +1,27 @@ +# ❗ Constraining generic parameters + +Given an impl, the compiler has to be able to decide the generic arguments used by that impl. +Consider the following snippet: + +```rust +struct Weird; + +impl Weird<{ A + B }> { + fn returns_a() -> usize { + A + } +} +``` + +When calling `Weird::<3>::returns_a()`, there is no way to restrict the generic parameters `A` or `B` so this has to error. +If a generic parameter is used by an injective expression, then we should allow this. The most relevant case here are +constructors: +```rust +struct UsesOption>; +impl UsesOption<{ Some(N) }> {} +``` +Here it is very clear which `N` we should use given `UsesOption::<{ Some(3) }>`. + +## Current status + +**Blocked**: Before making any decisions here we should first figure out [structural equality](./design/structural-equality.md) diff --git a/design/exhaustiveness.md b/design/exhaustiveness.md new file mode 100644 index 0000000..cd96311 --- /dev/null +++ b/design/exhaustiveness.md @@ -0,0 +1,15 @@ +# ❔ Exhaustiveness + +Whether we want to be able to unify different partial impls to consider them exhaustive. + +```rust +trait ForBool {} + +impl ForBool for u8 {} +impl ForBool for u8 {} +// Does `for u8: ForBool` hold? +``` + +## Status + +**Idle**: While not blocked, it may make sense to wait until we are able to [constrain generic parameters](./design/constraining-generic-parameters.html). \ No newline at end of file diff --git a/design/functions-as-const-parameters.md b/design/functions-as-const-parameters.md new file mode 100644 index 0000000..bb0f65b --- /dev/null +++ b/design/functions-as-const-parameters.md @@ -0,0 +1,17 @@ +# ❔🔙 Functions as const parameters + +**[project-const-generics#7](https://github.com/rust-lang/project-const-generics/issues/7)** + +It would be nice to allow function pointers as const parameter types. + +```rust +fn foo usize>() {} +``` + +While they do have a sensible definition of structural equality at compile time, +comparing them is not deterministic at runtime. This behavior might be fairly surprising, +so it might be better to not allow this. + +## Current status + +**Planning/Blocked**: needs `generic_const_exprs` to be closer to stable before it makes sense to start working on this. diff --git a/design-docs/generic-const-param-types.md b/design/generic-const-param-types.md similarity index 86% rename from design-docs/generic-const-param-types.md rename to design/generic-const-param-types.md index e975af2..d9ebd8b 100644 --- a/design-docs/generic-const-param-types.md +++ b/design/generic-const-param-types.md @@ -1,4 +1,4 @@ -# Generic const param types +# ❗⚖️🔄 Generic const parameter types We want to support the types of const parameters to depend on other generic parameters. @@ -33,4 +33,8 @@ break stuff. Potential dangers include partially resolved types and projections. -[WithOptConstParam]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.WithOptConstParam.html \ No newline at end of file +[WithOptConstParam]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.WithOptConstParam.html + +## Status + +**Blocked**: We should first stabilize `feature(adt_const_params)`. diff --git a/design/structural-equality.md b/design/structural-equality.md new file mode 100644 index 0000000..7ee5a83 --- /dev/null +++ b/design/structural-equality.md @@ -0,0 +1,7 @@ +# ❗🔙 ⚖️ Structural equality + +We have to figure out which values and types can be sensibly compared at compile time. + +## Status + +**In progress**: [lcnr](https://github.com/lcnr/) is working on this. diff --git a/design/valid-const-parameter-types.md b/design/valid-const-parameter-types.md new file mode 100644 index 0000000..9cd2e04 --- /dev/null +++ b/design/valid-const-parameter-types.md @@ -0,0 +1,9 @@ +# ❗⚖️ Valid const parameter types + +**[project-const-generics#6](https://github.com/rust-lang/project-const-generics/issues/6)** + +We have to decide which types may be used as a const parameter and whether there needs to be explicit opt-in. + +## Status + +**Blocked**: Waiting on [structural equality](./design/structural-equality.html). diff --git a/design/valtrees.md b/design/valtrees.md new file mode 100644 index 0000000..935ea89 --- /dev/null +++ b/design/valtrees.md @@ -0,0 +1,11 @@ +# ❗ Valtrees + +A new representation for `ty::Const`. + +## ❗ Figure out how they interact with references wrt padding + +**[project-const-generics#20](https://github.com/rust-lang/project-const-generics/issues/20)** + +## Status + +**In Progress**: [b-naber](https://github.com/rust-lang/project-const-generics/issues/20) is working on this.