#2846·sccache

parse_rustc_z_ls misparses deps without -HASH suffix → E0463 on dist workers

Author: justdoGITCreated Sep 11, 2026Updated Sep 11, 2026

Summary

parse_rustc_z_ls in src/compiler/rust.rs misparses dependency lines from rustc -Z ls=root when a crate appears without a -${HASH} suffix. The malformed dependency name never matches during crate_link_paths scanning, so the dep's rmeta is not packaged for the distributed worker, and the worker fails with E0463: can't find crate.

Environment

  • sccache: 0.17.0 (commit 4ffa89b, latest main)
  • rustc: 1.100.0-nightly (67eda617e 2026-09-10)
  • sccache-dist: 4 workers, bwrap overlay builder
  • A real crate (crc_fast, a build-script artifact from the crc-fast crate) that emits no -${HASH} suffix in -Z ls output.

Root cause

Modern rustc emits extended metadata per dependency line in rustc -Z ls=root:

=External Dependencies=
1 std-453218b5e9634890 hash c76be37... host_hash None kind Unconditional public
2 core-5f5c0031517c19c4 hash 4e0d6022... host_hash None kind Unconditional public
3 crc_fast hash 05bce60290e56777e3ae6d3ddcc01e6c host_hash None kind Unconditional public
4 crc-8c7d86e779319534 hash 49e85fac... host_hash None kind Unconditional public

Line 3 (crc_fast) has no -${HASH} suffix after the crate name. Line 4 (crc-8c7d...) does.

parse_rustc_z_ls does:

rust
let mut line_splits = line.splitn(2, ' ');
// line_splits.next() → "3"
let libstring = line_splits
    .next()
    .context("No lib string on line from rustc -Z ls")?;
// libstring = "crc_fast hash 05bce60290e56777e3ae6d3ddcc01e6c host_hash None kind Unconditional public"

splitn(2, ' ') splits on the first space, so libstring is the entire trailing metadata, not just the crate name.

Then:

rust
let mut libstring_splits = libstring.rsplitn(2, '-');
let maybe_hash = libstring_splits.next()?;
let libname = libstring_splits.next().unwrap_or(maybe_hash);

rsplitn(2, '-') finds no - in the long metadata string, so libname becomes the entire string "crc_fast hash 05bce60290e56777e3ae6d3ddcc01e6c host_hash None kind Unconditional public".

Impact

When RustInputsPackager scans -L paths for rmeta files, it parses each filename (e.g. libcrc_fast-c6657c97868f5464.rmeta) and extracts crate_name = "crc_fast". But dep_crate_names contains the broken "crc_fast hash 05bce6..." string — no match. The rmeta is silently skipped, not packaged, and not sent to the worker.

The worker receives xai_file_utils.rmeta (which references crc_fast) but not libcrc_fast.rmeta, so rustc fails:

error[E0463]: can't find crate for `crc_fast` which `xai_file_utils` depends on

Evidence

sccache TRACE log (SCCACHE_LOG=trace) shows the broken dep name in Identified dependency crate names:

TRACE sccache::compiler::rust] Identified dependency crate names: {
  ...,
  "aws_sdk_s3",
  "crc32fast",
  "crc_fast hash 05bce60290e56777e3ae6d3ddcc01e6c host_hash None kind Unconditional public",
  ...
}

Direct confirmation of the -Z ls output:

$ RUSTC_BOOTSTRAP=1 rustc -Z ls=root libxai_file_utils-*.rmeta 2>&1 | grep crc_fast
216 crc_fast hash 05bce60290e56777e3ae6d3ddcc01e6c host_hash None kind Unconditional public

Line 216 (crc_fast) has no -${HASH} suffix; line 217 (crc-8c7d...) does.

Reproduction

  1. Use sccache-dist with any crate graph where a dependency's rmeta emits without a -${HASH} suffix in -Z ls (observed with crc-fast build artifacts).
  2. Run a distributed compile of a crate that transitively depends on it.
  3. The worker fails with E0463: can't find crate for crc_fast``.

Proposed fix

Take only the first whitespace-delimited token of libstring before the existing rsplitn('-') logic, so both crc_fast and crc-8c7d... resolve to the bare crate name:

rust
let libstring = line_splits
    .next()
    .context("No lib string on line from rustc -Z ls")?;
let libstring = libstring
    .split_whitespace()
    .next()
    .context("No lib string on line from rustc -Z ls")?;

PR with the fix + regression test: https://github.com/mozilla/sccache/pull/