rust-lang / rust-lang/rust

stable CTFE layout intrinsics expand alias-doubled tuple types exponentially

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

Nobody has claimed this yet.

C-bug needs-triage
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

I tried this code:

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

DEPTH = int(os.environ.get("DEPTH", "24"))
KIND = os.environ.get("KIND", "size_of")
RUSTC = os.environ.get("RUSTC", "rustc")
TIMEOUT = float(os.environ.get("TIMEOUT", "60"))


def write_alias_doubled_tuple(path: Path) -> None:
    if KIND not in {"size_of", "align_of", "needs_drop"}:
        raise ValueError(f"unknown KIND: {KIND}")

    leaf = "String" if KIND == "needs_drop" else "u8"
    lines = ["#![allow(dead_code)]", f"type T0 = {leaf};"]
    for i in range(1, DEPTH + 1):
        lines.append(f"type T{i} = (T{i - 1}, T{i - 1});")

    if KIND == "size_of":
        lines.append(f"pub const V: usize = std::mem::size_of::<T{DEPTH}>();")
    elif KIND == "align_of":
        lines.append(f"pub const V: usize = std::mem::align_of::<T{DEPTH}>();")
    else:
        lines.append(f"pub const V: bool = std::mem::needs_drop::<T{DEPTH}>();")

    path.write_text("\n".join(lines) + "\n", encoding="utf-8")


src = Path(f"alias_doubled_tuple_{KIND}_{DEPTH}.rs")
out = Path(f"alias_doubled_tuple_{KIND}_{DEPTH}.rmeta")
write_alias_doubled_tuple(src)

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

RUSTC=/path/to/rustc KIND=size_of DEPTH=24 python3 stable_layout_alias_tuple_repro.py

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

kind        depth  source_bytes  elapsed_s     exit_status
size_of     16     423           0.050         0
size_of     20     515           0.522         0
size_of     24     607           7.784         0
size_of     28     699           timeout>45    -1
align_of    24     608           7.960         0
needs_drop  24     613           14.509        0
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 by running stable_layout_alias_tuple_repro.py with the provided rustc command and varying DEPTH and KIND. Compare size_of, align_of, and needs_drop timings, then trace the compiler's CTFE layout-intrinsic handling. Done means the alias-doubled tuple cases no longer expand exponentially and the reproducer remains covered by a regression test.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.