|
| 1 | +# cg meeting 2021-02-23 ([zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/260443-project-const-generics/topic/meeting.202021-02-23)) |
| 2 | + |
| 3 | +## anon consts in where bounds |
| 4 | + |
| 5 | +with anon consts being inside of their own where-bounds (since they inherit where bounds from their parent item) they can quite easily cause cycle errors (https://github.com/rust-lang/rust/issues/79356): |
| 6 | +```rust |
| 7 | +#![feature(const_generics)] |
| 8 | +struct Foo<T>(T); |
| 9 | + |
| 10 | +fn test() where [u8; { |
| 11 | + // `Foo<X>` requires `X: Sized`. |
| 12 | + // |
| 13 | + // We have a `[u8; unevaluated]: Sized` predicate in the |
| 14 | + // where bounds, we try to unify `[u8; 7]` with that array, |
| 15 | + // causing a cycle. |
| 16 | + // |
| 17 | + // We prioritize candidates from the where-bounds over global ones |
| 18 | + // which is why we don't just use the builtin candidate for `array: Sized`. |
| 19 | + let _: Foo<[u8; 7]>; |
| 20 | + 3 |
| 21 | +}]: Sized {} |
| 22 | +``` |
| 23 | +we can't just remove any bounds containing the anon const itself, as this wouldn't prevent cycles for |
| 24 | +```rust |
| 25 | +#![feature(const_generics)] |
| 26 | +struct Foo<T>(T); |
| 27 | + |
| 28 | +fn test() where [u8; { |
| 29 | + let _: Foo<[u8; 7]>; |
| 30 | + 3 |
| 31 | +}]: Sized, |
| 32 | +[u8; { |
| 33 | + let _: Foo<[u8; 7]>; |
| 34 | + 4 |
| 35 | +}]: Sized {} |
| 36 | +``` |
| 37 | + |
| 38 | +### Can we just not worry about this while stabilizing lazy norm |
| 39 | + |
| 40 | +I think just removing bounds containing the anon const itseft might not be an issue, as using that predicate probably caused a cycle so there won't be any code relying on this. Removing additional predicates which might cycle is a lot scarier and probably not possible after we stabilized lazy norm. |
| 41 | + |
| 42 | +Even if we can fix this without breaking back-compat, the user experience when encountering cycle errors is probably bad enough for us to still fix this first. |
| 43 | +These cycles happen for code currently compiling on stable, so this would also require a crater run. |
| 44 | + |
| 45 | +### the cycle |
| 46 | + |
| 47 | +``` |
| 48 | +error[E0391]: cycle detected when simplifying constant for the type system `test::{constant#0}` |
| 49 | + --> src/lib.rs:4:22 |
| 50 | + | |
| 51 | +4 | fn test() where [u8; { |
| 52 | + | ______________________^ |
| 53 | +5 | | // `Foo<X>` requires `X: Sized`. |
| 54 | +6 | | // |
| 55 | +7 | | // We have a `[u8; unevaluated]: Sized` predicate in the |
| 56 | +... | |
| 57 | +11 | | 3 |
| 58 | +12 | | }]: Sized {} |
| 59 | + | |_^ |
| 60 | + | |
| 61 | +note: ...which requires const-evaluating + checking `test::{constant#0}`... |
| 62 | + --> src/lib.rs:4:22 |
| 63 | + | |
| 64 | +4 | fn test() where [u8; { |
| 65 | + | ______________________^ |
| 66 | +5 | | // `Foo<X>` requires `X: Sized`. |
| 67 | +6 | | // |
| 68 | +7 | | // We have a `[u8; unevaluated]: Sized` predicate in the |
| 69 | +... | |
| 70 | +11 | | 3 |
| 71 | +12 | | }]: Sized {} |
| 72 | + | |_^ |
| 73 | +note: ...which requires type-checking `test::{constant#0}`... |
| 74 | + --> src/lib.rs:4:22 |
| 75 | + | |
| 76 | +4 | fn test() where [u8; { |
| 77 | + | ______________________^ |
| 78 | +5 | | // `Foo<X>` requires `X: Sized`. |
| 79 | +6 | | // |
| 80 | +7 | | // We have a `[u8; unevaluated]: Sized` predicate in the |
| 81 | +... | |
| 82 | +11 | | 3 |
| 83 | +12 | | }]: Sized {} |
| 84 | + | |_^ |
| 85 | + = note: ...which requires evaluating trait selection obligation `[u8; 7]: std::marker::Sized`... |
| 86 | + = note: ...which again requires simplifying constant for the type system `test::{constant#0}`, completing the cycle |
| 87 | + ``` |
| 88 | + |
| 89 | +### Results |
| 90 | + |
| 91 | +Using chalk we can solve this by allowing our query system to deal with cycles by trying something different when encountering them. This still has some open problems and is probably still somewhat far in the future. |
| 92 | + |
| 93 | +We did not have other promising ideas on how to otherwise solve this without being too restrictive. |
| 94 | + |
| 95 | +Requires some additional thought outside of the meeting. |
0 commit comments