Proposal
{cwd} placeholder in --remap-path-prefix
Motivation
When the same project is built from different directories that produce identical output — CI checkouts with per-build paths, build sandboxes, agent-driven git worktrees — two things should hold but don't:
- Incremental builds aren't reused across the directories, so each recompiles from scratch.
- The command line isn't reproducible, because it embeds the absolute working directory.
Both have the same cause. To strip the cwd from output you must remap it, and the only way to remap the cwd is to resolve it to an absolute path and pass that to --remap-path-prefix (what -Zremap-cwd-prefix does internally). That absolute path is stored in remap_path_prefix ([TRACKED_NO_CRATE_HASH]), so it enters the incremental command-line hash and varies per directory — even though the remapped output is identical (#132132).
The cwd is being treated as a concrete value on the command line when it should be a placeholder resolved at build time.
Design
Allow a {cwd} placeholder, as a whole path component, on the FROM side of --remap-path-prefix:
--remap-path-prefix={cwd}=.
--remap-path-prefix={cwd}/lib/std=std
The FROM is stored verbatim and {cwd} is expanded only when the FilePathMapping is built. So the tracked value is the placeholder text, not the absolute cwd — stable across directories, and a plain PathBuf still suffices (no new type).
Rules:
- A placeholder is a whole component of the form
{name}. cwd is the only recognized name; an unrecognized name is an error.
{{/}} are literal braces, so a literal {cwd} directory is written {{cwd}}.
- Only FROM is interpreted.
-Zremap-cwd-prefix=V becomes exactly sugar for --remap-path-prefix={cwd}=V, giving a path to sunset that unstable flag.
The one thing to weigh: it's a stable-flag behavior change
A FROM whose whole component is {cwd} now expands (instead of matching a literal {cwd} dir), and any other {name} now errors. The escape {{cwd}} is always available as migration, and the blast radius is small — {/} are rare in paths, illegal on Windows, and only matched as a whole component. This is the reason it's an MCP rather than just a PR.
Notes
- POC, passing CI, with tests: #157405. Small and localized to
rustc_session::config — no changes to the option type, dependency tracking, the metadata decoder, or rustdoc.
- No interaction with
--remap-path-scope or RFC 3127: this reuses the existing remap code path; placeholders expand into the same FilePathMapping scopes already act on.
- Other token syntaxes (
<cwd>, %cwd%, \(cwd)) were rejected for shell/portability reasons; {cwd} mirrors format! and is self-escaping.
- Follows up the accepted MCP #450 (where a
%CWD% placeholder was first floated) and tracking issue #89434.
- #157348 is a minimal, unstable-only fix for the same bug; it can land independently and is not blocked by this MCP.
Mentors or Reviewers
@Urgau and @davidtwco have engaged on #157348; happy to be mentored by either. I (@ashi009) can implement.
Proposal
{cwd}placeholder in--remap-path-prefixMotivation
When the same project is built from different directories that produce identical output — CI checkouts with per-build paths, build sandboxes, agent-driven git worktrees — two things should hold but don't:
Both have the same cause. To strip the cwd from output you must remap it, and the only way to remap the cwd is to resolve it to an absolute path and pass that to
--remap-path-prefix(what-Zremap-cwd-prefixdoes internally). That absolute path is stored inremap_path_prefix([TRACKED_NO_CRATE_HASH]), so it enters the incremental command-line hash and varies per directory — even though the remapped output is identical (#132132).The cwd is being treated as a concrete value on the command line when it should be a placeholder resolved at build time.
Design
Allow a
{cwd}placeholder, as a whole path component, on the FROM side of--remap-path-prefix:The FROM is stored verbatim and
{cwd}is expanded only when theFilePathMappingis built. So the tracked value is the placeholder text, not the absolute cwd — stable across directories, and a plainPathBufstill suffices (no new type).Rules:
{name}.cwdis the only recognized name; an unrecognized name is an error.{{/}}are literal braces, so a literal{cwd}directory is written{{cwd}}.-Zremap-cwd-prefix=Vbecomes exactly sugar for--remap-path-prefix={cwd}=V, giving a path to sunset that unstable flag.The one thing to weigh: it's a stable-flag behavior change
A FROM whose whole component is
{cwd}now expands (instead of matching a literal{cwd}dir), and any other{name}now errors. The escape{{cwd}}is always available as migration, and the blast radius is small —{/}are rare in paths, illegal on Windows, and only matched as a whole component. This is the reason it's an MCP rather than just a PR.Notes
rustc_session::config— no changes to the option type, dependency tracking, the metadata decoder, or rustdoc.--remap-path-scopeor RFC 3127: this reuses the existing remap code path; placeholders expand into the sameFilePathMappingscopes already act on.<cwd>,%cwd%,\(cwd)) were rejected for shell/portability reasons;{cwd}mirrorsformat!and is self-escaping.%CWD%placeholder was first floated) and tracking issue #89434.Mentors or Reviewers
@Urgau and @davidtwco have engaged on #157348; happy to be mentored by either. I (@ashi009) can implement.