Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7790,6 +7790,7 @@ Released 2018-09-13
[`allow-exact-repetitions`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-exact-repetitions
[`allow-expect-in-consts`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-expect-in-consts
[`allow-expect-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-expect-in-tests
[`allow-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-in-tests
[`allow-indexing-slicing-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-indexing-slicing-in-tests
[`allow-large-stack-frames-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-large-stack-frames-in-tests
[`allow-mixed-uninlined-format-args`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-mixed-uninlined-format-args
Expand Down
64 changes: 64 additions & 0 deletions book/src/lint_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ Don't lint when comparing the result of a modulo operation to zero.
## `allow-dbg-in-tests`
Whether `dbg!` should be allowed in test functions or `#[cfg(test)]`

Deprecated in favor of [`allow-in-tests`](#allow-in-tests): write
`allow-in-tests = ["dbg_macro"]` instead. This option still works.

**Default Value:** `false`

---
Expand Down Expand Up @@ -94,16 +97,65 @@ Whether `expect` should be allowed in code always evaluated at compile time
## `allow-expect-in-tests`
Whether `expect` should be allowed in test functions or `#[cfg(test)]`

Deprecated in favor of [`allow-in-tests`](#allow-in-tests): write
`allow-in-tests = ["expect_used"]` instead. This option still works.

**Default Value:** `false`

---
**Affected lints:**
* [`expect_used`](https://rust-lang.github.io/rust-clippy/main/index.html#expect_used)


## `allow-in-tests`
A list of Clippy lints to suppress in test functions and `#[cfg(test)]` items.

Entries are **lint names**, and only the lints named here are affected. This is not a
blanket "allow everything in tests" switch: a lint you don't list keeps firing in test
code, and lints added to Clippy in future releases are never included unless you add
them.

```toml
# `.expect()` is allowed in tests; `dbg!` is still reported there.
allow-in-tests = ["expect_used"]
```

#### Replaces the per-lint options

The older options are deprecated but still honored. Note that an option's name does not
always match the lint's, so the replacements are:

| deprecated option | write instead |
| --- | --- |
| `allow-dbg-in-tests = true` | `allow-in-tests = ["dbg_macro"]` |
| `allow-expect-in-tests = true` | `allow-in-tests = ["expect_used"]` |
| `allow-indexing-slicing-in-tests = true` | `allow-in-tests = ["indexing_slicing"]` |
| `allow-panic-in-tests = true` | `allow-in-tests = ["panic"]` |
| `allow-print-in-tests = true` | `allow-in-tests = ["print_stderr", "print_stdout"]` |
| `allow-unwrap-in-tests = true` | `allow-in-tests = ["unwrap_used"]` |
| `allow-useless-vec-in-tests = true` | `allow-in-tests = ["useless_vec"]` |

The two combine permissively: a lint is suppressed in test code if it is listed here
**or** its own option is set to `true`. Setting that option to `false` does not cancel a
listing here.

#### Noteworthy

- This only suppresses lints. It cannot make a lint fire in test code that would not
fire otherwise.
- Suppressing a lint leaves an `#[expect]` for it in test code unfulfilled, so such an
attribute will report `unfulfilled_lint_expectations`. This matches how the older
per-lint options have always behaved.

**Default Value:** `[]`


## `allow-indexing-slicing-in-tests`
Whether `indexing_slicing` should be allowed in test functions or `#[cfg(test)]`

Deprecated in favor of [`allow-in-tests`](#allow-in-tests): write
`allow-in-tests = ["indexing_slicing"]` instead. This option still works.

**Default Value:** `false`

---
Expand Down Expand Up @@ -144,6 +196,9 @@ Whether to allow `r#""#` when `r""` can be used
## `allow-panic-in-tests`
Whether `panic` should be allowed in test functions or `#[cfg(test)]`

Deprecated in favor of [`allow-in-tests`](#allow-in-tests): write
`allow-in-tests = ["panic"]` instead. This option still works.

**Default Value:** `false`

---
Expand All @@ -154,6 +209,9 @@ Whether `panic` should be allowed in test functions or `#[cfg(test)]`
## `allow-print-in-tests`
Whether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]`

Deprecated in favor of [`allow-in-tests`](#allow-in-tests): write
`allow-in-tests = ["print_stderr", "print_stdout"]` instead. This option still works.

**Default Value:** `false`

---
Expand Down Expand Up @@ -207,6 +265,9 @@ Whether `unwrap` should be allowed in code always evaluated at compile time
## `allow-unwrap-in-tests`
Whether `unwrap` should be allowed in test functions or `#[cfg(test)]`

Deprecated in favor of [`allow-in-tests`](#allow-in-tests): write
`allow-in-tests = ["unwrap_used"]` instead. This option still works.

**Default Value:** `false`

---
Expand Down Expand Up @@ -234,6 +295,9 @@ allow-unwrap-types = [ "std::sync::LockResult" ]
## `allow-useless-vec-in-tests`
Whether `useless_vec` should ignore test functions or `#[cfg(test)]`

Deprecated in favor of [`allow-in-tests`](#allow-in-tests): write
`allow-in-tests = ["useless_vec"]` instead. This option still works.

**Default Value:** `false`

---
Expand Down
98 changes: 97 additions & 1 deletion clippy_config/src/conf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
use rustc_hir::attrs::RustcVersion;
use rustc_session::Session;
use rustc_span::{Pos as _, SourceFile, Symbol};
use rustc_span::{Pos as _, SourceFile, Spanned, Symbol};
use std::path::PathBuf;
use std::sync::{Arc, OnceLock};
use std::{env, fs, io};
Expand Down Expand Up @@ -77,6 +77,16 @@ macro_rules! define_Conf {
$(#[doc = $doc:literal])*
$(#[default_text = $default_text:literal])?
$(#[rename = $new_name:ident])?
// Marks a `bool` field superseded by `allow-in-tests`, recording the lints its
// replacement should list. Documentation only for now: the option keeps working and
// says so in its docs, but setting it does not warn.
//
// TODO: once `allow-in-tests` has shipped in a stable release, emit a deprecation
// warning from here when the field is set to `true`. Setting one to `false` is the
// default and should stay silent, as `allow-in-tests` has no equivalent for it.
//
// Must precede `#[lints]`, which `cargo dev fmt` always re-emits last.
$(#[replaced_by_allow_in_tests($($replacement_lints:ident),* $(,)?)])?
$(#[lints($($for_lints:ident),* $(,)?)])?
// The type must exist for regular fields and shouldn't exist for deprecated ones.
$name:ident($name_str:literal) $(: $ty:ty $(= $default:expr)?)?,
Expand Down Expand Up @@ -215,6 +225,25 @@ macro_rules! define_Conf {
fn check_conf_names() {$(
assert_eq!(stringify!($name).replace('_', "-"), $name_str);
)*}

/// `#[replaced_by_allow_in_tests]` records the replacement in machine-readable form, but
/// until it emits a diagnostic the text users actually see lives in the doc comment. Keep
/// the two from drifting apart.
#[test]
fn check_replaced_by_allow_in_tests_docs() {$(
let _doc = concat!($($doc, '\n',)*);
$(
let expected = format!(
"`allow-in-tests = [{}]`",
[$(concat!("\"", stringify!($replacement_lints), "\"")),*].join(", "),
);
assert!(
_doc.contains(&expected),
"`{}` is marked `#[replaced_by_allow_in_tests]` but its docs don't mention {expected}",
$name_str,
);
)?
)*}
};
}

Expand All @@ -236,6 +265,10 @@ define_Conf! {
#[lints(modulo_arithmetic)]
allow_comparison_to_zero("allow-comparison-to-zero"): bool = true,
/// Whether `dbg!` should be allowed in test functions or `#[cfg(test)]`
///
/// Deprecated in favor of [`allow-in-tests`](#allow-in-tests): write
/// `allow-in-tests = ["dbg_macro"]` instead. This option still works.
#[replaced_by_allow_in_tests(dbg_macro)]
#[lints(dbg_macro)]
allow_dbg_in_tests("allow-dbg-in-tests"): bool = false,
/// Whether an item should be allowed to have the same name as its containing module
Expand All @@ -245,9 +278,56 @@ define_Conf! {
#[lints(expect_used)]
allow_expect_in_consts("allow-expect-in-consts"): bool = true,
/// Whether `expect` should be allowed in test functions or `#[cfg(test)]`
///
/// Deprecated in favor of [`allow-in-tests`](#allow-in-tests): write
/// `allow-in-tests = ["expect_used"]` instead. This option still works.
#[replaced_by_allow_in_tests(expect_used)]
#[lints(expect_used)]
allow_expect_in_tests("allow-expect-in-tests"): bool = false,
/// A list of Clippy lints to suppress in test functions and `#[cfg(test)]` items.
///
/// Entries are **lint names**, and only the lints named here are affected. This is not a
/// blanket "allow everything in tests" switch: a lint you don't list keeps firing in test
/// code, and lints added to Clippy in future releases are never included unless you add
/// them.
///
/// ```toml
/// # `.expect()` is allowed in tests; `dbg!` is still reported there.
/// allow-in-tests = ["expect_used"]
/// ```
///
/// #### Replaces the per-lint options
///
/// The older options are deprecated but still honored. Note that an option's name does not
/// always match the lint's, so the replacements are:
///
/// | deprecated option | write instead |
/// | --- | --- |
/// | `allow-dbg-in-tests = true` | `allow-in-tests = ["dbg_macro"]` |
/// | `allow-expect-in-tests = true` | `allow-in-tests = ["expect_used"]` |
/// | `allow-indexing-slicing-in-tests = true` | `allow-in-tests = ["indexing_slicing"]` |
/// | `allow-panic-in-tests = true` | `allow-in-tests = ["panic"]` |
/// | `allow-print-in-tests = true` | `allow-in-tests = ["print_stderr", "print_stdout"]` |
/// | `allow-unwrap-in-tests = true` | `allow-in-tests = ["unwrap_used"]` |
/// | `allow-useless-vec-in-tests = true` | `allow-in-tests = ["useless_vec"]` |
///
/// The two combine permissively: a lint is suppressed in test code if it is listed here
/// **or** its own option is set to `true`. Setting that option to `false` does not cancel a
/// listing here.
///
/// #### Noteworthy
///
/// - This only suppresses lints. It cannot make a lint fire in test code that would not
/// fire otherwise.
/// - Suppressing a lint leaves an `#[expect]` for it in test code unfulfilled, so such an
/// attribute will report `unfulfilled_lint_expectations`. This matches how the older
/// per-lint options have always behaved.
allow_in_tests("allow-in-tests"): Vec<Spanned<String>>,
/// Whether `indexing_slicing` should be allowed in test functions or `#[cfg(test)]`
///
/// Deprecated in favor of [`allow-in-tests`](#allow-in-tests): write
/// `allow-in-tests = ["indexing_slicing"]` instead. This option still works.
#[replaced_by_allow_in_tests(indexing_slicing)]
#[lints(indexing_slicing)]
allow_indexing_slicing_in_tests("allow-indexing-slicing-in-tests"): bool = false,
/// Whether functions inside `#[cfg(test)]` modules or test functions should be checked.
Expand All @@ -260,9 +340,17 @@ define_Conf! {
#[lints(needless_raw_string_hashes)]
allow_one_hash_in_raw_strings("allow-one-hash-in-raw-strings"): bool = false,
/// Whether `panic` should be allowed in test functions or `#[cfg(test)]`
///
/// Deprecated in favor of [`allow-in-tests`](#allow-in-tests): write
/// `allow-in-tests = ["panic"]` instead. This option still works.
#[replaced_by_allow_in_tests(panic)]
#[lints(panic)]
allow_panic_in_tests("allow-panic-in-tests"): bool = false,
/// Whether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]`
///
/// Deprecated in favor of [`allow-in-tests`](#allow-in-tests): write
/// `allow-in-tests = ["print_stderr", "print_stdout"]` instead. This option still works.
#[replaced_by_allow_in_tests(print_stderr, print_stdout)]
#[lints(print_stderr, print_stdout)]
allow_print_in_tests("allow-print-in-tests"): bool = false,
/// Whether to allow module inception if it's not public.
Expand All @@ -287,6 +375,10 @@ define_Conf! {
#[lints(unwrap_used)]
allow_unwrap_in_consts("allow-unwrap-in-consts"): bool = true,
/// Whether `unwrap` should be allowed in test functions or `#[cfg(test)]`
///
/// Deprecated in favor of [`allow-in-tests`](#allow-in-tests): write
/// `allow-in-tests = ["unwrap_used"]` instead. This option still works.
#[replaced_by_allow_in_tests(unwrap_used)]
#[lints(unwrap_used)]
allow_unwrap_in_tests("allow-unwrap-in-tests"): bool = false,
/// List of types to allow `unwrap()` and `expect()` on.
Expand All @@ -299,6 +391,10 @@ define_Conf! {
#[lints(expect_used, unwrap_used)]
allow_unwrap_types("allow-unwrap-types"): Vec<String>,
/// Whether `useless_vec` should ignore test functions or `#[cfg(test)]`
///
/// Deprecated in favor of [`allow-in-tests`](#allow-in-tests): write
/// `allow-in-tests = ["useless_vec"]` instead. This option still works.
#[replaced_by_allow_in_tests(useless_vec)]
#[lints(useless_vec)]
allow_useless_vec_in_tests("allow-useless-vec-in-tests"): bool = false,
/// Additional dotfiles (files or directories starting with a dot) to allow
Expand Down
18 changes: 13 additions & 5 deletions clippy_config/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,25 @@ impl ConfMetadata {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"## `{}`\n{}\n\n**Default Value:** `{}`\n\n---\n**Affected lints:**\n{}\n\n",
"## `{}`\n{}\n\n**Default Value:** `{}`\n\n",
self.0.name,
self.0
.doc
.lines()
.format_with("\n", |doc, f| f(&doc.strip_prefix(" ").unwrap_or(doc))),
self.0.default,
self.0.lints.iter().format_with("\n", |name, f| f(&format_args!(
"* [`{name}`](https://rust-lang.github.io/rust-clippy/main/index.html#{name})"
))),
)
)?;
// Options such as `allow-in-tests` apply to any lint, so they have no list to show.
if !self.0.lints.is_empty() {
write!(
f,
"---\n**Affected lints:**\n{}\n\n",
self.0.lints.iter().format_with("\n", |name, f| f(&format_args!(
"* [`{name}`](https://rust-lang.github.io/rust-clippy/main/index.html#{name})"
))),
)?;
}
Ok(())
}
}
S(self)
Expand Down
6 changes: 3 additions & 3 deletions clippy_lints/src/arbitrary_source_item_ordering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ use clippy_config::types::{
SourceItemOrderingTraitAssocItemKind, SourceItemOrderingTraitAssocItemKinds,
SourceItemOrderingWithinModuleItemGroupings, TraitImplItemOrder,
};
use clippy_utils::diagnostics::span_lint_and_note;
use clippy_utils::diagnostics::{ClippyLintContext, span_lint_and_note};
use clippy_utils::is_cfg_test;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::{
Attribute, FieldDef, HirId, ImplItemId, IsAuto, Item, ItemKind, Mod, OwnerId, QPath, TraitItemId, TyKind, Variant,
VariantData,
};
use rustc_lint::{LateContext, LateLintPass, LintContext, impl_lint_pass};
use rustc_lint::{LateContext, LateLintPass, LintContext as _, impl_lint_pass};
use rustc_middle::ty::{AssocKind, TyCtxt};
use rustc_span::{Ident, Symbol};

Expand Down Expand Up @@ -226,7 +226,7 @@ impl ArbitrarySourceItemOrdering {
}

/// Produces a linting warning for incorrectly ordered item members.
fn lint_member_name<T: LintContext>(cx: &T, ident: Ident, before_ident: Ident) {
fn lint_member_name<T: ClippyLintContext>(cx: &T, ident: Ident, before_ident: Ident) {
span_lint_and_note(
cx,
ARBITRARY_SOURCE_ITEM_ORDERING,
Expand Down
Loading