rust-lang / rust-lang/rust

next-solver associated-type alias cycles still scale explosively at deeper nesting

Open
#158,176 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug I-compiletime needs-triage T-types WG-trait-system-refactor
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

I tried this code:

cat > next_solver_alias_cycle_repro.py <<'PY'
#!/usr/bin/env python3
import os
import subprocess
import time
from pathlib import Path

DEPTH = int(os.environ.get("DEPTH", "16"))
RUSTC = os.environ.get("RUSTC", "rustc")


def nested_alias(depth: int, base: str) -> str:
    ty = base
    for _ in range(depth):
        ty = f"Alias<T, {ty}>"
    return ty


def write_alias_cycle(path: Path, depth: int) -> None:
    lines = [
        "#![allow(dead_code)]",
        "struct A;",
        "struct B;",
        "struct C;",
        "type Alias<T, U> = <T as Trait<U>>::Assoc;",
        "trait Trait<T> { type Assoc; }",
        "fn foo<T>()",
        "where",
        "    T: Trait<A> + Trait<B> + Trait<C>,",
    ]
    for d in range(1, depth + 1):
        for base in ("A", "B", "C"):
            lines.append(f"    T: Trait<{nested_alias(d, base)}>,")
    lines.extend(["{}", "fn main() {}"])
    path.write_text("\n".join(lines) + "\n", encoding="utf-8")


src = Path(f"next_solver_alias_cycle_{DEPTH}.rs")
write_alias_cycle(src, DEPTH)
out = Path(f"next_solver_alias_cycle_{DEPTH}.rmeta")

start = time.perf_counter()
proc = subprocess.run(
    [
        RUSTC,
        "-Znext-solver",
        "--edition=2024",
        "--crate-type=lib",
        "--emit=metadata",
        "-Awarnings",
        str(src),
        "-o",
        str(out),
    ],
    stdout=subprocess.DEVNULL,
    stderr=subprocess.DEVNULL,
    check=False,
)
seconds = time.perf_counter() - start
print(f"depth={DEPTH} status={proc.returncode} elapsed={seconds:.3f}s source={src.stat().st_size}")
PY

RUSTC=/path/to/rustc DEPTH=16 python3 next_solver_alias_cycle_repro.py

The program compiles successfully with -Znext-solver.

With DEPTH=16, I see:

depth=16 status=0 elapsed=150.869s

Here are the timings I collected with the same rustc binary:

depth  exit_status  elapsed_s
4      0            0.158
8      0            4.002
12     0            32.750
16     0            150.869

The source grows regularly with nesting depth, but compile time grows
explosively.

Meta

rustc --version --verbose: 4008bbdf34b

Backtrace

<backtrace>

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with next_solver_alias_cycle_repro.py and run it with the supplied DEPTH values using rustc -Znext-solver. Trace the associated-type alias cycle handling exercised by the generated bounds and compare timings at increasing depths. Done means the reproducer still compiles successfully without the explosive runtime growth.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.