Add a new lint to prevent create_dir from being used

This commit is contained in:
Hirochika Matsumoto 2020-08-28 18:40:22 +09:00
parent 07c5e9edb5
commit 5574182b4d
7 changed files with 104 additions and 0 deletions

View file

@ -1444,6 +1444,7 @@ Released 2018-09-13
[`collapsible_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_if
[`comparison_chain`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_chain
[`copy_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#copy_iterator
[`create_dir`]: https://rust-lang.github.io/rust-clippy/master/index.html#create_dir
[`crosspointer_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#crosspointer_transmute
[`dbg_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro
[`debug_assert_with_mut_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#debug_assert_with_mut_call

View file

@ -0,0 +1,50 @@
use crate::utils::{match_qpath, snippet, span_lint_and_sugg};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::*;
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! {
/// **What it does:** Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead.
///
/// **Why is this bad?** Sometimes `std::fs::crate_dir` is mistakenly chosen over `std::fs::create_dir_all`.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```rust
/// std::fs::create_dir("foo")
/// ```
/// Use instead:
/// ```rust
/// std::fs::create_dir_all("foo")
/// ```
pub CREATE_DIR,
restriction,
"calling `std::fs::create_dir` instead of `std::fs::create_dir_all`"
}
declare_lint_pass!(CreateDir => [CREATE_DIR]);
impl LateLintPass<'_> for CreateDir {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
if_chain! {
if let ExprKind::Call(ref func, ref args) = expr.kind;
if let ExprKind::Path(ref path) = func.kind;
if match_qpath(path, &["std", "fs", "create_dir"]);
then {
span_lint_and_sugg(
cx,
CREATE_DIR,
expr.span,
"calling `std::fs::create_dir` where there may be a better way",
"consider calling `std::fs::create_dir_all` instead",
format!("std::fs::create_dir_all({})", snippet(cx, args[0].span, "..")),
Applicability::MachineApplicable,
)
}
}
}
}

View file

@ -169,6 +169,7 @@ mod collapsible_if;
mod comparison_chain;
mod copies;
mod copy_iterator;
mod create_dir;
mod dbg_macro;
mod default_trait_access;
mod dereference;
@ -511,6 +512,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
&copies::MATCH_SAME_ARMS,
&copies::SAME_FUNCTIONS_IN_IF_CONDITION,
&copy_iterator::COPY_ITERATOR,
&create_dir::CREATE_DIR,
&dbg_macro::DBG_MACRO,
&default_trait_access::DEFAULT_TRAIT_ACCESS,
&dereference::EXPLICIT_DEREF_METHODS,
@ -1042,6 +1044,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_early_pass(|| box items_after_statements::ItemsAfterStatements);
store.register_early_pass(|| box precedence::Precedence);
store.register_early_pass(|| box needless_continue::NeedlessContinue);
store.register_late_pass(|| box create_dir::CreateDir);
store.register_early_pass(|| box needless_arbitrary_self_type::NeedlessArbitrarySelfType);
store.register_early_pass(|| box redundant_static_lifetimes::RedundantStaticLifetimes);
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:
LintId::of(&arithmetic::FLOAT_ARITHMETIC),
LintId::of(&arithmetic::INTEGER_ARITHMETIC),
LintId::of(&as_conversions::AS_CONVERSIONS),
LintId::of(&create_dir::CREATE_DIR),
LintId::of(&dbg_macro::DBG_MACRO),
LintId::of(&else_if_without_else::ELSE_IF_WITHOUT_ELSE),
LintId::of(&exit::EXIT),

View file

@ -290,6 +290,13 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
deprecation: None,
module: "copy_iterator",
},
Lint {
name: "create_dir",
group: "restriction",
desc: "calling `std::fs::create_dir` instead of `std::fs::create_dir_all`",
deprecation: None,
module: "create_dir",
},
Lint {
name: "crosspointer_transmute",
group: "complexity",

13
tests/ui/create_dir.fixed Normal file
View file

@ -0,0 +1,13 @@
// run-rustfix
#![allow(unused_must_use)]
#![warn(clippy::create_dir)]
fn not_create_dir() {}
fn main() {
std::fs::create_dir_all("foo");
std::fs::create_dir_all("bar").unwrap();
not_create_dir();
std::fs::create_dir_all("foobar");
}

13
tests/ui/create_dir.rs Normal file
View file

@ -0,0 +1,13 @@
// run-rustfix
#![allow(unused_must_use)]
#![warn(clippy::create_dir)]
fn not_create_dir() {}
fn main() {
std::fs::create_dir("foo");
std::fs::create_dir("bar").unwrap();
not_create_dir();
std::fs::create_dir_all("foobar");
}

View file

@ -0,0 +1,16 @@
error: calling `std::fs::create_dir` where there may be a better way
--> $DIR/create_dir.rs:8:5
|
LL | std::fs::create_dir("foo");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `std::fs::create_dir_all` instead: `std::fs::create_dir_all("foo")`
|
= note: `-D clippy::create-dir` implied by `-D warnings`
error: calling `std::fs::create_dir` where there may be a better way
--> $DIR/create_dir.rs:9:5
|
LL | std::fs::create_dir("bar").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `std::fs::create_dir_all` instead: `std::fs::create_dir_all("bar")`
error: aborting due to 2 previous errors