rust-lang / rust-lang/rust-clippy

join_absolute_paths is not always right on Windows when dealing with just drive letter paths ("C:")

Open
#12,244 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug I-false-positive
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

Summary

When dealing with a Path that consists solely of a drive letter and a colon (i.e. "C:"), joining it with a separator actually results in a meaningfully different path (i.e. "C:\"). Yes there actually are things that treat these two paths differently.

Lint Name

join_absolute_paths

Reproducer

I tried this code:

fn main() {
    let p = Path::new("C:");
    println!("{:?}, {:?}", p, terminate_drive_letter_paths(&p));
}

fn terminate_drive_letter_paths(path: &Path) -> PathBuf {
    if path.as_os_str().len() == 2 && path.to_str().map_or(false, |s| s.ends_with(':')) {
        path.join("\\")
    } else {
        path.to_owned()
    }
}

This emits the suggestion:

warning: argument to `Path::join` starts with a path separator
  --> src\main.rs:13:19
   |
13 |         path.join("\\")
   |                   ^^^^
   |
   = note: joining a path starting with separator will replace the path instead
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#join_absolute_paths
   = note: `#[warn(clippy::join_absolute_paths)]` on by default
help: if this is unintentional, try removing the starting separator
   |
13 |         path.join("\")
   |                   ~~~
help: if this is intentional, try using `Path::new` instead
   |
13 |         PathBuf::from("\\")
   |


However running the code shows that the suggestion and explanation are not entirely accurate. That path is not really "replaced", but rather gets a \ appended as we'd expect:

"C:", "C:\\"
Version
rustc 1.76.0 (07dca489a 2024-02-04)
binary: rustc
commit-hash: 07dca489ac2d933c78d3c5158e3f43beefeb02ce
commit-date: 2024-02-04
host: x86_64-pc-windows-msvc
release: 1.76.0
LLVM version: 17.0.6
Additional Labels

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the join_absolute_paths lint entry point and reproduce the provided example on Windows, comparing the diagnostic and suggested replacement with Path::join behavior for a drive-letter-only path. Trace the lint's existing coverage, then make the diagnostic and suggestion accurately reflect this case and verify the regression.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.