Skip to content

Truncate IR dump basenames to respect NAME_MAX - #1650

Open
npiesco wants to merge 1 commit into
rust-lang:mainfrom
npiesco:truncate-ir-dump-basenames
Open

Truncate IR dump basenames to respect NAME_MAX#1650
npiesco wants to merge 1 commit into
rust-lang:mainfrom
npiesco:truncate-ir-dump-basenames

Conversation

@npiesco

@npiesco npiesco commented Apr 23, 2026

Copy link
Copy Markdown

Resolves the // FIXME work around filename too long errors in src/pretty_clif.rs.

When --emit=llvm-ir is used with cg_clif, symbol-mangled basenames can exceed the filesystem per-component limit (255B on ext4/XFS/APFS, 143B on HFS+, 255 UTF-16 on NTFS). File::create returns ENAMETOOLONG; the current early_warn path silently drops the dump.

This patch truncates only names that would fail:

  • Stems short enough that no extension can overrun the limit pass through unchanged (zero overhead, borrowed Cow).
  • Longer: rewritten to <first 160 bytes of stem>_h<16-hex-FNV-1a-64 over the full stem>.<exts>.
  • Extension chains (.opt.clif, .unopt.clif, .vcode) preserved.
  • Char-boundary-safe truncation.

Called inside write_ir_file, so both write_clif_file and the vcode writer in base.rs benefit uniformly.

Why the length test looks at the stem, not the whole basename

One function is dumped to several files (.opt.clif, .unopt.clif, .vcode) and consumers pair them by their shared stem, so the rewrite must not depend on which artifact is being written.

Testing the whole basename makes it depend on exactly that. .opt.clif is 9 bytes and .vcode is 6, so a 192-byte symbol pushes the CLIF over the limit while the vcode stays under it: the CLIF is rewritten, the vcode is not, and the two land under unrelated names. Anything pairing a function's CLIF with its vcode then silently finds nothing to pair.

Every symbol between 190 and 194 bytes hits this. In an --emit=llvm-ir build of rustc itself that is 11,510 of 650,644 functions.

Deciding from the stem alone, reserving room for the longest extension chain written here, makes every artifact of a function truncate together.

Tests

Cover the pairing property, the length bound, char-boundary safety, and that distinct symbols stay distinct. The pairing test sweeps the whole boundary region rather than checking a single length — at any one length the artifact-dependent behaviour is invisible.

Supersedes #1649 (closed). Happy to adjust the shape on review feedback.

@npiesco

npiesco commented Apr 23, 2026

Copy link
Copy Markdown
Author

@folkertdev @Urgau — tagging you for a second pair of eyes since #1649 closed with a "not quite the right approach" note but no concrete alternative. Open to reshaping on feedback; the core point is that the current early_warn drop-on-ENAMETOOLONG silently loses requested IR dumps.

@npiesco
npiesco force-pushed the truncate-ir-dump-basenames branch from 2387999 to 2ec69f8 Compare July 31, 2026 17:51
@rustbot

This comment has been minimized.

Resolves the `// FIXME work around filename too long errors` in
`src/pretty_clif.rs`.

When `--emit=llvm-ir` is used with cg_clif, symbol-mangled basenames can
exceed the filesystem per-component limit (255B on ext4/XFS/APFS, 143B on
HFS+, 255 UTF-16 on NTFS). `File::create` returns `ENAMETOOLONG`; the current
`early_warn` path silently drops the dump.

This patch truncates only names that would fail:

- Stems short enough that no extension can overrun the limit pass through
  unchanged (zero overhead, borrowed `Cow`).
- Longer: rewritten to
  `<first 160 bytes of stem>_h<16-hex-FNV-1a-64 over the full stem>.<exts>`.
- Extension chains (`.opt.clif`, `.unopt.clif`, `.vcode`) preserved.
- Char-boundary-safe truncation.

The length test deliberately looks at the stem alone rather than the whole
basename, reserving room for the longest extension chain written here. Testing
the whole basename would make the rewrite depend on which artifact is being
written: a 192-byte symbol pushes `.opt.clif` over the limit but leaves
`.vcode` under it, so one function's dumps would land under two unrelated
names and anything pairing a CLIF with its vcode would silently find nothing
to pair. Symbols of 190 to 194 bytes all hit that; in an `--emit=llvm-ir`
build of rustc itself that is 11510 of 650644 functions.

Called inside `write_ir_file`, so both `write_clif_file` and the vcode writer
in `base.rs` benefit uniformly.

Tests cover the pairing property, the length bound, char-boundary safety, and
that distinct symbols stay distinct. The pairing test sweeps the whole
boundary region rather than checking one length, since at any single length
the artifact-dependent behaviour is invisible.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@npiesco
npiesco force-pushed the truncate-ir-dump-basenames branch from 2ec69f8 to 14e34de Compare August 1, 2026 01:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants