Skip to content

Commit 87efce4

Browse files
llogiqblyxyas
authored andcommitted
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`.
1 parent c6bf954 commit 87efce4

File tree

12 files changed

+97
-8
lines changed

12 files changed

+97
-8
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -5891,6 +5891,7 @@ Released 2018-09-13
58915891
[`allow-print-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-print-in-tests
58925892
[`allow-private-module-inception`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-private-module-inception
58935893
[`allow-unwrap-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-unwrap-in-tests
5894+
[`allow-useless-vec-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-useless-vec-in-tests
58945895
[`allowed-dotfiles`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-dotfiles
58955896
[`allowed-duplicate-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-duplicate-crates
58965897
[`allowed-idents-below-min-chars`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-idents-below-min-chars

book/src/lint_configuration.md

+10
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,16 @@ Whether `unwrap` should be allowed in test functions or `#[cfg(test)]`
132132
* [`unwrap_used`](https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used)
133133

134134

135+
## `allow-useless-vec-in-tests`
136+
Whether `useless_vec` should ignore test functions or `#[cfg(test)]`
137+
138+
**Default Value:** `false`
139+
140+
---
141+
**Affected lints:**
142+
* [`useless_vec`](https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec)
143+
144+
135145
## `allowed-dotfiles`
136146
Additional dotfiles (files or directories starting with a dot) to allow
137147

clippy_config/src/conf.rs

+4
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,10 @@ define_Conf! {
463463
///
464464
/// Whether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]`
465465
(allow_print_in_tests: bool = false),
466+
/// Lint: USELESS_VEC.
467+
///
468+
/// Whether `useless_vec` should ignore test functions or `#[cfg(test)]`
469+
(allow_useless_vec_in_tests: bool = false),
466470
/// Lint: RESULT_LARGE_ERR.
467471
///
468472
/// The maximum size of the `Err`-variant in a `Result` returned from a function

clippy_lints/src/dbg_macro.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
2+
use clippy_utils::is_in_test;
23
use clippy_utils::macros::{macro_backtrace, MacroCall};
34
use clippy_utils::source::snippet_with_applicability;
4-
use clippy_utils::{is_in_cfg_test, is_in_test_function};
55
use rustc_data_structures::fx::FxHashSet;
66
use rustc_errors::Applicability;
7-
use rustc_hir::{Expr, ExprKind, HirId, Node};
7+
use rustc_hir::{Expr, ExprKind, Node};
88
use rustc_lint::{LateContext, LateLintPass, LintContext};
99
use rustc_middle::lint::in_external_macro;
1010
use rustc_session::impl_lint_pass;
@@ -63,7 +63,7 @@ impl LateLintPass<'_> for DbgMacro {
6363
!in_external_macro(cx.sess(), macro_call.span) &&
6464
self.checked_dbg_call_site.insert(macro_call.span) &&
6565
// allows `dbg!` in test code if allow-dbg-in-test is set to true in clippy.toml
66-
!(self.allow_dbg_in_tests && is_in_test(cx, expr.hir_id))
66+
!(self.allow_dbg_in_tests && is_in_test(cx.tcx, expr.hir_id))
6767
{
6868
let mut applicability = Applicability::MachineApplicable;
6969

@@ -129,10 +129,6 @@ impl LateLintPass<'_> for DbgMacro {
129129
}
130130
}
131131

132-
fn is_in_test(cx: &LateContext<'_>, hir_id: HirId) -> bool {
133-
is_in_test_function(cx.tcx, hir_id) || is_in_cfg_test(cx.tcx, hir_id)
134-
}
135-
136132
fn first_dbg_macro_in_expansion(cx: &LateContext<'_>, span: Span) -> Option<MacroCall> {
137133
macro_backtrace(span).find(|mc| cx.tcx.is_diagnostic_item(sym::dbg_macro, mc.def_id))
138134
}

clippy_lints/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
535535
allow_print_in_tests,
536536
allow_private_module_inception,
537537
allow_unwrap_in_tests,
538+
allow_useless_vec_in_tests,
538539
ref allowed_dotfiles,
539540
ref allowed_idents_below_min_chars,
540541
ref allowed_scripts,
@@ -754,6 +755,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
754755
too_large_for_stack,
755756
msrv: msrv(),
756757
span_to_lint_map: BTreeMap::new(),
758+
allow_in_test: allow_useless_vec_in_tests,
757759
})
758760
});
759761
store.register_late_pass(|_| Box::new(panic_unimplemented::PanicUnimplemented));

