Auto merge of #11685 - Alexendoo:clippy_config, r=flip1995

Create `clippy_config` crate, hide internal representation from docs

r? `@flip1995`

The first commit moves a decent chunk of code out of `clippy_lints`/`clippy_utils` into a new crate `clippy_config`

The second commit changes how `--explain`, the book and the site render configuration values. The internal type is now hidden and the displayed defaults are now valid TOML values instead of `Debug` output

changelog: none
This commit is contained in:
bors 2023-10-24 11:54:54 +00:00
commit 4eb4192ae3
90 changed files with 578 additions and 554 deletions

View file

@ -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

View file

@ -21,11 +21,12 @@ name = "clippy-driver"
path = "src/driver.rs"
[dependencies]
clippy_config = { path = "clippy_config" }
clippy_lints = { path = "clippy_lints" }
rustc_tools_util = "0.3.0"
tempfile = { version = "3.2", optional = true }
termize = "0.1"
color-print = "0.3.4" # Sync version with Cargo
color-print = "0.3.4"
anstream = "0.5.0"
[dev-dependencies]

View file

@ -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:** `{}` (`rustc_data_structures::fx::FxHashSet<String>`)
**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:** `{}` (`rustc_data_structures::fx::FxHashSet<String>`)
**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: [] }` (`crate::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<String>`)
**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<String>`)
**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<u64>`)
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<crate::utils::conf::DisallowedPath>`)
**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<crate::utils::conf::DisallowedPath>`)
**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<crate::utils::conf::DisallowedPath>`)
**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` (`crate::manual_let_else::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<crate::nonstandard_macro_braces::MacroMatcher>`)
**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<crate::utils::conf::Rename>`)
**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<String>`)
**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<crate::utils::conf::DisallowedPath>`)
**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<String>`)
**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<T>` 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<T>` 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"}` (`rustc_data_structures::fx::FxHashSet<String>`)
**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:** `{}` (`rustc_data_structures::fx::FxHashSet<String>`)
**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:** `{}` (`rustc_data_structures::fx::FxHashSet<String>`)
**Default Value:** `[]`
---
**Affected lints:**
@ -789,7 +784,7 @@ for _ in &*rmvec {}
for _ in &mut *rmvec {}
```
**Default Value:** `false` (`bool`)
**Default Value:** `false`
---
**Affected lints:**

21
clippy_config/Cargo.toml Normal file
View file

@ -0,0 +1,21 @@
[package]
name = "clippy_config"
version = "0.1.75"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rustc-semver = "1.1"
serde = { version = "1.0", features = ["derive"] }
toml = "0.7.3"
[dev-dependencies]
walkdir = "2.3"
[features]
deny-warnings = []
[package.metadata.rust-analyzer]
# This crate uses #[feature(rustc_private)]
rustc_private = true

View file

@ -1,11 +1,11 @@
//! Read configurations files.
#![allow(clippy::module_name_repetitions)]
use crate::msrvs::Msrv;
use crate::types::{DisallowedPath, MacroMatcher, MatchLintBehaviour, Rename};
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;
@ -38,43 +38,12 @@ const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[
const DEFAULT_DISALLOWED_NAMES: &[&str] = &["foo", "baz", "quux"];
const DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS: &[&str] = &["i", "j", "x", "y", "z", "w", "n"];
/// Holds information used by `MISSING_ENFORCED_IMPORT_RENAMES` lint.
#[derive(Clone, Debug, Deserialize)]
pub struct Rename {
pub path: String,
pub rename: String,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(untagged)]
pub enum DisallowedPath {
Simple(String),
WithReason { path: String, reason: Option<String> },
}
impl DisallowedPath {
pub fn path(&self) -> &str {
let (Self::Simple(path) | Self::WithReason { path, .. }) = self;
path
}
pub fn reason(&self) -> Option<String> {
match self {
Self::WithReason {
reason: Some(reason), ..
} => Some(format!("{reason} (from clippy.toml)")),
_ => None,
}
}
}
/// Conf with parse errors
#[derive(Default)]
pub struct TryConf {
pub conf: Conf,
pub errors: Vec<ConfError>,
pub warnings: Vec<ConfError>,
struct TryConf {
conf: Conf,
errors: Vec<ConfError>,
warnings: Vec<ConfError>,
}
impl TryConf {
@ -88,9 +57,9 @@ impl TryConf {
}
#[derive(Debug)]
pub struct ConfError {
pub message: String,
pub span: Span,
struct ConfError {
message: String,
span: Span,
}
impl ConfError {
@ -112,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
@ -124,6 +114,7 @@ macro_rules! define_Conf {
}
mod defaults {
use super::*;
$(pub fn $name() -> $ty { $default })*
}
@ -190,31 +181,21 @@ macro_rules! define_Conf {
}
}
pub mod metadata {
use crate::utils::ClippyConfiguration;
pub fn get_configuration_metadata() -> Vec<ClippyConfiguration> {
vec![
$(
{
let deprecation_reason = wrap_option!($($dep)?);
macro_rules! wrap_option {
() => (None);
($x:literal) => (Some($x));
}
pub fn get_configuration_metadata() -> Vec<ClippyConfiguration> {
vec![
$(
{
let deprecation_reason = wrap_option!($($dep)?);
ClippyConfiguration::new(
stringify!($name),
stringify!($ty),
format!("{:?}", super::defaults::$name()),
concat!($($doc, '\n',)*),
deprecation_reason,
)
},
)+
]
}
ClippyConfiguration::new(
stringify!($name),
default_text!(defaults::$name() $(, $default_text)?),
concat!($($doc, '\n',)*),
deprecation_reason,
)
},
)+
]
}
};
}
@ -236,7 +217,7 @@ define_Conf! {
///
/// A type, say `SomeType`, listed in this configuration has the same behavior of
/// `["SomeType" , "*"], ["*", "SomeType"]` in `arithmetic_side_effects_allowed_binary`.
(arithmetic_side_effects_allowed: rustc_data_structures::fx::FxHashSet<String> = <_>::default()),
(arithmetic_side_effects_allowed: FxHashSet<String> = <_>::default()),
/// Lint: ARITHMETIC_SIDE_EFFECTS.
///
/// Suppress checking of the passed type pair names in binary operations like addition or
@ -263,15 +244,16 @@ define_Conf! {
/// ```toml
/// arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"]
/// ```
(arithmetic_side_effects_allowed_unary: rustc_data_structures::fx::FxHashSet<String> = <_>::default()),
(arithmetic_side_effects_allowed_unary: FxHashSet<String> = <_>::default()),
/// Lint: ENUM_VARIANT_NAMES, LARGE_TYPES_PASSED_BY_VALUE, TRIVIALLY_COPY_PASS_BY_REF, UNNECESSARY_WRAPS, UNUSED_SELF, UPPER_CASE_ACRONYMS, WRONG_SELF_CONVENTION, BOX_COLLECTION, REDUNDANT_ALLOCATION, RC_BUFFER, VEC_BOX, OPTION_OPTION, LINKEDLIST, RC_MUTEX, UNNECESSARY_BOX_RETURNS, SINGLE_CALL_FN.
///
/// Suppress lints whenever the suggested change would cause breakage for other crates.
(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
(msrv: crate::Msrv = crate::Msrv::empty()),
/// 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.
///
/// Use the Disallowed Names lint instead
@ -295,7 +277,7 @@ define_Conf! {
/// The list of disallowed names to lint about. NB: `bar` is not here since it has legitimate uses. The value
/// `".."` 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.
(disallowed_names: Vec<String> = super::DEFAULT_DISALLOWED_NAMES.iter().map(ToString::to_string).collect()),
(disallowed_names: Vec<String> = DEFAULT_DISALLOWED_NAMES.iter().map(ToString::to_string).collect()),
/// Lint: SEMICOLON_INSIDE_BLOCK.
///
/// Whether to lint only if it's multiline.
@ -311,9 +293,7 @@ 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<String> = super::DEFAULT_DOC_VALID_IDENTS.iter().map(ToString::to_string).collect()),
(doc_valid_idents: Vec<String> = DEFAULT_DOC_VALID_IDENTS.iter().map(ToString::to_string).collect()),
/// Lint: TOO_MANY_ARGUMENTS.
///
/// The maximum number of argument a function or method can have
@ -352,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<u64> = None),
/// Lint: LARGE_TYPES_PASSED_BY_VALUE.
///
@ -393,15 +375,15 @@ define_Conf! {
/// Lint: DISALLOWED_MACROS.
///
/// The list of disallowed macros, written as fully qualified paths.
(disallowed_macros: Vec<crate::utils::conf::DisallowedPath> = Vec::new()),
(disallowed_macros: Vec<DisallowedPath> = Vec::new()),
/// Lint: DISALLOWED_METHODS.
///
/// The list of disallowed methods, written as fully qualified paths.
(disallowed_methods: Vec<crate::utils::conf::DisallowedPath> = Vec::new()),
(disallowed_methods: Vec<DisallowedPath> = Vec::new()),
/// Lint: DISALLOWED_TYPES.
///
/// The list of disallowed types, written as fully qualified paths.
(disallowed_types: Vec<crate::utils::conf::DisallowedPath> = Vec::new()),
(disallowed_types: Vec<DisallowedPath> = Vec::new()),
/// Lint: UNREADABLE_LITERAL.
///
/// Should the fraction of a decimal be linted to include separators.
@ -414,9 +396,8 @@ define_Conf! {
///
/// Whether the matches should be considered by the lint, and whether there should
/// be filtering for common types.
(matches_for_let_else: crate::manual_let_else::MatchLintBehaviour =
crate::manual_let_else::MatchLintBehaviour::WellKnownTypes),
/// Lint: _CARGO_COMMON_METADATA.
(matches_for_let_else: MatchLintBehaviour = MatchLintBehaviour::WellKnownTypes),
/// Lint: CARGO_COMMON_METADATA.
///
/// For internal testing only, ignores the current `publish` settings in the Cargo manifest.
(cargo_ignore_publish: bool = false),
@ -427,11 +408,11 @@ define_Conf! {
/// A `MacroMatcher` can be added like so `{ name = "macro_name", brace = "(" }`. If the macro
/// 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.
(standard_macro_braces: Vec<crate::nonstandard_macro_braces::MacroMatcher> = Vec::new()),
(standard_macro_braces: Vec<MacroMatcher> = Vec::new()),
/// Lint: MISSING_ENFORCED_IMPORT_RENAMES.
///
/// The list of imports to always rename, a fully qualified path followed by the rename.
(enforced_import_renames: Vec<crate::utils::conf::Rename> = Vec::new()),
(enforced_import_renames: Vec<Rename> = Vec::new()),
/// Lint: DISALLOWED_SCRIPT_IDENTS.
///
/// The list of unicode scripts allowed to be used in the scope.
@ -447,7 +428,7 @@ define_Conf! {
/// For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements.
(max_suggested_slice_pattern_length: u64 = 3),
/// Lint: AWAIT_HOLDING_INVALID_TYPE.
(await_holding_invalid_types: Vec<crate::utils::conf::DisallowedPath> = Vec::new()),
(await_holding_invalid_types: Vec<DisallowedPath> = Vec::new()),
/// Lint: LARGE_INCLUDE_FILE.
///
/// The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
@ -511,8 +492,8 @@ define_Conf! {
/// Allowed names below the minimum allowed characters. The value `".."` 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.
(allowed_idents_below_min_chars: rustc_data_structures::fx::FxHashSet<String> =
super::DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS.iter().map(ToString::to_string).collect()),
(allowed_idents_below_min_chars: FxHashSet<String> =
DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS.iter().map(ToString::to_string).collect()),
/// Lint: MIN_IDENT_CHARS.
///
/// Minimum chars an ident can have, anything below or equal to this will be linted.
@ -537,13 +518,11 @@ define_Conf! {
/// Lint: ABSOLUTE_PATHS.
///
/// Which crates to allow absolute paths from
(absolute_paths_allowed_crates: rustc_data_structures::fx::FxHashSet<String> =
rustc_data_structures::fx::FxHashSet::default()),
(absolute_paths_allowed_crates: FxHashSet<String> = FxHashSet::default()),
/// Lint: PATH_ENDS_WITH_EXT.
///
/// Additional dotfiles (files or directories starting with a dot) to allow
(allowed_dotfiles: rustc_data_structures::fx::FxHashSet<String> =
rustc_data_structures::fx::FxHashSet::default()),
(allowed_dotfiles: FxHashSet<String> = FxHashSet::default()),
/// Lint: EXPLICIT_ITER_LOOP
///
/// Whether to recommend using implicit into iter for reborrowed values.
@ -779,7 +758,7 @@ mod tests {
#[test]
fn configs_are_tested() {
let mut names: FxHashSet<String> = super::metadata::get_configuration_metadata()
let mut names: FxHashSet<String> = crate::get_configuration_metadata()
.into_iter()
.map(|meta| meta.name.replace('_', "-"))
.collect();

23
clippy_config/src/lib.rs Normal file
View file

@ -0,0 +1,23 @@
#![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;
#[allow(unused_extern_crates)]
extern crate rustc_driver;
extern crate rustc_session;
extern crate rustc_span;
mod conf;
mod metadata;
pub mod msrvs;
pub mod types;
pub use conf::{get_configuration_metadata, lookup_conf_file, Conf};
pub use metadata::ClippyConfiguration;

View file

@ -0,0 +1,116 @@
use std::fmt::{self, Write};
#[derive(Debug, Clone, Default)]
pub struct ClippyConfiguration {
pub name: String,
pub default: String,
pub lints: Vec<String>,
pub doc: String,
pub deprecation_reason: Option<&'static str>,
}
impl fmt::Display for ClippyConfiguration {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
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,
default: String,
doc_comment: &'static str,
deprecation_reason: Option<&'static str>,
) -> Self {
let (lints, doc) = parse_config_field_doc(doc_comment)
.unwrap_or_else(|| (vec![], "[ERROR] MALFORMED DOC COMMENT".to_string()));
Self {
name: to_kebab(name),
lints,
doc,
default,
deprecation_reason,
}
}
pub fn to_markdown_paragraph(&self) -> String {
let mut out = format!(
"## `{}`\n{}\n\n",
self.name,
self.doc
.lines()
.map(|line| line.strip_prefix(" ").unwrap_or(line))
.collect::<Vec<_>>()
.join("\n"),
);
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())
.map(|name| format!("* [`{name}`](https://rust-lang.github.io/rust-clippy/master/index.html#{name})"))
.collect::<Vec<_>>()
.join("\n"),
)
.unwrap();
out
}
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)
}
}
/// This parses the field documentation of the config struct.
///
/// ```rust, ignore
/// parse_config_field_doc(cx, "Lint: LINT_NAME_1, LINT_NAME_2. Papa penguin, papa penguin")
/// ```
///
/// Would yield:
/// ```rust, ignore
/// Some(["lint_name_1", "lint_name_2"], "Papa penguin, papa penguin")
/// ```
fn parse_config_field_doc(doc_comment: &str) -> Option<(Vec<String>, String)> {
const DOC_START: &str = " Lint: ";
if doc_comment.starts_with(DOC_START)
&& let Some(split_pos) = doc_comment.find('.')
{
let mut doc_comment = doc_comment.to_string();
let mut documentation = doc_comment.split_off(split_pos);
// Extract lints
doc_comment.make_ascii_lowercase();
let lints: Vec<String> = doc_comment
.split_off(DOC_START.len())
.split(", ")
.map(str::to_string)
.collect();
// Format documentation correctly
// split off leading `.` from lint name list and indent for correct formatting
documentation = documentation.trim_start_matches('.').trim().replace("\n ", "\n ");
Some((lints, documentation))
} else {
None
}
}
/// Transforms a given `snake_case_string` to a tasty `kebab-case-string`
fn to_kebab(config_name: &str) -> String {
config_name.replace('_', "-")
}

View file

@ -1,10 +1,9 @@
use rustc_ast::Attribute;
use rustc_semver::RustcVersion;
use rustc_session::Session;
use rustc_span::{sym, Symbol};
use serde::Deserialize;
use crate::attrs::get_unique_attr;
macro_rules! msrv_aliases {
($($major:literal,$minor:literal,$patch:literal {
$($name:ident),* $(,)?
@ -101,7 +100,16 @@ impl Msrv {
}
fn parse_attr(sess: &Session, attrs: &[Attribute]) -> Option<RustcVersion> {
if let Some(msrv_attr) = get_unique_attr(sess, attrs, "msrv") {
let sym_msrv = Symbol::intern("msrv");
let mut msrv_attrs = attrs.iter().filter(|attr| attr.path_matches(&[sym::clippy, sym_msrv]));
if let Some(msrv_attr) = msrv_attrs.next() {
if let Some(duplicate) = msrv_attrs.last() {
sess.struct_span_err(duplicate.span, "`clippy::msrv` is defined multiple times")
.span_note(msrv_attr.span, "first definition found here")
.emit();
}
if let Some(msrv) = msrv_attr.value_str() {
if let Ok(version) = RustcVersion::parse(msrv.as_str()) {
return Some(version);

142
clippy_config/src/types.rs Normal file
View file

@ -0,0 +1,142 @@
use serde::de::{self, Deserializer, Visitor};
use serde::{ser, Deserialize, Serialize};
use std::fmt;
use std::hash::{Hash, Hasher};
#[derive(Clone, Debug, Deserialize)]
pub struct Rename {
pub path: String,
pub rename: String,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(untagged)]
pub enum DisallowedPath {
Simple(String),
WithReason { path: String, reason: Option<String> },
}
impl DisallowedPath {
pub fn path(&self) -> &str {
let (Self::Simple(path) | Self::WithReason { path, .. }) = self;
path
}
pub fn reason(&self) -> Option<String> {
match self {
Self::WithReason {
reason: Some(reason), ..
} => Some(format!("{reason} (from clippy.toml)")),
_ => None,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub enum MatchLintBehaviour {
AllTypes,
WellKnownTypes,
Never,
}
#[derive(Clone, Debug)]
pub struct MacroMatcher {
pub name: String,
pub braces: (String, String),
}
impl Hash for MacroMatcher {
fn hash<H: Hasher>(&self, state: &mut H) {
self.name.hash(state);
}
}
impl PartialEq for MacroMatcher {
fn eq(&self, other: &Self) -> bool {
self.name == other.name
}
}
impl Eq for MacroMatcher {}
impl<'de> Deserialize<'de> for MacroMatcher {
fn deserialize<D>(deser: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(field_identifier, rename_all = "lowercase")]
enum Field {
Name,
Brace,
}
struct MacVisitor;
impl<'de> Visitor<'de> for MacVisitor {
type Value = MacroMatcher;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("struct MacroMatcher")
}
fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
where
V: de::MapAccess<'de>,
{
let mut name = None;
let mut brace: Option<String> = None;
while let Some(key) = map.next_key()? {
match key {
Field::Name => {
if name.is_some() {
return Err(de::Error::duplicate_field("name"));
}
name = Some(map.next_value()?);
},
Field::Brace => {
if brace.is_some() {
return Err(de::Error::duplicate_field("brace"));
}
brace = Some(map.next_value()?);
},
}
}
let name = name.ok_or_else(|| de::Error::missing_field("name"))?;
let brace = brace.ok_or_else(|| de::Error::missing_field("brace"))?;
Ok(MacroMatcher {
name,
braces: [("(", ")"), ("{", "}"), ("[", "]")]
.into_iter()
.find(|b| b.0 == brace)
.map(|(o, c)| (o.to_owned(), c.to_owned()))
.ok_or_else(|| de::Error::custom(format!("expected one of `(`, `{{`, `[` found `{brace}`")))?,
})
}
}
const FIELDS: &[&str] = &["name", "brace"];
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<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
where
S: ser::Serializer,
{
Err(ser::Error::custom("unimplemented"))
}
}
)*
}
}
unimplemented_serialize! {
DisallowedPath,
Rename,
MacroMatcher,
}

View file

@ -11,6 +11,7 @@ edition = "2021"
[dependencies]
arrayvec = { version = "0.7", default-features = false }
cargo_metadata = "0.15.3"
clippy_config = { path = "../clippy_config" }
clippy_utils = { path = "../clippy_utils" }
declare_clippy_lint = { path = "../declare_clippy_lint" }
if_chain = "1.0"

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::{trim_span, walk_span_to_context};
use rustc_ast::ast::{Expr, ExprKind, LitKind, Pat, PatKind, RangeEnd, RangeLimits};
use rustc_errors::Applicability;

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::msrvs::{self, Msrv};
use rustc_ast::ast::{FloatTy, LitFloatType, LitKind};
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};

View file

@ -1,9 +1,9 @@
//! checks for attributes
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
use clippy_utils::is_from_proc_macro;
use clippy_utils::macros::{is_panic, macro_backtrace};
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::{first_line_of_span, is_present_in_source, snippet_opt, without_block_comments};
use if_chain::if_chain;
use rustc_ast::token::{Token, TokenKind};

View file

@ -1,3 +1,4 @@
use clippy_config::types::DisallowedPath;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::{match_def_path, paths};
use rustc_data_structures::fx::FxHashMap;
@ -8,8 +9,6 @@ use rustc_middle::mir::CoroutineLayout;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{sym, Span};
use crate::utils::conf::DisallowedPath;
declare_clippy_lint! {
/// ### What it does
/// Checks for calls to await while holding a non-async-aware MutexGuard.

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::sugg::Sugg;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};

View file

@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::in_constant;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::is_isize_or_usize;
use rustc_errors::Applicability;

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source;
use if_chain::if_chain;
use rustc_ast::Mutability;

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_context;
use if_chain::if_chain;
use rustc_errors::Applicability;

View file

@ -22,8 +22,8 @@ mod unnecessary_cast;
mod utils;
mod zero_ptr;
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::is_hir_ty_cfg_dependant;
use clippy_utils::msrvs::{self, Msrv};
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::sugg::Sugg;
use rustc_errors::Applicability;

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{Msrv, POINTER_CAST_CONSTNESS};
use clippy_utils::sugg::Sugg;
use if_chain::if_chain;
use rustc_errors::Applicability;
@ -18,7 +18,7 @@ pub(super) fn check<'tcx>(
msrv: &Msrv,
) {
if_chain! {
if msrv.meets(POINTER_CAST_CONSTNESS);
if msrv.meets(msrvs::POINTER_CAST_CONSTNESS);
if let ty::RawPtr(TypeAndMut { mutbl: from_mutbl, ty: from_ty }) = cast_from.kind();
if let ty::RawPtr(TypeAndMut { mutbl: to_mutbl, ty: to_ty }) = cast_to.kind();
if matches!((from_mutbl, to_mutbl),

View file

@ -1,7 +1,7 @@
//! lint on manually implemented checked conversions that could be transformed into `try_from`
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::{in_constant, is_integer_literal, SpanlessEq};
use if_chain::if_chain;

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::indent_of;
use clippy_utils::{is_default_equivalent, peel_blocks};
use rustc_errors::Applicability;

View file

@ -1,3 +1,4 @@
use clippy_config::types::DisallowedPath;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::macros::macro_backtrace;
use rustc_ast::Attribute;
@ -8,8 +9,6 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{ExpnId, Span};
use crate::utils::conf;
declare_clippy_lint! {
/// ### What it does
/// Denies the configured macros in clippy.toml
@ -55,13 +54,13 @@ declare_clippy_lint! {
}
pub struct DisallowedMacros {
conf_disallowed: Vec<conf::DisallowedPath>,
conf_disallowed: Vec<DisallowedPath>,
disallowed: DefIdMap<usize>,
seen: FxHashSet<ExpnId>,
}
impl DisallowedMacros {
pub fn new(conf_disallowed: Vec<conf::DisallowedPath>) -> Self {
pub fn new(conf_disallowed: Vec<DisallowedPath>) -> Self {
Self {
conf_disallowed,
disallowed: DefIdMap::default(),

View file

@ -1,13 +1,11 @@
use clippy_config::types::DisallowedPath;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::{fn_def_id, get_parent_expr, path_def_id};
use rustc_hir::def_id::DefIdMap;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use crate::utils::conf;
declare_clippy_lint! {
/// ### What it does
/// Denies the configured methods and functions in clippy.toml
@ -59,12 +57,12 @@ declare_clippy_lint! {
#[derive(Clone, Debug)]
pub struct DisallowedMethods {
conf_disallowed: Vec<conf::DisallowedPath>,
conf_disallowed: Vec<DisallowedPath>,
disallowed: DefIdMap<usize>,
}
impl DisallowedMethods {
pub fn new(conf_disallowed: Vec<conf::DisallowedPath>) -> Self {
pub fn new(conf_disallowed: Vec<DisallowedPath>) -> Self {
Self {
conf_disallowed,
disallowed: DefIdMap::default(),

View file

@ -1,5 +1,5 @@
use clippy_config::types::DisallowedPath;
use clippy_utils::diagnostics::span_lint_and_then;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def::Res;
use rustc_hir::def_id::DefId;
@ -8,8 +8,6 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::Span;
use crate::utils::conf;
declare_clippy_lint! {
/// ### What it does
/// Denies the configured types in clippy.toml.
@ -50,15 +48,16 @@ declare_clippy_lint! {
style,
"use of disallowed types"
}
#[derive(Clone, Debug)]
pub struct DisallowedTypes {
conf_disallowed: Vec<conf::DisallowedPath>,
conf_disallowed: Vec<DisallowedPath>,
def_ids: FxHashMap<DefId, usize>,
prim_tys: FxHashMap<PrimTy, usize>,
}
impl DisallowedTypes {
pub fn new(conf_disallowed: Vec<conf::DisallowedPath>) -> Self {
pub fn new(conf_disallowed: Vec<DisallowedPath>) -> Self {
Self {
conf_disallowed,
def_ids: FxHashMap::default(),
@ -123,7 +122,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedTypes {
}
}
fn emit(cx: &LateContext<'_>, name: &str, span: Span, conf: &conf::DisallowedPath) {
fn emit(cx: &LateContext<'_>, name: &str, span: Span, conf: &DisallowedPath) {
span_lint_and_then(
cx,
DISALLOWED_TYPES,

View file

@ -1,11 +1,11 @@
use arrayvec::ArrayVec;
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::is_diag_trait_item;
use clippy_utils::macros::{
find_format_arg_expr, find_format_args, format_arg_removal_span, format_placeholder_format_span, is_assert_macro,
is_format_macro, is_panic, root_macro_call, root_macro_call_first_node, FormatParamUsage,
};
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::{implements_trait, is_type_lang_item};
use if_chain::if_chain;

View file

@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::macros::span_is_local;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::path_def_id;
use clippy_utils::source::snippet_opt;
use rustc_errors::Applicability;

View file

@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::eager_or_lazy::switch_to_eager_eval;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_context;
use clippy_utils::sugg::Sugg;
use clippy_utils::{contains_return, higher, is_else_clause, is_res_lang_ctor, path_res, peel_blocks};

View file

@ -1,7 +1,7 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::higher::IfLet;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::ty::is_copy;
use clippy_utils::{is_expn_of, is_lint_allowed, path_to_local};
use if_chain::if_chain;

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::{self, span_lint_and_sugg};
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_context;
use clippy_utils::sugg::Sugg;
use clippy_utils::ty;

View file

@ -50,7 +50,6 @@ extern crate clippy_utils;
#[macro_use]
extern crate declare_clippy_lint;
use clippy_utils::msrvs::Msrv;
use rustc_data_structures::fx::FxHashSet;
use rustc_lint::{Lint, LintId};
use rustc_session::Session;
@ -358,9 +357,7 @@ mod zero_div_zero;
mod zero_sized_map_values;
// end lints modules, do not remove this comment, its used in `update_lints`
use crate::utils::conf::metadata::get_configuration_metadata;
pub use crate::utils::conf::{lookup_conf_file, Conf};
use crate::utils::FindAll;
use clippy_config::{get_configuration_metadata, Conf};
/// Register all pre expansion lints
///
@ -462,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

View file

@ -1,6 +1,6 @@
use super::EXPLICIT_ITER_LOOP;
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::{
implements_trait, implements_trait_with_env, is_copy, make_normalized_projection,

View file

@ -19,8 +19,8 @@ mod while_immutable_condition;
mod while_let_loop;
mod while_let_on_iterator;
use clippy_config::msrvs::Msrv;
use clippy_utils::higher;
use clippy_utils::msrvs::Msrv;
use rustc_hir::{Expr, ExprKind, LoopSource, Pat};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};

View file

@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::get_parent_expr;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_context;
use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;

View file

@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
use clippy_utils::higher::If;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::sugg::Sugg;
use clippy_utils::ty::implements_trait;
use clippy_utils::visitors::is_const_evaluatable;

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_opt;
use clippy_utils::visitors::{is_local_used, local_used_once};
use clippy_utils::{is_trait_method, path_to_local_id};

View file

@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::macros::root_macro_call;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::sugg::Sugg;
use clippy_utils::{higher, in_constant};
use rustc_ast::ast::RangeLimits;

View file

@ -1,10 +1,12 @@
use crate::question_mark::{QuestionMark, QUESTION_MARK};
use clippy_config::msrvs;
use clippy_config::types::MatchLintBehaviour;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::higher::IfLetOrMatch;
use clippy_utils::source::snippet_with_context;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::visitors::{Descend, Visitable};
use clippy_utils::{is_lint_allowed, msrvs, pat_and_expr_can_be_question_mark, peel_blocks};
use clippy_utils::{is_lint_allowed, pat_and_expr_can_be_question_mark, peel_blocks};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_expr, Visitor};
@ -14,7 +16,6 @@ use rustc_middle::lint::in_external_macro;
use rustc_session::declare_tool_lint;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::Span;
use serde::Deserialize;
use std::ops::ControlFlow;
use std::slice;
@ -477,10 +478,3 @@ fn expr_simple_identity_map<'a, 'hir>(
}
Some(ident_map)
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize)]
pub enum MatchLintBehaviour {
AllTypes,
WellKnownTypes,
Never,
}

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::{is_trait_method, match_def_path, paths, peel_hir_expr_refs};
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};

View file

@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
use clippy_utils::is_doc_hidden;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_opt;
use rustc_ast::ast::{self, VisibilityKind};
use rustc_ast::attr;

View file

@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::consts::{constant_full_int, FullInt};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_context;
use clippy_utils::{in_constant, path_to_local};
use rustc_errors::Applicability;

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet;
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
use clippy_utils::{get_parent_expr, match_def_path, paths, SpanlessEq};

View file

@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then};
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet;
use clippy_utils::usage::mutated_variables;
use clippy_utils::{eq_expr_value, higher, match_def_path, paths};

View file

@ -24,7 +24,7 @@ mod single_match;
mod try_err;
mod wild_in_or_pats;
use clippy_utils::msrvs::{self, Msrv};
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::source::{snippet_opt, walk_span_to_context};
use clippy_utils::{higher, in_constant, is_direct_expn_of, is_span_match, tokenize_with_text};
use rustc_hir::{Arm, Expr, ExprKind, Local, MatchSource, Pat};

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::{snippet, snippet_with_applicability};
use clippy_utils::sugg::Sugg;
use clippy_utils::ty::is_non_aggregate_primitive_type;

View file

@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::is_trait_method;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::ty::{get_iterator_item_ty, is_copy};
use rustc_errors::Applicability;
use rustc_hir::Expr;

View file

@ -1,6 +1,6 @@
use super::ERR_EXPECT;
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::ty::{has_debug_impl, is_type_diagnostic_item};
use rustc_errors::Applicability;
use rustc_lint::LateContext;

View file

@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
use clippy_utils::is_trait_method;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet;
use rustc_errors::Applicability;
use rustc_hir as hir;

View file

@ -1,9 +1,9 @@
//! Lint for `c.is_digit(10)`
use super::IS_DIGIT_ASCII_RADIX;
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::consts::{constant_full_int, FullInt};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_applicability;
use rustc_errors::Applicability;
use rustc_hir::Expr;

View file

@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::is_from_proc_macro;
use clippy_utils::msrvs::{Msrv, ITERATOR_TRY_FOLD};
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::implements_trait;
use rustc_errors::Applicability;
@ -21,7 +21,7 @@ pub(super) fn check<'tcx>(
msrv: &Msrv,
) {
if !in_external_macro(cx.sess(), fold_span)
&& msrv.meets(ITERATOR_TRY_FOLD)
&& msrv.meets(msrvs::ITERATOR_TRY_FOLD)
&& let init_ty = cx.typeck_results().expr_ty(init)
&& let Some(try_trait) = cx.tcx.lang_items().try_trait()
&& implements_trait(cx, init_ty, try_trait, &[])

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::{is_copy, is_type_diagnostic_item};
use clippy_utils::{is_diag_trait_item, peel_blocks};

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::usage::mutated_variables;

View file

@ -116,9 +116,9 @@ mod wrong_self_convention;
mod zst_offset;
use bind_instead_of_map::BindInsteadOfMap;
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::ty::{contains_ty_adt_constructor_opaque, implements_trait, is_copy, is_type_diagnostic_item};
use clippy_utils::{contains_return, is_bool, is_trait_method, iter_input_pats, peel_blocks, return_ty};
use if_chain::if_chain;

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{match_def_path, path_to_local_id, paths, peel_blocks};

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::{is_copy, is_type_diagnostic_item};
use rustc_data_structures::fx::FxHashSet;

View file

@ -1,7 +1,6 @@
use super::PATH_ENDS_WITH_EXT;
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs;
use clippy_utils::msrvs::Msrv;
use clippy_utils::source::snippet;
use clippy_utils::ty::is_type_diagnostic_item;
use rustc_ast::{LitKind, StrStyle};

View file

@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_context;
use clippy_utils::usage::local_used_after_expr;
use clippy_utils::visitors::{for_each_expr_with_closures, Descend};

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::msrvs::{Msrv, MATCHES_MACRO};
use clippy_utils::source::snippet_opt;
use clippy_utils::{is_from_proc_macro, is_trait_method, path_to_local};
use itertools::Itertools;
@ -19,7 +19,7 @@ pub(super) fn check<'tcx>(
body: &Expr<'_>,
msrv: &Msrv,
) {
if msrv.meets(MATCHES_MACRO)
if msrv.meets(msrvs::MATCHES_MACRO)
&& is_trait_method(cx, expr, sym::Iterator)
&& let PatKind::Binding(_, arg, _, _) = param.pat.kind
&& let ExprKind::Lit(lit_kind) = recv.kind

View file

@ -1,7 +1,7 @@
use super::implicit_clone::is_clone_like;
use super::unnecessary_iter_cloned::{self, is_into_iter};
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy, peel_mid_ty_refs};
use clippy_utils::visitors::find_all_ret_expressions;

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::qualify_min_const_fn::is_min_const_fn;
use clippy_utils::ty::has_drop;
use clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, is_from_proc_macro, trait_ref_of_method};

View file

@ -1,6 +1,6 @@
use clippy_config::types::Rename;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_opt;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::Applicability;
use rustc_hir::def::Res;
@ -10,8 +10,6 @@ use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::Symbol;
use crate::utils::conf::Rename;
declare_clippy_lint! {
/// ### What it does
/// Checks for imports that do not rename the item as specified

View file

@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::mir::{enclosing_mir, expr_local, local_assignments, used_exactly_once, PossibleBorrowerMap};
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_context;
use clippy_utils::ty::is_copy;
use clippy_utils::{expr_use_ctxt, peel_n_hir_expr_refs, DefinedTy, ExprUseNode};

View file

@ -1,6 +1,4 @@
use std::fmt;
use std::hash::{Hash, Hasher};
use clippy_config::types::MacroMatcher;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_opt;
use if_chain::if_chain;
@ -12,7 +10,6 @@ use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::hygiene::{ExpnKind, MacroKind};
use rustc_span::Span;
use serde::{de, Deserialize};
declare_clippy_lint! {
/// ### What it does
@ -36,8 +33,6 @@ declare_clippy_lint! {
"check consistent use of braces in macro"
}
const BRACES: &[(&str, &str)] = &[("(", ")"), ("{", "}"), ("[", "]")];
/// The (callsite span, (open brace, close brace), source snippet)
type MacroInfo<'a> = (Span, &'a (String, String), String);
@ -195,81 +190,3 @@ macro_rules! macro_matcher {
};
}
pub(crate) use macro_matcher;
#[derive(Clone, Debug)]
pub struct MacroMatcher {
name: String,
braces: (String, String),
}
impl Hash for MacroMatcher {
fn hash<H: Hasher>(&self, state: &mut H) {
self.name.hash(state);
}
}
impl PartialEq for MacroMatcher {
fn eq(&self, other: &Self) -> bool {
self.name == other.name
}
}
impl Eq for MacroMatcher {}
impl<'de> Deserialize<'de> for MacroMatcher {
fn deserialize<D>(deser: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(field_identifier, rename_all = "lowercase")]
enum Field {
Name,
Brace,
}
struct MacVisitor;
impl<'de> de::Visitor<'de> for MacVisitor {
type Value = MacroMatcher;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("struct MacroMatcher")
}
fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
where
V: de::MapAccess<'de>,
{
let mut name = None;
let mut brace: Option<String> = None;
while let Some(key) = map.next_key()? {
match key {
Field::Name => {
if name.is_some() {
return Err(de::Error::duplicate_field("name"));
}
name = Some(map.next_value()?);
},
Field::Brace => {
if brace.is_some() {
return Err(de::Error::duplicate_field("brace"));
}
brace = Some(map.next_value()?);
},
}
}
let name = name.ok_or_else(|| de::Error::missing_field("name"))?;
let brace = brace.ok_or_else(|| de::Error::missing_field("brace"))?;
Ok(MacroMatcher {
name,
braces: BRACES
.iter()
.find(|b| b.0 == brace)
.map(|(o, c)| ((*o).to_owned(), (*c).to_owned()))
.ok_or_else(|| de::Error::custom(format!("expected one of `(`, `{{`, `[` found `{brace}`")))?,
})
}
}
const FIELDS: &[&str] = &["name", "brace"];
deser.deserialize_struct("MacroMatcher", FIELDS, MacVisitor)
}
}

View file

@ -1,7 +1,8 @@
use crate::manual_let_else::{MatchLintBehaviour, MANUAL_LET_ELSE};
use crate::manual_let_else::MANUAL_LET_ELSE;
use crate::question_mark_used::QUESTION_MARK_USED;
use clippy_config::msrvs::Msrv;
use clippy_config::types::MatchLintBehaviour;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::Msrv;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{

View file

@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::{snippet, snippet_opt, snippet_with_applicability};
use clippy_utils::sugg::Sugg;
use clippy_utils::{get_parent_expr, higher, in_constant, is_integer_const, path_to_local};

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use rustc_ast::ast::{Expr, ExprKind};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet;
use rustc_ast::ast::{ConstItem, Item, ItemKind, StaticItem, Ty, TyKind};
use rustc_errors::Applicability;

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::{snippet, snippet_opt, snippet_with_applicability};
use clippy_utils::{is_from_proc_macro, SpanlessEq, SpanlessHash};
use core::hash::{Hash, Hasher};

View file

@ -17,8 +17,8 @@ mod useless_transmute;
mod utils;
mod wrong_transmute;
use clippy_config::msrvs::Msrv;
use clippy_utils::in_constant;
use clippy_utils::msrvs::Msrv;
use if_chain::if_chain;
use rustc_hir::{Expr, ExprKind, QPath};
use rustc_lint::{LateContext, LateLintPass};

View file

@ -1,6 +1,6 @@
use super::TRANSMUTE_PTR_TO_REF;
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::sugg;
use rustc_errors::Applicability;

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::visitors::for_each_local_use_after_expr;
use clippy_utils::{is_from_proc_macro, path_to_local};
use itertools::Itertools;

View file

@ -1,8 +1,8 @@
#![allow(clippy::wildcard_imports, clippy::enum_glob_use)]
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::ast_utils::{eq_field_pat, eq_id, eq_maybe_qself, eq_pat, eq_path};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::over;
use rustc_ast::mut_visit::*;
use rustc_ast::ptr::P;

View file

@ -1,6 +1,6 @@
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::is_from_proc_macro;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::ty::same_type_and_consts;
use if_chain::if_chain;
use rustc_data_structures::fx::FxHashSet;

View file

@ -5,27 +5,20 @@ use rustc_ast::{Crate, Expr, ExprKind, FormatArgs};
use rustc_data_structures::fx::FxHashMap;
use rustc_lexer::{tokenize, TokenKind};
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_session::impl_lint_pass;
use rustc_span::{hygiene, Span};
use std::iter::once;
use std::mem;
use std::rc::Rc;
declare_clippy_lint! {
/// ### What it does
/// Collects [`rustc_ast::FormatArgs`] so that future late passes can call
/// [`clippy_utils::macros::find_format_args`]
pub FORMAT_ARGS_COLLECTOR,
internal_warn,
"collects `format_args` AST nodes for use in later lints"
}
/// Collects [`rustc_ast::FormatArgs`] so that future late passes can call
/// [`clippy_utils::macros::find_format_args`]
#[derive(Default)]
pub struct FormatArgsCollector {
format_args: FxHashMap<Span, Rc<FormatArgs>>,
}
impl_lint_pass!(FormatArgsCollector => [FORMAT_ARGS_COLLECTOR]);
impl_lint_pass!(FormatArgsCollector => []);
impl EarlyLintPass for FormatArgsCollector {
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {

View file

@ -9,7 +9,7 @@
use crate::renamed_lints::RENAMED_LINTS;
use crate::utils::internal_lints::lint_without_lint_pass::{extract_clippy_version_value, is_lint_ref_type};
use crate::utils::{collect_configs, ClippyConfiguration};
use clippy_config::{get_configuration_metadata, ClippyConfiguration};
use clippy_utils::diagnostics::span_lint;
use clippy_utils::ty::{match_type, walk_ptrs_ty_depth};
@ -155,7 +155,7 @@ impl MetadataCollector {
Self {
lints: BinaryHeap::<LintMetadata>::default(),
applicability_info: FxHashMap::<String, ApplicabilityInfo>::default(),
config: collect_configs(),
config: get_configuration_metadata(),
clippy_project_root: std::env::current_dir()
.expect("failed to get current dir")
.ancestors()
@ -528,16 +528,6 @@ impl Serialize for ApplicabilityInfo {
}
}
impl fmt::Display for ClippyConfiguration {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
writeln!(
f,
"* `{}`: `{}`(defaults to `{}`): {}",
self.name, self.config_type, self.default, self.doc
)
}
}
// ==================================================================
// Lint pass
// ==================================================================

View file

@ -1,148 +1,5 @@
pub mod author;
pub mod conf;
pub mod dump_hir;
pub mod format_args_collector;
#[cfg(feature = "internal")]
pub mod internal_lints;
#[cfg(feature = "internal")]
use itertools::Itertools;
/// Transforms a given `snake_case_string` to a tasty `kebab-case-string`
fn to_kebab(config_name: &str) -> String {
config_name.replace('_', "-")
}
#[cfg(feature = "internal")]
const BOOK_CONFIGS_PATH: &str = "https://doc.rust-lang.org/clippy/lint_configuration.html";
// ==================================================================
// Configuration
// ==================================================================
#[derive(Debug, Clone, Default)]
pub struct ClippyConfiguration {
pub name: String,
#[allow(dead_code)]
config_type: &'static str,
pub default: String,
pub lints: Vec<String>,
pub doc: String,
#[allow(dead_code)]
deprecation_reason: Option<&'static str>,
}
impl ClippyConfiguration {
pub fn new(
name: &'static str,
config_type: &'static str,
default: String,
doc_comment: &'static str,
deprecation_reason: Option<&'static str>,
) -> Self {
let (lints, doc) = parse_config_field_doc(doc_comment)
.unwrap_or_else(|| (vec![], "[ERROR] MALFORMED DOC COMMENT".to_string()));
Self {
name: to_kebab(name),
lints,
doc,
config_type,
default,
deprecation_reason,
}
}
#[cfg(feature = "internal")]
fn to_markdown_paragraph(&self) -> String {
format!(
"## `{}`\n{}\n\n**Default Value:** `{}` (`{}`)\n\n---\n**Affected lints:**\n{}\n\n",
self.name,
self.doc
.lines()
.map(|line| line.strip_prefix(" ").unwrap_or(line))
.join("\n"),
self.default,
self.config_type,
self.lints
.iter()
.map(|name| name.to_string().split_whitespace().next().unwrap().to_string())
.map(|name| format!("* [`{name}`](https://rust-lang.github.io/rust-clippy/master/index.html#{name})"))
.join("\n"),
)
}
#[cfg(feature = "internal")]
fn to_markdown_link(&self) -> String {
format!("[`{}`]: {BOOK_CONFIGS_PATH}#{}", self.name, self.name)
}
}
#[cfg(feature = "internal")]
fn collect_configs() -> Vec<ClippyConfiguration> {
crate::utils::conf::metadata::get_configuration_metadata()
}
/// This parses the field documentation of the config struct.
///
/// ```rust, ignore
/// parse_config_field_doc(cx, "Lint: LINT_NAME_1, LINT_NAME_2. Papa penguin, papa penguin")
/// ```
///
/// Would yield:
/// ```rust, ignore
/// Some(["lint_name_1", "lint_name_2"], "Papa penguin, papa penguin")
/// ```
fn parse_config_field_doc(doc_comment: &str) -> Option<(Vec<String>, String)> {
const DOC_START: &str = " Lint: ";
if_chain! {
if doc_comment.starts_with(DOC_START);
if let Some(split_pos) = doc_comment.find('.');
then {
let mut doc_comment = doc_comment.to_string();
let mut documentation = doc_comment.split_off(split_pos);
// Extract lints
doc_comment.make_ascii_lowercase();
let lints: Vec<String> = doc_comment
.split_off(DOC_START.len())
.split(", ")
.map(str::to_string)
.collect();
// Format documentation correctly
// split off leading `.` from lint name list and indent for correct formatting
documentation = documentation.trim_start_matches('.').trim().replace("\n ", "\n ");
Some((lints, documentation))
} else {
None
}
}
}
// Shamelessly stolen from find_all (https://github.com/nectariner/find_all)
pub trait FindAll: Iterator + Sized {
fn find_all<P>(&mut self, predicate: P) -> Option<Vec<usize>>
where
P: FnMut(&Self::Item) -> bool;
}
impl<I> FindAll for I
where
I: Iterator,
{
fn find_all<P>(&mut self, mut predicate: P) -> Option<Vec<usize>>
where
P: FnMut(&Self::Item) -> bool,
{
let mut occurences = Vec::<usize>::default();
for (index, element) in self.enumerate() {
if predicate(&element) {
occurences.push(index);
}
}
match occurences.len() {
0 => None,
_ => Some(occurences),
}
}
}

View file

@ -1,8 +1,8 @@
use std::ops::ControlFlow;
use clippy_config::msrvs::{self, Msrv};
use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::is_copy;
use clippy_utils::visitors::for_each_local_use_after_expr;

View file

@ -5,11 +5,11 @@ edition = "2021"
publish = false
[dependencies]
clippy_config = { path = "../clippy_config" }
arrayvec = { version = "0.7", default-features = false }
if_chain = "1.0"
itertools = "0.10.1"
rustc-semver = "1.1"
serde = { version = "1.0" }
[features]
deny-warnings = []

View file

@ -54,7 +54,6 @@ pub mod higher;
mod hir_utils;
pub mod macros;
pub mod mir;
pub mod msrvs;
pub mod numeric_literal;
pub mod paths;
pub mod ptr;

View file

@ -53,7 +53,7 @@ pub const LATE_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "LateLintPass"];
#[cfg(feature = "internal")]
pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"];
#[cfg(feature = "internal")]
pub const MSRV: [&str; 3] = ["clippy_utils", "msrvs", "Msrv"];
pub const MSRV: [&str; 3] = ["clippy_config", "msrvs", "Msrv"];
pub const OS_STRING_AS_OS_STR: [&str; 5] = ["std", "ffi", "os_str", "OsString", "as_os_str"];
pub const OS_STR_TO_OS_STRING: [&str; 5] = ["std", "ffi", "os_str", "OsStr", "to_os_string"];
pub const PARKING_LOT_MUTEX_GUARD: [&str; 3] = ["lock_api", "mutex", "MutexGuard"];

View file

@ -3,7 +3,7 @@
// of terminologies might not be relevant in the context of Clippy. Note that its behavior might
// differ from the time of `rustc` even if the name stays the same.
use crate::msrvs::Msrv;
use clippy_config::msrvs::Msrv;
use hir::LangItem;
use rustc_const_eval::transform::check_consts::ConstCx;
use rustc_hir as hir;

View file

@ -126,7 +126,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
// JUSTIFICATION: necessary in clippy driver to set `mir_opt_level`
#[allow(rustc::bad_opt_access)]
fn config(&mut self, config: &mut interface::Config) {
let conf_path = clippy_lints::lookup_conf_file();
let conf_path = clippy_config::lookup_conf_file();
let previous = config.register_lints.take();
let clippy_args_var = self.clippy_args_var.take();
config.parse_sess_created = Some(Box::new(move |parse_sess| {
@ -147,7 +147,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
(previous)(sess, lint_store);
}
let conf = clippy_lints::Conf::read(sess, &conf_path);
let conf = clippy_config::Conf::read(sess, &conf_path);
clippy_lints::register_plugins(lint_store, sess, conf);
clippy_lints::register_pre_expansion_lints(lint_store, conf);
clippy_lints::register_renamed(lint_store);

View file

@ -30,6 +30,7 @@ mod test_utils;
/// All crates used in UI tests are listed here
static TEST_DEPENDENCIES: &[&str] = &[
"clippy_config",
"clippy_lints",
"clippy_utils",
"futures",

View file

@ -28,6 +28,7 @@ fn dogfood_clippy() {
"clippy_dev",
"clippy_lints",
"clippy_utils",
"clippy_config",
"lintcheck",
"rustc_tools_util",
] {
@ -56,7 +57,10 @@ fn run_metadata_collection_lint() {
// Run collection as is
std::env::set_var("ENABLE_METADATA_COLLECTION", "1");
run_clippy_for_package("clippy_lints", &["-A", "unfulfilled_lint_expectations"]);
assert!(run_clippy_for_package(
"clippy_lints",
&["-A", "unfulfilled_lint_expectations"]
));
// Check if cargo caching got in the way
if let Ok(file) = File::open(metadata_output_path) {
@ -79,9 +83,13 @@ fn run_metadata_collection_lint() {
.unwrap();
// Running the collection again
run_clippy_for_package("clippy_lints", &["-A", "unfulfilled_lint_expectations"]);
assert!(run_clippy_for_package(
"clippy_lints",
&["-A", "unfulfilled_lint_expectations"]
));
}
#[must_use]
fn run_clippy_for_package(project: &str, args: &[&str]) -> bool {
let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));

View file

@ -8,8 +8,8 @@ extern crate rustc_lint;
extern crate rustc_middle;
#[macro_use]
extern crate rustc_session;
use clippy_config::msrvs::Msrv;
use clippy_utils::extract_msrv_attr;
use clippy_utils::msrvs::Msrv;
use rustc_hir::Expr;
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};

View file

@ -8,8 +8,8 @@ extern crate rustc_lint;
extern crate rustc_middle;
#[macro_use]
extern crate rustc_session;
use clippy_config::msrvs::Msrv;
use clippy_utils::extract_msrv_attr;
use clippy_utils::msrvs::Msrv;
use rustc_hir::Expr;
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};

View file

@ -11,13 +11,12 @@ fn outer_attr() {}
mod multiple {
#![clippy::msrv = "1.40"]
#![clippy::msrv = "=1.35.0"]
//~^ ERROR: `msrv` is defined multiple times
#![clippy::msrv = "1.10.1"]
//~^ ERROR: `msrv` is defined multiple times
//~^ ERROR: `clippy::msrv` is defined multiple times
mod foo {
#![clippy::msrv = "1"]
#![clippy::msrv = "1.0.0"]
//~^ ERROR: `msrv` is defined multiple times
//~^ ERROR: `clippy::msrv` is defined multiple times
}
}

View file

@ -10,20 +10,8 @@ error: `invalid.version` is not a valid Rust version
LL | #[clippy::msrv = "invalid.version"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `msrv` is defined multiple times
--> $DIR/min_rust_version_invalid_attr.rs:13:5
|
LL | #![clippy::msrv = "=1.35.0"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first definition found here
--> $DIR/min_rust_version_invalid_attr.rs:12:5
|
LL | #![clippy::msrv = "1.40"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: `msrv` is defined multiple times
--> $DIR/min_rust_version_invalid_attr.rs:15:5
error: `clippy::msrv` is defined multiple times
--> $DIR/min_rust_version_invalid_attr.rs:14:5
|
LL | #![clippy::msrv = "1.10.1"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -34,17 +22,17 @@ note: first definition found here
LL | #![clippy::msrv = "1.40"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: `msrv` is defined multiple times
--> $DIR/min_rust_version_invalid_attr.rs:20:9
error: `clippy::msrv` is defined multiple times
--> $DIR/min_rust_version_invalid_attr.rs:19:9
|
LL | #![clippy::msrv = "1.0.0"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first definition found here
--> $DIR/min_rust_version_invalid_attr.rs:19:9
--> $DIR/min_rust_version_invalid_attr.rs:18:9
|
LL | #![clippy::msrv = "1"]
| ^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 5 previous errors
error: aborting due to 4 previous errors

View file

@ -26,6 +26,7 @@ fn consistent_clippy_crate_versions() {
let paths = [
"declare_clippy_lint/Cargo.toml",
"clippy_config/Cargo.toml",
"clippy_lints/Cargo.toml",
"clippy_utils/Cargo.toml",
];