Skip to content

Commit a41214f

Browse files
committed
Auto merge of rust-lang#147779 - flip1995:clippy-subtree-update, r=Manishearth
Clippy subtree update r? `@Manishearth` `Cargo.lock` update, because `clippy_utils` is now also using `itertools`
2 parents 28c4c7d + 4b0cfb6 commit a41214f

File tree

471 files changed

+7417
-2694
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

471 files changed

+7417
-2694
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,7 @@ version = "0.0.1"
645645
dependencies = [
646646
"clippy_config",
647647
"clippy_utils",
648+
"itertools",
648649
"regex",
649650
"rustc-semver",
650651
]

src/tools/clippy/.github/workflows/remark.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ jobs:
1717
persist-credentials: false
1818

1919
- name: Setup Node.js
20-
uses: actions/setup-node@v4
20+
uses: actions/setup-node@v5
2121
with:
22-
node-version: '18.x'
22+
node-version: '20.x'
2323

2424
- name: Install remark
2525
run: npm install remark-cli remark-lint remark-lint-maximum-line-length@^3.1.3 remark-preset-lint-recommended remark-gfm

src/tools/clippy/CHANGELOG.md

Lines changed: 270 additions & 107 deletions
Large diffs are not rendered by default.

src/tools/clippy/book/src/development/adding_lints.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -759,8 +759,7 @@ for some users. Adding a configuration is done in the following steps:
759759
Here are some pointers to things you are likely going to need for every lint:
760760

761761
* [Clippy utils][utils] - Various helper functions. Maybe the function you need
762-
is already in here ([`is_type_diagnostic_item`], [`implements_trait`],
763-
[`snippet`], etc)
762+
is already in here ([`implements_trait`], [`snippet`], etc)
764763
* [Clippy diagnostics][diagnostics]
765764
* [Let chains][let-chains]
766765
* [`from_expansion`][from_expansion] and
@@ -790,7 +789,6 @@ get away with copying things from existing similar lints. If you are stuck,
790789
don't hesitate to ask on [Zulip] or in the issue/PR.
791790

