Skip to content

Commit 20f19f4

Browse files
committed
Auto merge of rust-lang#154176 - flip1995:clippy-subtree-update, r=matthiaskrgr
Clippy subtree update r? Manishearth 2 days late as I didn't get to it during the week.
2 parents 7218b7f + 36e06eb commit 20f19f4

File tree

77 files changed

+2197
-481
lines changed

Some content is hidden

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

77 files changed

+2197
-481
lines changed

src/tools/clippy/CHANGELOG.md

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,103 @@ document.
66

77
## Unreleased / Beta / In Rust Nightly
88

9-
[92b4b68...master](https://github.com/rust-lang/rust-clippy/compare/92b4b68...master)
9+
[500e0ff...master](https://github.com/rust-lang/rust-clippy/compare/500e0ff...master)
10+
11+
## Rust 1.94
12+
13+
Current stable, released 2026-03-05
14+
15+
[View all 94 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2025-11-29T21%3A01%3A29Z..2026-01-08T20%3A33%3A22Z+base%3Amaster)
16+
17+
### New Lints
18+
19+
* Added [`same_length_and_capacity`] to `pedantic`
20+
[#15656](https://github.com/rust-lang/rust-clippy/pull/15656)
21+
* Added [`manual_ilog2`] to `pedantic`
22+
[#15865](https://github.com/rust-lang/rust-clippy/pull/15865)
23+
* Added [`needless_type_cast`] to `nursery`
24+
[#16139](https://github.com/rust-lang/rust-clippy/pull/16139)
25+
* Added [`ptr_offset_by_literal`] to `pedantic`
26+
[#15606](https://github.com/rust-lang/rust-clippy/pull/15606)
27+
* Added [`decimal_bitwise_operands`] to `pedantic`
28+
[#15215](https://github.com/rust-lang/rust-clippy/pull/15215)
29+
30+
### Moves and Deprecations
31+
32+
* Moved [`multiple_bound_locations`] from `suspicious` to `style`
33+
[#16302](https://github.com/rust-lang/rust-clippy/pull/16302)
34+
* Moved [`collapsible_else_if`] from `style` to `pedantic`
35+
[#16211](https://github.com/rust-lang/rust-clippy/pull/16211)
36+
* Moved [`needless_type_cast`] from `pedantic` to `nursery`
37+
[#16246](https://github.com/rust-lang/rust-clippy/pull/16246)
38+
39+
### Enhancements
40+
41+
* [`never_loop`] do not consider `return` as preventing the iterator from looping; lint diverging
42+
iterator reduction closures like `for_each` and `fold`
43+
[#16364](https://github.com/rust-lang/rust-clippy/pull/16364)
44+
* [`single_range_in_vec_init`] don't apply the suggestion automatically
45+
[#16365](https://github.com/rust-lang/rust-clippy/pull/16365)
46+
* [`useless_conversion`] refine `.into_iter()` suggestions to stop at final target type
47+
[#16238](https://github.com/rust-lang/rust-clippy/pull/16238)
48+
* Multiple lints fix wrongly unmangled macros
49+
[#16337](https://github.com/rust-lang/rust-clippy/pull/16337)
50+
* [`large_stack_arrays`] do not warn for libtest harness
51+
[#16347](https://github.com/rust-lang/rust-clippy/pull/16347)
52+
* [`derive_ord_xor_partial_ord`] allow `expect` on `impl` block
53+
[#16303](https://github.com/rust-lang/rust-clippy/pull/16303)
54+
* [`match_bool`] restrict to 2 arms
55+
[#16333](https://github.com/rust-lang/rust-clippy/pull/16333)
56+
* [`multiple_inherent_impl`] fix false negatives for generic impl blocks
57+
[#16284](https://github.com/rust-lang/rust-clippy/pull/16284)
58+
* [`unnecessary_fold`] warn about semantics change and lint `Add::add`/`Mul::mul` folds
59+
[#16324](https://github.com/rust-lang/rust-clippy/pull/16324)
60+
* [`transmuting_null`] check const blocks and const integer casts
61+
[#16260](https://github.com/rust-lang/rust-clippy/pull/16260)
62+
* [`needless_pass_by_ref_mut`] preserve user-provided lifetime information
63+
[#16273](https://github.com/rust-lang/rust-clippy/pull/16273)
64+
* [`while_let_on_iterator`] use reborrow for non-`Sized` trait references
65+
[#16100](https://github.com/rust-lang/rust-clippy/pull/16100)
66+
* [`collapsible_else_if`] prevent emitting when arms only `if {..} else {..}`
67+
[#16286](https://github.com/rust-lang/rust-clippy/pull/16286)
68+
* [`multiple_unsafe_ops_per_block`] count only towards innermost unsafe block
69+
[#16117](https://github.com/rust-lang/rust-clippy/pull/16117)
70+
* [`manual_saturating_arithmetic`] lint `x.checked_sub(y).unwrap_or_default()`
71+
[#15845](https://github.com/rust-lang/rust-clippy/pull/15845)
72+
* [`transmute_ptr_to_ref`] handle pointer in struct
73+
[#15948](https://github.com/rust-lang/rust-clippy/pull/15948)
74+
* [`disallowed_methods`] skip compiler-generated code
75+
[#16186](https://github.com/rust-lang/rust-clippy/pull/16186)
76+
* [`missing_enforced_import_renames`] do not enforce for "as _"
77+
[#16352](https://github.com/rust-lang/rust-clippy/pull/16352)
78+
79+
### False Positive Fixes
80+
81+
* [`double_parens`] fix FP on macro repetition patterns
82+
[#16301](https://github.com/rust-lang/rust-clippy/pull/16301)
83+
* [`assertions_on_constants`] fix false positive when there is non-constant value in condition expr
84+
[#16297](https://github.com/rust-lang/rust-clippy/pull/16297)
85+
* [`use_self`] fix FP on type in const generics
86+
[#16172](https://github.com/rust-lang/rust-clippy/pull/16172)
87+
* [`set_contains_or_insert`] fix FP when set is mutated before `insert`
88+
[#16009](https://github.com/rust-lang/rust-clippy/pull/16009)
89+
* [`if_then_some_else_none`] fix FP when then block contains `await`
90+
[#16178](https://github.com/rust-lang/rust-clippy/pull/16178)
91+
* [`match_like_matches_macro`] fix FP with guards containing `if let`
92+
[#15876](https://github.com/rust-lang/rust-clippy/pull/15876)
93+
* [`tuple_array_conversions`] fix FP when binded vars are used before conversion
94+
[#16197](https://github.com/rust-lang/rust-clippy/pull/16197)
95+
* [`map_entry`] fix FP when it would cause `MutexGuard` to be held across await
96+
[#16199](https://github.com/rust-lang/rust-clippy/pull/16199)
97+
* [`panicking_unwrap`] fix FP on field access with implicit deref
98+
[#16196](https://github.com/rust-lang/rust-clippy/pull/16196)
99+
* [`large_stack_frames`] fix FP on compiler generated targets
100+
[#15101](https://github.com/rust-lang/rust-clippy/pull/15101)
101+
102+
### ICE Fixes
103+
104+
* [`needless_type_cast`] do not ICE on struct constructor
105+
[#16245](https://github.com/rust-lang/rust-clippy/pull/16245)
10106

11107
### New Lints
12108

@@ -6705,6 +6801,7 @@ Released 2018-09-13
67056801
[`manual_ok_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ok_or
67066802
[`manual_option_as_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_option_as_slice
67076803
[`manual_pattern_char_comparison`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_pattern_char_comparison
6804+
[`manual_pop_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_pop_if
67086805
[`manual_range_contains`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains
67096806
[`manual_range_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_patterns
67106807
[`manual_rem_euclid`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_rem_euclid

src/tools/clippy/clippy.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ check-inconsistent-struct-field-initializers = true
55
lint-commented-code = true
66

77
[[disallowed-methods]]
8-
path = "rustc_lint::context::LintContext::lint"
8+
path = "rustc_lint::context::LintContext::opt_span_lint"
99
reason = "this function does not add a link to our documentation; please use the `clippy_utils::diagnostics::span_lint*` functions instead"
1010

1111
[[disallowed-methods]]
12-
path = "rustc_lint::context::LintContext::span_lint"
12+
path = "rustc_lint::context::LintContext::emit_span_lint"
1313
reason = "this function does not add a link to our documentation; please use the `clippy_utils::diagnostics::span_lint*` functions instead"
1414

1515
[[disallowed-methods]]

src/tools/clippy/clippy_dev/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
os_str_slice,
66
os_string_truncate,
77
pattern,
8-
rustc_private,
9-
slice_split_once
8+
rustc_private
109
)]
1110
#![warn(
1211
trivial_casts,

src/tools/clippy/clippy_lints/src/bool_to_int_with_if.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use clippy_utils::diagnostics::span_lint_and_then;
2-
use clippy_utils::source::HasSession;
32
use clippy_utils::sugg::Sugg;
43
use clippy_utils::{higher, is_else_clause, is_in_const_context, span_contains_comment};
54
use rustc_ast::LitKind;
@@ -60,7 +59,7 @@ impl<'tcx> LateLintPass<'tcx> for BoolToIntWithIf {
6059
&& !is_in_const_context(cx)
6160
{
6261
let ty = cx.typeck_results().expr_ty(then);
63-
let mut applicability = if span_contains_comment(cx.sess().source_map(), expr.span) {
62+
let mut applicability = if span_contains_comment(cx, expr.span) {
6463
Applicability::MaybeIncorrect
6564
} else {
6665
Applicability::MachineApplicable

src/tools/clippy/clippy_lints/src/casts/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,7 @@ declare_clippy_lint! {
691691
/// const SIZE: usize = 15;
692692
/// let arr: [u8; SIZE] = [0; SIZE];
693693
/// ```
694-
#[clippy::version = "1.93.0"]
694+
#[clippy::version = "1.94.0"]
695695
pub NEEDLESS_TYPE_CAST,
696696
nursery,
697697
"binding defined with one type but always cast to another"

src/tools/clippy/clippy_lints/src/collapsible_if.rs

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
use clippy_config::Conf;
22
use clippy_utils::diagnostics::span_lint_hir_and_then;
33
use clippy_utils::msrvs::Msrv;
4-
use clippy_utils::source::{IntoSpan as _, SpanRangeExt, snippet, snippet_block_with_applicability};
4+
use clippy_utils::source::{HasSession, IntoSpan as _, SpanRangeExt, snippet, snippet_block_with_applicability};
55
use clippy_utils::{can_use_if_let_chains, span_contains_non_whitespace, sym, tokenize_with_text};
66
use rustc_ast::{BinOpKind, MetaItemInner};
77
use rustc_errors::Applicability;
88
use rustc_hir::{Block, Expr, ExprKind, StmtKind};
99
use rustc_lexer::TokenKind;
1010
use rustc_lint::{LateContext, LateLintPass, Level};
1111
use rustc_session::impl_lint_pass;
12-
use rustc_span::source_map::SourceMap;
1312
use rustc_span::{BytePos, Span, Symbol};
1413

1514
declare_clippy_lint! {
@@ -111,10 +110,8 @@ impl CollapsibleIf {
111110
let up_to_else = then_span.between(else_block.span);
112111
let else_before_if = else_.span.shrink_to_lo().with_hi(else_if_cond.span.lo() - BytePos(1));
113112
if self.lint_commented_code
114-
&& let Some(else_keyword_span) =
115-
span_extract_keyword(cx.tcx.sess.source_map(), up_to_else, "else")
116-
&& let Some(else_if_keyword_span) =
117-
span_extract_keyword(cx.tcx.sess.source_map(), else_before_if, "if")
113+
&& let Some(else_keyword_span) = span_extract_keyword(cx, up_to_else, "else")
114+
&& let Some(else_if_keyword_span) = span_extract_keyword(cx, else_before_if, "if")
118115
{
119116
let else_keyword_span = else_keyword_span.with_leading_whitespace(cx).into_span();
120117
let else_open_bracket = else_block.span.split_at(1).0.with_leading_whitespace(cx).into_span();
@@ -139,7 +136,7 @@ impl CollapsibleIf {
139136
}
140137

141138
// Peel off any parentheses.
142-
let (_, else_block_span, _) = peel_parens(cx.tcx.sess.source_map(), else_.span);
139+
let (_, else_block_span, _) = peel_parens(cx, else_.span);
143140

144141
// Prevent "elseif"
145142
// Check that the "else" is followed by whitespace
@@ -187,7 +184,7 @@ impl CollapsibleIf {
187184
.with_leading_whitespace(cx)
188185
.into_span()
189186
};
190-
let (paren_start, inner_if_span, paren_end) = peel_parens(cx.tcx.sess.source_map(), inner.span);
187+
let (paren_start, inner_if_span, paren_end) = peel_parens(cx, inner.span);
191188
let inner_if = inner_if_span.split_at(2).0;
192189
let mut sugg = vec![
193190
// Remove the outer then block `{`
@@ -320,33 +317,36 @@ pub(super) fn parens_around(expr: &Expr<'_>) -> Vec<(Span, String)> {
320317
}
321318
}
322319

323-
fn span_extract_keyword(sm: &SourceMap, span: Span, keyword: &str) -> Option<Span> {
324-
let snippet = sm.span_to_snippet(span).ok()?;
325-
tokenize_with_text(&snippet)
326-
.filter(|(t, s, _)| matches!(t, TokenKind::Ident if *s == keyword))
327-
.map(|(_, _, inner)| {
328-
span.split_at(u32::try_from(inner.start).unwrap())
329-
.1
330-
.split_at(u32::try_from(inner.end - inner.start).unwrap())
331-
.0
332-
})
333-
.next()
320+
fn span_extract_keyword(cx: &impl HasSession, span: Span, keyword: &str) -> Option<Span> {
321+
span.with_source_text(cx, |snippet| {
322+
tokenize_with_text(snippet)
323+
.filter(|(t, s, _)| matches!(t, TokenKind::Ident if *s == keyword))
324+
.map(|(_, _, inner)| {
325+
span.split_at(u32::try_from(inner.start).unwrap())
326+
.1
327+
.split_at(u32::try_from(inner.end - inner.start).unwrap())
328+
.0
329+
})
330+
.next()
331+
})
332+
.flatten()
334333
}
335334

336335
/// Peel the parentheses from an `if` expression, e.g. `((if true {} else {}))`.
337-
pub(super) fn peel_parens(sm: &SourceMap, mut span: Span) -> (Span, Span, Span) {
336+
pub(super) fn peel_parens(cx: &impl HasSession, mut span: Span) -> (Span, Span, Span) {
338337
use crate::rustc_span::Pos;
339338

340339
let start = span.shrink_to_lo();
341340
let end = span.shrink_to_hi();
342341

343-
let snippet = sm.span_to_snippet(span).unwrap();
344-
if let Some((trim_start, _, trim_end)) = peel_parens_str(&snippet) {
345-
let mut data = span.data();
346-
data.lo = data.lo + BytePos::from_usize(trim_start);
347-
data.hi = data.hi - BytePos::from_usize(trim_end);
348-
span = data.span();
349-
}
342+
span.with_source_text(cx, |snippet| {
343+
if let Some((trim_start, _, trim_end)) = peel_parens_str(snippet) {
344+
let mut data = span.data();
345+
data.lo = data.lo + BytePos::from_usize(trim_start);
346+
data.hi = data.hi - BytePos::from_usize(trim_end);
347+
span = data.span();
348+
}
349+
});
350350

351351
(start.with_hi(span.lo()), span, end.with_lo(span.hi()))
352352
}

src/tools/clippy/clippy_lints/src/declared_lints.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[
312312
crate::manual_main_separator_str::MANUAL_MAIN_SEPARATOR_STR_INFO,
313313
crate::manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE_INFO,
314314
crate::manual_option_as_slice::MANUAL_OPTION_AS_SLICE_INFO,
315+
crate::manual_pop_if::MANUAL_POP_IF_INFO,
315316
crate::manual_range_patterns::MANUAL_RANGE_PATTERNS_INFO,
316317
crate::manual_rem_euclid::MANUAL_REM_EUCLID_INFO,
317318
crate::manual_retain::MANUAL_RETAIN_INFO,

src/tools/clippy/clippy_lints/src/floating_point_arithmetic/custom_abs.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ use clippy_utils::{eq_expr_value, higher, peel_blocks};
66
use rustc_errors::Applicability;
77
use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
88
use rustc_lint::LateContext;
9-
use rustc_span::SyntaxContext;
10-
use rustc_span::Spanned;
9+
use rustc_span::{Spanned, SyntaxContext};
1110

1211
use super::SUBOPTIMAL_FLOPS;
1312

src/tools/clippy/clippy_lints/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ mod manual_let_else;
210210
mod manual_main_separator_str;
211211
mod manual_non_exhaustive;
212212
mod manual_option_as_slice;
213+
mod manual_pop_if;
213214
mod manual_range_patterns;
214215
mod manual_rem_euclid;
215216
mod manual_retain;
@@ -863,6 +864,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co
863864
Box::new(move |tcx| Box::new(duration_suboptimal_units::DurationSuboptimalUnits::new(tcx, conf))),
864865
Box::new(move |_| Box::new(manual_take::ManualTake::new(conf))),
865866
Box::new(|_| Box::new(manual_checked_ops::ManualCheckedOps)),
867+
Box::new(move |_| Box::new(manual_pop_if::ManualPopIf::new(conf))),
866868
// add late passes here, used by `cargo dev new_lint`
867869
];
868870
store.late_passes.extend(late_lints);

src/tools/clippy/clippy_lints/src/loops/manual_flatten.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use super::utils::make_iterator_snippet;
33
use clippy_utils::diagnostics::span_lint_and_then;
44
use clippy_utils::msrvs::{self, Msrv};
55
use clippy_utils::res::MaybeResPath;
6-
use clippy_utils::source::{HasSession, indent_of, reindent_multiline, snippet_with_applicability};
6+
use clippy_utils::source::{indent_of, reindent_multiline, snippet_with_applicability};
77
use clippy_utils::visitors::is_local_used;
88
use clippy_utils::{higher, is_refutable, peel_blocks_with_stmt, span_contains_comment};
99
use rustc_errors::Applicability;
@@ -50,7 +50,7 @@ pub(super) fn check<'tcx>(
5050
format!("unnecessary `if let` since only the `{if_let_type}` variant of the iterator element is used");
5151

5252
// Prepare the help message
53-
let mut applicability = if span_contains_comment(cx.sess().source_map(), body.span) {
53+
let mut applicability = if span_contains_comment(cx, body.span) {
5454
Applicability::MaybeIncorrect
5555
} else {
5656
Applicability::MachineApplicable

0 commit comments

Comments
 (0)