Skip to content

Don't track cwd for -Zremap-cwd-prefix in incremental compilation#157348

Draft
ashi009 wants to merge 1 commit into
rust-lang:mainfrom
ashi009:remap-cwd-prefix-incremental
Draft

Don't track cwd for -Zremap-cwd-prefix in incremental compilation#157348
ashi009 wants to merge 1 commit into
rust-lang:mainfrom
ashi009:remap-cwd-prefix-incremental

Conversation

@ashi009
Copy link
Copy Markdown

@ashi009 ashi009 commented Jun 3, 2026

Summary

-Zremap-cwd-prefix=<to> defeats incremental compilation whenever the build directory changes (Bazel sandboxes, CI checkouts with per-build paths), even though the remapped output is identical:

[incremental] completely ignoring cache because of differing commandline arguments

Root cause

-Zremap-cwd-prefix and --remap-path-prefix have two separate options (remap_cwd_prefix and remap_path_prefix), but parse_remap_path_prefix merges them: it resolves std::env::current_dir() and pushes (cwd, to) onto remap_path_prefix, which is [TRACKED_NO_CRATE_HASH]. The absolute cwd thus enters dep_tracking_hash(false) (compared in rustc_incremental::persist::load), so the same build from a different directory purges the whole incremental session. This is the cwd half of #132132.

Fix: apply the cwd prefix where the mapping is built, not where options are tracked

Keep each option holding exactly its own flag, and apply -Zremap-cwd-prefix in file_path_mapping — i.e. while building the (untracked) applied FilePathMapping — instead of in parse_remap_path_prefix. The absolute cwd then lives only in the runtime mapping and never in a tracked option.

Behaviour-preserving for output: the applied mapping is identical (the cwd entry is still appended last), so all emitted paths (debuginfo, diagnostics, metadata) are unchanged.

Sound for tracking: the cwd's effect is still tracked, by the two options that should carry it —

  • remap_cwd_prefix ([TRACKED]) — the target prefix baked into output;

  • working_dir ([TRACKED]) — and RealFileName's hash already includes the real local path only when the path was not fully remapped (was_fully_remapped() = scopes.is_all()):

    if !self.was_fully_remapped() { self.local.hash(state); }
    self.maybe_remapped.hash(state);

    So under a restrictive -Zremap-path-scope (where the cwd can still leak into output) the real cwd stays tracked via working_dir; under full remapping (where it cannot leak) it is correctly ignored. Dropping the cwd from remap_path_prefix's hash is therefore sound in every scope.

The stable --remap-path-prefix flag is entirely unchanged in data and in tracking. No SVH/crate-hash change (remap_path_prefix is TRACKED_NO_CRATE_HASH). One file, +32/-17, no new types and no special-case hashing.

Status

  • Draft. Not yet validated against a built rustc end-to-end (root cause confirmed empirically under a Bazel sandbox; reasoning above). Needs a tests/run-make test: same crate built from two directories sharing one -Cincremental dir with -Zremap-cwd-prefix=. → expect reuse; plus a restricted -Zremap-path-scope variant → expect a rebuild (proving the working_dir guard).

r? compiler

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 3, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Jun 3, 2026

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @davidtwco (or someone else) some time within the next two weeks.

Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue
Why was this reviewer chosen?

The reviewer was selected based on:

  • compiler expanded to 73 candidates
  • Random selection from 17 candidates

@ashi009 ashi009 force-pushed the remap-cwd-prefix-incremental branch from b094991 to b9c4f73 Compare June 3, 2026 03:35
@rust-log-analyzer

This comment has been minimized.

@ashi009 ashi009 force-pushed the remap-cwd-prefix-incremental branch 2 times, most recently from b96a8fc to 273c1cb Compare June 3, 2026 06:40
@rust-log-analyzer

This comment has been minimized.

@ashi009 ashi009 force-pushed the remap-cwd-prefix-incremental branch from 273c1cb to 6d0225c Compare June 3, 2026 06:48
@rust-log-analyzer

This comment has been minimized.

@ashi009 ashi009 force-pushed the remap-cwd-prefix-incremental branch 2 times, most recently from ae39a0c to eb85a15 Compare June 3, 2026 07:53
@rust-log-analyzer

This comment has been minimized.

@ashi009 ashi009 force-pushed the remap-cwd-prefix-incremental branch from eb85a15 to 5789e68 Compare June 3, 2026 08:50
`-Zremap-cwd-prefix=<to>` was applied inside `parse_remap_path_prefix`, which
resolved `std::env::current_dir()` and pushed `(cwd, to)` onto
`remap_path_prefix`. That option is `[TRACKED_NO_CRATE_HASH]`, so the absolute
working directory entered the incremental command-line-args hash, and building
the same sources from a different directory (e.g. a Bazel sandbox, whose path
contains a per-action counter) purged the whole incremental cache even though the
remapped output is identical (rust-lang#132132).

`--remap-path-prefix` and `-Zremap-cwd-prefix` already have separate options
(`remap_path_prefix` and `remap_cwd_prefix`). Keep each option holding exactly its
own flag, and apply `-Zremap-cwd-prefix` in `file_path_mapping` — i.e. when
building the (untracked) applied `FilePathMapping` — rather than when
parsing/tracking options. The absolute cwd then lives only in the runtime mapping,
never in a tracked field.

Output is unchanged (the cwd entry is still appended last). Tracking stays sound:
the cwd's effect is tracked via `remap_cwd_prefix` (the target prefix baked into
output) and `working_dir` (whose `RealFileName` hash includes the real path only
when it was not fully remapped, i.e. exactly when the cwd can leak into output).
The stable `--remap-path-prefix` flag is unchanged in data and in tracking.

A unit test guards against the cwd being merged back into `remap_path_prefix`.

Addresses the cwd half of rust-lang#132132.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants