Skip to content

Commit b4eda3c

Browse files
authored
Create anon-const-substs.md
1 parent 5f95175 commit b4eda3c

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed

design-docs/anon-const-substs.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Anon consts substs
2+
3+
Currently locked behind `feature(lazy_normalization_consts)` or `feature(const_generics)`, we do not supply anonymous constants
4+
with their parents generics.
5+
6+
Doing so is needed if we want to ever support more complex generic expressions in anonymous constants.
7+
8+
## Known blockers
9+
10+
Unless said otherwise, "currently" means "with `feature(const_generics)` enabled" for the rest of this document.
11+
12+
### Unused substs
13+
14+
Anon consts currently inherit all of their parents generic parameters. This breaks code already compiling on stable and causes unexpected compilation failures:
15+
16+
[#78369](https://github.com/rust-lang/rust/issues/78369)
17+
```rust
18+
#![feature(lazy_normalization_consts)]
19+
struct P<T: ?Sized>([u8; 1 + 4], T);
20+
21+
fn main() {
22+
let x: Box<P<[u8; 0]>> = Box::new(P(Default::default(), [0; 0]));
23+
let _: Box<P<[u8]>> = x; //~ ERROR mismatched types
24+
}
25+
```
26+
const occurs check (with [#81351](https://github.com/rust-lang/rust/pull/81351)):
27+
```rust
28+
#![feature(lazy_normalization_consts)]
29+
30+
fn bind<const N: usize>(value: [u8; N]) -> [u8; 3 + 4] {
31+
todo!()
32+
}
33+
34+
fn main() {
35+
let mut arr = Default::default();
36+
arr = bind(arr); //~ ERROR mismatched type
37+
}
38+
```
39+
40+
#### Status
41+
42+
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)
43+
44+
A solution has been found and is currently getting implemented in [#83086](https://github.com/rust-lang/rust/pull/83086)
45+
46+
### Consts in where bounds can reference themselves
47+
48+
This causes query cycles for code that should compile and already compiles on stable
49+
50+
[#79356](https://github.com/rust-lang/rust/issues/79356)
51+
```rust
52+
#![feature(const_generics)]
53+
#![allow(incomplete_features)]
54+
55+
struct Foo<T>(T);
56+
57+
fn test() where [u8; {
58+
let _: Foo<[u8; 3 + 4]>;
59+
3
60+
}]: Sized {}
61+
```
62+
#### Status
63+
64+
Discussed in the following meetings: [2021.02.23](../meetings/2021.02.23-ct-in-where-bounds.md)
65+
66+
Not yet solved, potentially fixed by improving the query/trait system to deal with cycles. Maybe blocked on *chalk*.
67+
68+
### Consts in where clauses are executed with inconsistent substs
69+
70+
We evaluate consts in where clauses without first proving the where clauses of the const itself, potentially causing ICE.
71+
72+
```rust
73+
#![feature(const_generics, const_evaluatable_checked)]
74+
75+
trait Foo {
76+
type Assoc;
77+
const ASSOC: <Self as Foo>::Assoc;
78+
}
79+
80+
impl Foo for i32 {
81+
type Assoc = i64;
82+
const ASSOC: i64 = 3;
83+
}
84+
85+
const fn bar<T>(x: T) -> usize {
86+
std::mem::forget(x);
87+
3
88+
}
89+
90+
fn foo<T>() where
91+
T: Foo<Assoc = T>,
92+
[u8; bar::<T>(<T as Foo>::ASSOC)]: Sized,
93+
{}
94+
95+
fn main() {
96+
foo::<i32>();
97+
}
98+
```
99+
100+
#### Status
101+
102+
Discussed in the following meetings: [2021.03.23](../meetings/2021.03.23-ct-in-where-bounds.md)
103+
104+
Not yet solved, requires us to either change typeck to not evaluate constants without checking their
105+
where clauses or to stop assuming ctfe to only deal with well typed MIR.
106+
107+
108+
109+
110+
111+
112+
113+
114+

0 commit comments

Comments
 (0)