Skip to content

Commit 15727e0

Browse files
committed
Merge remote-tracking branch 'upstream/master' into rustup
2 parents d36a560 + 23b1ace commit 15727e0

File tree

297 files changed

+6962
-4052
lines changed

Some content is hidden

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

297 files changed

+6962
-4052
lines changed

.github/workflows/clippy_mq.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ jobs:
181181
182182
# Download
183183
- name: Download target dir
184-
uses: actions/download-artifact@v4
184+
uses: actions/download-artifact@v5
185185
with:
186186
name: binaries
187187
path: target/debug

.github/workflows/lintcheck.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ jobs:
126126
fail-on-cache-miss: true
127127

128128
- name: Download JSON
129-
uses: actions/download-artifact@v4
129+
uses: actions/download-artifact@v5
130130

131131
- name: Store PR number
132132
run: echo ${{ github.event.pull_request.number }} > pr.txt

.github/workflows/lintcheck_summary.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ jobs:
2727
if: ${{ github.event.workflow_run.conclusion == 'success' }}
2828
steps:
2929
- name: Download artifact
30-
uses: actions/download-artifact@v4
30+
uses: actions/download-artifact@v5
3131
with:
3232
name: summary
3333
path: untrusted
3434
run-id: ${{ github.event.workflow_run.id }}
3535
github-token: ${{ github.token }}
3636

