# rust-lang/rust-clippy

Merged
merged 1 commit into from Apr 18, 2019

## Conversation

Projects
None yet
4 participants
Contributor

### andrehjr commented Apr 13, 2019

 Closes #3923 This is a very simple Lint that checks if push is being called with a Root Path. Because that can make it overwrite the previous path. I used std::path::Path to check if it's root, in order to keep it working across windows/linux environments instead of checking for '/'. Is that alright? On the if_chain! block, Is there a way to make it short while getting the value of the first argument? I got the example from other lints. Note that this is first Lint, I hope I got everything covered 🚀

### JamesHinshelwood reviewed Apr 13, 2019

 if let ExprKind::Lit(ref lit) = get_index_arg.node; if let LitKind::Str(ref r, _) = lit.node; then { if Path::new(&r.as_str()).has_root() {

#### JamesHinshelwood Apr 13, 2019

Would is_absolute be better than has_root here? The docs for push seem to suggest the path will be replaced if the other path is absolute.
Also, could this if be part of the if_chain! above?

#### andrehjr Apr 13, 2019

Author Contributor

That makes sense! Seems like is_absolute is better. As It's only equivalent to is_root on Unix. I'll make the changes.

#### flip1995 Apr 15, 2019

Collaborator

Copying from below: #3954 (comment)

I'm not sure about the is_absolute vs has_root thing. ::push("\windows") on windows will result in c:\windows, while it doesn't matter what the previous path was (except the prefix). But is_absolute does not cover this case.

Collaborator

### flip1995 left a comment • edited

 Thanks for the contribution! Basic implementation LGTM. Some minor things need to be changed. Also AppVeyor is not happy with the unix-like paths. probably because of the is_absolute vs has_root thing.
clippy_lints/src/path_buf_push_overwrite.rs Outdated
clippy_lints/src/path_buf_push_overwrite.rs Outdated
clippy_lints/src/path_buf_push_overwrite.rs Outdated
clippy_lints/src/path_buf_push_overwrite.rs Outdated
clippy_lints/src/path_buf_push_overwrite.rs
clippy_lints/src/path_buf_push_overwrite.rs Outdated
 then { span_help_and_lint(cx, PATH_BUF_PUSH_OVERWRITE, expr.span, "Calling push with '/' (file system root) can overwrite the previous path definition", "Remove the '/' (file system root) from the start of the path instead");

#### flip1995 Apr 15, 2019

Collaborator

You should be able to use span_lint_and_sugg. You can build the suggestion with https://doc.rust-lang.org/std/primitive.str.html#method.trim_left_matches.

Also formatting:

span_lint_and_sugg(
cx,
LINT,
span,
// ...
);
clippy_lints/src/path_buf_push_overwrite.rs Outdated

Collaborator

### flip1995 commented Apr 16, 2019

 This LGTM now. I just would like to see, that you change the span_help_and_lint with span_lint_and_sugg: #3954 (comment) If you need help with this just let me know! :)
Contributor Author

### andrehjr commented Apr 16, 2019

 Sure! I fixed the other issues first, I'll do the span_lint_and_sugg today! 🚀 Another thing that I left for today, is that one of the builds on travisci failing because of this doctest: thread 'main' panicked at 'assertion failed: (left == right) left: "/foo\\bar", right: "/foo/bar"', doctest.rs:7:1  https://travis-ci.com/rust-lang/rust-clippy/jobs/193169548 Is the best alternative here to add a if cfg!(windows) and have both assert! versions for linux/windows ?
Collaborator

### flip1995 commented Apr 16, 2019

 Try to write the assert like this, instead of comparing strings (like in the push documentation): assert_eq!(x, PathBuf::from("/bar"));
Contributor Author

### andrehjr commented Apr 17, 2019

 I 'almost' got it, added the suggestion and rustfix. I tried using Component::RootDir from the Path in order to replace the the Root correctly for both win/linux use cases. It did work for linux, but it's failing now on windows. I'll get a windows vm to debug this better, or find a better way to do it. Thanks for the reviews so far @flip1995 !

### flip1995 reviewed Apr 17, 2019

clippy_lints/src/path_buf_push_overwrite.rs Outdated
Collaborator

### flip1995 commented Apr 17, 2019

 I'll get a windows vm to debug this better, or find a better way to do it. Stupid (?) idea: You could setup a test repo with travis for windows. Then you push your clippy binaries there and debug it in Travis. Not sure if that or the windows VM is more work.
Contributor Author

### andrehjr commented Apr 18, 2019 • edited

 @flip1995 that was a very good idea indeed! Much better than getting a VM just for that. Thanks so much! :D In the end, I think the best impl to remove 'root' paths is the following: path.trim_start_matches(|c| c == '/' || c == '\\')) when path.has_root() => true. Digging more on how this is being tested on Rust And seeing how windows, unix and others, look for their MAIN_SEPARATOR. And also because calling components() on a path Component::RootDir changes the root from '/' to '\' on windows.

Collaborator

### flip1995 commented Apr 18, 2019

 This LGTM now! Could you squash some commits and drop 53e34fa? This commit is already implemented in #3968 and would lead to conflicts. Once #3968 is merged you probably have to rebase (Sorry).
Contributor

### bors commented Apr 18, 2019

 ☔️ The latest upstream changes (presumably #3968) made this pull request unmergeable. Please resolve the merge conflicts.

### andrehjrforce-pushed the andrehjr:add-lint-path-buf-overwrite branch from 645683d to 6d4e682Apr 18, 2019

 Add lint PathBufPushOverwrite 
 7e9cb5b 

### andrehjrforce-pushed the andrehjr:add-lint-path-buf-overwrite branch from 6d4e682 to 7e9cb5bApr 18, 2019

Contributor Author

### andrehjr commented Apr 18, 2019

 Awesome 🚀 no worries, I was going to rebase it anyway!
Collaborator

### flip1995 commented Apr 18, 2019

 Thanks! @bors r+
Contributor

### bors commented Apr 18, 2019

 📌 Commit 7e9cb5b has been approved by flip1995
Contributor

### bors commented Apr 18, 2019

 ⌛️ Testing commit 7e9cb5b with merge c6e43b1...

### bors added a commit that referenced this pull request Apr 18, 2019

 Auto merge of #3954 - andrehjr:add-lint-path-buf-overwrite, r=flip1995 
Add Lint PathBufPushOverwrite

Closes #3923

This is a very simple Lint that checks if push is being called with a Root Path. Because that can make it overwrite the previous path.

I used std::path::Path to check if it's root, in order to keep it working across windows/linux environments instead of checking for '/'. Is that alright?

On the if_chain! block, Is there a way to make it short while getting the value of the first argument? I got the example from other lints.

Note that this is first Lint, I hope I got everything covered  🚀
 c6e43b1 
Contributor

### bors commented Apr 18, 2019

 ☀️ Test successful - checks-travis, status-appveyor Approved by: flip1995 Pushing c6e43b1 to master...

### bors merged commit 7e9cb5b into rust-lang:master Apr 18, 2019 3 checks passed

#### 3 checks passed

Travis CI - Pull Request Build Passed
Details
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
homu Test successful
Details