Skip to content

Commit 5574182

Browse files
committed
Add a new lint to prevent create_dir from being used
1 parent 07c5e9e commit 5574182

File tree

7 files changed

+104
-0
lines changed

7 files changed

+104
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,6 +1444,7 @@ Released 2018-09-13
14441444
[`collapsible_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_if
14451445
[`comparison_chain`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_chain
14461446
[`copy_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#copy_iterator
1447+
[`create_dir`]: https://rust-lang.github.io/rust-clippy/master/index.html#create_dir
14471448
[`crosspointer_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#crosspointer_transmute
14481449
[`dbg_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro
14491450
[`debug_assert_with_mut_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#debug_assert_with_mut_call

clippy_lints/src/create_dir.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
use crate::utils::{match_qpath, snippet, span_lint_and_sugg};
2+
use if_chain::if_chain;
3+
use rustc_errors::Applicability;
4+
use rustc_hir::*;
5+
use rustc_lint::{LateContext, LateLintPass};
6+
use rustc_session::{declare_lint_pass, declare_tool_lint};
7+
8+
declare_clippy_lint! {
9+
/// **What it does:** Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead.
10+
///
11+
/// **Why is this bad?** Sometimes `std::fs::crate_dir` is mistakenly chosen over `std::fs::create_dir_all`.
12+
///
13+
/// **Known problems:** None.
14+
///
15+
/// **Example:**
16+
///
17+
/// ```rust
18+
/// std::fs::create_dir("foo")
19+
/// ```
20+
/// Use instead:
21+
/// ```rust
22+
/// std::fs::create_dir_all("foo")
23+
/// ```
24+
pub CREATE_DIR,
25+
restriction,
26+
"calling `std::fs::create_dir` instead of `std::fs::create_dir_all`"
27+
}
28+
29+
declare_lint_pass!(CreateDir => [CREATE_DIR]);
30+
31+
impl LateLintPass<'_> for CreateDir {
32+
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
33+
if_chain! {
34+
if let ExprKind::Call(ref func, ref args) = expr.kind;
35+
if let ExprKind::Path(ref path) = func.kind;
36+
if match_qpath(path, &["std", "fs", "create_dir"]);
37+
then {
38+
span_lint_and_sugg(
39+
cx,
40+
CREATE_DIR,
41+
expr.span,
42+
"calling `std::fs::create_dir` where there may be a better way",
43+
"consider calling `std::fs::create_dir_all` instead",
44+
format!("std::fs::create_dir_all({})", snippet(cx, args[0].span, "..")),
45+
Applicability::MachineApplicable,
46+
)
47+
}
48+
}
49+
}
50+
}

clippy_lints/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ mod collapsible_if;
169169
mod comparison_chain;
170170
mod copies;
171171
mod copy_iterator;
172+
mod create_dir;
172173
mod dbg_macro;
173174
mod default_trait_access;
174175
mod dereference;
@@ -511,6 +512,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
511512
&copies::MATCH_SAME_ARMS,
512513
&copies::SAME_FUNCTIONS_IN_IF_CONDITION,
513514
&copy_iterator::COPY_ITERATOR,
515+
&create_dir::CREATE_DIR,
514516
&dbg_macro::DBG_MACRO,
515517
&default_trait_access::DEFAULT_TRAIT_ACCESS,
516518
&dereference::EXPLICIT_DEREF_METHODS,
@@ -1042,6 +1044,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
10421044
store.register_early_pass(|| box items_after_statements::ItemsAfterStatements);
10431045
store.register_early_pass(|| box precedence::Precedence);
10441046
store.register_early_pass(|| box needless_continue::NeedlessContinue);
1047+
store.register_late_pass(|| box create_dir::CreateDir);
10451048
store.register_early_pass(|| box needless_arbitrary_self_type::NeedlessArbitrarySelfType);
10461049
store.register_early_pass(|| box redundant_static_lifetimes::RedundantStaticLifetimes);
10471050
store.register_late_pass(|| box cargo_common_metadata::CargoCommonMetadata);
@@ -1104,6 +1107,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
11041107
LintId::of(&arithmetic::FLOAT_ARITHMETIC),
11051108
LintId::of(&arithmetic::INTEGER_ARITHMETIC),
11061109
LintId::of(&as_conversions::AS_CONVERSIONS),
1110+
LintId::of(&create_dir::CREATE_DIR),
11071111
LintId::of(&dbg_macro::DBG_MACRO),
11081112
LintId::of(&else_if_without_else::ELSE_IF_WITHOUT_ELSE),
11091113
LintId::of(&exit::EXIT),

src/lintlist/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,13 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
290290
deprecation: None,
291291
module: "copy_iterator",
292292
},
293+
Lint {
294+
name: "create_dir",
295+
group: "restriction",
296+
desc: "calling `std::fs::create_dir` instead of `std::fs::create_dir_all`",
297+
deprecation: None,
298+
module: "create_dir",
299+
},
293300
Lint {
294301
name: "crosspointer_transmute",
295302
group: "complexity",

tests/ui/create_dir.fixed

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// run-rustfix
2+
#![allow(unused_must_use)]
3+
#![warn(clippy::create_dir)]
4+
5+
fn not_create_dir() {}
6+
7+
fn main() {
8+
std::fs::create_dir_all("foo");
9+
std::fs::create_dir_all("bar").unwrap();
10+
11+
not_create_dir();
12+
std::fs::create_dir_all("foobar");
13+
}

tests/ui/create_dir.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// run-rustfix
2+
#![allow(unused_must_use)]
3+
#![warn(clippy::create_dir)]
4+
5+
fn not_create_dir() {}
6+
7+
fn main() {
8+
std::fs::create_dir("foo");
9+
std::fs::create_dir("bar").unwrap();
10+
11+
not_create_dir();
12+
std::fs::create_dir_all("foobar");
13+
}

tests/ui/create_dir.stderr

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error: calling `std::fs::create_dir` where there may be a better way
2+
--> $DIR/create_dir.rs:8:5
3+
|
4+
LL | std::fs::create_dir("foo");
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `std::fs::create_dir_all` instead: `std::fs::create_dir_all("foo")`
6+
|
7+
= note: `-D clippy::create-dir` implied by `-D warnings`
8+
9+
error: calling `std::fs::create_dir` where there may be a better way
10+
--> $DIR/create_dir.rs:9:5
11+
|
12+
LL | std::fs::create_dir("bar").unwrap();
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `std::fs::create_dir_all` instead: `std::fs::create_dir_all("bar")`
14+
15+
error: aborting due to 2 previous errors
16+

0 commit comments

Comments
 (0)