3737
- name: Format comment
38-
uses: actions/github-script@v7
38+
uses: actions/github-script@v8
3939
with:
4040
script: |
4141
const fs = require("fs");

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Current stable, released 2025-09-18
1717
Note: This Clippy release does not introduce many new lints and is focused entirely on bug fixes — see
1818
[#15086](https://github.com/rust-lang/rust-clippy/issues/15086) for more details.
1919

20-
## New Lints
20+
### New Lints
2121

2222
* Added [`manual_is_multiple_of`] to `complexity` [#14292](https://github.com/rust-lang/rust-clippy/pull/14292)
2323
* Added [`doc_broken_link`] to `pedantic` [#13696](https://github.com/rust-lang/rust-clippy/pull/13696)
@@ -6598,6 +6598,7 @@ Released 2018-09-13
65986598
[`self_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_assignment
65996599
[`self_named_constructors`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_named_constructors
66006600
[`self_named_module_files`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_named_module_files
6601+
[`self_only_used_in_recursion`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_only_used_in_recursion
66016602
[`semicolon_if_nothing_returned`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
66026603
[`semicolon_inside_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_inside_block
66036604
[`semicolon_outside_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_outside_block
@@ -6703,6 +6704,7 @@ Released 2018-09-13
67036704
[`type_repetition_in_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds
67046705
[`unbuffered_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#unbuffered_bytes
67056706
[`unchecked_duration_subtraction`]: https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_duration_subtraction
6707+
[`unchecked_time_subtraction`]: https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_time_subtraction
67066708
[`unconditional_recursion`]: https://rust-lang.github.io/rust-clippy/master/index.html#unconditional_recursion
67076709
[`undocumented_unsafe_blocks`]: https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks
67086710
[`undropped_manually_drops`]: https://rust-lang.github.io/rust-clippy/master/index.html#undropped_manually_drops

Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,18 @@ ui_test = "0.30.2"
3838
regex = "1.5.5"
3939
serde = { version = "1.0.145", features = ["derive"] }
4040
serde_json = "1.0.122"
41-
toml = "0.7.3"
4241
walkdir = "2.3"
4342
filetime = "0.2.9"
4443
itertools = "0.12"
4544
pulldown-cmark = { version = "0.11", default-features = false, features = ["html"] }
4645
askama = { version = "0.14", default-features = false, features = ["alloc", "config", "derive"] }
4746

47+
[dev-dependencies.toml]
48+
version = "0.9.7"
49+
default-features = false
50+
# preserve_order keeps diagnostic output in file order
51+
features = ["parse", "preserve_order"]
52+
4853
[build-dependencies]
4954
rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" }
5055

book/src/development/trait_checking.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,11 @@ use rustc_span::symbol::sym;
2424

2525
impl LateLintPass<'_> for CheckIteratorTraitLint {
2626
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
27-
let implements_iterator = cx.tcx.get_diagnostic_item(sym::Iterator).map_or(false, |id| {
28-
implements_trait(cx, cx.typeck_results().expr_ty(expr), id, &[])
29-
});
30-
if implements_iterator {
31-
// [...]
32-
}
27+
let implements_iterator = (cx.tcx.get_diagnostic_item(sym::Iterator))
28+
.is_some_and(|id| implements_trait(cx, cx.typeck_results().expr_ty(expr), id, &[]));
29+
if implements_iterator {
30+
// [...]
31+
}
3332

3433
}
3534
}

book/src/lint_configuration.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
845845
* [`from_over_into`](https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into)
846846
* [`if_then_some_else_none`](https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none)
847847
* [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice)
848+
* [`inefficient_to_string`](https://rust-lang.github.io/rust-clippy/master/index.html#inefficient_to_string)
848849
* [`io_other_error`](https://rust-lang.github.io/rust-clippy/master/index.html#io_other_error)
849850
* [`iter_kv_map`](https://rust-lang.github.io/rust-clippy/master/index.html#iter_kv_map)
850851
* [`legacy_numeric_constants`](https://rust-lang.github.io/rust-clippy/master/index.html#legacy_numeric_constants)
@@ -883,6 +884,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
883884
* [`needless_borrow`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow)
884885
* [`non_std_lazy_statics`](https://rust-lang.github.io/rust-clippy/master/index.html#non_std_lazy_statics)
885886
* [`option_as_ref_deref`](https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref)
887+
* [`or_fun_call`](https://rust-lang.github.io/rust-clippy/master/index.html#or_fun_call)
886888
* [`ptr_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr)
887889
* [`question_mark`](https://rust-lang.github.io/rust-clippy/master/index.html#question_mark)
888890
* [`redundant_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names)
@@ -894,9 +896,10 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
894896
* [`transmute_ptr_to_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ref)
895897
* [`tuple_array_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#tuple_array_conversions)
896898
* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds)
897-
* [`unchecked_duration_subtraction`](https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_duration_subtraction)
899+
* [`unchecked_time_subtraction`](https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_time_subtraction)
898900
* [`uninlined_format_args`](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args)
899901
* [`unnecessary_lazy_evaluations`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations)
902+
* [`unnecessary_unwrap`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap)
900903
* [`unnested_or_patterns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnested_or_patterns)
901904
* [`unused_trait_names`](https://rust-lang.github.io/rust-clippy/master/index.html#unused_trait_names)
902905
* [`use_self`](https://rust-lang.github.io/rust-clippy/master/index.html#use_self)

clippy_config/src/conf.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,7 @@ define_Conf! {
741741
from_over_into,
742742
if_then_some_else_none,
743743
index_refutable_slice,
744+
inefficient_to_string,
744745
io_other_error,
745746
iter_kv_map,
746747
legacy_numeric_constants,
@@ -779,6 +780,7 @@ define_Conf! {
779780
needless_borrow,
780781
non_std_lazy_statics,
781782
option_as_ref_deref,
783+
or_fun_call,
782784
ptr_as_ptr,
783785
question_mark,
784786
redundant_field_names,
@@ -790,9 +792,10 @@ define_Conf! {
790792
transmute_ptr_to_ref,
791793
tuple_array_conversions,
792794
type_repetition_in_bounds,
793-
unchecked_duration_subtraction,
795+
unchecked_time_subtraction,
794796
uninlined_format_args,
795797
unnecessary_lazy_evaluations,
798+
unnecessary_unwrap,
796799
unnested_or_patterns,
797800
unused_trait_names,
798801
use_self,

clippy_lints/Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,17 @@ itertools = "0.12"
1818
quine-mc_cluskey = "0.2"
1919
regex-syntax = "0.8"
2020
serde = { version = "1.0", features = ["derive"] }
21-
toml = "0.7.3"
2221
unicode-normalization = "0.1"
2322
unicode-script = { version = "0.5", default-features = false }
2423
semver = "1.0"
2524
url = "2.2"
2625

26+
[dependencies.toml]
27+
version = "0.9.7"
28+
default-features = false
29+
# preserve_order keeps diagnostic output in file order
30+
features = ["parse", "preserve_order"]
31+
2732
[dev-dependencies]
2833
walkdir = "2.3"
2934

Lines changed: 55 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
use clippy_config::Conf;
12
use clippy_utils::consts::{ConstEvalCtxt, Constant};
23
use clippy_utils::diagnostics::span_lint_and_help;
3-
use clippy_utils::is_inside_always_const_context;
4-
use clippy_utils::macros::{PanicExpn, find_assert_args, root_macro_call_first_node};
4+
use clippy_utils::macros::{find_assert_args, root_macro_call_first_node};
5+
use clippy_utils::msrvs::Msrv;
6+
use clippy_utils::{is_inside_always_const_context, msrvs};
7+
use rustc_ast::LitKind;
58
use rustc_hir::{Expr, ExprKind};
69
use rustc_lint::{LateContext, LateLintPass};
7-
use rustc_session::declare_lint_pass;
10+
use rustc_session::impl_lint_pass;
811
use rustc_span::sym;
912

1013
declare_clippy_lint! {
@@ -28,56 +31,60 @@ declare_clippy_lint! {
2831
"`assert!(true)` / `assert!(false)` will be optimized out by the compiler, and should probably be replaced by a `panic!()` or `unreachable!()`"
2932
}
3033

31-
declare_lint_pass!(AssertionsOnConstants => [ASSERTIONS_ON_CONSTANTS]);
34+
impl_lint_pass!(AssertionsOnConstants => [ASSERTIONS_ON_CONSTANTS]);
35+
pub struct AssertionsOnConstants {
36+
msrv: Msrv,
37+
}
38+
impl AssertionsOnConstants {
39+
pub fn new(conf: &Conf) -> Self {
40+
Self { msrv: conf.msrv }
41+
}
42+
}
3243

3344
impl<'tcx> LateLintPass<'tcx> for AssertionsOnConstants {
3445
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
35-
let Some(macro_call) = root_macro_call_first_node(cx, e) else {
36-
return;
37-
};
38-
let is_debug = match cx.tcx.get_diagnostic_name(macro_call.def_id) {
39-
Some(sym::debug_assert_macro) => true,
40-
Some(sym::assert_macro) => false,
41-
_ => return,
42-
};
43-
let Some((condition, panic_expn)) = find_assert_args(cx, e, macro_call.expn) else {
44-
return;
45-
};
46-
let Some(Constant::Bool(val)) = ConstEvalCtxt::new(cx).eval(condition) else {
47-
return;
48-
};
46+
if let Some(macro_call) = root_macro_call_first_node(cx, e)
47+
&& let is_debug = match cx.tcx.get_diagnostic_name(macro_call.def_id) {
48+
Some(sym::debug_assert_macro) => true,
49+
Some(sym::assert_macro) => false,
50+
_ => return,
51+
}
52+
&& let Some((condition, _)) = find_assert_args(cx, e, macro_call.expn)
53+
&& let Some((Constant::Bool(assert_val), const_src)) =
54+
ConstEvalCtxt::new(cx).eval_with_source(condition, macro_call.span.ctxt())
55+
&& let in_const_context = is_inside_always_const_context(cx.tcx, e.hir_id)
56+
&& (const_src.is_local() || !in_const_context)
57+
&& !(is_debug && as_bool_lit(condition) == Some(false))
58+
{
59+
let (msg, help) = if !const_src.is_local() {
60+
let help = if self.msrv.meets(cx, msrvs::CONST_BLOCKS) {
61+
"consider moving this into a const block: `const { assert!(..) }`"
62+
} else if self.msrv.meets(cx, msrvs::CONST_PANIC) {
63+
"consider moving this to an anonymous constant: `const _: () = { assert!(..); }`"
64+
} else {
65+
return;
66+
};
67+
("this assertion has a constant value", help)
68+
} else if assert_val {
69+
("this assertion is always `true`", "remove the assertion")
70+
} else {
71+
(
72+
"this assertion is always `false`",
73+
"replace this with `panic!()` or `unreachable!()`",
74+
)
75+
};
4976

50-
match condition.kind {
51-
ExprKind::Path(..) | ExprKind::Lit(_) => {},
52-
_ if is_inside_always_const_context(cx.tcx, e.hir_id) => return,
53-
_ => {},
77+
span_lint_and_help(cx, ASSERTIONS_ON_CONSTANTS, macro_call.span, msg, None, help);
5478
}
79+
}
80+
}
5581

56-
if val {
57-
span_lint_and_help(
58-
cx,
59-
ASSERTIONS_ON_CONSTANTS,
60-
macro_call.span,
61-
format!(
62-
"`{}!(true)` will be optimized out by the compiler",
63-
cx.tcx.item_name(macro_call.def_id)
64-
),
65-
None,
66-
"remove it",
67-
);
68-
} else if !is_debug {
69-
let (assert_arg, panic_arg) = match panic_expn {
70-
PanicExpn::Empty => ("", ""),
71-
_ => (", ..", ".."),
72-
};
73-
span_lint_and_help(
74-
cx,
75-
ASSERTIONS_ON_CONSTANTS,
76-
macro_call.span,
77-
format!("`assert!(false{assert_arg})` should probably be replaced"),
78-
None,
79-
format!("use `panic!({panic_arg})` or `unreachable!({panic_arg})`"),
80-
);
81-
}
82+
fn as_bool_lit(e: &Expr<'_>) -> Option<bool> {
83+
if let ExprKind::Lit(l) = e.kind
84+
&& let LitKind::Bool(b) = l.node
85+
{
86+
Some(b)
87+
} else {
88+
None
8289
}
8390
}

0 commit comments

Comments
 (0)