clippy_lints/src/vec.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use clippy_utils::diagnostics::span_lint_hir_and_then;
77
use clippy_utils::source::snippet_opt;
88
use clippy_utils::ty::is_copy;
99
use clippy_utils::visitors::for_each_local_use_after_expr;
10-
use clippy_utils::{get_parent_expr, higher, is_trait_method};
10+
use clippy_utils::{get_parent_expr, higher, is_in_test, is_trait_method};
1111
use rustc_errors::Applicability;
1212
use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, LetStmt, Mutability, Node, Pat, PatKind};
1313
use rustc_lint::{LateContext, LateLintPass};
@@ -22,6 +22,7 @@ pub struct UselessVec {
2222
pub too_large_for_stack: u64,
2323
pub msrv: Msrv,
2424
pub span_to_lint_map: BTreeMap<Span, Option<(HirId, SuggestedType, String, Applicability)>>,
25+
pub allow_in_test: bool,
2526
}
2627

2728
declare_clippy_lint! {
@@ -57,6 +58,9 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
5758
let Some(vec_args) = higher::VecArgs::hir(cx, expr.peel_borrows()) else {
5859
return;
5960
};
61+
if self.allow_in_test && is_in_test(cx.tcx, expr.hir_id) {
62+
return;
63+
};
6064
// the parent callsite of this `vec!` expression, or span to the borrowed one such as `&vec!`
6165
let callsite = expr.span.parent_callsite().unwrap_or(expr.span);
6266

clippy_utils/src/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -2548,6 +2548,11 @@ pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool {
25482548
.any(|parent_id| is_cfg_test(tcx, parent_id))
25492549
}
25502550

2551+
/// Checks if the node is in a `#[test]` function or has any parent node marked `#[cfg(test)]`
2552+
pub fn is_in_test(tcx: TyCtxt<'_>, hir_id: HirId) -> bool {
2553+
is_in_test_function(tcx, hir_id) || is_in_cfg_test(tcx, hir_id)
2554+
}
2555+
25512556
/// Checks if the item of any of its parents has `#[cfg(...)]` attribute applied.
25522557
pub fn inherits_cfg(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
25532558
let hir = tcx.hir();

tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
1111
allow-print-in-tests
1212
allow-private-module-inception
1313
allow-unwrap-in-tests
14+
allow-useless-vec-in-tests
1415
allowed-dotfiles
1516
allowed-duplicate-crates
1617
allowed-idents-below-min-chars
@@ -91,6 +92,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
9192
allow-print-in-tests
9293
allow-private-module-inception
9394
allow-unwrap-in-tests
95+
allow-useless-vec-in-tests
9496
allowed-dotfiles
9597
allowed-duplicate-crates
9698
allowed-idents-below-min-chars
@@ -171,6 +173,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni
171173
allow-print-in-tests
172174
allow-private-module-inception
173175
allow-unwrap-in-tests
176+
allow-useless-vec-in-tests
174177
allowed-dotfiles
175178
allowed-duplicate-crates
176179
allowed-idents-below-min-chars

tests/ui-toml/useless_vec/clippy.toml

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
allow-useless-vec-in-tests = true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//@compile-flags: --test
2+
#![warn(clippy::useless_vec)]
3+
#![allow(clippy::unnecessary_operation, clippy::no_effect)]
4+
5+
fn foo(_: &[u32]) {}
6+
7+
fn main() {
8+
foo(&[1_u32]);
9+
}
10+
11+
#[test]
12+
pub fn in_test() {
13+
foo(&vec![2_u32]);
14+
}
15+
16+
#[cfg(test)]
17+
fn in_cfg_test() {
18+
foo(&vec![3_u32]);
19+
}
20+
21+
#[cfg(test)]
22+
mod mod1 {
23+
fn in_cfg_test_mod() {
24+
super::foo(&vec![4_u32]);
25+
}
26+
}
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//@compile-flags: --test
2+
#![warn(clippy::useless_vec)]
3+
#![allow(clippy::unnecessary_operation, clippy::no_effect)]
4+
5+
fn foo(_: &[u32]) {}
6+
7+
fn main() {
8+
foo(&vec![1_u32]);
9+
}
10+
11+
#[test]
12+
pub fn in_test() {
13+
foo(&vec![2_u32]);
14+
}
15+
16+
#[cfg(test)]
17+
fn in_cfg_test() {
18+
foo(&vec![3_u32]);
19+
}
20+
21+
#[cfg(test)]
22+
mod mod1 {
23+
fn in_cfg_test_mod() {
24+
super::foo(&vec![4_u32]);
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: useless use of `vec!`
2+
--> tests/ui-toml/useless_vec/useless_vec.rs:8:9
3+
|
4+
LL | foo(&vec![1_u32]);
5+
| ^^^^^^^^^^^^ help: you can use a slice directly: `&[1_u32]`
6+
|
7+
= note: `-D clippy::useless-vec` implied by `-D warnings`
8+
= help: to override `-D warnings` add `#[allow(clippy::useless_vec)]`
9+
10+
error: aborting due to 1 previous error
11+

0 commit comments

Comments
 (0)