Project version
0.7.2
Project
compiler
What happened?
The compiler can represent nested type aliases very compactly by sharing their underlying Arc nodes. This means a sequence of aliases such as:
type A0 = u8;
type A1 = (A0, A0);
type A2 = (A1, A1);
type A3 = (A2, A2);
...
forms a small DAG rather than storing the fully expanded type. With N aliases, the stored representation is therefore roughly linear in size.
when this type is later used impl From<&ResolvedType> for StructuralType (src/types.rs:1175) traverses the type using post_order_iter(). The TreeLike implementation for &ResolvedType (src/types.rs:571) returns the child Arcs, but the traversal does not deduplicate already-seen nodes by pointer identity.
As a result, when the same alias is referenced multiple times, the compiler walks the same underlying subtree again for every path that reaches it. So a depth of N can therefore result in roughly 2^N leaf visits.
This was my observation.
depth 16: 0.39 s
depth 20: 5.74 s
depth 22: 23.9 s
Minimal reproduction steps
This is one of the examples that demonstrates the bug
type A0 = u8;
type A1 = (A0, A0);
type A2 = (A1, A1);
type A3 = (A2, A2);
type A4 = (A3, A3);
type A5 = (A4, A4);
type A6 = (A5, A5);
type A7 = (A6, A6);
type A8 = (A7, A7);
type A9 = (A8, A8);
...
type A30 = (A29, A29);
fn main() { let _x: A30 = witness::W; }
trying to compile this leads to the compiler being hung.
Project version
0.7.2
Project
compiler
What happened?
The compiler can represent nested type aliases very compactly by sharing their underlying Arc nodes. This means a sequence of aliases such as:
forms a small DAG rather than storing the fully expanded type. With N aliases, the stored representation is therefore roughly linear in size.
when this type is later used
impl From<&ResolvedType> for StructuralType (src/types.rs:1175)traverses the type usingpost_order_iter(). The TreeLike implementation for&ResolvedType(src/types.rs:571) returns the child Arcs, but the traversal does not deduplicate already-seen nodes by pointer identity.As a result, when the same alias is referenced multiple times, the compiler walks the same underlying subtree again for every path that reaches it. So a depth of N can therefore result in roughly 2^N leaf visits.
This was my observation.
depth 16: 0.39 s
depth 20: 5.74 s
depth 22: 23.9 s
Minimal reproduction steps
This is one of the examples that demonstrates the bug
trying to compile this leads to the compiler being hung.