diff --git a/Cargo.toml b/Cargo.toml index fee885d8fa7e..f0f9c05e4330 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,7 @@ tempfile = { version = "3.20", optional = true } termize = "0.2" color-print = "0.3.4" anstream = "0.6.18" +tikv-jemalloc-sys = { version = "0.6.1", optional = true, features = ['override_allocator_on_supported_platforms'] } [dev-dependencies] cargo_metadata = "0.18.1" @@ -56,7 +57,7 @@ rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" } [features] integration = ["dep:tempfile"] internal = ["dep:clippy_lints_internal", "dep:tempfile"] -jemalloc = [] +jemalloc = ["dep:tikv-jemalloc-sys"] [package.metadata.rust-analyzer] # This package uses #[feature(rustc_private)] diff --git a/book/src/development/infrastructure/changelog_update.md b/book/src/development/infrastructure/changelog_update.md index c96ff228b01a..9eb7e7cc9c9e 100644 --- a/book/src/development/infrastructure/changelog_update.md +++ b/book/src/development/infrastructure/changelog_update.md @@ -112,7 +112,7 @@ written for. If not, update the version to the changelog version. [changelog]: https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md [forge]: https://forge.rust-lang.org/ -[rust_master_tools]: https://github.com/rust-lang/rust/tree/master/src/tools/clippy +[rust_master_tools]: https://github.com/rust-lang/rust/tree/HEAD/src/tools/clippy [rust_beta_tools]: https://github.com/rust-lang/rust/tree/beta/src/tools/clippy [rust_stable_tools]: https://github.com/rust-lang/rust/releases [`beta-accepted`]: https://github.com/rust-lang/rust-clippy/issues?q=label%3Abeta-accepted+ diff --git a/clippy_lints/src/disallowed_script_idents.rs b/clippy_lints/src/disallowed_script_idents.rs index cf964d4b5804..5b4fe2a6b803 100644 --- a/clippy_lints/src/disallowed_script_idents.rs +++ b/clippy_lints/src/disallowed_script_idents.rs @@ -67,7 +67,7 @@ impl_lint_pass!(DisallowedScriptIdents => [DISALLOWED_SCRIPT_IDENTS]); impl EarlyLintPass for DisallowedScriptIdents { fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) { // Implementation is heavily inspired by the implementation of [`non_ascii_idents`] lint: - // https://github.com/rust-lang/rust/blob/master/compiler/rustc_lint/src/non_ascii_idents.rs + // https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_lint/src/non_ascii_idents.rs let check_disallowed_script_idents = cx.builder.lint_level(DISALLOWED_SCRIPT_IDENTS).level != Level::Allow; if !check_disallowed_script_idents { diff --git a/clippy_lints/src/equatable_if_let.rs b/clippy_lints/src/equatable_if_let.rs index c3fc09343dbf..9b5cd7e1731f 100644 --- a/clippy_lints/src/equatable_if_let.rs +++ b/clippy_lints/src/equatable_if_let.rs @@ -55,7 +55,7 @@ fn unary_pattern(pat: &Pat<'_>) -> bool { | PatKind::Err(_) => false, PatKind::Struct(_, a, etc) => etc.is_none() && a.iter().all(|x| unary_pattern(x.pat)), PatKind::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => etc.as_opt_usize().is_none() && array_rec(a), - PatKind::Ref(x, _) | PatKind::Box(x) | PatKind::Deref(x) | PatKind::Guard(x, _) => unary_pattern(x), + PatKind::Ref(x, _, _) | PatKind::Box(x) | PatKind::Deref(x) | PatKind::Guard(x, _) => unary_pattern(x), PatKind::Expr(_) => true, } } diff --git a/clippy_lints/src/index_refutable_slice.rs b/clippy_lints/src/index_refutable_slice.rs index 919702c5714a..e95816353df6 100644 --- a/clippy_lints/src/index_refutable_slice.rs +++ b/clippy_lints/src/index_refutable_slice.rs @@ -94,7 +94,7 @@ fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxIndexMap for ItemNameRepetitions { | ItemKind::Macro(ident, ..) | ItemKind::Static(_, ident, ..) | ItemKind::Trait(_, _, _, ident, ..) - | ItemKind::TraitAlias(ident, ..) + | ItemKind::TraitAlias(_, ident, ..) | ItemKind::TyAlias(ident, ..) | ItemKind::Union(ident, ..) | ItemKind::Use(_, UseKind::Single(ident)) => ident, diff --git a/clippy_lints/src/loops/manual_find.rs b/clippy_lints/src/loops/manual_find.rs index 34917252d049..d94dcfab23c7 100644 --- a/clippy_lints/src/loops/manual_find.rs +++ b/clippy_lints/src/loops/manual_find.rs @@ -42,7 +42,7 @@ pub(super) fn check<'tcx>( let mut snippet = make_iterator_snippet(cx, arg, &mut applicability); // Checks if `pat` is a single reference to a binding (`&x`) let is_ref_to_binding = - matches!(pat.kind, PatKind::Ref(inner, _) if matches!(inner.kind, PatKind::Binding(..))); + matches!(pat.kind, PatKind::Ref(inner, _, _) if matches!(inner.kind, PatKind::Binding(..))); // If `pat` is not a binding or a reference to a binding (`x` or `&x`) // we need to map it to the binding returned by the function (i.e. `.map(|(x, _)| x)`) if !(matches!(pat.kind, PatKind::Binding(..)) || is_ref_to_binding) { diff --git a/clippy_lints/src/manual_retain.rs b/clippy_lints/src/manual_retain.rs index 674f0da818f5..6870c9819fc0 100644 --- a/clippy_lints/src/manual_retain.rs +++ b/clippy_lints/src/manual_retain.rs @@ -157,7 +157,7 @@ fn check_iter( ), ); }, - hir::PatKind::Ref(pat, _) => make_span_lint_and_sugg( + hir::PatKind::Ref(pat, _, _) => make_span_lint_and_sugg( cx, parent_expr_span, format!( @@ -196,7 +196,7 @@ fn check_to_owned( && let filter_body = cx.tcx.hir_body(closure.body) && let [filter_params] = filter_body.params && msrv.meets(cx, msrvs::STRING_RETAIN) - && let hir::PatKind::Ref(pat, _) = filter_params.pat.kind + && let hir::PatKind::Ref(pat, _, _) = filter_params.pat.kind { make_span_lint_and_sugg( cx, diff --git a/clippy_lints/src/matches/manual_ok_err.rs b/clippy_lints/src/matches/manual_ok_err.rs index 3259655c9a1f..c35c3d1f62e6 100644 --- a/clippy_lints/src/matches/manual_ok_err.rs +++ b/clippy_lints/src/matches/manual_ok_err.rs @@ -78,7 +78,7 @@ fn is_variant_or_wildcard(cx: &LateContext<'_>, pat: &Pat<'_>, can_be_wild: bool .is_lang_item(cx, ResultErr) == must_match_err }, - PatKind::Binding(_, _, _, Some(pat)) | PatKind::Ref(pat, _) => { + PatKind::Binding(_, _, _, Some(pat)) | PatKind::Ref(pat, _, _) => { is_variant_or_wildcard(cx, pat, can_be_wild, must_match_err) }, _ => false, diff --git a/clippy_lints/src/matches/manual_utils.rs b/clippy_lints/src/matches/manual_utils.rs index 09e49c16624c..6a755fac45fe 100644 --- a/clippy_lints/src/matches/manual_utils.rs +++ b/clippy_lints/src/matches/manual_utils.rs @@ -253,7 +253,7 @@ pub(super) fn try_parse_pattern<'tcx>( ) -> Option> { match pat.kind { PatKind::Wild => Some(OptionPat::Wild), - PatKind::Ref(pat, _) => f(cx, pat, ref_count + 1, ctxt), + PatKind::Ref(pat, _, _) => f(cx, pat, ref_count + 1, ctxt), _ if is_none_pattern(cx, pat) => Some(OptionPat::None), _ if let Some([pattern]) = as_some_pattern(cx, pat) && pat.span.ctxt() == ctxt => diff --git a/clippy_lints/src/matches/match_as_ref.rs b/clippy_lints/src/matches/match_as_ref.rs index 30d703df4df4..795355f25f9e 100644 --- a/clippy_lints/src/matches/match_as_ref.rs +++ b/clippy_lints/src/matches/match_as_ref.rs @@ -82,7 +82,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: // Checks if arm has the form `Some(ref v) => Some(v)` (checks for `ref` and `ref mut`) fn as_ref_some_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> Option { if let Some([first_pat, ..]) = as_some_pattern(cx, arm.pat) - && let PatKind::Binding(BindingMode(ByRef::Yes(mutabl), _), .., ident, _) = first_pat.kind + && let PatKind::Binding(BindingMode(ByRef::Yes(_, mutabl), _), .., ident, _) = first_pat.kind && let Some(arg) = as_some_expr(cx, peel_blocks(arm.body)) && let ExprKind::Path(QPath::Resolved(_, path2)) = arg.kind && path2.segments.len() == 1 diff --git a/clippy_lints/src/matches/match_ref_pats.rs b/clippy_lints/src/matches/match_ref_pats.rs index 5934ec409935..042817f5cdb8 100644 --- a/clippy_lints/src/matches/match_ref_pats.rs +++ b/clippy_lints/src/matches/match_ref_pats.rs @@ -50,7 +50,7 @@ where } let remaining_suggs = pats.filter_map(|pat| { - if let PatKind::Ref(refp, _) = pat.kind { + if let PatKind::Ref(refp, _, _) = pat.kind { Some((pat.span, snippet(cx, refp.span, "..").to_string())) } else { None diff --git a/clippy_lints/src/matches/match_same_arms.rs b/clippy_lints/src/matches/match_same_arms.rs index be914429edb4..c20217563d62 100644 --- a/clippy_lints/src/matches/match_same_arms.rs +++ b/clippy_lints/src/matches/match_same_arms.rs @@ -264,7 +264,7 @@ impl<'a> NormalizedPat<'a> { PatKind::Binding(.., Some(pat)) | PatKind::Box(pat) | PatKind::Deref(pat) - | PatKind::Ref(pat, _) + | PatKind::Ref(pat, _, _) | PatKind::Guard(pat, _) => Self::from_pat(cx, arena, pat), PatKind::Never => Self::Never, PatKind::Struct(ref path, fields, _) => { diff --git a/clippy_lints/src/matches/needless_match.rs b/clippy_lints/src/matches/needless_match.rs index c9b6821ad98f..9c6cf66019f0 100644 --- a/clippy_lints/src/matches/needless_match.rs +++ b/clippy_lints/src/matches/needless_match.rs @@ -172,7 +172,7 @@ fn pat_same_as_expr(pat: &Pat<'_>, expr: &Expr<'_>) -> bool { }, )), ) => { - return !matches!(annot, BindingMode(ByRef::Yes(_), _)) && pat_ident.name == first_seg.ident.name; + return !matches!(annot, BindingMode(ByRef::Yes(..), _)) && pat_ident.name == first_seg.ident.name; }, // Example: `Custom::TypeA => Custom::TypeB`, or `None => None` ( diff --git a/clippy_lints/src/matches/redundant_guards.rs b/clippy_lints/src/matches/redundant_guards.rs index d39e315cae1f..757ecf75ed45 100644 --- a/clippy_lints/src/matches/redundant_guards.rs +++ b/clippy_lints/src/matches/redundant_guards.rs @@ -30,7 +30,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv: && !pat_contains_disallowed_or(cx, arm.pat, msrv) { let pat_span = match (arm.pat.kind, binding.byref_ident) { - (PatKind::Ref(pat, _), Some(_)) => pat.span, + (PatKind::Ref(pat, _, _), Some(_)) => pat.span, (PatKind::Ref(..), None) | (_, Some(_)) => continue, _ => arm.pat.span, }; @@ -49,7 +49,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv: && !pat_contains_disallowed_or(cx, let_expr.pat, msrv) { let pat_span = match (let_expr.pat.kind, binding.byref_ident) { - (PatKind::Ref(pat, _), Some(_)) => pat.span, + (PatKind::Ref(pat, _, _), Some(_)) => pat.span, (PatKind::Ref(..), None) | (_, Some(_)) => continue, _ => let_expr.pat.span, }; @@ -176,7 +176,7 @@ fn get_pat_binding<'tcx>( if let PatKind::Binding(bind_annot, hir_id, ident, _) = pat.kind && hir_id == local { - if matches!(bind_annot.0, rustc_ast::ByRef::Yes(_)) { + if matches!(bind_annot.0, rustc_ast::ByRef::Yes(..)) { let _ = byref_ident.insert(ident); } // the second call of `replace()` returns a `Some(span)`, meaning a multi-binding pattern diff --git a/clippy_lints/src/matches/redundant_pattern_match.rs b/clippy_lints/src/matches/redundant_pattern_match.rs index a0f88cf911d8..bc3783750e5c 100644 --- a/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/clippy_lints/src/matches/redundant_pattern_match.rs @@ -186,7 +186,7 @@ fn find_method_sugg_for_if_let<'tcx>( // also look inside refs // if we have &None for example, peel it so we can detect "if let None = x" let check_pat = match let_pat.kind { - PatKind::Ref(inner, _mutability) => inner, + PatKind::Ref(inner, _pinnedness, _mutability) => inner, _ => let_pat, }; let op_ty = cx.typeck_results().expr_ty(let_expr); diff --git a/clippy_lints/src/matches/single_match.rs b/clippy_lints/src/matches/single_match.rs index 44c4d7a31ff3..8642c7e349b1 100644 --- a/clippy_lints/src/matches/single_match.rs +++ b/clippy_lints/src/matches/single_match.rs @@ -373,7 +373,10 @@ impl<'a> PatState<'a> { }, // Patterns for things which can only contain a single sub-pattern. - PatKind::Binding(_, _, _, Some(pat)) | PatKind::Ref(pat, _) | PatKind::Box(pat) | PatKind::Deref(pat) => { + PatKind::Binding(_, _, _, Some(pat)) + | PatKind::Ref(pat, _, _) + | PatKind::Box(pat) + | PatKind::Deref(pat) => { self.add_pat(cx, pat) }, PatKind::Tuple([sub_pat], pos) diff --git a/clippy_lints/src/methods/clone_on_copy.rs b/clippy_lints/src/methods/clone_on_copy.rs index 8980a22ad613..18087bd96deb 100644 --- a/clippy_lints/src/methods/clone_on_copy.rs +++ b/clippy_lints/src/methods/clone_on_copy.rs @@ -57,7 +57,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) _ => false, }, // local binding capturing a reference - Node::LetStmt(l) if matches!(l.pat.kind, PatKind::Binding(BindingMode(ByRef::Yes(_), _), ..)) => { + Node::LetStmt(l) if matches!(l.pat.kind, PatKind::Binding(BindingMode(ByRef::Yes(..), _), ..)) => { return; }, _ => false, diff --git a/clippy_lints/src/methods/filter_map.rs b/clippy_lints/src/methods/filter_map.rs index 26b19848fe1b..7b10c37de42d 100644 --- a/clippy_lints/src/methods/filter_map.rs +++ b/clippy_lints/src/methods/filter_map.rs @@ -404,7 +404,7 @@ fn is_find_or_filter<'a>( && let filter_body = cx.tcx.hir_body(filter_body_id) && let [filter_param] = filter_body.params // optional ref pattern: `filter(|&x| ..)` - && let (filter_pat, is_filter_param_ref) = if let PatKind::Ref(ref_pat, _) = filter_param.pat.kind { + && let (filter_pat, is_filter_param_ref) = if let PatKind::Ref(ref_pat, _, _) = filter_param.pat.kind { (ref_pat, true) } else { (filter_param.pat, false) diff --git a/clippy_lints/src/methods/iter_filter.rs b/clippy_lints/src/methods/iter_filter.rs index 8d95b70c6a4b..aaface3aa971 100644 --- a/clippy_lints/src/methods/iter_filter.rs +++ b/clippy_lints/src/methods/iter_filter.rs @@ -50,7 +50,7 @@ fn is_method( fn pat_is_recv(ident: Ident, param: &hir::Pat<'_>) -> bool { match param.kind { hir::PatKind::Binding(_, _, other, _) => ident == other, - hir::PatKind::Ref(pat, _) => pat_is_recv(ident, pat), + hir::PatKind::Ref(pat, _, _) => pat_is_recv(ident, pat), _ => false, } } diff --git a/clippy_lints/src/methods/iter_overeager_cloned.rs b/clippy_lints/src/methods/iter_overeager_cloned.rs index d43dc23a86b2..e3bcca64e923 100644 --- a/clippy_lints/src/methods/iter_overeager_cloned.rs +++ b/clippy_lints/src/methods/iter_overeager_cloned.rs @@ -81,7 +81,8 @@ pub(super) fn check<'tcx>( } match it.kind { - PatKind::Binding(BindingMode(_, Mutability::Mut), _, _, _) | PatKind::Ref(_, Mutability::Mut) => { + PatKind::Binding(BindingMode(_, Mutability::Mut), _, _, _) + | PatKind::Ref(_, _, Mutability::Mut) => { to_be_discarded = true; false }, diff --git a/clippy_lints/src/methods/map_clone.rs b/clippy_lints/src/methods/map_clone.rs index 1bc29c9c1dd1..a1aac96ccf86 100644 --- a/clippy_lints/src/methods/map_clone.rs +++ b/clippy_lints/src/methods/map_clone.rs @@ -8,7 +8,7 @@ use rustc_errors::Applicability; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, LangItem}; use rustc_lint::LateContext; -use rustc_middle::mir::Mutability; +use rustc_middle::mir::{Mutability, Pinnedness}; use rustc_middle::ty; use rustc_middle::ty::adjustment::Adjust; use rustc_span::symbol::Ident; @@ -50,7 +50,7 @@ pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_ let closure_body = cx.tcx.hir_body(body); let closure_expr = peel_blocks(closure_body.value); match closure_body.params[0].pat.kind { - hir::PatKind::Ref(inner, Mutability::Not) => { + hir::PatKind::Ref(inner, Pinnedness::Not, Mutability::Not) => { if let hir::PatKind::Binding(hir::BindingMode::NONE, .., name, None) = inner.kind && ident_eq(name, closure_expr) { diff --git a/clippy_lints/src/needless_borrowed_ref.rs b/clippy_lints/src/needless_borrowed_ref.rs index 1b6896827fed..29b4da93b7fb 100644 --- a/clippy_lints/src/needless_borrowed_ref.rs +++ b/clippy_lints/src/needless_borrowed_ref.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; use rustc_errors::Applicability; -use rustc_hir::{BindingMode, Mutability, Node, Pat, PatKind}; +use rustc_hir::{BindingMode, Mutability, Node, Pat, PatKind, Pinnedness}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; @@ -37,7 +37,7 @@ declare_lint_pass!(NeedlessBorrowedRef => [NEEDLESS_BORROWED_REFERENCE]); impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef { fn check_pat(&mut self, cx: &LateContext<'tcx>, ref_pat: &'tcx Pat<'_>) { - if let PatKind::Ref(pat, Mutability::Not) = ref_pat.kind + if let PatKind::Ref(pat, Pinnedness::Not, Mutability::Not) = ref_pat.kind && !ref_pat.span.from_expansion() && cx .tcx diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs index 2fffc4244a73..9b0008a29c6b 100644 --- a/clippy_lints/src/non_copy_const.rs +++ b/clippy_lints/src/non_copy_const.rs @@ -18,7 +18,7 @@ // definitely contains interior mutability. use clippy_config::Conf; -use clippy_utils::consts::{ConstEvalCtxt, Constant}; +use clippy_utils::consts::{ConstEvalCtxt, Constant, const_item_rhs_to_expr}; use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; use clippy_utils::is_in_const_context; use clippy_utils::macros::macro_backtrace; @@ -28,7 +28,8 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_hir::{ - Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, Node, StructTailExpr, TraitItem, TraitItemKind, UnOp, + ConstArgKind, ConstItemRhs, Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, Node, StructTailExpr, + TraitItem, TraitItemKind, UnOp, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::mir::{ConstValue, UnevaluatedConst}; @@ -272,6 +273,7 @@ impl<'tcx> NonCopyConst<'tcx> { /// Checks if a value of the given type is `Freeze`, or may be depending on the value. fn is_ty_freeze(&mut self, tcx: TyCtxt<'tcx>, typing_env: TypingEnv<'tcx>, ty: Ty<'tcx>) -> IsFreeze { + // FIXME: this should probably be using the trait solver let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); match self.freeze_tys.entry(ty) { Entry::Occupied(e) => *e.get(), @@ -695,7 +697,7 @@ impl<'tcx> NonCopyConst<'tcx> { impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { - if let ItemKind::Const(ident, .., body_id) = item.kind + if let ItemKind::Const(ident, .., ct_rhs) = item.kind && !ident.is_special() && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() && match self.is_ty_freeze(cx.tcx, cx.typing_env(), ty) { @@ -703,13 +705,14 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { IsFreeze::Yes => false, IsFreeze::Maybe => match cx.tcx.const_eval_poly(item.owner_id.to_def_id()) { Ok(val) if let Ok(is_freeze) = self.is_value_freeze(cx.tcx, cx.typing_env(), ty, val) => !is_freeze, - _ => !self.is_init_expr_freeze( + // FIXME: we just assume mgca rhs's are freeze + _ => const_item_rhs_to_expr(cx.tcx, ct_rhs).is_some_and(|e| !self.is_init_expr_freeze( cx.tcx, cx.typing_env(), cx.tcx.typeck(item.owner_id), GenericArgs::identity_for_item(cx.tcx, item.owner_id), - cx.tcx.hir_body(body_id).value, - ), + e + )), }, } && !item.span.in_external_macro(cx.sess().source_map()) @@ -736,22 +739,25 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { } fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { - if let TraitItemKind::Const(_, body_id_opt) = item.kind + if let TraitItemKind::Const(_, ct_rhs_opt) = item.kind && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() && match self.is_ty_freeze(cx.tcx, cx.typing_env(), ty) { IsFreeze::No => true, - IsFreeze::Maybe if let Some(body_id) = body_id_opt => { + IsFreeze::Maybe if let Some(ct_rhs) = ct_rhs_opt => { match cx.tcx.const_eval_poly(item.owner_id.to_def_id()) { Ok(val) if let Ok(is_freeze) = self.is_value_freeze(cx.tcx, cx.typing_env(), ty, val) => { !is_freeze }, - _ => !self.is_init_expr_freeze( - cx.tcx, - cx.typing_env(), - cx.tcx.typeck(item.owner_id), - GenericArgs::identity_for_item(cx.tcx, item.owner_id), - cx.tcx.hir_body(body_id).value, - ), + // FIXME: we just assume mgca rhs's are freeze + _ => const_item_rhs_to_expr(cx.tcx, ct_rhs).is_some_and(|e| { + !self.is_init_expr_freeze( + cx.tcx, + cx.typing_env(), + cx.tcx.typeck(item.owner_id), + GenericArgs::identity_for_item(cx.tcx, item.owner_id), + e, + ) + }), } }, IsFreeze::Yes | IsFreeze::Maybe => false, @@ -768,7 +774,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { } fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { - if let ImplItemKind::Const(_, body_id) = item.kind + if let ImplItemKind::Const(_, ct_rhs) = item.kind && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() && match self.is_ty_freeze(cx.tcx, cx.typing_env(), ty) { IsFreeze::Yes => false, @@ -799,13 +805,16 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { // interior mutability. IsFreeze::Maybe => match cx.tcx.const_eval_poly(item.owner_id.to_def_id()) { Ok(val) if let Ok(is_freeze) = self.is_value_freeze(cx.tcx, cx.typing_env(), ty, val) => !is_freeze, - _ => !self.is_init_expr_freeze( - cx.tcx, - cx.typing_env(), - cx.tcx.typeck(item.owner_id), - GenericArgs::identity_for_item(cx.tcx, item.owner_id), - cx.tcx.hir_body(body_id).value, - ), + // FIXME: we just assume mgca rhs's are freeze + _ => const_item_rhs_to_expr(cx.tcx, ct_rhs).is_some_and(|e| { + !self.is_init_expr_freeze( + cx.tcx, + cx.typing_env(), + cx.tcx.typeck(item.owner_id), + GenericArgs::identity_for_item(cx.tcx, item.owner_id), + e, + ) + }), }, } && !item.span.in_external_macro(cx.sess().source_map()) @@ -913,20 +922,26 @@ fn get_const_hir_value<'tcx>( args: GenericArgsRef<'tcx>, ) -> Option<(&'tcx TypeckResults<'tcx>, &'tcx Expr<'tcx>)> { let did = did.as_local()?; - let (did, body_id) = match tcx.hir_node(tcx.local_def_id_to_hir_id(did)) { - Node::Item(item) if let ItemKind::Const(.., body_id) = item.kind => (did, body_id), - Node::ImplItem(item) if let ImplItemKind::Const(.., body_id) = item.kind => (did, body_id), + let (did, ct_rhs) = match tcx.hir_node(tcx.local_def_id_to_hir_id(did)) { + Node::Item(item) if let ItemKind::Const(.., ct_rhs) = item.kind => (did, ct_rhs), + Node::ImplItem(item) if let ImplItemKind::Const(.., ct_rhs) = item.kind => (did, ct_rhs), Node::TraitItem(_) if let Ok(Some(inst)) = Instance::try_resolve(tcx, typing_env, did.into(), args) && let Some(did) = inst.def_id().as_local() => { match tcx.hir_node(tcx.local_def_id_to_hir_id(did)) { - Node::ImplItem(item) if let ImplItemKind::Const(.., body_id) = item.kind => (did, body_id), - Node::TraitItem(item) if let TraitItemKind::Const(.., Some(body_id)) = item.kind => (did, body_id), + Node::ImplItem(item) if let ImplItemKind::Const(.., ct_rhs) = item.kind => (did, ct_rhs), + Node::TraitItem(item) if let TraitItemKind::Const(.., Some(ct_rhs)) = item.kind => (did, ct_rhs), _ => return None, } }, _ => return None, }; - Some((tcx.typeck(did), tcx.hir_body(body_id).value)) + match ct_rhs { + ConstItemRhs::Body(body_id) => Some((tcx.typeck(did), tcx.hir_body(body_id).value)), + ConstItemRhs::TypeConst(ct_arg) => match ct_arg.kind { + ConstArgKind::Anon(anon_const) => Some((tcx.typeck(did), tcx.hir_body(anon_const.body).value)), + _ => None, + }, + } } diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs index 1a6165d0af83..59d31f782bc3 100644 --- a/clippy_lints/src/question_mark.rs +++ b/clippy_lints/src/question_mark.rs @@ -150,7 +150,7 @@ fn check_let_some_else_return_none(cx: &LateContext<'_>, stmt: &Stmt<'_>) { let init_expr_str = Sugg::hir_with_applicability(cx, init_expr, "..", &mut applicability).maybe_paren(); // Take care when binding is `ref` let sugg = if let PatKind::Binding( - BindingMode(ByRef::Yes(ref_mutability), binding_mutability), + BindingMode(ByRef::Yes(_, ref_mutability), binding_mutability), _hir_id, ident, subpattern, @@ -169,7 +169,7 @@ fn check_let_some_else_return_none(cx: &LateContext<'_>, stmt: &Stmt<'_>) { // Handle subpattern (@ subpattern) let maybe_subpattern = match subpattern { Some(Pat { - kind: PatKind::Binding(BindingMode(ByRef::Yes(_), _), _, subident, None), + kind: PatKind::Binding(BindingMode(ByRef::Yes(..), _), _, subident, None), .. }) => { // avoid `&ref` @@ -504,8 +504,8 @@ fn check_if_let_some_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: let receiver_str = snippet_with_applicability(cx, let_expr.span, "..", &mut applicability); let requires_semi = matches!(cx.tcx.parent_hir_node(expr.hir_id), Node::Stmt(_)); let method_call_str = match by_ref { - ByRef::Yes(Mutability::Mut) => ".as_mut()", - ByRef::Yes(Mutability::Not) => ".as_ref()", + ByRef::Yes(_, Mutability::Mut) => ".as_mut()", + ByRef::Yes(_, Mutability::Not) => ".as_ref()", ByRef::No => "", }; let sugg = format!( diff --git a/clippy_lints/src/toplevel_ref_arg.rs b/clippy_lints/src/toplevel_ref_arg.rs index 074b79263d37..250c277ab5e1 100644 --- a/clippy_lints/src/toplevel_ref_arg.rs +++ b/clippy_lints/src/toplevel_ref_arg.rs @@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for ToplevelRefArg { ) { if !matches!(k, FnKind::Closure) { for arg in iter_input_pats(decl, body) { - if let PatKind::Binding(BindingMode(ByRef::Yes(_), _), ..) = arg.pat.kind + if let PatKind::Binding(BindingMode(ByRef::Yes(..), _), ..) = arg.pat.kind && is_lint_allowed(cx, REF_PATTERNS, arg.pat.hir_id) && !arg.span.in_external_macro(cx.tcx.sess.source_map()) { @@ -80,7 +80,7 @@ impl<'tcx> LateLintPass<'tcx> for ToplevelRefArg { fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) { if let StmtKind::Let(local) = stmt.kind - && let PatKind::Binding(BindingMode(ByRef::Yes(mutabl), _), .., name, None) = local.pat.kind + && let PatKind::Binding(BindingMode(ByRef::Yes(_, mutabl), _), .., name, None) = local.pat.kind && let Some(init) = local.init // Do not emit if clippy::ref_patterns is not allowed to avoid having two lints for the same issue. && is_lint_allowed(cx, REF_PATTERNS, local.pat.hir_id) diff --git a/clippy_lints/src/undocumented_unsafe_blocks.rs b/clippy_lints/src/undocumented_unsafe_blocks.rs index 9935dc309611..9d27a66a9ab8 100644 --- a/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -2,6 +2,7 @@ use std::ops::ControlFlow; use std::sync::Arc; use clippy_config::Conf; +use clippy_utils::consts::const_item_rhs_to_expr; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::is_lint_allowed; use clippy_utils::source::walk_span_to_context; @@ -184,7 +185,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { } } - fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &hir::Item<'tcx>) { if item.span.in_external_macro(cx.tcx.sess.source_map()) { return; } @@ -214,7 +215,13 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { } } -fn check_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>, (span, help_span): (Span, Span), is_doc: bool) { +#[expect(clippy::too_many_lines)] +fn check_has_safety_comment<'tcx>( + cx: &LateContext<'tcx>, + item: &hir::Item<'tcx>, + (span, help_span): (Span, Span), + is_doc: bool, +) { match &item.kind { ItemKind::Impl(Impl { of_trait: Some(of_trait), @@ -234,7 +241,31 @@ fn check_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>, (span, h }, ItemKind::Impl(_) => {}, // const and static items only need a safety comment if their body is an unsafe block, lint otherwise - &ItemKind::Const(.., body) | &ItemKind::Static(.., body) => { + &ItemKind::Const(.., ct_rhs) => { + if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, ct_rhs.hir_id()) { + let expr = const_item_rhs_to_expr(cx.tcx, ct_rhs); + if let Some(expr) = expr + && !matches!( + expr.kind, hir::ExprKind::Block(block, _) + if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) + ) + { + span_lint_and_then( + cx, + UNNECESSARY_SAFETY_COMMENT, + span, + format!( + "{} has unnecessary safety comment", + cx.tcx.def_descr(item.owner_id.to_def_id()), + ), + |diag| { + diag.span_help(help_span, "consider removing the safety comment"); + }, + ); + } + } + }, + &ItemKind::Static(.., body) => { if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, body.hir_id) { let body = cx.tcx.hir_body(body); if !matches!( diff --git a/clippy_lints/src/unnested_or_patterns.rs b/clippy_lints/src/unnested_or_patterns.rs index 66a1dfc1f486..975dd332ad06 100644 --- a/clippy_lints/src/unnested_or_patterns.rs +++ b/clippy_lints/src/unnested_or_patterns.rs @@ -7,7 +7,7 @@ use clippy_utils::msrvs::{self, MsrvStack}; use clippy_utils::over; use rustc_ast::PatKind::*; use rustc_ast::mut_visit::*; -use rustc_ast::{self as ast, DUMMY_NODE_ID, Mutability, Pat, PatKind}; +use rustc_ast::{self as ast, DUMMY_NODE_ID, Mutability, Pat, PatKind, Pinnedness}; use rustc_ast_pretty::pprust; use rustc_data_structures::thin_vec::{ThinVec, thin_vec}; use rustc_data_structures::thinvec::ExtractIf; @@ -152,8 +152,9 @@ fn insert_necessary_parens(pat: &mut Pat) { walk_pat(self, pat); let target = match &mut pat.kind { // `i @ a | b`, `box a | b`, and `& mut? a | b`. - Ident(.., Some(p)) | Box(p) | Ref(p, _) if matches!(&p.kind, Or(ps) if ps.len() > 1) => p, - Ref(p, Mutability::Not) if matches!(p.kind, Ident(BindingMode::MUT, ..)) => p, // `&(mut x)` + Ident(.., Some(p)) | Box(p) | Ref(p, _, _) if matches!(&p.kind, Or(ps) if ps.len() > 1) => p, + // `&(mut x)` + Ref(p, Pinnedness::Not, Mutability::Not) if matches!(p.kind, Ident(BindingMode::MUT, ..)) => p, _ => return, }; target.kind = Paren(Box::new(take_pat(target))); @@ -242,7 +243,8 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec, focus_idx: usize // Skip immutable refs, as grouping them saves few characters, // and almost always requires adding parens (increasing noisiness). // In the case of only two patterns, replacement adds net characters. - | Ref(_, Mutability::Not) + // FIXME(pin_ergonomics): handle pinned patterns + | Ref(_, _, Mutability::Not) // Dealt with elsewhere. | Or(_) | Paren(_) | Deref(_) | Guard(..) => false, // Transform `box x | ... | box y` into `box (x | y)`. @@ -255,10 +257,10 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec, focus_idx: usize |k| always_pat!(k, Box(p) => *p), ), // Transform `&mut x | ... | &mut y` into `&mut (x | y)`. - Ref(target, Mutability::Mut) => extend_with_matching( + Ref(target, _, Mutability::Mut) => extend_with_matching( target, start, alternatives, - |k| matches!(k, Ref(_, Mutability::Mut)), - |k| always_pat!(k, Ref(p, _) => *p), + |k| matches!(k, Ref(_, _, Mutability::Mut)), + |k| always_pat!(k, Ref(p, _, _) => *p), ), // Transform `b @ p0 | ... b @ p1` into `b @ (p0 | p1)`. Ident(b1, i1, Some(target)) => extend_with_matching( diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index ac80c9b39006..03cbb0311c6c 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -320,6 +320,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { self.body(field!(anon_const.body)); }, ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"), + ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"), } } @@ -743,10 +744,14 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { let ann = match ann { BindingMode::NONE => "NONE", BindingMode::REF => "REF", + BindingMode::REF_PIN => "REF_PIN", BindingMode::MUT => "MUT", BindingMode::REF_MUT => "REF_MUT", + BindingMode::REF_PIN_MUT => "REF_PIN_MUT", BindingMode::MUT_REF => "MUT_REF", + BindingMode::MUT_REF_PIN => "MUT_REF_PIN", BindingMode::MUT_REF_MUT => "MUT_REF_MUT", + BindingMode::MUT_REF_PIN_MUT => "MUT_REF_PIN_MUT", }; kind!("Binding(BindingMode::{ann}, _, {name}, {sub})"); self.ident(name); @@ -788,9 +793,9 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { kind!("Deref({pat})"); self.pat(pat); }, - PatKind::Ref(pat, muta) => { + PatKind::Ref(pat, pinn, muta) => { bind!(self, pat); - kind!("Ref({pat}, Mutability::{muta:?})"); + kind!("Ref({pat}, Pinning::{pinn:?}, Mutability::{muta:?})"); self.pat(pat); }, PatKind::Guard(pat, cond) => { diff --git a/clippy_utils/README.md b/clippy_utils/README.md index 45463b4fa1db..6f976094fc2d 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-10-31 +nightly-2025-11-14 ``` diff --git a/clippy_utils/src/ast_utils/mod.rs b/clippy_utils/src/ast_utils/mod.rs index 31416f12c698..9c08f7b4d80f 100644 --- a/clippy_utils/src/ast_utils/mod.rs +++ b/clippy_utils/src/ast_utils/mod.rs @@ -45,9 +45,8 @@ pub fn eq_pat(l: &Pat, r: &Pat) -> bool { && eq_expr_opt(lt.as_deref(), rt.as_deref()) && eq_range_end(&le.node, &re.node) }, - (Box(l), Box(r)) - | (Ref(l, Mutability::Not), Ref(r, Mutability::Not)) - | (Ref(l, Mutability::Mut), Ref(r, Mutability::Mut)) => eq_pat(l, r), + (Box(l), Box(r)) => eq_pat(l, r), + (Ref(l, l_pin, l_mut), Ref(r, r_pin, r_mut)) => l_pin == r_pin && l_mut == r_mut && eq_pat(l, r), (Tuple(l), Tuple(r)) | (Slice(l), Slice(r)) => over(l, r, eq_pat), (Path(lq, lp), Path(rq, rp)) => both(lq.as_deref(), rq.as_deref(), eq_qself) && eq_path(lp, rp), (TupleStruct(lqself, lp, lfs), TupleStruct(rqself, rp, rfs)) => { @@ -356,7 +355,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { ident: li, generics: lg, ty: lt, - expr: le, + rhs: lb, define_opaque: _, }), Const(box ConstItem { @@ -364,7 +363,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { ident: ri, generics: rg, ty: rt, - expr: re, + rhs: rb, define_opaque: _, }), ) => { @@ -372,7 +371,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { && eq_id(*li, *ri) && eq_generics(lg, rg) && eq_ty(lt, rt) - && eq_expr_opt(le.as_deref(), re.as_deref()) + && both(lb.as_ref(), rb.as_ref(), eq_const_item_rhs) }, ( Fn(box ast::Fn { @@ -471,8 +470,24 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { && over(lb, rb, eq_generic_bound) && over(lis, ris, |l, r| eq_item(l, r, eq_assoc_item_kind)) }, - (TraitAlias(li, lg, lb), TraitAlias(ri, rg, rb)) => { - eq_id(*li, *ri) && eq_generics(lg, rg) && over(lb, rb, eq_generic_bound) + ( + TraitAlias(box ast::TraitAlias { + ident: li, + generics: lg, + bounds: lb, + constness: lc, + }), + TraitAlias(box ast::TraitAlias { + ident: ri, + generics: rg, + bounds: rb, + constness: rc, + }), + ) => { + matches!(lc, ast::Const::No) == matches!(rc, ast::Const::No) + && eq_id(*li, *ri) + && eq_generics(lg, rg) + && over(lb, rb, eq_generic_bound) }, ( Impl(ast::Impl { @@ -594,7 +609,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { ident: li, generics: lg, ty: lt, - expr: le, + rhs: lb, define_opaque: _, }), Const(box ConstItem { @@ -602,7 +617,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { ident: ri, generics: rg, ty: rt, - expr: re, + rhs: rb, define_opaque: _, }), ) => { @@ -610,7 +625,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { && eq_id(*li, *ri) && eq_generics(lg, rg) && eq_ty(lt, rt) - && eq_expr_opt(le.as_deref(), re.as_deref()) + && both(lb.as_ref(), rb.as_ref(), eq_const_item_rhs) }, ( Fn(box ast::Fn { @@ -768,6 +783,15 @@ pub fn eq_anon_const(l: &AnonConst, r: &AnonConst) -> bool { eq_expr(&l.value, &r.value) } +pub fn eq_const_item_rhs(l: &ConstItemRhs, r: &ConstItemRhs) -> bool { + use ConstItemRhs::*; + match (l, r) { + (TypeConst(l), TypeConst(r)) => eq_anon_const(l, r), + (Body(l), Body(r)) => eq_expr(l, r), + (TypeConst(..), Body(..)) | (Body(..), TypeConst(..)) => false, + } +} + pub fn eq_use_tree_kind(l: &UseTreeKind, r: &UseTreeKind) -> bool { use UseTreeKind::*; match (l, r) { diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index 7b8c7f3f0d6b..7e3fa4f9909b 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -13,7 +13,10 @@ use rustc_apfloat::Float; use rustc_apfloat::ieee::{Half, Quad}; use rustc_ast::ast::{LitFloatType, LitKind}; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, PatExpr, PatExprKind, QPath, TyKind, UnOp}; +use rustc_hir::{ + BinOpKind, Block, ConstArgKind, ConstBlock, ConstItemRhs, Expr, ExprKind, HirId, PatExpr, PatExprKind, QPath, + TyKind, UnOp, +}; use rustc_lexer::{FrontmatterAllowed, tokenize}; use rustc_lint::LateContext; use rustc_middle::mir::ConstValue; @@ -1130,3 +1133,13 @@ pub fn integer_const(cx: &LateContext<'_>, expr: &Expr<'_>, ctxt: SyntaxContext) pub fn is_zero_integer_const(cx: &LateContext<'_>, expr: &Expr<'_>, ctxt: SyntaxContext) -> bool { integer_const(cx, expr, ctxt) == Some(0) } + +pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx>) -> Option<&'tcx Expr<'tcx>> { + match ct_rhs { + ConstItemRhs::Body(body_id) => Some(tcx.hir_body(body_id).value), + ConstItemRhs::TypeConst(const_arg) => match const_arg.kind { + ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value), + ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => None, + }, + } +} diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index 710b88e92154..b286701fbed1 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -8,9 +8,9 @@ use rustc_data_structures::fx::FxHasher; use rustc_hir::MatchSource::TryDesugar; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{ - AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr, ExprField, - ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeKind, - Node, Pat, PatExpr, PatExprKind, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, + AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, ByRef, Closure, ConstArg, ConstArgKind, Expr, + ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, + LifetimeKind, Node, Pat, PatExpr, PatExprKind, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, StructTailExpr, TraitBoundModifiers, Ty, TyKind, TyPat, TyPatKind, }; use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize}; @@ -480,8 +480,8 @@ impl HirEqInterExpr<'_, '_, '_> { // Use explicit match for now since ConstArg is undergoing flux. (ConstArgKind::Path(..), ConstArgKind::Anon(..)) | (ConstArgKind::Anon(..), ConstArgKind::Path(..)) - | (ConstArgKind::Infer(..), _) - | (_, ConstArgKind::Infer(..)) => false, + | (ConstArgKind::Infer(..) | ConstArgKind::Error(..), _) + | (_, ConstArgKind::Infer(..) | ConstArgKind::Error(..)) => false, } } @@ -536,7 +536,7 @@ impl HirEqInterExpr<'_, '_, '_> { && both(le.as_ref(), re.as_ref(), |a, b| self.eq_pat_expr(a, b)) && (li == ri) }, - (PatKind::Ref(le, lm), PatKind::Ref(re, rm)) => lm == rm && self.eq_pat(le, re), + (PatKind::Ref(le, lp, lm), PatKind::Ref(re, rp, rm)) => lp == rp && lm == rm && self.eq_pat(le, re), (PatKind::Slice(ls, li, le), PatKind::Slice(rs, ri, re)) => { over(ls, rs, |l, r| self.eq_pat(l, r)) && over(le, re, |l, r| self.eq_pat(l, r)) @@ -1129,6 +1129,10 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { PatKind::Missing => unreachable!(), PatKind::Binding(BindingMode(by_ref, mutability), _, _, pat) => { std::mem::discriminant(by_ref).hash(&mut self.s); + if let ByRef::Yes(pi, mu) = by_ref { + std::mem::discriminant(pi).hash(&mut self.s); + std::mem::discriminant(mu).hash(&mut self.s); + } std::mem::discriminant(mutability).hash(&mut self.s); if let Some(pat) = pat { self.hash_pat(pat); @@ -1150,8 +1154,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } std::mem::discriminant(i).hash(&mut self.s); }, - PatKind::Ref(pat, mu) => { + PatKind::Ref(pat, pi, mu) => { self.hash_pat(pat); + std::mem::discriminant(pi).hash(&mut self.s); std::mem::discriminant(mu).hash(&mut self.s); }, PatKind::Guard(pat, guard) => { @@ -1330,7 +1335,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { match &const_arg.kind { ConstArgKind::Path(path) => self.hash_qpath(path), ConstArgKind::Anon(anon) => self.hash_body(anon.body), - ConstArgKind::Infer(..) => {}, + ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {}, } } diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 46c5af058ccc..c9302b17eb7e 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -818,7 +818,7 @@ pub fn capture_local_usage(cx: &LateContext<'_>, e: &Expr<'_>) -> CaptureKind { ByRef::No if !is_copy(cx, cx.typeck_results().node_type(id)) => { capture = CaptureKind::Value; }, - ByRef::Yes(Mutability::Mut) if capture != CaptureKind::Value => { + ByRef::Yes(_, Mutability::Mut) if capture != CaptureKind::Value => { capture = CaptureKind::Ref(Mutability::Mut); }, _ => (), @@ -1498,7 +1498,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool { PatKind::Missing => unreachable!(), PatKind::Wild | PatKind::Never => false, // If `!` typechecked then the type is empty, so not refutable. PatKind::Binding(_, _, _, pat) => pat.is_some_and(|pat| is_refutable(cx, pat)), - PatKind::Box(pat) | PatKind::Ref(pat, _) => is_refutable(cx, pat), + PatKind::Box(pat) | PatKind::Ref(pat, _, _) => is_refutable(cx, pat), PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, @@ -1648,7 +1648,7 @@ pub fn is_lint_allowed(cx: &LateContext<'_>, lint: &'static Lint, id: HirId) -> } pub fn strip_pat_refs<'hir>(mut pat: &'hir Pat<'hir>) -> &'hir Pat<'hir> { - while let PatKind::Ref(subpat, _) = pat.kind { + while let PatKind::Ref(subpat, _, _) = pat.kind { pat = subpat; } pat @@ -1866,7 +1866,7 @@ pub fn is_expr_identity_of_pat(cx: &LateContext<'_>, pat: &Pat<'_>, expr: &Expr< .typeck_results() .pat_binding_modes() .get(pat.hir_id) - .is_some_and(|mode| matches!(mode.0, ByRef::Yes(_))) + .is_some_and(|mode| matches!(mode.0, ByRef::Yes(..))) { // If the parameter is `(x, y)` of type `&(T, T)`, or `[x, y]` of type `&[T; 2]`, then // due to match ergonomics, the inner patterns become references. Don't consider this @@ -2193,7 +2193,7 @@ where /// references removed. pub fn peel_hir_pat_refs<'a>(pat: &'a Pat<'a>) -> (&'a Pat<'a>, usize) { fn peel<'a>(pat: &'a Pat<'a>, count: usize) -> (&'a Pat<'a>, usize) { - if let PatKind::Ref(pat, _) = pat.kind { + if let PatKind::Ref(pat, _, _) = pat.kind { peel(pat, count + 1) } else { (pat, count) diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index 90ea2616890a..296da9fec8c0 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -194,8 +194,7 @@ fn check_rvalue<'tcx>( )) } }, - Rvalue::NullaryOp(NullOp::OffsetOf(_) | NullOp::UbChecks | NullOp::ContractChecks, _) - | Rvalue::ShallowInitBox(_, _) => Ok(()), + Rvalue::NullaryOp(NullOp::OffsetOf(_) | NullOp::RuntimeChecks(_), _) | Rvalue::ShallowInitBox(_, _) => Ok(()), Rvalue::UnaryOp(_, operand) => { let ty = operand.ty(body, cx.tcx); if ty.is_integral() || ty.is_bool() { diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index 72d8f6df8d05..1d1537dd0e91 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -167,7 +167,6 @@ generate! { from_ne_bytes, from_ptr, from_raw, - from_str, from_str_radix, fs, fuse, diff --git a/rust-toolchain.toml b/rust-toolchain.toml index d23fd74d9acc..f6809da98f2b 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,6 +1,6 @@ [toolchain] # begin autogenerated nightly -channel = "nightly-2025-10-31" +channel = "nightly-2025-11-14" # end autogenerated nightly components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] profile = "minimal" diff --git a/src/driver.rs b/src/driver.rs index 102ca3fa69f7..edbf92b8b060 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -13,10 +13,10 @@ extern crate rustc_interface; extern crate rustc_session; extern crate rustc_span; -// See docs in https://github.com/rust-lang/rust/blob/master/compiler/rustc/src/main.rs -// about jemalloc. +/// See docs in +/// and for why we need this `use` statement. #[cfg(feature = "jemalloc")] -extern crate tikv_jemalloc_sys as jemalloc_sys; +use tikv_jemalloc_sys as _; use clippy_utils::sym; use declare_clippy_lint::LintListBuilder; @@ -187,38 +187,7 @@ fn display_help() { const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/new?template=ice.yml"; -#[expect(clippy::too_many_lines)] pub fn main() { - // See docs in https://github.com/rust-lang/rust/blob/master/compiler/rustc/src/main.rs - // about jemalloc. - #[cfg(feature = "jemalloc")] - { - use std::os::raw::{c_int, c_void}; - - #[used] - static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; - #[used] - static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = jemalloc_sys::posix_memalign; - #[used] - static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; - #[used] - static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; - #[used] - static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; - #[used] - static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; - - #[cfg(target_os = "macos")] - { - unsafe extern "C" { - fn _rjem_je_zone_register(); - } - - #[used] - static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; - } - } - let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); rustc_driver::init_rustc_env_logger(&early_dcx); diff --git a/tests/ui/author/macro_in_closure.stdout b/tests/ui/author/macro_in_closure.stdout index 786c61e0c018..43753c3288c0 100644 --- a/tests/ui/author/macro_in_closure.stdout +++ b/tests/ui/author/macro_in_closure.stdout @@ -30,19 +30,16 @@ if let StmtKind::Let(local) = stmt.kind && let PatKind::Binding(BindingMode::NONE, _, name1, None) = local2.pat.kind && name1.as_str() == "args" && let Some(trailing_expr) = block1.expr - && let ExprKind::Call(func2, args2) = trailing_expr.kind - && paths::CORE_FMT_RT_NEW_V1.matches_path(cx, func2) // Add the path to `clippy_utils::paths` if needed + && let ExprKind::Block(block2, None) = trailing_expr.kind + && block2.stmts.is_empty() + && let Some(trailing_expr1) = block2.expr + && let ExprKind::Call(func2, args2) = trailing_expr1.kind + && paths::CORE_FMT_ARGUMENTS_NEW.matches_path(cx, func2) // Add the path to `clippy_utils::paths` if needed && args2.len() == 2 - && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args2[0].kind - && let ExprKind::Array(elements2) = inner1.kind - && elements2.len() == 2 - && let ExprKind::Lit(ref lit) = elements2[0].kind - && let LitKind::Str(s, _) = lit.node - && s.as_str() == "" - && let ExprKind::Lit(ref lit1) = elements2[1].kind - && let LitKind::Str(s1, _) = lit1.node - && s1.as_str() == "\n" - && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[1].kind + && let ExprKind::Lit(ref lit) = args2[0].kind + && let LitKind::ByteStr(ref vec) = lit.node + && let [[192, 1, 10, 0]] = **vec + && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args2[1].kind && block.expr.is_none() && let PatKind::Binding(BindingMode::NONE, _, name2, None) = local.pat.kind && name2.as_str() == "print_text" diff --git a/tests/ui/author/macro_in_loop.stdout b/tests/ui/author/macro_in_loop.stdout index ba3b7e244204..561a2dcbd7fe 100644 --- a/tests/ui/author/macro_in_loop.stdout +++ b/tests/ui/author/macro_in_loop.stdout @@ -41,19 +41,16 @@ if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::Fo && let PatKind::Binding(BindingMode::NONE, _, name2, None) = local1.pat.kind && name2.as_str() == "args" && let Some(trailing_expr) = block2.expr - && let ExprKind::Call(func2, args2) = trailing_expr.kind - && paths::CORE_FMT_RT_NEW_V1.matches_path(cx, func2) // Add the path to `clippy_utils::paths` if needed + && let ExprKind::Block(block3, None) = trailing_expr.kind + && block3.stmts.is_empty() + && let Some(trailing_expr1) = block3.expr + && let ExprKind::Call(func2, args2) = trailing_expr1.kind + && paths::CORE_FMT_ARGUMENTS_NEW.matches_path(cx, func2) // Add the path to `clippy_utils::paths` if needed && args2.len() == 2 - && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args2[0].kind - && let ExprKind::Array(elements2) = inner1.kind - && elements2.len() == 2 - && let ExprKind::Lit(ref lit2) = elements2[0].kind - && let LitKind::Str(s, _) = lit2.node - && s.as_str() == "" - && let ExprKind::Lit(ref lit3) = elements2[1].kind - && let LitKind::Str(s1, _) = lit3.node - && s1.as_str() == "\n" - && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[1].kind + && let ExprKind::Lit(ref lit2) = args2[0].kind + && let LitKind::ByteStr(ref vec) = lit2.node + && let [[192, 1, 10, 0]] = **vec + && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args2[1].kind && block1.expr.is_none() && block.expr.is_none() { diff --git a/tests/ui/bool_assert_comparison.stderr b/tests/ui/bool_assert_comparison.stderr index f823f08f31dc..72aa6303a202 100644 --- a/tests/ui/bool_assert_comparison.stderr +++ b/tests/ui/bool_assert_comparison.stderr @@ -272,10 +272,8 @@ LL | assert_eq!(a!(), true); | help: replace it with `assert!(..)` | -LL | true -... -LL | -LL ~ assert!(a!()); +LL - assert_eq!(a!(), true); +LL + assert!(a!()); | error: used `assert_eq!` with a literal bool @@ -286,10 +284,8 @@ LL | assert_eq!(true, b!()); | help: replace it with `assert!(..)` | -LL | true -... -LL | -LL ~ assert!(b!()); +LL - assert_eq!(true, b!()); +LL + assert!(b!()); | error: used `debug_assert_eq!` with a literal bool diff --git a/tests/ui/cast_enum_constructor.rs b/tests/ui/cast_enum_constructor.rs index eecf56f71a33..6d70387b6ce2 100644 --- a/tests/ui/cast_enum_constructor.rs +++ b/tests/ui/cast_enum_constructor.rs @@ -1,5 +1,5 @@ #![warn(clippy::cast_enum_constructor)] -#![allow(clippy::fn_to_numeric_cast)] +#![allow(clippy::fn_to_numeric_cast, function_casts_as_integer)] fn main() { enum Foo { diff --git a/tests/ui/confusing_method_to_numeric_cast.fixed b/tests/ui/confusing_method_to_numeric_cast.fixed index e698b99edd5c..b9691a3284ac 100644 --- a/tests/ui/confusing_method_to_numeric_cast.fixed +++ b/tests/ui/confusing_method_to_numeric_cast.fixed @@ -1,5 +1,6 @@ #![feature(float_minimum_maximum)] #![warn(clippy::confusing_method_to_numeric_cast)] +#![allow(function_casts_as_integer)] fn main() { let _ = u16::MAX as usize; //~ confusing_method_to_numeric_cast diff --git a/tests/ui/confusing_method_to_numeric_cast.rs b/tests/ui/confusing_method_to_numeric_cast.rs index ef65c21563d9..b402cbf92cb2 100644 --- a/tests/ui/confusing_method_to_numeric_cast.rs +++ b/tests/ui/confusing_method_to_numeric_cast.rs @@ -1,5 +1,6 @@ #![feature(float_minimum_maximum)] #![warn(clippy::confusing_method_to_numeric_cast)] +#![allow(function_casts_as_integer)] fn main() { let _ = u16::max as usize; //~ confusing_method_to_numeric_cast diff --git a/tests/ui/confusing_method_to_numeric_cast.stderr b/tests/ui/confusing_method_to_numeric_cast.stderr index ba90df2059af..0d5e08f88077 100644 --- a/tests/ui/confusing_method_to_numeric_cast.stderr +++ b/tests/ui/confusing_method_to_numeric_cast.stderr @@ -1,5 +1,5 @@ error: casting function pointer `u16::max` to `usize` - --> tests/ui/confusing_method_to_numeric_cast.rs:5:13 + --> tests/ui/confusing_method_to_numeric_cast.rs:6:13 | LL | let _ = u16::max as usize; | ^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL + let _ = u16::MAX as usize; | error: casting function pointer `u16::min` to `usize` - --> tests/ui/confusing_method_to_numeric_cast.rs:6:13 + --> tests/ui/confusing_method_to_numeric_cast.rs:7:13 | LL | let _ = u16::min as usize; | ^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + let _ = u16::MIN as usize; | error: casting function pointer `u16::max_value` to `usize` - --> tests/ui/confusing_method_to_numeric_cast.rs:7:13 + --> tests/ui/confusing_method_to_numeric_cast.rs:8:13 | LL | let _ = u16::max_value as usize; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + let _ = u16::MAX as usize; | error: casting function pointer `u16::min_value` to `usize` - --> tests/ui/confusing_method_to_numeric_cast.rs:8:13 + --> tests/ui/confusing_method_to_numeric_cast.rs:9:13 | LL | let _ = u16::min_value as usize; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + let _ = u16::MIN as usize; | error: casting function pointer `f32::maximum` to `usize` - --> tests/ui/confusing_method_to_numeric_cast.rs:10:13 + --> tests/ui/confusing_method_to_numeric_cast.rs:11:13 | LL | let _ = f32::maximum as usize; | ^^^^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + let _ = f32::MAX as usize; | error: casting function pointer `f32::max` to `usize` - --> tests/ui/confusing_method_to_numeric_cast.rs:11:13 + --> tests/ui/confusing_method_to_numeric_cast.rs:12:13 | LL | let _ = f32::max as usize; | ^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL + let _ = f32::MAX as usize; | error: casting function pointer `f32::minimum` to `usize` - --> tests/ui/confusing_method_to_numeric_cast.rs:12:13 + --> tests/ui/confusing_method_to_numeric_cast.rs:13:13 | LL | let _ = f32::minimum as usize; | ^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + let _ = f32::MIN as usize; | error: casting function pointer `f32::min` to `usize` - --> tests/ui/confusing_method_to_numeric_cast.rs:13:13 + --> tests/ui/confusing_method_to_numeric_cast.rs:14:13 | LL | let _ = f32::min as usize; | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/explicit_write_in_test.stderr b/tests/ui/explicit_write_in_test.stderr deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/ui/fn_to_numeric_cast.32bit.stderr b/tests/ui/fn_to_numeric_cast.32bit.stderr index 2affd0b7d6e9..86c189cb44cb 100644 --- a/tests/ui/fn_to_numeric_cast.32bit.stderr +++ b/tests/ui/fn_to_numeric_cast.32bit.stderr @@ -1,5 +1,5 @@ error: casting function pointer `foo` to `i8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:12:13 + --> tests/ui/fn_to_numeric_cast.rs:13:13 | LL | let _ = foo as i8; | ^^^^^^^^^ help: try: `foo as usize` @@ -8,13 +8,13 @@ LL | let _ = foo as i8; = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_with_truncation)]` error: casting function pointer `foo` to `i16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:14:13 + --> tests/ui/fn_to_numeric_cast.rs:15:13 | LL | let _ = foo as i16; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `i32` - --> tests/ui/fn_to_numeric_cast.rs:16:13 + --> tests/ui/fn_to_numeric_cast.rs:17:13 | LL | let _ = foo as i32; | ^^^^^^^^^^ help: try: `foo as usize` @@ -23,121 +23,121 @@ LL | let _ = foo as i32; = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast)]` error: casting function pointer `foo` to `i64` - --> tests/ui/fn_to_numeric_cast.rs:19:13 + --> tests/ui/fn_to_numeric_cast.rs:20:13 | LL | let _ = foo as i64; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `i128` - --> tests/ui/fn_to_numeric_cast.rs:21:13 + --> tests/ui/fn_to_numeric_cast.rs:22:13 | LL | let _ = foo as i128; | ^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `isize` - --> tests/ui/fn_to_numeric_cast.rs:23:13 + --> tests/ui/fn_to_numeric_cast.rs:24:13 | LL | let _ = foo as isize; | ^^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:26:13 + --> tests/ui/fn_to_numeric_cast.rs:27:13 | LL | let _ = foo as u8; | ^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:28:13 + --> tests/ui/fn_to_numeric_cast.rs:29:13 | LL | let _ = foo as u16; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u32` - --> tests/ui/fn_to_numeric_cast.rs:30:13 + --> tests/ui/fn_to_numeric_cast.rs:31:13 | LL | let _ = foo as u32; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u64` - --> tests/ui/fn_to_numeric_cast.rs:33:13 + --> tests/ui/fn_to_numeric_cast.rs:34:13 | LL | let _ = foo as u64; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u128` - --> tests/ui/fn_to_numeric_cast.rs:35:13 + --> tests/ui/fn_to_numeric_cast.rs:36:13 | LL | let _ = foo as u128; | ^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `abc` to `i8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:49:13 + --> tests/ui/fn_to_numeric_cast.rs:50:13 | LL | let _ = abc as i8; | ^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:51:13 + --> tests/ui/fn_to_numeric_cast.rs:52:13 | LL | let _ = abc as i16; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i32` - --> tests/ui/fn_to_numeric_cast.rs:53:13 + --> tests/ui/fn_to_numeric_cast.rs:54:13 | LL | let _ = abc as i32; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i64` - --> tests/ui/fn_to_numeric_cast.rs:56:13 + --> tests/ui/fn_to_numeric_cast.rs:57:13 | LL | let _ = abc as i64; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i128` - --> tests/ui/fn_to_numeric_cast.rs:58:13 + --> tests/ui/fn_to_numeric_cast.rs:59:13 | LL | let _ = abc as i128; | ^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `isize` - --> tests/ui/fn_to_numeric_cast.rs:60:13 + --> tests/ui/fn_to_numeric_cast.rs:61:13 | LL | let _ = abc as isize; | ^^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:63:13 + --> tests/ui/fn_to_numeric_cast.rs:64:13 | LL | let _ = abc as u8; | ^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:65:13 + --> tests/ui/fn_to_numeric_cast.rs:66:13 | LL | let _ = abc as u16; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u32` - --> tests/ui/fn_to_numeric_cast.rs:67:13 + --> tests/ui/fn_to_numeric_cast.rs:68:13 | LL | let _ = abc as u32; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u64` - --> tests/ui/fn_to_numeric_cast.rs:70:13 + --> tests/ui/fn_to_numeric_cast.rs:71:13 | LL | let _ = abc as u64; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u128` - --> tests/ui/fn_to_numeric_cast.rs:72:13 + --> tests/ui/fn_to_numeric_cast.rs:73:13 | LL | let _ = abc as u128; | ^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `f` to `i32` - --> tests/ui/fn_to_numeric_cast.rs:80:5 + --> tests/ui/fn_to_numeric_cast.rs:81:5 | LL | f as i32 | ^^^^^^^^ help: try: `f as usize` diff --git a/tests/ui/fn_to_numeric_cast.64bit.stderr b/tests/ui/fn_to_numeric_cast.64bit.stderr index 48961d14f2bb..694690ae5bfa 100644 --- a/tests/ui/fn_to_numeric_cast.64bit.stderr +++ b/tests/ui/fn_to_numeric_cast.64bit.stderr @@ -1,5 +1,5 @@ error: casting function pointer `foo` to `i8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:12:13 + --> tests/ui/fn_to_numeric_cast.rs:13:13 | LL | let _ = foo as i8; | ^^^^^^^^^ help: try: `foo as usize` @@ -8,19 +8,19 @@ LL | let _ = foo as i8; = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_with_truncation)]` error: casting function pointer `foo` to `i16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:14:13 + --> tests/ui/fn_to_numeric_cast.rs:15:13 | LL | let _ = foo as i16; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `i32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:16:13 + --> tests/ui/fn_to_numeric_cast.rs:17:13 | LL | let _ = foo as i32; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `i64` - --> tests/ui/fn_to_numeric_cast.rs:19:13 + --> tests/ui/fn_to_numeric_cast.rs:20:13 | LL | let _ = foo as i64; | ^^^^^^^^^^ help: try: `foo as usize` @@ -29,115 +29,115 @@ LL | let _ = foo as i64; = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast)]` error: casting function pointer `foo` to `i128` - --> tests/ui/fn_to_numeric_cast.rs:21:13 + --> tests/ui/fn_to_numeric_cast.rs:22:13 | LL | let _ = foo as i128; | ^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `isize` - --> tests/ui/fn_to_numeric_cast.rs:23:13 + --> tests/ui/fn_to_numeric_cast.rs:24:13 | LL | let _ = foo as isize; | ^^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:26:13 + --> tests/ui/fn_to_numeric_cast.rs:27:13 | LL | let _ = foo as u8; | ^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:28:13 + --> tests/ui/fn_to_numeric_cast.rs:29:13 | LL | let _ = foo as u16; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:30:13 + --> tests/ui/fn_to_numeric_cast.rs:31:13 | LL | let _ = foo as u32; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u64` - --> tests/ui/fn_to_numeric_cast.rs:33:13 + --> tests/ui/fn_to_numeric_cast.rs:34:13 | LL | let _ = foo as u64; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u128` - --> tests/ui/fn_to_numeric_cast.rs:35:13 + --> tests/ui/fn_to_numeric_cast.rs:36:13 | LL | let _ = foo as u128; | ^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `abc` to `i8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:49:13 + --> tests/ui/fn_to_numeric_cast.rs:50:13 | LL | let _ = abc as i8; | ^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:51:13 + --> tests/ui/fn_to_numeric_cast.rs:52:13 | LL | let _ = abc as i16; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:53:13 + --> tests/ui/fn_to_numeric_cast.rs:54:13 | LL | let _ = abc as i32; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i64` - --> tests/ui/fn_to_numeric_cast.rs:56:13 + --> tests/ui/fn_to_numeric_cast.rs:57:13 | LL | let _ = abc as i64; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i128` - --> tests/ui/fn_to_numeric_cast.rs:58:13 + --> tests/ui/fn_to_numeric_cast.rs:59:13 | LL | let _ = abc as i128; | ^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `isize` - --> tests/ui/fn_to_numeric_cast.rs:60:13 + --> tests/ui/fn_to_numeric_cast.rs:61:13 | LL | let _ = abc as isize; | ^^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:63:13 + --> tests/ui/fn_to_numeric_cast.rs:64:13 | LL | let _ = abc as u8; | ^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:65:13 + --> tests/ui/fn_to_numeric_cast.rs:66:13 | LL | let _ = abc as u16; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:67:13 + --> tests/ui/fn_to_numeric_cast.rs:68:13 | LL | let _ = abc as u32; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u64` - --> tests/ui/fn_to_numeric_cast.rs:70:13 + --> tests/ui/fn_to_numeric_cast.rs:71:13 | LL | let _ = abc as u64; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u128` - --> tests/ui/fn_to_numeric_cast.rs:72:13 + --> tests/ui/fn_to_numeric_cast.rs:73:13 | LL | let _ = abc as u128; | ^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `f` to `i32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:80:5 + --> tests/ui/fn_to_numeric_cast.rs:81:5 | LL | f as i32 | ^^^^^^^^ help: try: `f as usize` diff --git a/tests/ui/fn_to_numeric_cast.rs b/tests/ui/fn_to_numeric_cast.rs index f53cbacdb377..0a07aeff366e 100644 --- a/tests/ui/fn_to_numeric_cast.rs +++ b/tests/ui/fn_to_numeric_cast.rs @@ -3,6 +3,7 @@ //@[64bit]ignore-bitwidth: 32 //@no-rustfix #![warn(clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation)] +#![allow(function_casts_as_integer)] fn foo() -> String { String::new() diff --git a/tests/ui/fn_to_numeric_cast_any.rs b/tests/ui/fn_to_numeric_cast_any.rs index 42f2128cd378..83c1e9a8387e 100644 --- a/tests/ui/fn_to_numeric_cast_any.rs +++ b/tests/ui/fn_to_numeric_cast_any.rs @@ -1,5 +1,6 @@ #![warn(clippy::fn_to_numeric_cast_any)] #![allow(clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation)] +#![allow(function_casts_as_integer)] //@no-rustfix fn foo() -> u8 { 0 diff --git a/tests/ui/fn_to_numeric_cast_any.stderr b/tests/ui/fn_to_numeric_cast_any.stderr index 58fac2d406a0..f7c49b8ff88b 100644 --- a/tests/ui/fn_to_numeric_cast_any.stderr +++ b/tests/ui/fn_to_numeric_cast_any.stderr @@ -1,5 +1,5 @@ error: casting function pointer `foo` to `i8` - --> tests/ui/fn_to_numeric_cast_any.rs:23:13 + --> tests/ui/fn_to_numeric_cast_any.rs:24:13 | LL | let _ = foo as i8; | ^^^^^^^^^ @@ -12,7 +12,7 @@ LL | let _ = foo() as i8; | ++ error: casting function pointer `foo` to `i16` - --> tests/ui/fn_to_numeric_cast_any.rs:26:13 + --> tests/ui/fn_to_numeric_cast_any.rs:27:13 | LL | let _ = foo as i16; | ^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | let _ = foo() as i16; | ++ error: casting function pointer `foo` to `i32` - --> tests/ui/fn_to_numeric_cast_any.rs:29:13 + --> tests/ui/fn_to_numeric_cast_any.rs:30:13 | LL | let _ = foo as i32; | ^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = foo() as i32; | ++ error: casting function pointer `foo` to `i64` - --> tests/ui/fn_to_numeric_cast_any.rs:32:13 + --> tests/ui/fn_to_numeric_cast_any.rs:33:13 | LL | let _ = foo as i64; | ^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | let _ = foo() as i64; | ++ error: casting function pointer `foo` to `i128` - --> tests/ui/fn_to_numeric_cast_any.rs:35:13 + --> tests/ui/fn_to_numeric_cast_any.rs:36:13 | LL | let _ = foo as i128; | ^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | let _ = foo() as i128; | ++ error: casting function pointer `foo` to `isize` - --> tests/ui/fn_to_numeric_cast_any.rs:38:13 + --> tests/ui/fn_to_numeric_cast_any.rs:39:13 | LL | let _ = foo as isize; | ^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | let _ = foo() as isize; | ++ error: casting function pointer `foo` to `u8` - --> tests/ui/fn_to_numeric_cast_any.rs:41:13 + --> tests/ui/fn_to_numeric_cast_any.rs:42:13 | LL | let _ = foo as u8; | ^^^^^^^^^ @@ -78,7 +78,7 @@ LL | let _ = foo() as u8; | ++ error: casting function pointer `foo` to `u16` - --> tests/ui/fn_to_numeric_cast_any.rs:44:13 + --> tests/ui/fn_to_numeric_cast_any.rs:45:13 | LL | let _ = foo as u16; | ^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | let _ = foo() as u16; | ++ error: casting function pointer `foo` to `u32` - --> tests/ui/fn_to_numeric_cast_any.rs:47:13 + --> tests/ui/fn_to_numeric_cast_any.rs:48:13 | LL | let _ = foo as u32; | ^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | let _ = foo() as u32; | ++ error: casting function pointer `foo` to `u64` - --> tests/ui/fn_to_numeric_cast_any.rs:50:13 + --> tests/ui/fn_to_numeric_cast_any.rs:51:13 | LL | let _ = foo as u64; | ^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | let _ = foo() as u64; | ++ error: casting function pointer `foo` to `u128` - --> tests/ui/fn_to_numeric_cast_any.rs:53:13 + --> tests/ui/fn_to_numeric_cast_any.rs:54:13 | LL | let _ = foo as u128; | ^^^^^^^^^^^ @@ -122,7 +122,7 @@ LL | let _ = foo() as u128; | ++ error: casting function pointer `foo` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:56:13 + --> tests/ui/fn_to_numeric_cast_any.rs:57:13 | LL | let _ = foo as usize; | ^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | let _ = foo() as usize; | ++ error: casting function pointer `Struct::static_method` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:61:13 + --> tests/ui/fn_to_numeric_cast_any.rs:62:13 | LL | let _ = Struct::static_method as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -144,7 +144,7 @@ LL | let _ = Struct::static_method() as usize; | ++ error: casting function pointer `f` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:66:5 + --> tests/ui/fn_to_numeric_cast_any.rs:67:5 | LL | f as usize | ^^^^^^^^^^ @@ -155,7 +155,7 @@ LL | f() as usize | ++ error: casting function pointer `T::static_method` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:71:5 + --> tests/ui/fn_to_numeric_cast_any.rs:72:5 | LL | T::static_method as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +166,7 @@ LL | T::static_method() as usize | ++ error: casting function pointer `(clos as fn(u32) -> u32)` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:78:13 + --> tests/ui/fn_to_numeric_cast_any.rs:79:13 | LL | let _ = (clos as fn(u32) -> u32) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -177,7 +177,7 @@ LL | let _ = (clos as fn(u32) -> u32)() as usize; | ++ error: casting function pointer `foo` to `*const ()` - --> tests/ui/fn_to_numeric_cast_any.rs:83:13 + --> tests/ui/fn_to_numeric_cast_any.rs:84:13 | LL | let _ = foo as *const (); | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/new_without_default.stderr b/tests/ui/new_without_default.stderr index 1e0d5e213199..0593dbb00fb6 100644 --- a/tests/ui/new_without_default.stderr +++ b/tests/ui/new_without_default.stderr @@ -191,7 +191,6 @@ LL + fn default() -> Self { LL + Self::new() LL + } LL + } -LL | impl NewWithCfg { | error: you should consider adding a `Default` implementation for `NewWith2Cfgs` @@ -212,7 +211,6 @@ LL + fn default() -> Self { LL + Self::new() LL + } LL + } -LL | impl NewWith2Cfgs { | error: you should consider adding a `Default` implementation for `NewWithExtraneous` @@ -250,7 +248,6 @@ LL + fn default() -> Self { LL + Self::new() LL + } LL + } -LL | impl NewWithCfgAndExtraneous { | error: aborting due to 13 previous errors diff --git a/tests/ui/ptr_eq.fixed b/tests/ui/ptr_eq.fixed index 9629b3eea587..d3624a129b5f 100644 --- a/tests/ui/ptr_eq.fixed +++ b/tests/ui/ptr_eq.fixed @@ -1,4 +1,5 @@ #![warn(clippy::ptr_eq)] +#![allow(function_casts_as_integer)] macro_rules! mac { ($a:expr, $b:expr) => { diff --git a/tests/ui/ptr_eq.rs b/tests/ui/ptr_eq.rs index 2b741d8df468..f06a99cabc81 100644 --- a/tests/ui/ptr_eq.rs +++ b/tests/ui/ptr_eq.rs @@ -1,4 +1,5 @@ #![warn(clippy::ptr_eq)] +#![allow(function_casts_as_integer)] macro_rules! mac { ($a:expr, $b:expr) => { diff --git a/tests/ui/ptr_eq.stderr b/tests/ui/ptr_eq.stderr index e7340624b595..f6be4c3f016b 100644 --- a/tests/ui/ptr_eq.stderr +++ b/tests/ui/ptr_eq.stderr @@ -1,5 +1,5 @@ error: use `std::ptr::eq` when comparing raw pointers - --> tests/ui/ptr_eq.rs:22:13 + --> tests/ui/ptr_eq.rs:23:13 | LL | let _ = a as *const _ as usize == b as *const _ as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a, b)` @@ -8,31 +8,31 @@ LL | let _ = a as *const _ as usize == b as *const _ as usize; = help: to override `-D warnings` add `#[allow(clippy::ptr_eq)]` error: use `std::ptr::eq` when comparing raw pointers - --> tests/ui/ptr_eq.rs:24:13 + --> tests/ui/ptr_eq.rs:25:13 | LL | let _ = a as *const _ == b as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a, b)` error: use `std::ptr::eq` when comparing raw pointers - --> tests/ui/ptr_eq.rs:50:13 + --> tests/ui/ptr_eq.rs:51:13 | LL | let _ = x as *const u32 == y as *mut u32 as *const u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(x, y)` error: use `std::ptr::eq` when comparing raw pointers - --> tests/ui/ptr_eq.rs:53:13 + --> tests/ui/ptr_eq.rs:54:13 | LL | let _ = x as *const u32 != y as *mut u32 as *const u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!std::ptr::eq(x, y)` error: use `std::ptr::eq` when comparing raw pointers - --> tests/ui/ptr_eq.rs:61:13 + --> tests/ui/ptr_eq.rs:62:13 | LL | let _ = mac!(cast a) as *const _ == mac!(cast b) as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(mac!(cast a), mac!(cast b))` error: use `std::ptr::eq` when comparing raw pointers - --> tests/ui/ptr_eq.rs:65:13 + --> tests/ui/ptr_eq.rs:66:13 | LL | let _ = mac!(cast a) as *const _ == mac!(cast b) as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(mac!(cast a), mac!(cast b))` diff --git a/tests/ui/trait_duplication_in_bounds.fixed b/tests/ui/trait_duplication_in_bounds.fixed index 88ba5f810b4e..959f5db11265 100644 --- a/tests/ui/trait_duplication_in_bounds.fixed +++ b/tests/ui/trait_duplication_in_bounds.fixed @@ -1,6 +1,6 @@ #![deny(clippy::trait_duplication_in_bounds)] #![allow(unused)] -#![feature(associated_const_equality, const_trait_impl)] +#![feature(const_trait_impl)] use std::any::Any; @@ -194,12 +194,3 @@ where T: Iterator + Iterator, { } -trait AssocConstTrait { - const ASSOC: usize; -} -fn assoc_const_args() -where - T: AssocConstTrait, - //~^ trait_duplication_in_bounds -{ -} diff --git a/tests/ui/trait_duplication_in_bounds.rs b/tests/ui/trait_duplication_in_bounds.rs index 19a4e70e294e..9bfecf40fc03 100644 --- a/tests/ui/trait_duplication_in_bounds.rs +++ b/tests/ui/trait_duplication_in_bounds.rs @@ -1,6 +1,6 @@ #![deny(clippy::trait_duplication_in_bounds)] #![allow(unused)] -#![feature(associated_const_equality, const_trait_impl)] +#![feature(const_trait_impl)] use std::any::Any; @@ -194,12 +194,3 @@ where T: Iterator + Iterator, { } -trait AssocConstTrait { - const ASSOC: usize; -} -fn assoc_const_args() -where - T: AssocConstTrait + AssocConstTrait, - //~^ trait_duplication_in_bounds -{ -} diff --git a/tests/ui/trait_duplication_in_bounds.stderr b/tests/ui/trait_duplication_in_bounds.stderr index a56a683de973..93488ea8e74d 100644 --- a/tests/ui/trait_duplication_in_bounds.stderr +++ b/tests/ui/trait_duplication_in_bounds.stderr @@ -70,11 +70,5 @@ error: these where clauses contain repeated elements LL | T: IntoIterator + IntoIterator, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `IntoIterator` -error: these where clauses contain repeated elements - --> tests/ui/trait_duplication_in_bounds.rs:202:8 - | -LL | T: AssocConstTrait + AssocConstTrait, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `AssocConstTrait` - -error: aborting due to 12 previous errors +error: aborting due to 11 previous errors diff --git a/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed b/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed new file mode 100644 index 000000000000..f2bd306a99e4 --- /dev/null +++ b/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed @@ -0,0 +1,14 @@ +#![deny(clippy::trait_duplication_in_bounds)] +#![expect(incomplete_features)] +#![feature(associated_const_equality, min_generic_const_args)] + +trait AssocConstTrait { + #[type_const] + const ASSOC: usize; +} +fn assoc_const_args() +where + T: AssocConstTrait, + //~^ trait_duplication_in_bounds +{ +} diff --git a/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs b/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs new file mode 100644 index 000000000000..8e7d843a44c0 --- /dev/null +++ b/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs @@ -0,0 +1,14 @@ +#![deny(clippy::trait_duplication_in_bounds)] +#![expect(incomplete_features)] +#![feature(associated_const_equality, min_generic_const_args)] + +trait AssocConstTrait { + #[type_const] + const ASSOC: usize; +} +fn assoc_const_args() +where + T: AssocConstTrait + AssocConstTrait, + //~^ trait_duplication_in_bounds +{ +} diff --git a/tests/ui/trait_duplication_in_bounds_assoc_const_eq.stderr b/tests/ui/trait_duplication_in_bounds_assoc_const_eq.stderr new file mode 100644 index 000000000000..accc4d7b5bb8 --- /dev/null +++ b/tests/ui/trait_duplication_in_bounds_assoc_const_eq.stderr @@ -0,0 +1,14 @@ +error: these where clauses contain repeated elements + --> tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs:11:8 + | +LL | T: AssocConstTrait + AssocConstTrait, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `AssocConstTrait` + | +note: the lint level is defined here + --> tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs:1:9 + | +LL | #![deny(clippy::trait_duplication_in_bounds)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/transmutes_expressible_as_ptr_casts.fixed b/tests/ui/transmutes_expressible_as_ptr_casts.fixed index 02f67f79e2b1..f332e02a2d32 100644 --- a/tests/ui/transmutes_expressible_as_ptr_casts.fixed +++ b/tests/ui/transmutes_expressible_as_ptr_casts.fixed @@ -4,6 +4,7 @@ #![warn(clippy::useless_transmute)] #![warn(clippy::transmute_ptr_to_ptr)] #![allow(unused, clippy::borrow_as_ptr, clippy::missing_transmute_annotations)] +#![allow(function_casts_as_integer)] use std::mem::{size_of, transmute}; diff --git a/tests/ui/transmutes_expressible_as_ptr_casts.rs b/tests/ui/transmutes_expressible_as_ptr_casts.rs index c5e156405ebc..c29a42ddca53 100644 --- a/tests/ui/transmutes_expressible_as_ptr_casts.rs +++ b/tests/ui/transmutes_expressible_as_ptr_casts.rs @@ -4,6 +4,7 @@ #![warn(clippy::useless_transmute)] #![warn(clippy::transmute_ptr_to_ptr)] #![allow(unused, clippy::borrow_as_ptr, clippy::missing_transmute_annotations)] +#![allow(function_casts_as_integer)] use std::mem::{size_of, transmute}; diff --git a/tests/ui/transmutes_expressible_as_ptr_casts.stderr b/tests/ui/transmutes_expressible_as_ptr_casts.stderr index f39a64d57eb4..5ddc3de6a039 100644 --- a/tests/ui/transmutes_expressible_as_ptr_casts.stderr +++ b/tests/ui/transmutes_expressible_as_ptr_casts.stderr @@ -1,5 +1,5 @@ error: transmute from a pointer to a pointer - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:19:38 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:20:38 | LL | let _ptr_i8_transmute = unsafe { transmute::<*const i32, *const i8>(ptr_i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL + let _ptr_i8_transmute = unsafe { ptr_i32.cast::() }; | error: transmute from a pointer to a pointer - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:26:46 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:27:46 | LL | let _ptr_to_unsized_transmute = unsafe { transmute::<*const [i32], *const [u32]>(slice_ptr) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + let _ptr_to_unsized_transmute = unsafe { slice_ptr as *const [u32] }; | error: transmute from `*const i32` to `usize` which could be expressed as a pointer cast instead - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:33:50 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:34:50 | LL | let _usize_from_int_ptr_transmute = unsafe { transmute::<*const i32, usize>(ptr_i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ptr_i32 as usize` @@ -34,7 +34,7 @@ LL | let _usize_from_int_ptr_transmute = unsafe { transmute::<*const i32, us = help: to override `-D warnings` add `#[allow(clippy::transmutes_expressible_as_ptr_casts)]` error: transmute from a reference to a pointer - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:40:41 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:41:41 | LL | let _array_ptr_transmute = unsafe { transmute::<&[i32; 4], *const [i32; 4]>(array_ref) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `array_ref as *const [i32; 4]` @@ -43,31 +43,31 @@ LL | let _array_ptr_transmute = unsafe { transmute::<&[i32; 4], *const [i32; = help: to override `-D warnings` add `#[allow(clippy::useless_transmute)]` error: transmute from `fn(usize) -> u8` to `*const usize` which could be expressed as a pointer cast instead - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:49:41 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:50:41 | LL | let _usize_ptr_transmute = unsafe { transmute:: u8, *const usize>(foo) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `foo as *const usize` error: transmute from `fn(usize) -> u8` to `usize` which could be expressed as a pointer cast instead - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:54:49 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:55:49 | LL | let _usize_from_fn_ptr_transmute = unsafe { transmute:: u8, usize>(foo) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `foo as usize` error: transmute from `*const u32` to `usize` which could be expressed as a pointer cast instead - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:58:36 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:59:36 | LL | let _usize_from_ref = unsafe { transmute::<*const u32, usize>(&1u32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&1u32 as *const u32 as usize` error: transmute from a reference to a pointer - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:70:14 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:71:14 | LL | unsafe { transmute::<&[i32; 1], *const u8>(in_param) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `in_param as *const [i32; 1] as *const u8` error: transmute from `fn()` to `*const u8` which could be expressed as a pointer cast instead - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:89:28 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:90:28 | LL | let _x: u8 = unsafe { *std::mem::transmute::(f) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(f as *const u8)`