mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-23 05:03:21 +00:00
configurably allow useless_vec
in tests
This adds a `àllow-useless-vec-in-test` configuration which, when set to `true` will allow the `useless_vec` lint in `#[test]` functions and code within `#[cfg(test)]`. It also moves a `is_in_test` helper to `clippy_utils`.
This commit is contained in:
parent
c6bf9548d5
commit
87efce4fa2
12 changed files with 97 additions and 8 deletions
|
@ -5891,6 +5891,7 @@ Released 2018-09-13
|
||||||
[`allow-print-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-print-in-tests
|
[`allow-print-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-print-in-tests
|
||||||
[`allow-private-module-inception`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-private-module-inception
|
[`allow-private-module-inception`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-private-module-inception
|
||||||
[`allow-unwrap-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-unwrap-in-tests
|
[`allow-unwrap-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-unwrap-in-tests
|
||||||
|
[`allow-useless-vec-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-useless-vec-in-tests
|
||||||
[`allowed-dotfiles`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-dotfiles
|
[`allowed-dotfiles`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-dotfiles
|
||||||
[`allowed-duplicate-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-duplicate-crates
|
[`allowed-duplicate-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-duplicate-crates
|
||||||
[`allowed-idents-below-min-chars`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-idents-below-min-chars
|
[`allowed-idents-below-min-chars`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-idents-below-min-chars
|
||||||
|
|
|
@ -132,6 +132,16 @@ Whether `unwrap` should be allowed in test functions or `#[cfg(test)]`
|
||||||
* [`unwrap_used`](https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used)
|
* [`unwrap_used`](https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used)
|
||||||
|
|
||||||
|
|
||||||
|
## `allow-useless-vec-in-tests`
|
||||||
|
Whether `useless_vec` should ignore test functions or `#[cfg(test)]`
|
||||||
|
|
||||||
|
**Default Value:** `false`
|
||||||
|
|
||||||
|
---
|
||||||
|
**Affected lints:**
|
||||||
|
* [`useless_vec`](https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec)
|
||||||
|
|
||||||
|
|
||||||
## `allowed-dotfiles`
|
## `allowed-dotfiles`
|
||||||
Additional dotfiles (files or directories starting with a dot) to allow
|
Additional dotfiles (files or directories starting with a dot) to allow
|
||||||
|
|
||||||
|
|
|
@ -463,6 +463,10 @@ define_Conf! {
|
||||||
///
|
///
|
||||||
/// Whether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]`
|
/// Whether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]`
|
||||||
(allow_print_in_tests: bool = false),
|
(allow_print_in_tests: bool = false),
|
||||||
|
/// Lint: USELESS_VEC.
|
||||||
|
///
|
||||||
|
/// Whether `useless_vec` should ignore test functions or `#[cfg(test)]`
|
||||||
|
(allow_useless_vec_in_tests: bool = false),
|
||||||
/// Lint: RESULT_LARGE_ERR.
|
/// Lint: RESULT_LARGE_ERR.
|
||||||
///
|
///
|
||||||
/// The maximum size of the `Err`-variant in a `Result` returned from a function
|
/// The maximum size of the `Err`-variant in a `Result` returned from a function
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
|
use clippy_utils::is_in_test;
|
||||||
use clippy_utils::macros::{macro_backtrace, MacroCall};
|
use clippy_utils::macros::{macro_backtrace, MacroCall};
|
||||||
use clippy_utils::source::snippet_with_applicability;
|
use clippy_utils::source::snippet_with_applicability;
|
||||||
use clippy_utils::{is_in_cfg_test, is_in_test_function};
|
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{Expr, ExprKind, HirId, Node};
|
use rustc_hir::{Expr, ExprKind, Node};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
|
@ -63,7 +63,7 @@ impl LateLintPass<'_> for DbgMacro {
|
||||||
!in_external_macro(cx.sess(), macro_call.span) &&
|
!in_external_macro(cx.sess(), macro_call.span) &&
|
||||||
self.checked_dbg_call_site.insert(macro_call.span) &&
|
self.checked_dbg_call_site.insert(macro_call.span) &&
|
||||||
// allows `dbg!` in test code if allow-dbg-in-test is set to true in clippy.toml
|
// allows `dbg!` in test code if allow-dbg-in-test is set to true in clippy.toml
|
||||||
!(self.allow_dbg_in_tests && is_in_test(cx, expr.hir_id))
|
!(self.allow_dbg_in_tests && is_in_test(cx.tcx, expr.hir_id))
|
||||||
{
|
{
|
||||||
let mut applicability = Applicability::MachineApplicable;
|
let mut applicability = Applicability::MachineApplicable;
|
||||||
|
|
||||||
|
@ -129,10 +129,6 @@ impl LateLintPass<'_> for DbgMacro {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_in_test(cx: &LateContext<'_>, hir_id: HirId) -> bool {
|
|
||||||
is_in_test_function(cx.tcx, hir_id) || is_in_cfg_test(cx.tcx, hir_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn first_dbg_macro_in_expansion(cx: &LateContext<'_>, span: Span) -> Option<MacroCall> {
|
fn first_dbg_macro_in_expansion(cx: &LateContext<'_>, span: Span) -> Option<MacroCall> {
|
||||||
macro_backtrace(span).find(|mc| cx.tcx.is_diagnostic_item(sym::dbg_macro, mc.def_id))
|
macro_backtrace(span).find(|mc| cx.tcx.is_diagnostic_item(sym::dbg_macro, mc.def_id))
|
||||||
}
|
}
|
||||||
|
|
|
@ -535,6 +535,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
|
||||||
allow_print_in_tests,
|
allow_print_in_tests,
|
||||||
allow_private_module_inception,
|
allow_private_module_inception,
|
||||||
allow_unwrap_in_tests,
|
allow_unwrap_in_tests,
|
||||||
|
allow_useless_vec_in_tests,
|
||||||
ref allowed_dotfiles,
|
ref allowed_dotfiles,
|
||||||
ref allowed_idents_below_min_chars,
|
ref allowed_idents_below_min_chars,
|
||||||
ref allowed_scripts,
|
ref allowed_scripts,
|
||||||
|
@ -754,6 +755,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
|
||||||
too_large_for_stack,
|
too_large_for_stack,
|
||||||
msrv: msrv(),
|
msrv: msrv(),
|
||||||
span_to_lint_map: BTreeMap::new(),
|
span_to_lint_map: BTreeMap::new(),
|
||||||
|
allow_in_test: allow_useless_vec_in_tests,
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
store.register_late_pass(|_| Box::new(panic_unimplemented::PanicUnimplemented));
|
store.register_late_pass(|_| Box::new(panic_unimplemented::PanicUnimplemented));
|
||||||
|
|
|
@ -7,7 +7,7 @@ use clippy_utils::diagnostics::span_lint_hir_and_then;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::snippet_opt;
|
||||||
use clippy_utils::ty::is_copy;
|
use clippy_utils::ty::is_copy;
|
||||||
use clippy_utils::visitors::for_each_local_use_after_expr;
|
use clippy_utils::visitors::for_each_local_use_after_expr;
|
||||||
use clippy_utils::{get_parent_expr, higher, is_trait_method};
|
use clippy_utils::{get_parent_expr, higher, is_in_test, is_trait_method};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, LetStmt, Mutability, Node, Pat, PatKind};
|
use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, LetStmt, Mutability, Node, Pat, PatKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
|
@ -22,6 +22,7 @@ pub struct UselessVec {
|
||||||
pub too_large_for_stack: u64,
|
pub too_large_for_stack: u64,
|
||||||
pub msrv: Msrv,
|
pub msrv: Msrv,
|
||||||
pub span_to_lint_map: BTreeMap<Span, Option<(HirId, SuggestedType, String, Applicability)>>,
|
pub span_to_lint_map: BTreeMap<Span, Option<(HirId, SuggestedType, String, Applicability)>>,
|
||||||
|
pub allow_in_test: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
|
@ -57,6 +58,9 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
|
||||||
let Some(vec_args) = higher::VecArgs::hir(cx, expr.peel_borrows()) else {
|
let Some(vec_args) = higher::VecArgs::hir(cx, expr.peel_borrows()) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
if self.allow_in_test && is_in_test(cx.tcx, expr.hir_id) {
|
||||||
|
return;
|
||||||
|
};
|
||||||
// the parent callsite of this `vec!` expression, or span to the borrowed one such as `&vec!`
|
// the parent callsite of this `vec!` expression, or span to the borrowed one such as `&vec!`
|
||||||
let callsite = expr.span.parent_callsite().unwrap_or(expr.span);
|
let callsite = expr.span.parent_callsite().unwrap_or(expr.span);
|
||||||
|
|
||||||
|
|
|
@ -2548,6 +2548,11 @@ pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool {
|
||||||
.any(|parent_id| is_cfg_test(tcx, parent_id))
|
.any(|parent_id| is_cfg_test(tcx, parent_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks if the node is in a `#[test]` function or has any parent node marked `#[cfg(test)]`
|
||||||
|
pub fn is_in_test(tcx: TyCtxt<'_>, hir_id: HirId) -> bool {
|
||||||
|
is_in_test_function(tcx, hir_id) || is_in_cfg_test(tcx, hir_id)
|
||||||
|
}
|
||||||
|
|
||||||
/// Checks if the item of any of its parents has `#[cfg(...)]` attribute applied.
|
/// Checks if the item of any of its parents has `#[cfg(...)]` attribute applied.
|
||||||
pub fn inherits_cfg(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
|
pub fn inherits_cfg(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
|
||||||
let hir = tcx.hir();
|
let hir = tcx.hir();
|
||||||
|
|
|
@ -11,6 +11,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
|
||||||
allow-print-in-tests
|
allow-print-in-tests
|
||||||
allow-private-module-inception
|
allow-private-module-inception
|
||||||
allow-unwrap-in-tests
|
allow-unwrap-in-tests
|
||||||
|
allow-useless-vec-in-tests
|
||||||
allowed-dotfiles
|
allowed-dotfiles
|
||||||
allowed-duplicate-crates
|
allowed-duplicate-crates
|
||||||
allowed-idents-below-min-chars
|
allowed-idents-below-min-chars
|
||||||
|
@ -91,6 +92,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
|
||||||
allow-print-in-tests
|
allow-print-in-tests
|
||||||
allow-private-module-inception
|
allow-private-module-inception
|
||||||
allow-unwrap-in-tests
|
allow-unwrap-in-tests
|
||||||
|
allow-useless-vec-in-tests
|
||||||
allowed-dotfiles
|
allowed-dotfiles
|
||||||
allowed-duplicate-crates
|
allowed-duplicate-crates
|
||||||
allowed-idents-below-min-chars
|
allowed-idents-below-min-chars
|
||||||
|
@ -171,6 +173,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni
|
||||||
allow-print-in-tests
|
allow-print-in-tests
|
||||||
allow-private-module-inception
|
allow-private-module-inception
|
||||||
allow-unwrap-in-tests
|
allow-unwrap-in-tests
|
||||||
|
allow-useless-vec-in-tests
|
||||||
allowed-dotfiles
|
allowed-dotfiles
|
||||||
allowed-duplicate-crates
|
allowed-duplicate-crates
|
||||||
allowed-idents-below-min-chars
|
allowed-idents-below-min-chars
|
||||||
|
|
1
tests/ui-toml/useless_vec/clippy.toml
Normal file
1
tests/ui-toml/useless_vec/clippy.toml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
allow-useless-vec-in-tests = true
|
26
tests/ui-toml/useless_vec/useless_vec.fixed
Normal file
26
tests/ui-toml/useless_vec/useless_vec.fixed
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
//@compile-flags: --test
|
||||||
|
#![warn(clippy::useless_vec)]
|
||||||
|
#![allow(clippy::unnecessary_operation, clippy::no_effect)]
|
||||||
|
|
||||||
|
fn foo(_: &[u32]) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
foo(&[1_u32]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn in_test() {
|
||||||
|
foo(&vec![2_u32]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
fn in_cfg_test() {
|
||||||
|
foo(&vec![3_u32]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod mod1 {
|
||||||
|
fn in_cfg_test_mod() {
|
||||||
|
super::foo(&vec![4_u32]);
|
||||||
|
}
|
||||||
|
}
|
26
tests/ui-toml/useless_vec/useless_vec.rs
Normal file
26
tests/ui-toml/useless_vec/useless_vec.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
//@compile-flags: --test
|
||||||
|
#![warn(clippy::useless_vec)]
|
||||||
|
#![allow(clippy::unnecessary_operation, clippy::no_effect)]
|
||||||
|
|
||||||
|
fn foo(_: &[u32]) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
foo(&vec![1_u32]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn in_test() {
|
||||||
|
foo(&vec![2_u32]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
fn in_cfg_test() {
|
||||||
|
foo(&vec![3_u32]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod mod1 {
|
||||||
|
fn in_cfg_test_mod() {
|
||||||
|
super::foo(&vec![4_u32]);
|
||||||
|
}
|
||||||
|
}
|
11
tests/ui-toml/useless_vec/useless_vec.stderr
Normal file
11
tests/ui-toml/useless_vec/useless_vec.stderr
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
error: useless use of `vec!`
|
||||||
|
--> tests/ui-toml/useless_vec/useless_vec.rs:8:9
|
||||||
|
|
|
||||||
|
LL | foo(&vec![1_u32]);
|
||||||
|
| ^^^^^^^^^^^^ help: you can use a slice directly: `&[1_u32]`
|
||||||
|
|
|
||||||
|
= note: `-D clippy::useless-vec` implied by `-D warnings`
|
||||||
|
= help: to override `-D warnings` add `#[allow(clippy::useless_vec)]`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
Loading…
Reference in a new issue