From 436dd19898cf64d6e3b67da8d820ffeca03eb52e Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Thu, 19 Oct 2023 18:12:49 +0000 Subject: [PATCH] Hide config implementation details from public docs --- .github/workflows/clippy_bors.yml | 4 + Cargo.toml | 2 +- book/src/lint_configuration.md | 139 ++++++++++++++---------------- clippy_config/Cargo.toml | 4 +- clippy_config/src/conf.rs | 60 ++++++++----- clippy_config/src/lib.rs | 5 ++ clippy_config/src/metadata.rs | 36 ++++---- clippy_config/src/msrvs.rs | 2 +- clippy_config/src/types.rs | 27 +++++- clippy_lints/Cargo.toml | 2 +- clippy_lints/src/lib.rs | 16 ++-- clippy_lints/src/utils/mod.rs | 33 ------- tests/dogfood.rs | 1 + 13 files changed, 172 insertions(+), 159 deletions(-) diff --git a/.github/workflows/clippy_bors.yml b/.github/workflows/clippy_bors.yml index 9b96f8dc2533..cb2b4d8d6215 100644 --- a/.github/workflows/clippy_bors.yml +++ b/.github/workflows/clippy_bors.yml @@ -123,6 +123,10 @@ jobs: run: cargo test --features deny-warnings,internal working-directory: clippy_utils + - name: Test clippy_config + run: cargo test --features deny-warnings + working-directory: clippy_config + - name: Test rustc_tools_util run: cargo test --features deny-warnings working-directory: rustc_tools_util diff --git a/Cargo.toml b/Cargo.toml index 28f006957cd5..4b6688a76b46 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,7 +55,7 @@ rustc_tools_util = "0.3.0" [features] deny-warnings = ["clippy_lints/deny-warnings"] integration = ["tempfile"] -internal = ["clippy_config/internal", "clippy_lints/internal", "tempfile"] +internal = ["clippy_lints/internal", "tempfile"] [package.metadata.rust-analyzer] # This package uses #[feature(rustc_private)] diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index 6b1a7ba54c69..841a5b6d0077 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -26,7 +26,7 @@ arithmetic-side-effects-allowed = ["SomeType", "AnotherType"] A type, say `SomeType`, listed in this configuration has the same behavior of `["SomeType" , "*"], ["*", "SomeType"]` in `arithmetic_side_effects_allowed_binary`. -**Default Value:** `{}` (`FxHashSet`) +**Default Value:** `[]` --- **Affected lints:** @@ -49,7 +49,7 @@ Pairs are asymmetric, which means that `["SomeType", "AnotherType"]` is not the arithmetic-side-effects-allowed-binary = [["SomeType" , "f32"], ["AnotherType", "*"]] ``` -**Default Value:** `[]` (`Vec<[String; 2]>`) +**Default Value:** `[]` --- **Affected lints:** @@ -65,7 +65,7 @@ Suppress checking of the passed type names in unary operations like "negation" ( arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"] ``` -**Default Value:** `{}` (`FxHashSet`) +**Default Value:** `[]` --- **Affected lints:** @@ -75,7 +75,7 @@ arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"] ## `avoid-breaking-exported-api` Suppress lints whenever the suggested change would cause breakage for other crates. -**Default Value:** `true` (`bool`) +**Default Value:** `true` --- **Affected lints:** @@ -98,9 +98,7 @@ Suppress lints whenever the suggested change would cause breakage for other crat ## `msrv` -The minimum rust version that the project supports - -**Default Value:** `Msrv { stack: [] }` (`Msrv`) +The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml` --- **Affected lints:** @@ -157,7 +155,7 @@ The minimum rust version that the project supports ## `cognitive-complexity-threshold` The maximum cognitive complexity a function can have -**Default Value:** `25` (`u64`) +**Default Value:** `25` --- **Affected lints:** @@ -167,7 +165,7 @@ The maximum cognitive complexity a function can have ## `excessive-nesting-threshold` The maximum amount of nesting a block can reside in -**Default Value:** `0` (`u64`) +**Default Value:** `0` --- **Affected lints:** @@ -179,7 +177,7 @@ The list of disallowed names to lint about. NB: `bar` is not here since it has l `".."` can be used as part of the list to indicate that the configured values should be appended to the default configuration of Clippy. By default, any configuration will replace the default value. -**Default Value:** `["foo", "baz", "quux"]` (`Vec`) +**Default Value:** `["foo", "baz", "quux"]` --- **Affected lints:** @@ -189,7 +187,7 @@ default configuration of Clippy. By default, any configuration will replace the ## `semicolon-inside-block-ignore-singleline` Whether to lint only if it's multiline. -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -199,7 +197,7 @@ Whether to lint only if it's multiline. ## `semicolon-outside-block-ignore-multiline` Whether to lint only if it's singleline. -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -213,9 +211,7 @@ default configuration of Clippy. By default, any configuration will replace the * `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`. * `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list. -Default list: - -**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS", "WebGL", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]` (`Vec`) +**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS", "WebGL", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]` --- **Affected lints:** @@ -225,7 +221,7 @@ Default list: ## `too-many-arguments-threshold` The maximum number of argument a function or method can have -**Default Value:** `7` (`u64`) +**Default Value:** `7` --- **Affected lints:** @@ -235,7 +231,7 @@ The maximum number of argument a function or method can have ## `type-complexity-threshold` The maximum complexity a type can have -**Default Value:** `250` (`u64`) +**Default Value:** `250` --- **Affected lints:** @@ -245,7 +241,7 @@ The maximum complexity a type can have ## `single-char-binding-names-threshold` The maximum number of single char bindings a scope may have -**Default Value:** `4` (`u64`) +**Default Value:** `4` --- **Affected lints:** @@ -255,7 +251,7 @@ The maximum number of single char bindings a scope may have ## `too-large-for-stack` The maximum size of objects (in bytes) that will be linted. Larger objects are ok on the heap -**Default Value:** `200` (`u64`) +**Default Value:** `200` --- **Affected lints:** @@ -266,7 +262,7 @@ The maximum size of objects (in bytes) that will be linted. Larger objects are o ## `enum-variant-name-threshold` The minimum number of enum variants for the lints about variant names to trigger -**Default Value:** `3` (`u64`) +**Default Value:** `3` --- **Affected lints:** @@ -276,7 +272,7 @@ The minimum number of enum variants for the lints about variant names to trigger ## `struct-field-name-threshold` The minimum number of struct fields for the lints about field names to trigger -**Default Value:** `3` (`u64`) +**Default Value:** `3` --- **Affected lints:** @@ -286,7 +282,7 @@ The minimum number of struct fields for the lints about field names to trigger ## `enum-variant-size-threshold` The maximum size of an enum's variant to avoid box suggestion -**Default Value:** `200` (`u64`) +**Default Value:** `200` --- **Affected lints:** @@ -296,7 +292,7 @@ The maximum size of an enum's variant to avoid box suggestion ## `verbose-bit-mask-threshold` The maximum allowed size of a bit mask before suggesting to use 'trailing_zeros' -**Default Value:** `1` (`u64`) +**Default Value:** `1` --- **Affected lints:** @@ -306,7 +302,7 @@ The maximum allowed size of a bit mask before suggesting to use 'trailing_zeros' ## `literal-representation-threshold` The lower bound for linting decimal literals -**Default Value:** `16384` (`u64`) +**Default Value:** `16384` --- **Affected lints:** @@ -314,9 +310,8 @@ The lower bound for linting decimal literals ## `trivial-copy-size-limit` -The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by reference. - -**Default Value:** `None` (`Option`) +The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by +reference. By default there is no limit --- **Affected lints:** @@ -326,7 +321,7 @@ The maximum size (in bytes) to consider a `Copy` type for passing by value inste ## `pass-by-value-size-limit` The minimum size (in bytes) to consider a type for passing by reference instead of by value. -**Default Value:** `256` (`u64`) +**Default Value:** `256` --- **Affected lints:** @@ -336,7 +331,7 @@ The minimum size (in bytes) to consider a type for passing by reference instead ## `too-many-lines-threshold` The maximum number of lines a function or method can have -**Default Value:** `100` (`u64`) +**Default Value:** `100` --- **Affected lints:** @@ -346,7 +341,7 @@ The maximum number of lines a function or method can have ## `array-size-threshold` The maximum allowed size for arrays on the stack -**Default Value:** `512000` (`u64`) +**Default Value:** `512000` --- **Affected lints:** @@ -357,7 +352,7 @@ The maximum allowed size for arrays on the stack ## `stack-size-threshold` The maximum allowed stack size for functions in bytes -**Default Value:** `512000` (`u64`) +**Default Value:** `512000` --- **Affected lints:** @@ -367,7 +362,7 @@ The maximum allowed stack size for functions in bytes ## `vec-box-size-threshold` The size of the boxed type in bytes, where boxing in a `Vec` is allowed -**Default Value:** `4096` (`u64`) +**Default Value:** `4096` --- **Affected lints:** @@ -377,7 +372,7 @@ The size of the boxed type in bytes, where boxing in a `Vec` is allowed ## `max-trait-bounds` The maximum number of bounds a trait can have to be linted -**Default Value:** `3` (`u64`) +**Default Value:** `3` --- **Affected lints:** @@ -387,7 +382,7 @@ The maximum number of bounds a trait can have to be linted ## `max-struct-bools` The maximum number of bool fields a struct can have -**Default Value:** `3` (`u64`) +**Default Value:** `3` --- **Affected lints:** @@ -397,7 +392,7 @@ The maximum number of bool fields a struct can have ## `max-fn-params-bools` The maximum number of bool parameters a function can have -**Default Value:** `3` (`u64`) +**Default Value:** `3` --- **Affected lints:** @@ -407,7 +402,7 @@ The maximum number of bool parameters a function can have ## `warn-on-all-wildcard-imports` Whether to allow certain wildcard imports (prelude, super in tests). -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -417,7 +412,7 @@ Whether to allow certain wildcard imports (prelude, super in tests). ## `disallowed-macros` The list of disallowed macros, written as fully qualified paths. -**Default Value:** `[]` (`Vec`) +**Default Value:** `[]` --- **Affected lints:** @@ -427,7 +422,7 @@ The list of disallowed macros, written as fully qualified paths. ## `disallowed-methods` The list of disallowed methods, written as fully qualified paths. -**Default Value:** `[]` (`Vec`) +**Default Value:** `[]` --- **Affected lints:** @@ -437,7 +432,7 @@ The list of disallowed methods, written as fully qualified paths. ## `disallowed-types` The list of disallowed types, written as fully qualified paths. -**Default Value:** `[]` (`Vec`) +**Default Value:** `[]` --- **Affected lints:** @@ -447,7 +442,7 @@ The list of disallowed types, written as fully qualified paths. ## `unreadable-literal-lint-fractions` Should the fraction of a decimal be linted to include separators. -**Default Value:** `true` (`bool`) +**Default Value:** `true` --- **Affected lints:** @@ -457,7 +452,7 @@ Should the fraction of a decimal be linted to include separators. ## `upper-case-acronyms-aggressive` Enables verbose mode. Triggers if there is more than one uppercase char next to each other -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -468,7 +463,7 @@ Enables verbose mode. Triggers if there is more than one uppercase char next to Whether the matches should be considered by the lint, and whether there should be filtering for common types. -**Default Value:** `WellKnownTypes` (`MatchLintBehaviour`) +**Default Value:** `"WellKnownTypes"` --- **Affected lints:** @@ -478,11 +473,11 @@ be filtering for common types. ## `cargo-ignore-publish` For internal testing only, ignores the current `publish` settings in the Cargo manifest. -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** -* [`_cargo_common_metadata`](https://rust-lang.github.io/rust-clippy/master/index.html#_cargo_common_metadata) +* [`cargo_common_metadata`](https://rust-lang.github.io/rust-clippy/master/index.html#cargo_common_metadata) ## `standard-macro-braces` @@ -492,7 +487,7 @@ A `MacroMatcher` can be added like so `{ name = "macro_name", brace = "(" }`. If could be used with a full path two `MacroMatcher`s have to be added one with the full path `crate_name::macro_name` and one with just the macro name. -**Default Value:** `[]` (`Vec`) +**Default Value:** `[]` --- **Affected lints:** @@ -502,7 +497,7 @@ could be used with a full path two `MacroMatcher`s have to be added one with the ## `enforced-import-renames` The list of imports to always rename, a fully qualified path followed by the rename. -**Default Value:** `[]` (`Vec`) +**Default Value:** `[]` --- **Affected lints:** @@ -512,7 +507,7 @@ The list of imports to always rename, a fully qualified path followed by the ren ## `allowed-scripts` The list of unicode scripts allowed to be used in the scope. -**Default Value:** `["Latin"]` (`Vec`) +**Default Value:** `["Latin"]` --- **Affected lints:** @@ -522,7 +517,7 @@ The list of unicode scripts allowed to be used in the scope. ## `enable-raw-pointer-heuristic-for-send` Whether to apply the raw pointer heuristic to determine if a type is `Send`. -**Default Value:** `true` (`bool`) +**Default Value:** `true` --- **Affected lints:** @@ -534,7 +529,7 @@ When Clippy suggests using a slice pattern, this is the maximum number of elemen the slice pattern that is suggested. If more elements are necessary, the lint is suppressed. For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements. -**Default Value:** `3` (`u64`) +**Default Value:** `3` --- **Affected lints:** @@ -544,7 +539,7 @@ For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements. ## `await-holding-invalid-types` -**Default Value:** `[]` (`Vec`) +**Default Value:** `[]` --- **Affected lints:** @@ -554,7 +549,7 @@ For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements. ## `max-include-file-size` The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes -**Default Value:** `1000000` (`u64`) +**Default Value:** `1000000` --- **Affected lints:** @@ -564,7 +559,7 @@ The maximum size of a file included via `include_bytes!()` or `include_str!()`, ## `allow-expect-in-tests` Whether `expect` should be allowed in test functions or `#[cfg(test)]` -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -574,7 +569,7 @@ Whether `expect` should be allowed in test functions or `#[cfg(test)]` ## `allow-unwrap-in-tests` Whether `unwrap` should be allowed in test functions or `#[cfg(test)]` -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -584,7 +579,7 @@ Whether `unwrap` should be allowed in test functions or `#[cfg(test)]` ## `allow-dbg-in-tests` Whether `dbg!` should be allowed in test functions or `#[cfg(test)]` -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -594,7 +589,7 @@ Whether `dbg!` 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)]` -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -605,7 +600,7 @@ Whether print macros (ex. `println!`) should be allowed in test functions or `#[ ## `large-error-threshold` The maximum size of the `Err`-variant in a `Result` returned from a function -**Default Value:** `128` (`u64`) +**Default Value:** `128` --- **Affected lints:** @@ -616,7 +611,7 @@ The maximum size of the `Err`-variant in a `Result` returned from a function A list of paths to types that should be treated like `Arc`, i.e. ignored but for the generic parameters for determining interior mutability -**Default Value:** `["bytes::Bytes"]` (`Vec`) +**Default Value:** `["bytes::Bytes"]` --- **Affected lints:** @@ -627,7 +622,7 @@ for the generic parameters for determining interior mutability ## `allow-mixed-uninlined-format-args` Whether to allow mixed uninlined format args, e.g. `format!("{} {}", a, foo.bar)` -**Default Value:** `true` (`bool`) +**Default Value:** `true` --- **Affected lints:** @@ -641,7 +636,7 @@ suggested counterparts are unavailable in constant code. This configuration will cause restriction lints to trigger even if no suggestion can be made. -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -652,7 +647,7 @@ if no suggestion can be made. Whether to **only** check for missing documentation in items visible within the current crate. For example, `pub(crate)` items. -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -662,7 +657,7 @@ crate. For example, `pub(crate)` items. ## `future-size-threshold` The maximum byte size a `Future` can have, before it triggers the `clippy::large_futures` lint -**Default Value:** `16384` (`u64`) +**Default Value:** `16384` --- **Affected lints:** @@ -672,7 +667,7 @@ The maximum byte size a `Future` can have, before it triggers the `clippy::large ## `unnecessary-box-size` The byte size a `T` in `Box` can have, below which it triggers the `clippy::unnecessary_box` lint -**Default Value:** `128` (`u64`) +**Default Value:** `128` --- **Affected lints:** @@ -682,7 +677,7 @@ The byte size a `T` in `Box` can have, below which it triggers the `clippy::u ## `allow-private-module-inception` Whether to allow module inception if it's not public. -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -694,7 +689,7 @@ Allowed names below the minimum allowed characters. The value `".."` can be used the list to indicate, that the configured values should be appended to the default configuration of Clippy. By default, any configuration will replace the default value. -**Default Value:** `{"j", "z", "i", "y", "n", "x", "w"}` (`FxHashSet`) +**Default Value:** `["j", "z", "i", "y", "n", "x", "w"]` --- **Affected lints:** @@ -704,7 +699,7 @@ configuration of Clippy. By default, any configuration will replace the default ## `min-ident-chars-threshold` Minimum chars an ident can have, anything below or equal to this will be linted. -**Default Value:** `1` (`u64`) +**Default Value:** `1` --- **Affected lints:** @@ -714,7 +709,7 @@ Minimum chars an ident can have, anything below or equal to this will be linted. ## `accept-comment-above-statement` Whether to accept a safety comment to be placed above the statement containing the `unsafe` block -**Default Value:** `true` (`bool`) +**Default Value:** `true` --- **Affected lints:** @@ -724,7 +719,7 @@ Whether to accept a safety comment to be placed above the statement containing t ## `accept-comment-above-attributes` Whether to accept a safety comment to be placed above the attributes for the `unsafe` block -**Default Value:** `true` (`bool`) +**Default Value:** `true` --- **Affected lints:** @@ -734,7 +729,7 @@ Whether to accept a safety comment to be placed above the attributes for the `un ## `allow-one-hash-in-raw-strings` Whether to allow `r#""#` when `r""` can be used -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** @@ -745,7 +740,7 @@ Whether to allow `r#""#` when `r""` can be used The maximum number of segments a path can have before being linted, anything above this will be linted. -**Default Value:** `2` (`u64`) +**Default Value:** `2` --- **Affected lints:** @@ -755,7 +750,7 @@ be linted. ## `absolute-paths-allowed-crates` Which crates to allow absolute paths from -**Default Value:** `{}` (`FxHashSet`) +**Default Value:** `[]` --- **Affected lints:** @@ -765,7 +760,7 @@ Which crates to allow absolute paths from ## `allowed-dotfiles` Additional dotfiles (files or directories starting with a dot) to allow -**Default Value:** `{}` (`FxHashSet`) +**Default Value:** `[]` --- **Affected lints:** @@ -789,7 +784,7 @@ for _ in &*rmvec {} for _ in &mut *rmvec {} ``` -**Default Value:** `false` (`bool`) +**Default Value:** `false` --- **Affected lints:** diff --git a/clippy_config/Cargo.toml b/clippy_config/Cargo.toml index 55f67b585e20..2d41087b51d1 100644 --- a/clippy_config/Cargo.toml +++ b/clippy_config/Cargo.toml @@ -10,9 +10,11 @@ rustc-semver = "1.1" serde = { version = "1.0", features = ["derive"] } toml = "0.7.3" +[dev-dependencies] +walkdir = "2.3" + [features] deny-warnings = [] -internal = [] [package.metadata.rust-analyzer] # This crate uses #[feature(rustc_private)] diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index d010dd5f42ae..47259776921b 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -4,8 +4,8 @@ use crate::ClippyConfiguration; use rustc_data_structures::fx::FxHashSet; use rustc_session::Session; use rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext}; -use serde::de::{Deserializer, IgnoredAny, IntoDeserializer, MapAccess, Visitor}; -use serde::Deserialize; +use serde::de::{IgnoredAny, IntoDeserializer, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; use std::fmt::{Debug, Display, Formatter}; use std::ops::Range; use std::path::PathBuf; @@ -40,10 +40,10 @@ const DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS: &[&str] = &["i", "j", "x", "y", "z /// Conf with parse errors #[derive(Default)] -pub struct TryConf { - pub conf: Conf, - pub errors: Vec, - pub warnings: Vec, +struct TryConf { + conf: Conf, + errors: Vec, + warnings: Vec, } impl TryConf { @@ -57,9 +57,9 @@ impl TryConf { } #[derive(Debug)] -pub struct ConfError { - pub message: String, - pub span: Span, +struct ConfError { + message: String, + span: Span, } impl ConfError { @@ -81,10 +81,31 @@ impl ConfError { } } +macro_rules! wrap_option { + () => { + None + }; + ($x:literal) => { + Some($x) + }; +} + +macro_rules! default_text { + ($value:expr) => {{ + let mut text = String::new(); + $value.serialize(toml::ser::ValueSerializer::new(&mut text)).unwrap(); + text + }}; + ($value:expr, $override:expr) => { + $override.to_string() + }; +} + macro_rules! define_Conf { ($( $(#[doc = $doc:literal])+ $(#[conf_deprecated($dep:literal, $new_conf:ident)])? + $(#[default_text = $default_text:expr])? ($name:ident: $ty:ty = $default:expr), )*) => { /// Clippy lint configuration @@ -160,11 +181,6 @@ macro_rules! define_Conf { } } - macro_rules! wrap_option { - () => (None); - ($x:literal) => (Some($x)); - } - pub fn get_configuration_metadata() -> Vec { vec![ $( @@ -173,8 +189,7 @@ macro_rules! define_Conf { ClippyConfiguration::new( stringify!($name), - stringify!($ty), - format!("{:?}", defaults::$name()), + default_text!(defaults::$name() $(, $default_text)?), concat!($($doc, '\n',)*), deprecation_reason, ) @@ -236,7 +251,8 @@ define_Conf! { (avoid_breaking_exported_api: bool = true), /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD, MANUAL_HASH_ONE. /// - /// The minimum rust version that the project supports + /// The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml` + #[default_text = ""] (msrv: Msrv = Msrv::empty()), /// DEPRECATED LINT: BLACKLISTED_NAME. /// @@ -277,8 +293,6 @@ define_Conf! { /// default configuration of Clippy. By default, any configuration will replace the default value. For example: /// * `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`. /// * `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list. - /// - /// Default list: (doc_valid_idents: Vec = DEFAULT_DOC_VALID_IDENTS.iter().map(ToString::to_string).collect()), /// Lint: TOO_MANY_ARGUMENTS. /// @@ -318,7 +332,9 @@ define_Conf! { (literal_representation_threshold: u64 = 16384), /// Lint: TRIVIALLY_COPY_PASS_BY_REF. /// - /// The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by reference. + /// The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by + /// reference. By default there is no limit + #[default_text = ""] (trivial_copy_size_limit: Option = None), /// Lint: LARGE_TYPES_PASSED_BY_VALUE. /// @@ -381,7 +397,7 @@ define_Conf! { /// Whether the matches should be considered by the lint, and whether there should /// be filtering for common types. (matches_for_let_else: MatchLintBehaviour = MatchLintBehaviour::WellKnownTypes), - /// Lint: _CARGO_COMMON_METADATA. + /// Lint: CARGO_COMMON_METADATA. /// /// For internal testing only, ignores the current `publish` settings in the Cargo manifest. (cargo_ignore_publish: bool = false), @@ -742,7 +758,7 @@ mod tests { #[test] fn configs_are_tested() { - let mut names: FxHashSet = super::metadata::get_configuration_metadata() + let mut names: FxHashSet = crate::get_configuration_metadata() .into_iter() .map(|meta| meta.name.replace('_', "-")) .collect(); diff --git a/clippy_config/src/lib.rs b/clippy_config/src/lib.rs index 44bbeb17209e..5dc8d285ecbb 100644 --- a/clippy_config/src/lib.rs +++ b/clippy_config/src/lib.rs @@ -1,6 +1,11 @@ #![feature(rustc_private, let_chains)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] #![warn(rust_2018_idioms, unused_lifetimes)] +#![allow( + clippy::must_use_candidate, + clippy::missing_panics_doc, + rustc::untranslatable_diagnostic_trivial +)] extern crate rustc_ast; extern crate rustc_data_structures; diff --git a/clippy_config/src/metadata.rs b/clippy_config/src/metadata.rs index c40cbd6330fb..2451fbc91e89 100644 --- a/clippy_config/src/metadata.rs +++ b/clippy_config/src/metadata.rs @@ -1,30 +1,27 @@ -use std::fmt; +use std::fmt::{self, Write}; #[derive(Debug, Clone, Default)] pub struct ClippyConfiguration { pub name: String, - config_type: &'static str, pub default: String, pub lints: Vec, pub doc: String, - #[allow(dead_code)] pub deprecation_reason: Option<&'static str>, } impl fmt::Display for ClippyConfiguration { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - writeln!( - f, - "* `{}`: `{}`(defaults to `{}`): {}", - self.name, self.config_type, self.default, self.doc - ) + write!(f, "- `{}`: {}", self.name, self.doc)?; + if !self.default.is_empty() { + write!(f, " (default: `{}`)", self.default)?; + } + Ok(()) } } impl ClippyConfiguration { pub fn new( name: &'static str, - config_type: &'static str, default: String, doc_comment: &'static str, deprecation_reason: Option<&'static str>, @@ -36,24 +33,29 @@ impl ClippyConfiguration { name: to_kebab(name), lints, doc, - config_type, default, deprecation_reason, } } - #[cfg(feature = "internal")] pub fn to_markdown_paragraph(&self) -> String { - format!( - "## `{}`\n{}\n\n**Default Value:** `{}` (`{}`)\n\n---\n**Affected lints:**\n{}\n\n", + let mut out = format!( + "## `{}`\n{}\n\n", self.name, self.doc .lines() .map(|line| line.strip_prefix(" ").unwrap_or(line)) .collect::>() .join("\n"), - self.default, - self.config_type, + ); + + if !self.default.is_empty() { + write!(out, "**Default Value:** `{}`\n\n", self.default).unwrap(); + } + + write!( + out, + "---\n**Affected lints:**\n{}\n\n", self.lints .iter() .map(|name| name.to_string().split_whitespace().next().unwrap().to_string()) @@ -61,9 +63,11 @@ impl ClippyConfiguration { .collect::>() .join("\n"), ) + .unwrap(); + + out } - #[cfg(feature = "internal")] pub fn to_markdown_link(&self) -> String { const BOOK_CONFIGS_PATH: &str = "https://doc.rust-lang.org/clippy/lint_configuration.html"; format!("[`{}`]: {BOOK_CONFIGS_PATH}#{}", self.name, self.name) diff --git a/clippy_config/src/msrvs.rs b/clippy_config/src/msrvs.rs index 2cdfa6b42f93..011d54629d41 100644 --- a/clippy_config/src/msrvs.rs +++ b/clippy_config/src/msrvs.rs @@ -105,7 +105,7 @@ impl Msrv { if let Some(msrv_attr) = msrv_attrs.next() { if let Some(duplicate) = msrv_attrs.last() { - sess.struct_span_err(duplicate.span, format!("`clippy::msrv` is defined multiple times")) + sess.struct_span_err(duplicate.span, "`clippy::msrv` is defined multiple times") .span_note(msrv_attr.span, "first definition found here") .emit(); } diff --git a/clippy_config/src/types.rs b/clippy_config/src/types.rs index d179f6baab7e..e898221ffa77 100644 --- a/clippy_config/src/types.rs +++ b/clippy_config/src/types.rs @@ -1,5 +1,5 @@ use serde::de::{self, Deserializer, Visitor}; -use serde::Deserialize; +use serde::{ser, Deserialize, Serialize}; use std::fmt; use std::hash::{Hash, Hasher}; @@ -33,7 +33,7 @@ impl DisallowedPath { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)] pub enum MatchLintBehaviour { AllTypes, WellKnownTypes, @@ -117,3 +117,26 @@ impl<'de> Deserialize<'de> for MacroMatcher { deser.deserialize_struct("MacroMatcher", FIELDS, MacVisitor) } } + +// these impls are never actually called but are used by the various config options that default to +// empty lists +macro_rules! unimplemented_serialize { + ($($t:ty,)*) => { + $( + impl Serialize for $t { + fn serialize(&self, _serializer: S) -> Result + where + S: ser::Serializer, + { + Err(ser::Error::custom("unimplemented")) + } + } + )* + } +} + +unimplemented_serialize! { + DisallowedPath, + Rename, + MacroMatcher, +} diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index 54f67c597617..bb74ef237cff 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -35,7 +35,7 @@ walkdir = "2.3" [features] deny-warnings = ["clippy_utils/deny-warnings"] # build clippy with internal lints enabled, off by default -internal = ["clippy_config/internal", "clippy_utils/internal", "serde_json", "tempfile", "regex"] +internal = ["clippy_utils/internal", "serde_json", "tempfile", "regex"] [package.metadata.rust-analyzer] # This crate uses #[feature(rustc_private)] diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index a64efbca74fc..37053c84e9bb 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -357,7 +357,6 @@ mod zero_div_zero; mod zero_sized_map_values; // end lints modules, do not remove this comment, it’s used in `update_lints` -use crate::utils::FindAll; use clippy_config::{get_configuration_metadata, Conf}; /// Register all pre expansion lints @@ -460,16 +459,13 @@ pub fn explain(name: &str) -> i32 { if let Some(info) = declared_lints::LINTS.iter().find(|info| info.lint.name == target) { println!("{}", info.explanation); // Check if the lint has configuration - let mdconf = get_configuration_metadata(); - if let Some(config_vec_positions) = mdconf - .iter() - .find_all(|cconf| cconf.lints.contains(&info.lint.name_lower()[8..].to_owned())) - { - // If it has, print it + let mut mdconf = get_configuration_metadata(); + let name = name.to_ascii_lowercase(); + mdconf.retain(|cconf| cconf.lints.contains(&name)); + if !mdconf.is_empty() { println!("### Configuration for {}:\n", info.lint.name_lower()); - for position in config_vec_positions { - let conf = &mdconf[position]; - println!(" - {}: {} (default: {})", conf.name, conf.doc, conf.default); + for conf in mdconf { + println!("{conf}"); } } 0 diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 78096092a0e2..13e9ead9a57f 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -3,36 +3,3 @@ pub mod dump_hir; pub mod format_args_collector; #[cfg(feature = "internal")] pub mod internal_lints; - -// ================================================================== -// Configuration -// ================================================================== - -// Shamelessly stolen from find_all (https://github.com/nectariner/find_all) -pub trait FindAll: Iterator + Sized { - fn find_all

(&mut self, predicate: P) -> Option> - where - P: FnMut(&Self::Item) -> bool; -} - -impl FindAll for I -where - I: Iterator, -{ - fn find_all

(&mut self, mut predicate: P) -> Option> - where - P: FnMut(&Self::Item) -> bool, - { - let mut occurences = Vec::::default(); - for (index, element) in self.enumerate() { - if predicate(&element) { - occurences.push(index); - } - } - - match occurences.len() { - 0 => None, - _ => Some(occurences), - } - } -} diff --git a/tests/dogfood.rs b/tests/dogfood.rs index 59c7c53000bc..3f16c180ea78 100644 --- a/tests/dogfood.rs +++ b/tests/dogfood.rs @@ -28,6 +28,7 @@ fn dogfood_clippy() { "clippy_dev", "clippy_lints", "clippy_utils", + "clippy_config", "lintcheck", "rustc_tools_util", ] {