diff --git a/Cargo.toml b/Cargo.toml index fee885d8fa7e..67078adea2b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy" -version = "0.1.93" +version = "0.1.94" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/clippy_config/Cargo.toml b/clippy_config/Cargo.toml index 3f6b26d3334e..a65fe7bcbda5 100644 --- a/clippy_config/Cargo.toml +++ b/clippy_config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_config" -version = "0.1.93" +version = "0.1.94" edition = "2024" publish = false diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index bc97746a1cba..7a78ef32bf3c 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_lints" -version = "0.1.93" +version = "0.1.94" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 5b39d8844797..40487fe48f22 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(array_windows)] +#![cfg_attr(bootstrap, feature(array_windows))] #![feature(box_patterns)] #![feature(macro_metavar_expr_concat)] #![feature(f128)] diff --git a/clippy_lints/src/manual_non_exhaustive.rs b/clippy_lints/src/manual_non_exhaustive.rs index 08e7c7593cb2..0d783fde3313 100644 --- a/clippy_lints/src/manual_non_exhaustive.rs +++ b/clippy_lints/src/manual_non_exhaustive.rs @@ -92,8 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { (matches!(v.data, VariantData::Unit(_, _)) && is_doc_hidden(cx.tcx.hir_attrs(v.hir_id))) .then_some((v.def_id, v.span)) }); - // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 - if let Ok((id, span)) = Itertools::exactly_one(iter) + if let Ok((id, span)) = iter.exactly_one() && !find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::NonExhaustive(..)) { self.potential_enums.push((item.owner_id.def_id, id, item.span, span)); @@ -105,8 +104,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { .iter() .filter(|field| !cx.effective_visibilities.is_exported(field.def_id)); if fields.len() > 1 - // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 - && let Ok(field) = Itertools::exactly_one(private_fields) + && let Ok(field) = private_fields.exactly_one() && let TyKind::Tup([]) = field.ty.kind { span_lint_and_then( diff --git a/clippy_lints/src/suspicious_operation_groupings.rs b/clippy_lints/src/suspicious_operation_groupings.rs index 0d809c17989d..af5e3ccb674a 100644 --- a/clippy_lints/src/suspicious_operation_groupings.rs +++ b/clippy_lints/src/suspicious_operation_groupings.rs @@ -545,7 +545,7 @@ fn ident_difference_expr_with_base_location( | (Field(_, _), Field(_, _)) | (AssignOp(_, _, _), AssignOp(_, _, _)) | (Assign(_, _, _), Assign(_, _, _)) - | (TryBlock(_), TryBlock(_)) + | (TryBlock(_, _), TryBlock(_, _)) | (Await(_, _), Await(_, _)) | (Gen(_, _, _, _), Gen(_, _, _, _)) | (Block(_, _), Block(_, _)) diff --git a/clippy_utils/Cargo.toml b/clippy_utils/Cargo.toml index a1e1b763dccb..503d581d6c7f 100644 --- a/clippy_utils/Cargo.toml +++ b/clippy_utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_utils" -version = "0.1.93" +version = "0.1.94" edition = "2024" description = "Helpful tools for writing lints, provided as they are used in Clippy" repository = "https://github.com/rust-lang/rust-clippy" @@ -16,6 +16,10 @@ itertools = "0.12" rustc_apfloat = "0.2.0" serde = { version = "1.0", features = ["derive"] } +[lints.rust.unexpected_cfgs] +level = "warn" +check-cfg = ['cfg(bootstrap)'] + [package.metadata.rust-analyzer] # This crate uses #[feature(rustc_private)] rustc_private = true diff --git a/clippy_utils/README.md b/clippy_utils/README.md index 4b1a10a3d9cf..dc8695fef9f5 100644 --- a/clippy_utils/README.md +++ b/clippy_utils/README.md @@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain: ``` -nightly-2025-11-28 +nightly-2025-12-11 ``` diff --git a/clippy_utils/src/ast_utils/mod.rs b/clippy_utils/src/ast_utils/mod.rs index 27b5a57c737d..08663782a1d5 100644 --- a/clippy_utils/src/ast_utils/mod.rs +++ b/clippy_utils/src/ast_utils/mod.rs @@ -199,7 +199,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool { ) => eq_label(ll.as_ref(), rl.as_ref()) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt) && lk == rk, (Loop(lt, ll, _), Loop(rt, rl, _)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_block(lt, rt), (Block(lb, ll), Block(rb, rl)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_block(lb, rb), - (TryBlock(l), TryBlock(r)) => eq_block(l, r), + (TryBlock(lb, lt), TryBlock(rb, rt)) => eq_block(lb, rb) && both(lt.as_deref(), rt.as_deref(), eq_ty), (Yield(l), Yield(r)) => eq_expr_opt(l.expr().map(Box::as_ref), r.expr().map(Box::as_ref)) && l.same_kind(r), (Ret(l), Ret(r)) => eq_expr_opt(l.as_deref(), r.as_deref()), (Break(ll, le), Break(rl, re)) => { diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index ed164fcf371b..409f13013489 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -5,7 +5,7 @@ #![feature(rustc_private)] #![feature(assert_matches)] #![feature(unwrap_infallible)] -#![feature(array_windows)] +#![cfg_attr(bootstrap, feature(array_windows))] #![recursion_limit = "512"] #![allow( clippy::missing_errors_doc, diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index 1fc8e86f3193..462cc644d4be 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -150,7 +150,7 @@ fn check_rvalue<'tcx>( CastKind::PointerCoercion( PointerCoercion::UnsafeFnPointer | PointerCoercion::ClosureFnPointer(_) - | PointerCoercion::ReifyFnPointer, + | PointerCoercion::ReifyFnPointer(_), _, ), _, diff --git a/declare_clippy_lint/Cargo.toml b/declare_clippy_lint/Cargo.toml index b73a7c7bb4d9..ee6d6cdbc34e 100644 --- a/declare_clippy_lint/Cargo.toml +++ b/declare_clippy_lint/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "declare_clippy_lint" -version = "0.1.93" +version = "0.1.94" edition = "2024" repository = "https://github.com/rust-lang/rust-clippy" license = "MIT OR Apache-2.0" diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 5157b79832a3..1384f4078ebe 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,6 +1,6 @@ [toolchain] # begin autogenerated nightly -channel = "nightly-2025-11-28" +channel = "nightly-2025-12-11" # end autogenerated nightly components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] profile = "minimal" diff --git a/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr b/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr index 70d71f6c4ea1..c94b7777f3e9 100644 --- a/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr +++ b/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr @@ -71,10 +71,10 @@ LL | impl core::fmt::Display for X | ^^^^^^^^^^^^^^^^^^ error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:113:14 + --> tests/ui-toml/absolute_paths/absolute_paths.rs:113:10 | -LL | pub const _: crate::S = { - | ^^^^^^^^ +LL | const _: crate::S = { + | ^^^^^^^^ error: consider bringing this path into scope with the `use` keyword --> tests/ui-toml/absolute_paths/absolute_paths.rs:114:9 diff --git a/tests/ui-toml/absolute_paths/absolute_paths.rs b/tests/ui-toml/absolute_paths/absolute_paths.rs index c024f2f513ce..a3982b8f6540 100644 --- a/tests/ui-toml/absolute_paths/absolute_paths.rs +++ b/tests/ui-toml/absolute_paths/absolute_paths.rs @@ -110,7 +110,7 @@ mod m1 { } //~[no_short]v absolute_paths -pub const _: crate::S = { +const _: crate::S = { let crate::S = m1::S; //~[no_short] absolute_paths crate::m1::S diff --git a/tests/ui/crashes/ice-6252.stderr b/tests/ui/crashes/ice-6252.stderr index 201a897b2319..b6a2597a44d5 100644 --- a/tests/ui/crashes/ice-6252.stderr +++ b/tests/ui/crashes/ice-6252.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `PhantomData` in this scope +error[E0425]: cannot find type `PhantomData` in this scope --> tests/ui/crashes/ice-6252.rs:9:9 | LL | _n: PhantomData, @@ -9,7 +9,7 @@ help: consider importing this struct LL + use std::marker::PhantomData; | -error[E0412]: cannot find type `VAL` in this scope +error[E0425]: cannot find type `VAL` in this scope --> tests/ui/crashes/ice-6252.rs:12:63 | LL | impl TypeVal for Multiply where N: TypeVal {} @@ -31,5 +31,5 @@ LL | impl TypeVal for Multiply where N: TypeVal {} error: aborting due to 3 previous errors -Some errors have detailed explanations: E0046, E0412. +Some errors have detailed explanations: E0046, E0425. For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/future_not_send.stderr b/tests/ui/future_not_send.stderr index e366dc2d2195..8b8af1ebaed3 100644 --- a/tests/ui/future_not_send.stderr +++ b/tests/ui/future_not_send.stderr @@ -1,8 +1,8 @@ error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:8:1 + --> tests/ui/future_not_send.rs:8:62 | LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future` is not `Send` + | ^^^^ future returned by `private_future` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:11:20 @@ -23,10 +23,10 @@ LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { = help: to override `-D warnings` add `#[allow(clippy::future_not_send)]` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:14:1 + --> tests/ui/future_not_send.rs:14:41 | LL | pub async fn public_future(rc: Rc<[u8]>) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future` is not `Send` + | ^ future returned by `public_future` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:17:20 @@ -39,10 +39,10 @@ LL | async { true }.await; = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:24:1 + --> tests/ui/future_not_send.rs:24:63 | LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell) -> bool { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future2` is not `Send` + | ^^^^ future returned by `private_future2` is not `Send` | note: captured value is not `Send` --> tests/ui/future_not_send.rs:24:26 @@ -58,10 +58,10 @@ LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell) -> bool { = note: `std::cell::Cell` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:30:1 + --> tests/ui/future_not_send.rs:30:42 | LL | pub async fn public_future2(rc: Rc<[u8]>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future2` is not `Send` + | ^ future returned by `public_future2` is not `Send` | note: captured value is not `Send` --> tests/ui/future_not_send.rs:30:29 @@ -71,10 +71,10 @@ LL | pub async fn public_future2(rc: Rc<[u8]>) {} = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:42:5 + --> tests/ui/future_not_send.rs:42:39 | LL | async fn private_future(&self) -> usize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future` is not `Send` + | ^^^^^ future returned by `private_future` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:45:24 @@ -87,10 +87,10 @@ LL | async { true }.await; = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:49:5 + --> tests/ui/future_not_send.rs:49:38 | LL | pub async fn public_future(&self) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future` is not `Send` + | ^ future returned by `public_future` is not `Send` | note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` --> tests/ui/future_not_send.rs:49:32 @@ -100,13 +100,10 @@ LL | pub async fn public_future(&self) { = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:61:1 + --> tests/ui/future_not_send.rs:61:37 | -LL | / async fn generic_future(t: T) -> T -LL | | -LL | | where -LL | | T: Send, - | |____________^ future returned by `generic_future` is not `Send` +LL | async fn generic_future(t: T) -> T + | ^ future returned by `generic_future` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:67:20 @@ -118,10 +115,10 @@ LL | async { true }.await; = note: `T` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:83:1 + --> tests/ui/future_not_send.rs:83:51 | LL | async fn generic_future_always_unsend(_: Rc) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `generic_future_always_unsend` is not `Send` + | ^ future returned by `generic_future_always_unsend` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:86:20 diff --git a/tests/ui/manual_async_fn.stderr b/tests/ui/manual_async_fn.stderr index 54a9b1d40a11..fe6a20589b96 100644 --- a/tests/ui/manual_async_fn.stderr +++ b/tests/ui/manual_async_fn.stderr @@ -9,6 +9,9 @@ LL | fn fut() -> impl Future { help: make the function `async` and return the output of the future directly | LL - fn fut() -> impl Future { +LL - +LL - async { 42 } +LL - } LL + async fn fut() -> i32 { 42 } | @@ -21,6 +24,9 @@ LL | fn fut2() ->impl Future { help: make the function `async` and return the output of the future directly | LL - fn fut2() ->impl Future { +LL - +LL - async { 42 } +LL - } LL + async fn fut2() -> i32 { 42 } | @@ -33,6 +39,9 @@ LL | fn fut3()-> impl Future { help: make the function `async` and return the output of the future directly | LL - fn fut3()-> impl Future { +LL - +LL - async { 42 } +LL - } LL + async fn fut3() -> i32 { 42 } | @@ -45,6 +54,9 @@ LL | fn empty_fut() -> impl Future { help: make the function `async` and return the output of the future directly | LL - fn empty_fut() -> impl Future { +LL - +LL - async {} +LL - } LL + async fn empty_fut() {} | @@ -57,6 +69,9 @@ LL | fn empty_fut2() ->impl Future { help: make the function `async` and return the output of the future directly | LL - fn empty_fut2() ->impl Future { +LL - +LL - async {} +LL - } LL + async fn empty_fut2() {} | @@ -69,6 +84,9 @@ LL | fn empty_fut3()-> impl Future { help: make the function `async` and return the output of the future directly | LL - fn empty_fut3()-> impl Future { +LL - +LL - async {} +LL - } LL + async fn empty_fut3() {} | @@ -81,6 +99,9 @@ LL | fn core_fut() -> impl core::future::Future { help: make the function `async` and return the output of the future directly | LL - fn core_fut() -> impl core::future::Future { +LL - +LL - async move { 42 } +LL - } LL + async fn core_fut() -> i32 { 42 } | @@ -116,6 +137,9 @@ LL | fn elided(_: &i32) -> impl Future + '_ { help: make the function `async` and return the output of the future directly | LL - fn elided(_: &i32) -> impl Future + '_ { +LL - +LL - async { 42 } +LL - } LL + async fn elided(_: &i32) -> i32 { 42 } | @@ -128,6 +152,9 @@ LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future + help: make the function `async` and return the output of the future directly | LL - fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future + 'a + 'b { +LL - +LL - async { 42 } +LL - } LL + async fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 { 42 } | @@ -140,6 +167,9 @@ LL | pub fn issue_10450() -> impl Future { help: make the function `async` and return the output of the future directly | LL - pub fn issue_10450() -> impl Future { +LL - +LL - async { 42 } +LL - } LL + pub async fn issue_10450() -> i32 { 42 } | @@ -152,6 +182,9 @@ LL | pub(crate) fn issue_10450_2() -> impl Future { help: make the function `async` and return the output of the future directly | LL - pub(crate) fn issue_10450_2() -> impl Future { +LL - +LL - async { 42 } +LL - } LL + pub(crate) async fn issue_10450_2() -> i32 { 42 } | @@ -164,6 +197,9 @@ LL | pub(self) fn issue_10450_3() -> impl Future { help: make the function `async` and return the output of the future directly | LL - pub(self) fn issue_10450_3() -> impl Future { +LL - +LL - async { 42 } +LL - } LL + pub(self) async fn issue_10450_3() -> i32 { 42 } | diff --git a/tests/ui/map_unwrap_or.stderr b/tests/ui/map_unwrap_or.stderr index 0b6c9b7fcf19..b0b02f3f8d6b 100644 --- a/tests/ui/map_unwrap_or.stderr +++ b/tests/ui/map_unwrap_or.stderr @@ -12,6 +12,9 @@ LL | | .unwrap_or(0); help: use `map_or(, )` instead | LL - let _ = opt.map(|x| x + 1) +LL - +LL - // Should lint even though this call is on a separate line. +LL - .unwrap_or(0); LL + let _ = opt.map_or(0, |x| x + 1); | @@ -98,6 +101,7 @@ LL | | .unwrap_or(None); help: use `and_then()` instead | LL - .map(|x| Some(x + 1)) +LL - .unwrap_or(None); LL + .and_then(|x| Some(x + 1)); | diff --git a/tests/ui/match_same_arms.stderr b/tests/ui/match_same_arms.stderr index 8aa60f835766..bd0b7b2871ec 100644 --- a/tests/ui/match_same_arms.stderr +++ b/tests/ui/match_same_arms.stderr @@ -30,7 +30,6 @@ help: otherwise remove the non-wildcard arms | LL - 2 => 'b', LL - 3 => 'b', -LL + _ => 'b', | error: these match arms have identical bodies diff --git a/tests/ui/non_canonical_partial_ord_impl.stderr b/tests/ui/non_canonical_partial_ord_impl.stderr index 8e55603dd9da..a134df17691e 100644 --- a/tests/ui/non_canonical_partial_ord_impl.stderr +++ b/tests/ui/non_canonical_partial_ord_impl.stderr @@ -28,6 +28,8 @@ LL | | } help: change this to | LL - fn partial_cmp(&self, _: &Self) -> Option { +LL - todo!(); +LL - } LL + fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } | diff --git a/tests/ui/print_literal.stderr b/tests/ui/print_literal.stderr index c136f52800f6..229f3bf269d3 100644 --- a/tests/ui/print_literal.stderr +++ b/tests/ui/print_literal.stderr @@ -310,6 +310,7 @@ LL | "name", 5, "x", 0.01 help: try | LL - "Hello {}: {2} is {3:.*} (which {3} with {1} places)", +LL - "name", 5, "x", 0.01 LL + "Hello name: x is {1:.*} (which {1} with {0} places)", 5, 0.01 |