Skip to content

Commit 9a7bf41

Browse files
author
Mason Ray Hanna III
committed
Added new lint for issue rust-lang#10655
1 parent 90cb0fa commit 9a7bf41

File tree

6 files changed

+87
-0
lines changed

6 files changed

+87
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4814,6 +4814,7 @@ Released 2018-09-13
48144814
[`partialeq_ne_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_ne_impl
48154815
[`partialeq_to_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_to_none
48164816
[`path_buf_push_overwrite`]: https://rust-lang.github.io/rust-clippy/master/index.html#path_buf_push_overwrite
4817+
[`path_join_correction`]: https://rust-lang.github.io/rust-clippy/master/index.html#path_join_correction
48174818
[`pattern_type_mismatch`]: https://rust-lang.github.io/rust-clippy/master/index.html#pattern_type_mismatch
48184819
[`permissions_set_readonly_false`]: https://rust-lang.github.io/rust-clippy/master/index.html#permissions_set_readonly_false
48194820
[`positional_named_format_parameters`]: https://rust-lang.github.io/rust-clippy/master/index.html#positional_named_format_parameters

clippy_lints/src/declared_lints.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
376376
crate::methods::OR_FUN_CALL_INFO,
377377
crate::methods::OR_THEN_UNWRAP_INFO,
378378
crate::methods::PATH_BUF_PUSH_OVERWRITE_INFO,
379+
crate::methods::PATH_JOIN_CORRECTION_INFO,
379380
crate::methods::RANGE_ZIP_WITH_LEN_INFO,
380381
crate::methods::REPEAT_ONCE_INFO,
381382
crate::methods::RESULT_MAP_OR_INTO_OPTION_INFO,

clippy_lints/src/methods/mod.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod path_join_correction;
12
mod bind_instead_of_map;
23
mod bytecount;
34
mod bytes_count_to_len;
@@ -3216,6 +3217,25 @@ declare_clippy_lint! {
32163217
"calling `drain` in order to `clear` a container"
32173218
}
32183219

3220+
declare_clippy_lint! {
3221+
/// ### What it does
3222+
///
3223+
/// ### Why is this bad?
3224+
///
3225+
/// ### Example
3226+
/// ```rust
3227+
/// // example code where clippy issues a warning
3228+
/// ```
3229+
/// Use instead:
3230+
/// ```rust
3231+
/// // example code which does not raise clippy warning
3232+
/// ```
3233+
#[clippy::version = "1.70.0"]
3234+
pub PATH_JOIN_CORRECTION,
3235+
pedantic,
3236+
"default lint description"
3237+
}
3238+
32193239
pub struct Methods {
32203240
avoid_breaking_exported_api: bool,
32213241
msrv: Msrv,
@@ -3345,6 +3365,7 @@ impl_lint_pass!(Methods => [
33453365
NEEDLESS_COLLECT,
33463366
SUSPICIOUS_COMMAND_ARG_SPACE,
33473367
CLEAR_WITH_DRAIN,
3368+
PATH_JOIN_CORRECTION,
33483369
]);
33493370

33503371
/// Extracts a method call name, args, and `Span` of the method name.
@@ -3655,7 +3676,11 @@ impl Methods {
36553676
if let Some(("collect", _, _, span, _)) = method_call(recv) {
36563677
unnecessary_join::check(cx, expr, recv, join_arg, span);
36573678
}
3679+
else {path_join_correction::check(cx, expr, join_arg, span);}
36583680
},
3681+
/*("join", [join_arg]) => {
3682+
path_join_correction::check(cx, expr, join_arg, span);
3683+
},*/
36593684
("last", []) | ("skip", [_]) => {
36603685
if let Some((name2, recv2, args2, _span2, _)) = method_call(recv) {
36613686
if let ("cloned", []) = (name2, args2) {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use clippy_utils::diagnostics::span_lint_and_sugg;
2+
use rustc_lint::{LateContext};
3+
use rustc_ast::ast::LitKind;
4+
use rustc_errors::Applicability;
5+
use rustc_hir::{Expr, ExprKind};
6+
use rustc_span::Span;
7+
8+
use super::PATH_JOIN_CORRECTION;
9+
10+
// TODO: Adjust the parameters as necessary
11+
12+
pub(super) fn check<'tcx>(
13+
cx: &LateContext<'tcx>,
14+
expr: &'tcx Expr<'tcx>,
15+
join_arg: &'tcx Expr<'tcx>,
16+
span: Span,
17+
) {
18+
let applicability = Applicability::MachineApplicable;
19+
if_chain!(
20+
if let ExprKind::Lit(spanned) = &join_arg.kind;
21+
if let LitKind::Str(symbol, _) = spanned.node;
22+
if symbol.as_str().starts_with('/');
23+
then {
24+
span_lint_and_sugg(
25+
cx,
26+
PATH_JOIN_CORRECTION,
27+
span.with_hi(expr.span.hi()),
28+
r#"argument in join called on path contains a starting '/'"#,
29+
"try removing first '/'",
30+
"join(\"your/path/here\")".to_owned(),
31+
applicability
32+
);
33+
}
34+
);
35+
}

tests/ui/path_join_correction.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![allow(unused)]
2+
#![warn(clippy::path_join_correction)]
3+
4+
fn main() {
5+
// should be linted
6+
let path = std::path::Path::new("/bin");
7+
path.join("/sh");
8+
println!("{}", path.display());
9+
10+
//should not be linted
11+
let path = std::path::Path::new("/bin");
12+
path.join("sh");
13+
println!("{}", path.display());
14+
15+
}

tests/ui/path_join_correction.stderr

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: argument in join called on path contains a starting '/'
2+
--> $DIR/path_join_correction.rs:7:8
3+
|
4+
LL | path.join("/sh");
5+
| ^^^^^^^^^^^ help: try removing first '/': `join("your/path/here")`
6+
|
7+
= note: `-D clippy::path-join-correction` implied by `-D warnings`
8+
9+
error: aborting due to previous error
10+

0 commit comments

Comments
 (0)