You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The one hazard neither catches: a raw Path/PathBuf used as a HashMap/HashSet key or compared with ==. Raw Path equality is byte-exact, so C:\Foo ≠ c:/foo and //?/C:\x ≠ C:\x — exactly the Windows cache-key/watcher mismatch from #436/#437. NormalizedPath (case-folded, slash-normalized, UNC-stripped key) is the fix, and it is already used in the ~51 files that hold the primary keys.
Scope (bounded — do NOT expand to a type-wide ban)
Audit sites where a path is a map/set key or an ==/match operand: rg 'HashMap<PathBuf|HashSet<PathBuf|BTreeMap<PathBuf|HashMap<.*&?Path' plus raw path_a == path_b comparisons in crates/*/src/.
For each, confirm the key type is NormalizedPath (or the comparison routes through normalize_for_key). Migrate only these.
Consider a focused dylint: "raw Path/PathBuf as HashMap/HashSet key" — the residual the existing two lints miss. Only if the audit finds enough live sites to justify it.
Explicit non-goals
Not a blanket PathBuf→NormalizedPath swap. Plumbing paths (the ~3200 .join() + ~650 -> PathBuf that feed argv/Command) stay PathBuf.
Not driving the ban_std_pathbuf allowlist to zero. Leave it as a documented legacy no-op (or delete it — the operation lints carry the real load).
Prerequisite if a migration reveals path-algebra needs
Only NormalizedPath::join() returns Self; parent()/with_extension()/components()/strip_prefix() deref to &Path/PathBuf. If the audit needs in-type path manipulation, add those Self-returning methods first — with a written decision on the lexical-.. / case-fold semantics — rather than sprinkling .into().
Narrow replacement for #1271 (closed — see the closing comment there for why the blanket
PathBuf→NormalizedPathmigration is the wrong shape).The gap
fbuild's path-identity bug class (#436/#437/#282) is already covered by two operation-targeting lints:
ban_raw_path_prefix_compare—starts_with/strip_prefixon raw paths (allowlist: 17)ban_manual_slash_normalize— hand-rolled\→/(allowlist: 5)The one hazard neither catches: a raw
Path/PathBufused as aHashMap/HashSetkey or compared with==. RawPathequality is byte-exact, soC:\Foo≠c:/fooand//?/C:\x≠C:\x— exactly the Windows cache-key/watcher mismatch from #436/#437.NormalizedPath(case-folded, slash-normalized, UNC-strippedkey) is the fix, and it is already used in the ~51 files that hold the primary keys.Scope (bounded — do NOT expand to a type-wide ban)
==/matchoperand:rg 'HashMap<PathBuf|HashSet<PathBuf|BTreeMap<PathBuf|HashMap<.*&?Path'plus rawpath_a == path_bcomparisons incrates/*/src/.NormalizedPath(or the comparison routes throughnormalize_for_key). Migrate only these.Path/PathBufasHashMap/HashSetkey" — the residual the existing two lints miss. Only if the audit finds enough live sites to justify it.Explicit non-goals
PathBuf→NormalizedPathswap. Plumbing paths (the ~3200.join()+ ~650-> PathBufthat feed argv/Command) stayPathBuf.ban_std_pathbufallowlist to zero. Leave it as a documented legacy no-op (or delete it — the operation lints carry the real load).NormalizedPath:NormalizedPath::new()strips..lexically (path.rs:295) and case-foldskey(path.rs:332), which is wrong across symlinks.library_manager::resolve_local_library_dir(test-emu does not resolve symlink library dependencies on Windows #1256/fix(library): resolve relative local dependency roots #1258) must keepstd::fs::canonicalize.Prerequisite if a migration reveals path-algebra needs
Only
NormalizedPath::join()returnsSelf;parent()/with_extension()/components()/strip_prefix()deref to&Path/PathBuf. If the audit needs in-type path manipulation, add thoseSelf-returning methods first — with a written decision on the lexical-../ case-fold semantics — rather than sprinkling.into().Related
#1271 (closed), #436, #437, #282,
ban_raw_path_prefix_compare,ban_manual_slash_normalize.