diff options
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | clippy_lints/src/create_dir.rs | 51 | ||||
| -rw-r--r-- | clippy_lints/src/lib.rs | 4 | ||||
| -rw-r--r-- | clippy_lints/src/utils/paths.rs | 1 | ||||
| -rw-r--r-- | src/lintlist/mod.rs | 7 | ||||
| -rw-r--r-- | tests/ui/create_dir.fixed | 17 | ||||
| -rw-r--r-- | tests/ui/create_dir.rs | 17 | ||||
| -rw-r--r-- | tests/ui/create_dir.stderr | 16 |
8 files changed, 114 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 99a8b1a6293..64f9379b303 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1547,6 +1547,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 diff --git a/clippy_lints/src/create_dir.rs b/clippy_lints/src/create_dir.rs new file mode 100644 index 00000000000..4002fb655a5 --- /dev/null +++ b/clippy_lints/src/create_dir.rs @@ -0,0 +1,51 @@ +use crate::utils::{match_def_path, paths, snippet, span_lint_and_sugg}; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind}; +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 let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id(); + if match_def_path(cx, def_id, &paths::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!("create_dir_all({})", snippet(cx, args[0].span, "..")), + Applicability::MaybeIncorrect, + ) + } + } + } +} diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 0eb1d331366..2020ef78509 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -170,6 +170,7 @@ mod collapsible_if; mod comparison_chain; mod copies; mod copy_iterator; +mod create_dir; mod dbg_macro; mod default_trait_access; mod dereference; @@ -513,6 +514,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &copies::MATCH_SAME_ARMS, &copies::SAME_FUNCTIONS_IN_IF_CONDITION, ©_iterator::COPY_ITERATOR, + &create_dir::CREATE_DIR, &dbg_macro::DBG_MACRO, &default_trait_access::DEFAULT_TRAIT_ACCESS, &dereference::EXPLICIT_DEREF_METHODS, @@ -1044,6 +1046,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); @@ -1107,6 +1110,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), diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs index d44854aefe9..65320d6a0e0 100644 --- a/clippy_lints/src/utils/paths.rs +++ b/clippy_lints/src/utils/paths.rs @@ -110,6 +110,7 @@ pub const SLICE_ITER: [&str; 3] = ["core", "slice", "Iter"]; pub const STDERR: [&str; 4] = ["std", "io", "stdio", "stderr"]; pub const STDOUT: [&str; 4] = ["std", "io", "stdio", "stdout"]; pub const STD_CONVERT_IDENTITY: [&str; 3] = ["std", "convert", "identity"]; +pub const STD_FS_CREATE_DIR: [&str; 3] = ["std", "fs", "create_dir"]; pub const STD_MEM_TRANSMUTE: [&str; 3] = ["std", "mem", "transmute"]; pub const STD_PTR_NULL: [&str; 3] = ["std", "ptr", "null"]; pub const STRING_AS_MUT_STR: [&str; 4] = ["alloc", "string", "String", "as_mut_str"]; diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs index dff19ef440f..6697835e950 100644 --- a/src/lintlist/mod.rs +++ b/src/lintlist/mod.rs @@ -298,6 +298,13 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![ 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", desc: "transmutes that have to or from types that are a pointer to the other", diff --git a/tests/ui/create_dir.fixed b/tests/ui/create_dir.fixed new file mode 100644 index 00000000000..8ed53a56ac0 --- /dev/null +++ b/tests/ui/create_dir.fixed @@ -0,0 +1,17 @@ +// run-rustfix +#![allow(unused_must_use)] +#![warn(clippy::create_dir)] + +use std::fs::create_dir_all; + +fn create_dir() {} + +fn main() { + // Should be warned + create_dir_all("foo"); + create_dir_all("bar").unwrap(); + + // Shouldn't be warned + create_dir(); + std::fs::create_dir_all("foobar"); +} diff --git a/tests/ui/create_dir.rs b/tests/ui/create_dir.rs new file mode 100644 index 00000000000..19c8fc24ba2 --- /dev/null +++ b/tests/ui/create_dir.rs @@ -0,0 +1,17 @@ +// run-rustfix +#![allow(unused_must_use)] +#![warn(clippy::create_dir)] + +use std::fs::create_dir_all; + +fn create_dir() {} + +fn main() { + // Should be warned + std::fs::create_dir("foo"); + std::fs::create_dir("bar").unwrap(); + + // Shouldn't be warned + create_dir(); + std::fs::create_dir_all("foobar"); +} diff --git a/tests/ui/create_dir.stderr b/tests/ui/create_dir.stderr new file mode 100644 index 00000000000..67298fc4709 --- /dev/null +++ b/tests/ui/create_dir.stderr @@ -0,0 +1,16 @@ +error: calling `std::fs::create_dir` where there may be a better way + --> $DIR/create_dir.rs:11:5 + | +LL | std::fs::create_dir("foo"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `std::fs::create_dir_all` instead: `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:12:5 + | +LL | std::fs::create_dir("bar").unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `std::fs::create_dir_all` instead: `create_dir_all("bar")` + +error: aborting due to 2 previous errors + |