792791
[utils]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/index.html
793-
[`is_type_diagnostic_item`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/ty/fn.is_type_diagnostic_item.html
794792
[`implements_trait`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/ty/fn.implements_trait.html
795793
[`snippet`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/source/fn.snippet.html
796794
[let-chains]: https://github.com/rust-lang/rust/pull/94927

src/tools/clippy/book/src/development/common_tools_writing_lints.md

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for MyStructLint {
6868
// Check our expr is calling a method
6969
if let hir::ExprKind::MethodCall(path, _, _self_arg, ..) = &expr.kind
7070
// Check the name of this method is `some_method`
71-
&& path.ident.name.as_str() == "some_method"
71+
&& path.ident.name == sym::some_method
7272
// Optionally, check the type of the self argument.
7373
// - See "Checking for a specific type"
7474
{
@@ -85,9 +85,8 @@ to check for. All of these methods only check for the base type, generic
8585
arguments have to be checked separately.
8686

8787
```rust
88-
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
89-
use clippy_utils::paths;
90-
use rustc_span::symbol::sym;
88+
use clippy_utils::{paths, sym};
89+
use clippy_utils::res::MaybeDef;
9190
use rustc_hir::LangItem;
9291

9392
impl LateLintPass<'_> for MyStructLint {
@@ -97,12 +96,12 @@ impl LateLintPass<'_> for MyStructLint {
9796

9897
// 1. Using diagnostic items
9998
// The last argument is the diagnostic item to check for
100-
if is_type_diagnostic_item(cx, ty, sym::Option) {
99+
if ty.is_diag_item(cx, sym::Option) {
101100
// The type is an `Option`
102101
}
103102

104103
// 2. Using lang items
105-
if is_type_lang_item(cx, ty, LangItem::RangeFull) {
104+
if ty.is_lang_item(cx, LangItem::RangeFull) {
106105
// The type is a full range like `.drain(..)`
107106
}
108107

@@ -123,27 +122,29 @@ There are three ways to do this, depending on if the target trait has a
123122
diagnostic item, lang item or neither.
124123

125124
```rust
125+
use clippy_utils::sym;
126126
use clippy_utils::ty::implements_trait;
127-
use clippy_utils::is_trait_method;
128-
use rustc_span::symbol::sym;
129127

130128
impl LateLintPass<'_> for MyStructLint {
131129
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
132-
// 1. Using diagnostic items with the expression
133-
// we use `is_trait_method` function from Clippy's utils
134-
if is_trait_method(cx, expr, sym::Iterator) {
135-
// method call in `expr` belongs to `Iterator` trait
136-
}
137130

138-
// 2. Using lang items with the expression type
131+
// 1. Get the `DefId` of the trait.
132+
// via lang items
133+
let trait_id = cx.tcx.lang_items().drop_trait();
134+
// via diagnostic items
135+
let trait_id = cx.tcx.get_diagnostic_item(sym::Eq);
136+
137+
// 2. Check for the trait implementation via the `implements_trait` util.
139138
let ty = cx.typeck_results().expr_ty(expr);
140-
if cx.tcx.lang_items()
141-
// we are looking for the `DefId` of `Drop` trait in lang items
142-
.drop_trait()
143-
// then we use it with our type `ty` by calling `implements_trait` from Clippy's utils
144-
.is_some_and(|id| implements_trait(cx, ty, id, &[])) {
145-
// `expr` implements `Drop` trait
146-
}
139+
if trait_id.is_some_and(|id| implements_trait(cx, ty, id, &[])) {
140+
// `ty` implements the trait.
141+
}
142+
143+
// 3. If the trait requires additional generic arguments
144+
let trait_id = cx.tcx.lang_items().eq_trait();
145+
if trait_id.is_some_and(|id| implements_trait(cx, ty, id, &[ty])) {
146+
// `ty` implements `PartialEq<Self>`
147+
}
147148
}
148149
}
149150
```
@@ -173,7 +174,7 @@ impl<'tcx> LateLintPass<'tcx> for MyTypeImpl {
173174
// We can also check it has a parameter `self`
174175
&& signature.decl.implicit_self.has_implicit_self()
175176
// We can go further and even check if its return type is `String`
176-
&& is_type_lang_item(cx, return_ty(cx, impl_item.hir_id), LangItem::String)
177+
&& return_ty(cx, impl_item.hir_id).is_lang_item(cx, LangItem::String)
177178
{
178179
// ...
179180
}

src/tools/clippy/book/src/development/macro_expansions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ before emitting suggestions to the end user to avoid false positives.
3737

3838
Several functions are available for working with macros.
3939

40-
### The `Span.from_expansion` method
40+
### The `Span::from_expansion` method
4141

4242
We could utilize a `span`'s [`from_expansion`] method, which
4343
detects if the `span` is from a macro expansion / desugaring.
@@ -50,7 +50,7 @@ if expr.span.from_expansion() {
5050
}
5151
```
5252

53-
### `Span.ctxt` method
53+
### `Span::ctxt` method
5454

5555
The `span`'s context, given by the method [`ctxt`] and returning [SyntaxContext],
5656
represents if the span is from a macro expansion and, if it is, which

src/tools/clippy/book/src/development/method_checking.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,20 @@ the [`ExprKind`] that we can access from `expr.kind`:
1515
```rust
1616
use rustc_hir as hir;
1717
use rustc_lint::{LateContext, LateLintPass};
18-
use rustc_span::sym;
19-
use clippy_utils::is_trait_method;
18+
use clippy_utils::res::{MaybeDef, MaybeTypeckRes};
19+
use clippy_utils::sym;
2020

2121
impl<'tcx> LateLintPass<'tcx> for OurFancyMethodLint {
2222
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
2323
// Check our expr is calling a method with pattern matching
2424
if let hir::ExprKind::MethodCall(path, _, [self_arg, ..], _) = &expr.kind
2525
// Check if the name of this method is `our_fancy_method`
26-
&& path.ident.name.as_str() == "our_fancy_method"
26+
&& path.ident.name == sym::our_fancy_method
2727
// We can check the type of the self argument whenever necessary.
2828
// (It's necessary if we want to check that method is specifically belonging to a specific trait,
2929
// for example, a `map` method could belong to user-defined trait instead of to `Iterator`)
3030
// See the next section for more information.
31-
&& is_trait_method(cx, self_arg, sym::OurFancyTrait)
31+
&& cx.ty_based_def(self_arg).opt_parent(cx).is_diag_item(cx, sym::OurFancyTrait)
3232
{
3333
println!("`expr` is a method call for `our_fancy_method`");
3434
}
@@ -41,6 +41,10 @@ information on the pattern matching. As mentioned in [Define
4141
Lints](defining_lints.md#lint-types), the `methods` lint type is full of pattern
4242
matching with `MethodCall` in case the reader wishes to explore more.
4343

44+
New symbols such as `our_fancy_method` need to be added to the `clippy_utils::sym` module.
45+
This module extends the list of symbols already provided by the compiler crates
46+
in `rustc_span::sym`.
47+
4448
## Checking if a `impl` block implements a method
4549

4650
While sometimes we want to check whether a method is being called or not, other
@@ -56,11 +60,10 @@ Let us take a look at how we might check for the implementation of
5660
`our_fancy_method` on a type:
5761

5862
```rust
59-
use clippy_utils::ty::is_type_diagnostic_item;
60-
use clippy_utils::return_ty;
63+
use clippy_utils::{return_ty, sym};
64+
use clippy_utils::res::MaybeDef;
6165
use rustc_hir::{ImplItem, ImplItemKind};
6266
use rustc_lint::{LateContext, LateLintPass};
63-
use rustc_span::symbol::sym;
6467

6568
impl<'tcx> LateLintPass<'tcx> for MyTypeImpl {
6669
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) {
@@ -71,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for MyTypeImpl {
7174
// We can also check it has a parameter `self`
7275
&& signature.decl.implicit_self.has_implicit_self()
7376
// We can go even further and even check if its return type is `String`
74-
&& is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id), sym::String)
77+
&& return_ty(cx, impl_item.hir_id).is_diag_item(cx, sym::String)
7578
{
7679
println!("`our_fancy_method` is implemented!");
7780
}

src/tools/clippy/book/src/development/trait_checking.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ providing the `LateContext` (`cx`), our expression at hand, and
1717
the symbol of the trait in question:
1818

1919
```rust
20+
use clippy_utils::sym;
2021
use clippy_utils::ty::implements_trait;
2122
use rustc_hir::Expr;
2223
use rustc_lint::{LateContext, LateLintPass};
23-
use rustc_span::symbol::sym;
2424

2525
impl LateLintPass<'_> for CheckIteratorTraitLint {
2626
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
@@ -53,7 +53,7 @@ For instance, if we want to examine whether an expression `expr` implements
5353
we can check that the `Ty` of the `expr` implements the trait:
5454

5555
```rust
56-
use clippy_utils::implements_trait;
56+
use clippy_utils::ty::implements_trait;
5757
use rustc_hir::Expr;
5858
use rustc_lint::{LateContext, LateLintPass};
5959

@@ -79,7 +79,8 @@ If neither diagnostic item nor a language item is available, we can use
7979
Below, we check if the given `expr` implements [`core::iter::Step`](https://doc.rust-lang.org/std/iter/trait.Step.html):
8080

8181
```rust
82-
use clippy_utils::{implements_trait, paths};
82+
use clippy_utils::paths;
83+
use clippy_utils::ty::implements_trait;
8384
use rustc_hir::Expr;
8485
use rustc_lint::{LateContext, LateLintPass};
8586

@@ -124,8 +125,8 @@ The following code demonstrates how to do this:
124125
```rust
125126

126127
use rustc_middle::ty::Ty;
128+
use clippy_utils::sym;
127129
use clippy_utils::ty::implements_trait;
128-
use rustc_span::symbol::sym;
129130

130131
let ty = todo!("Get the `Foo` type to check for a trait implementation");
131132
let borrow_id = cx.tcx.get_diagnostic_item(sym::Borrow).unwrap(); // avoid unwrap in real code

src/tools/clippy/book/src/lint_configuration.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,16 @@ A list of paths to types that should be treated as if they do not contain interi
671671
* [`mutable_key_type`](https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type)
672672

673673

674+
## `inherent-impl-lint-scope`
675+
Sets the scope ("crate", "file", or "module") in which duplicate inherent `impl` blocks for the same type are linted.
676+
677+
**Default Value:** `"crate"`
678+
679+
---
680+
**Affected lints:**
681+
* [`multiple_inherent_impl`](https://rust-lang.github.io/rust-clippy/master/index.html#multiple_inherent_impl)
682+
683+
674684
## `large-error-threshold`
675685
The maximum size of the `Err`-variant in a `Result` returned from a function
676686

@@ -927,6 +937,16 @@ exported visibility, or whether they are marked as "pub".
927937
* [`pub_underscore_fields`](https://rust-lang.github.io/rust-clippy/master/index.html#pub_underscore_fields)
928938

929939

940+
## `recursive-self-in-type-definitions`
941+
Whether the type itself in a struct or enum should be replaced with `Self` when encountering recursive types.
942+
943+
**Default Value:** `true`
944+
945+
---
946+
**Affected lints:**
947+
* [`use_self`](https://rust-lang.github.io/rust-clippy/master/index.html#use_self)
948+
949+
930950
## `semicolon-inside-block-ignore-singleline`
931951
Whether to lint only if it's multiline.
932952

src/tools/clippy/clippy_config/src/conf.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use crate::ClippyConfiguration;
22
use crate::types::{
3-
DisallowedPath, DisallowedPathWithoutReplacement, MacroMatcher, MatchLintBehaviour, PubUnderscoreFieldsBehaviour,
4-
Rename, SourceItemOrdering, SourceItemOrderingCategory, SourceItemOrderingModuleItemGroupings,
5-
SourceItemOrderingModuleItemKind, SourceItemOrderingTraitAssocItemKind, SourceItemOrderingTraitAssocItemKinds,
6-
SourceItemOrderingWithinModuleItemGroupings,
3+
DisallowedPath, DisallowedPathWithoutReplacement, InherentImplLintScope, MacroMatcher, MatchLintBehaviour,
4+
PubUnderscoreFieldsBehaviour, Rename, SourceItemOrdering, SourceItemOrderingCategory,
5+
SourceItemOrderingModuleItemGroupings, SourceItemOrderingModuleItemKind, SourceItemOrderingTraitAssocItemKind,
6+
SourceItemOrderingTraitAssocItemKinds, SourceItemOrderingWithinModuleItemGroupings,
77
};
88
use clippy_utils::msrvs::Msrv;
99
use itertools::Itertools;
@@ -248,7 +248,7 @@ macro_rules! define_Conf {
248248

249249
#[derive(Deserialize)]
250250
#[serde(field_identifier, rename_all = "kebab-case")]
251-
#[allow(non_camel_case_types)]
251+
#[expect(non_camel_case_types)]
252252
enum Field { $($name,)* third_party, }
253253

254254
struct ConfVisitor<'a>(&'a SourceFile);
@@ -663,6 +663,9 @@ define_Conf! {
663663
/// A list of paths to types that should be treated as if they do not contain interior mutability
664664
#[lints(borrow_interior_mutable_const, declare_interior_mutable_const, ifs_same_cond, mutable_key_type)]
665665
ignore_interior_mutability: Vec<String> = Vec::from(["bytes::Bytes".into()]),
666+
/// Sets the scope ("crate", "file", or "module") in which duplicate inherent `impl` blocks for the same type are linted.
667+
#[lints(multiple_inherent_impl)]
668+
inherent_impl_lint_scope: InherentImplLintScope = InherentImplLintScope::Crate,
666669
/// The maximum size of the `Err`-variant in a `Result` returned from a function
667670
#[lints(result_large_err)]
668671
large_error_threshold: u64 = 128,
@@ -809,6 +812,9 @@ define_Conf! {
809812
/// exported visibility, or whether they are marked as "pub".
810813
#[lints(pub_underscore_fields)]
811814
pub_underscore_fields_behavior: PubUnderscoreFieldsBehaviour = PubUnderscoreFieldsBehaviour::PubliclyExported,
815+
/// Whether the type itself in a struct or enum should be replaced with `Self` when encountering recursive types.
816+
#[lints(use_self)]
817+
recursive_self_in_type_definitions: bool = true,
812818
/// Whether to lint only if it's multiline.
813819
#[lints(semicolon_inside_block)]
814820
semicolon_inside_block_ignore_singleline: bool = false,
@@ -1213,7 +1219,7 @@ mod tests {
12131219

12141220
for entry in toml_files {
12151221
let file = fs::read_to_string(entry.path()).unwrap();
1216-
#[allow(clippy::zero_sized_map_values)]
1222+
#[expect(clippy::zero_sized_map_values)]
12171223
if let Ok(map) = toml::from_str::<HashMap<String, IgnoredAny>>(&file) {
12181224
for name in map.keys() {
12191225
names.remove(name.as_str());

0 commit comments

Comments
 (0)