diff options
| author | Philipp Krones <hello@philkrones.com> | 2025-08-22 12:36:32 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-22 12:36:32 +0000 |
| commit | 877967959ae8da9814df4f2614971f4d784bf53f (patch) | |
| tree | 0f00bf40e511e7ccb07ba358f477d4db7139f081 | |
| parent | 6d89c55e1a21d5a147373f2161473294860c9665 (diff) | |
| parent | 60374e257a224b46ef19eaebb23cf6e7be9ab4d9 (diff) | |
| download | rust-877967959ae8da9814df4f2614971f4d784bf53f.tar.gz rust-877967959ae8da9814df4f2614971f4d784bf53f.zip | |
Rustup (#15531)
Letting rustbot assign a reviewer, so that someone can double check 9de86f40d7e1a2cbcc308e39fdbc7447d691c527. changelog: none
58 files changed, 430 insertions, 305 deletions
diff --git a/Cargo.toml b/Cargo.toml index 9e250774631..2add525b7e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,3 +71,7 @@ harness = false # without increasing total build times. [profile.dev.package.quine-mc_cluskey] opt-level = 3 + +[lints.rust.unexpected_cfgs] +level = "warn" +check-cfg = ['cfg(bootstrap)'] diff --git a/clippy_lints/src/arbitrary_source_item_ordering.rs b/clippy_lints/src/arbitrary_source_item_ordering.rs index d6469d32931..36498adff50 100644 --- a/clippy_lints/src/arbitrary_source_item_ordering.rs +++ b/clippy_lints/src/arbitrary_source_item_ordering.rs @@ -534,6 +534,7 @@ fn get_item_name(item: &Item<'_>) -> Option<String> { if let Some(of_trait) = im.of_trait { let mut trait_segs: Vec<String> = of_trait + .trait_ref .path .segments .iter() diff --git a/clippy_lints/src/bool_assert_comparison.rs b/clippy_lints/src/bool_assert_comparison.rs index 581fe33ea0b..f31b67f470f 100644 --- a/clippy_lints/src/bool_assert_comparison.rs +++ b/clippy_lints/src/bool_assert_comparison.rs @@ -130,18 +130,22 @@ impl<'tcx> LateLintPass<'tcx> for BoolAssertComparison { let mut suggestions = vec![(name_span, non_eq_mac.to_string()), (lit_span, String::new())]; - if bool_value ^ eq_macro { - let Some(sugg) = Sugg::hir_opt(cx, non_lit_expr) else { - return; + if let Some(sugg) = Sugg::hir_opt(cx, non_lit_expr) { + let sugg = if bool_value ^ eq_macro { + !sugg.maybe_paren() + } else if ty::Bool == *non_lit_ty.kind() { + sugg + } else { + !!sugg.maybe_paren() }; - suggestions.push((non_lit_expr.span, (!sugg).to_string())); - } + suggestions.push((non_lit_expr.span, sugg.to_string())); - diag.multipart_suggestion( - format!("replace it with `{non_eq_mac}!(..)`"), - suggestions, - Applicability::MachineApplicable, - ); + diag.multipart_suggestion( + format!("replace it with `{non_eq_mac}!(..)`"), + suggestions, + Applicability::MachineApplicable, + ); + } }, ); } diff --git a/clippy_lints/src/copy_iterator.rs b/clippy_lints/src/copy_iterator.rs index 4ecf3e41611..51aebd8b0cf 100644 --- a/clippy_lints/src/copy_iterator.rs +++ b/clippy_lints/src/copy_iterator.rs @@ -37,12 +37,12 @@ declare_lint_pass!(CopyIterator => [COPY_ITERATOR]); impl<'tcx> LateLintPass<'tcx> for CopyIterator { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if let ItemKind::Impl(Impl { - of_trait: Some(trait_ref), + of_trait: Some(of_trait), .. }) = item.kind && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() && is_copy(cx, ty) - && let Some(trait_id) = trait_ref.trait_def_id() + && let Some(trait_id) = of_trait.trait_ref.trait_def_id() && cx.tcx.is_diagnostic_item(sym::Iterator, trait_id) { span_lint_and_note( diff --git a/clippy_lints/src/derivable_impls.rs b/clippy_lints/src/derivable_impls.rs index 0a481ddcd12..7580d6cab66 100644 --- a/clippy_lints/src/derivable_impls.rs +++ b/clippy_lints/src/derivable_impls.rs @@ -183,14 +183,14 @@ fn check_enum<'tcx>(cx: &LateContext<'tcx>, item: &'tcx Item<'_>, func_expr: &Ex impl<'tcx> LateLintPass<'tcx> for DerivableImpls { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if let ItemKind::Impl(Impl { - of_trait: Some(trait_ref), + of_trait: Some(of_trait), items: [child], self_ty, .. }) = item.kind && !cx.tcx.is_automatically_derived(item.owner_id.to_def_id()) && !item.span.from_expansion() - && let Some(def_id) = trait_ref.trait_def_id() + && let Some(def_id) = of_trait.trait_ref.trait_def_id() && cx.tcx.is_diagnostic_item(sym::Default, def_id) && let impl_item_hir = child.hir_id() && let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir) diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs index 49dd1bb09c6..c53a957f6a8 100644 --- a/clippy_lints/src/derive.rs +++ b/clippy_lints/src/derive.rs @@ -201,10 +201,11 @@ declare_lint_pass!(Derive => [ impl<'tcx> LateLintPass<'tcx> for Derive { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if let ItemKind::Impl(Impl { - of_trait: Some(trait_ref), + of_trait: Some(of_trait), .. }) = item.kind { + let trait_ref = &of_trait.trait_ref; let ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); let is_automatically_derived = cx.tcx.is_automatically_derived(item.owner_id.to_def_id()); diff --git a/clippy_lints/src/duplicate_mod.rs b/clippy_lints/src/duplicate_mod.rs index ce551a64d99..759b7b6837b 100644 --- a/clippy_lints/src/duplicate_mod.rs +++ b/clippy_lints/src/duplicate_mod.rs @@ -63,7 +63,7 @@ impl_lint_pass!(DuplicateMod => [DUPLICATE_MOD]); impl EarlyLintPass for DuplicateMod { fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { - if let ItemKind::Mod(_, _, ModKind::Loaded(_, Inline::No, mod_spans, _)) = &item.kind + if let ItemKind::Mod(_, _, ModKind::Loaded(_, Inline::No { .. }, mod_spans)) = &item.kind && let FileName::Real(real) = cx.sess().source_map().span_to_filename(mod_spans.inner_span) && let Some(local_path) = real.into_local_path() && let Ok(absolute_path) = local_path.canonicalize() diff --git a/clippy_lints/src/empty_drop.rs b/clippy_lints/src/empty_drop.rs index 4e948701da4..2b822188434 100644 --- a/clippy_lints/src/empty_drop.rs +++ b/clippy_lints/src/empty_drop.rs @@ -36,11 +36,11 @@ declare_lint_pass!(EmptyDrop => [EMPTY_DROP]); impl LateLintPass<'_> for EmptyDrop { fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { if let ItemKind::Impl(Impl { - of_trait: Some(trait_ref), + of_trait: Some(of_trait), items: [child], .. }) = item.kind - && trait_ref.trait_def_id() == cx.tcx.lang_items().drop_trait() + && of_trait.trait_ref.trait_def_id() == cx.tcx.lang_items().drop_trait() && let impl_item_hir = child.hir_id() && let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir) && let ImplItemKind::Fn(_, b) = &impl_item.kind diff --git a/clippy_lints/src/empty_line_after.rs b/clippy_lints/src/empty_line_after.rs index 3bd74856165..76e67b1154b 100644 --- a/clippy_lints/src/empty_line_after.rs +++ b/clippy_lints/src/empty_line_after.rs @@ -442,7 +442,7 @@ impl EmptyLineAfter { None => span.shrink_to_lo(), }, mod_items: match kind { - ItemKind::Mod(_, _, ModKind::Loaded(items, _, _, _)) => items + ItemKind::Mod(_, _, ModKind::Loaded(items, _, _)) => items .iter() .filter(|i| !matches!(i.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_))) .map(|i| i.id) diff --git a/clippy_lints/src/error_impl_error.rs b/clippy_lints/src/error_impl_error.rs index 6525648efb1..3018e1f1273 100644 --- a/clippy_lints/src/error_impl_error.rs +++ b/clippy_lints/src/error_impl_error.rs @@ -52,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for ErrorImplError { ); }, ItemKind::Impl(imp) - if let Some(trait_def_id) = imp.of_trait.and_then(|t| t.trait_def_id()) + if let Some(trait_def_id) = imp.of_trait.and_then(|t| t.trait_ref.trait_def_id()) && let Some(error_def_id) = cx.tcx.get_diagnostic_item(sym::Error) && error_def_id == trait_def_id && let Some(def_id) = path_res(cx, imp.self_ty).opt_def_id().and_then(DefId::as_local) diff --git a/clippy_lints/src/excessive_nesting.rs b/clippy_lints/src/excessive_nesting.rs index 1d3ae894944..5368701c304 100644 --- a/clippy_lints/src/excessive_nesting.rs +++ b/clippy_lints/src/excessive_nesting.rs @@ -164,7 +164,7 @@ impl Visitor<'_> for NestingVisitor<'_, '_> { } match &item.kind { - ItemKind::Trait(_) | ItemKind::Impl(_) | ItemKind::Mod(.., ModKind::Loaded(_, Inline::Yes, _, _)) => { + ItemKind::Trait(_) | ItemKind::Impl(_) | ItemKind::Mod(.., ModKind::Loaded(_, Inline::Yes, _)) => { self.nest_level += 1; if !self.check_indent(item.span, item.id) { diff --git a/clippy_lints/src/format_impl.rs b/clippy_lints/src/format_impl.rs index 0535ecf5240..416aea51ea1 100644 --- a/clippy_lints/src/format_impl.rs +++ b/clippy_lints/src/format_impl.rs @@ -254,10 +254,10 @@ fn is_format_trait_impl(cx: &LateContext<'_>, impl_item: &ImplItem<'_>) -> Optio if impl_item.ident.name == sym::fmt && let ImplItemKind::Fn(_, body_id) = impl_item.kind && let Some(Impl { - of_trait: Some(trait_ref), + of_trait: Some(of_trait), .. }) = get_parent_as_impl(cx.tcx, impl_item.hir_id()) - && let Some(did) = trait_ref.trait_def_id() + && let Some(did) = of_trait.trait_ref.trait_def_id() && let Some(name) = cx.tcx.get_diagnostic_name(did) && matches!(name, sym::Debug | sym::Display) { diff --git a/clippy_lints/src/from_over_into.rs b/clippy_lints/src/from_over_into.rs index 1da6952eb64..e3bb5ee10db 100644 --- a/clippy_lints/src/from_over_into.rs +++ b/clippy_lints/src/from_over_into.rs @@ -67,12 +67,12 @@ impl_lint_pass!(FromOverInto => [FROM_OVER_INTO]); impl<'tcx> LateLintPass<'tcx> for FromOverInto { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if let ItemKind::Impl(Impl { - of_trait: Some(hir_trait_ref), + of_trait: Some(of_trait), self_ty, items: [impl_item_ref], .. }) = item.kind - && let Some(into_trait_seg) = hir_trait_ref.path.segments.last() + && let Some(into_trait_seg) = of_trait.trait_ref.path.segments.last() // `impl Into<target_ty> for self_ty` && let Some(GenericArgs { args: [GenericArg::Type(target_ty)], .. }) = into_trait_seg.args && span_is_local(item.span) diff --git a/clippy_lints/src/functions/impl_trait_in_params.rs b/clippy_lints/src/functions/impl_trait_in_params.rs index cb83b1395d2..3105e303ae3 100644 --- a/clippy_lints/src/functions/impl_trait_in_params.rs +++ b/clippy_lints/src/functions/impl_trait_in_params.rs @@ -54,8 +54,7 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, impl_item: &ImplItem<'_>) { if let ImplItemKind::Fn(_, body_id) = impl_item.kind && let hir::Node::Item(item) = cx.tcx.parent_hir_node(impl_item.hir_id()) && let hir::ItemKind::Impl(impl_) = item.kind - && let hir::Impl { of_trait, .. } = *impl_ - && of_trait.is_none() + && let hir::Impl { of_trait: None, .. } = impl_ && let body = cx.tcx.hir_body(body_id) && cx.tcx.visibility(cx.tcx.hir_body_owner_def_id(body.id())).is_public() && !is_in_test(cx.tcx, impl_item.hir_id()) diff --git a/clippy_lints/src/functions/renamed_function_params.rs b/clippy_lints/src/functions/renamed_function_params.rs index ba0cefaa33b..f8e8f5544b9 100644 --- a/clippy_lints/src/functions/renamed_function_params.rs +++ b/clippy_lints/src/functions/renamed_function_params.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use rustc_errors::{Applicability, MultiSpan}; use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_hir::hir_id::OwnerId; -use rustc_hir::{ImplItem, ImplItemKind, ItemKind, Node, TraitRef}; +use rustc_hir::{Impl, ImplItem, ImplItemKind, ItemKind, Node, TraitRef}; use rustc_lint::LateContext; use rustc_span::Span; use rustc_span::symbol::{Ident, kw}; @@ -15,10 +15,12 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, item: &ImplItem<'_>, ignored && let ImplItemKind::Fn(_, body_id) = item.kind && let parent_node = cx.tcx.parent_hir_node(item.hir_id()) && let Node::Item(parent_item) = parent_node - && let ItemKind::Impl(impl_) = &parent_item.kind - && let Some(trait_ref) = impl_.of_trait + && let ItemKind::Impl(Impl { + of_trait: Some(of_trait), + .. + }) = &parent_item.kind && let Some(did) = trait_item_def_id_of_impl(cx, item.owner_id) - && !is_from_ignored_trait(&trait_ref, ignored_traits) + && !is_from_ignored_trait(&of_trait.trait_ref, ignored_traits) { let mut param_idents_iter = cx.tcx.hir_body_param_idents(body_id); let mut default_param_idents_iter = cx.tcx.fn_arg_idents(did).iter().copied(); diff --git a/clippy_lints/src/impl_hash_with_borrow_str_and_bytes.rs b/clippy_lints/src/impl_hash_with_borrow_str_and_bytes.rs index 940adbae428..f73182d3af0 100644 --- a/clippy_lints/src/impl_hash_with_borrow_str_and_bytes.rs +++ b/clippy_lints/src/impl_hash_with_borrow_str_and_bytes.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::ty::implements_trait; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{Item, ItemKind, Path, TraitRef}; +use rustc_hir::{Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::Ty; use rustc_session::declare_lint_pass; @@ -76,10 +76,10 @@ impl LateLintPass<'_> for ImplHashWithBorrowStrBytes { /// three of `Hash`, `Borrow<str>` and `Borrow<[u8]>`. fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { if let ItemKind::Impl(imp) = item.kind - && let Some(TraitRef {path: Path {span, res, ..}, ..}) = imp.of_trait + && let Some(of_trait) = imp.of_trait && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() && let Some(hash_id) = cx.tcx.get_diagnostic_item(sym::Hash) - && Res::Def(DefKind::Trait, hash_id) == *res + && Res::Def(DefKind::Trait, hash_id) == of_trait.trait_ref.path.res && let Some(borrow_id) = cx.tcx.get_diagnostic_item(sym::Borrow) // since we are in the `Hash` impl, we don't need to check for that. // we need only to check for `Borrow<str>` and `Borrow<[u8]>` @@ -89,7 +89,7 @@ impl LateLintPass<'_> for ImplHashWithBorrowStrBytes { span_lint_and_then( cx, IMPL_HASH_BORROW_WITH_STR_AND_BYTES, - *span, + of_trait.trait_ref.path.span, "the semantics of `Borrow<T>` around `Hash` can't be satisfied when both `Borrow<str>` and `Borrow<[u8]>` are implemented", |diag| { diag.note("the `Borrow` semantics require that `Hash` must behave the same for all implementations of Borrow<T>"); diff --git a/clippy_lints/src/infallible_try_from.rs b/clippy_lints/src/infallible_try_from.rs index 589c294a678..36df07a4370 100644 --- a/clippy_lints/src/infallible_try_from.rs +++ b/clippy_lints/src/infallible_try_from.rs @@ -45,8 +45,8 @@ declare_lint_pass!(InfallibleTryFrom => [INFALLIBLE_TRY_FROM]); impl<'tcx> LateLintPass<'tcx> for InfallibleTryFrom { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { let ItemKind::Impl(imp) = item.kind else { return }; - let Some(r#trait) = imp.of_trait else { return }; - let Some(trait_def_id) = r#trait.trait_def_id() else { + let Some(of_trait) = imp.of_trait else { return }; + let Some(trait_def_id) = of_trait.trait_ref.trait_def_id() else { return; }; if !cx.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id) { diff --git a/clippy_lints/src/item_name_repetitions.rs b/clippy_lints/src/item_name_repetitions.rs index 95e16aae40f..945bb84708f 100644 --- a/clippy_lints/src/item_name_repetitions.rs +++ b/clippy_lints/src/item_name_repetitions.rs @@ -8,7 +8,6 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::{EnumDef, FieldDef, Item, ItemKind, OwnerId, QPath, TyKind, Variant, VariantData}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; -use rustc_span::MacroKind; use rustc_span::symbol::Symbol; declare_clippy_lint! { @@ -503,8 +502,8 @@ impl LateLintPass<'_> for ItemNameRepetitions { ); } - let is_macro_rule = matches!(item.kind, ItemKind::Macro(_, _, MacroKind::Bang)); - if both_are_public && item_camel.len() > mod_camel.len() && !is_macro_rule { + let is_macro = matches!(item.kind, ItemKind::Macro(_, _, _)); + if both_are_public && item_camel.len() > mod_camel.len() && !is_macro { let matching = count_match_start(mod_camel, &item_camel); let rmatching = count_match_end(mod_camel, &item_camel); let nchars = mod_camel.chars().count(); diff --git a/clippy_lints/src/iter_without_into_iter.rs b/clippy_lints/src/iter_without_into_iter.rs index b89f91f7255..645e0f981f2 100644 --- a/clippy_lints/src/iter_without_into_iter.rs +++ b/clippy_lints/src/iter_without_into_iter.rs @@ -125,8 +125,9 @@ impl LateLintPass<'_> for IterWithoutIntoIter { fn check_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::Item<'_>) { if let ItemKind::Impl(imp) = item.kind && let TyKind::Ref(_, self_ty_without_ref) = &imp.self_ty.kind - && let Some(trait_ref) = imp.of_trait - && trait_ref + && let Some(of_trait) = imp.of_trait + && of_trait + .trait_ref .trait_def_id() .is_some_and(|did| cx.tcx.is_diagnostic_item(sym::IntoIterator, did)) && !item.span.in_external_macro(cx.sess().source_map()) diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index 35c9d2fd4eb..149ae5e710c 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -150,7 +150,7 @@ impl<'tcx> LateLintPass<'tcx> for Lifetimes { } = item.kind { check_fn_inner(cx, sig, Some(id), None, generics, item.span, true, self.msrv); - } else if let ItemKind::Impl(impl_) = item.kind + } else if let ItemKind::Impl(impl_) = &item.kind && !item.span.from_expansion() { report_extra_impl_lifetimes(cx, impl_); @@ -712,8 +712,8 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<' let mut checker = LifetimeChecker::<middle_nested_filter::All>::new(cx, impl_.generics); walk_generics(&mut checker, impl_.generics); - if let Some(ref trait_ref) = impl_.of_trait { - walk_trait_ref(&mut checker, trait_ref); + if let Some(of_trait) = impl_.of_trait { + walk_trait_ref(&mut checker, &of_trait.trait_ref); } walk_unambig_ty(&mut checker, impl_.self_ty); for &item in impl_.items { diff --git a/clippy_lints/src/missing_asserts_for_indexing.rs b/clippy_lints/src/missing_asserts_for_indexing.rs index cf0c85990b1..788a04357b1 100644 --- a/clippy_lints/src/missing_asserts_for_indexing.rs +++ b/clippy_lints/src/missing_asserts_for_indexing.rs @@ -11,7 +11,7 @@ use rustc_ast::{BinOpKind, LitKind, RangeLimits}; use rustc_data_structures::packed::Pu128; use rustc_data_structures::unhash::UnindexMap; use rustc_errors::{Applicability, Diag}; -use rustc_hir::{Block, Body, Expr, ExprKind, UnOp}; +use rustc_hir::{Body, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; use rustc_span::source_map::Spanned; @@ -135,12 +135,12 @@ fn assert_len_expr<'hir>( cx: &LateContext<'_>, expr: &'hir Expr<'hir>, ) -> Option<(LengthComparison, usize, &'hir Expr<'hir>)> { - let (cmp, asserted_len, slice_len) = if let Some(higher::If { cond, then, .. }) = higher::If::hir(expr) - && let ExprKind::Unary(UnOp::Not, condition) = &cond.kind - && let ExprKind::Binary(bin_op, left, right) = &condition.kind + let (cmp, asserted_len, slice_len) = if let Some( + higher::IfLetOrMatch::Match(cond, [_, then], _) + ) = higher::IfLetOrMatch::parse(cx, expr) + && let ExprKind::Binary(bin_op, left, right) = &cond.kind // check if `then` block has a never type expression - && let ExprKind::Block(Block { expr: Some(then_expr), .. }, _) = then.kind - && cx.typeck_results().expr_ty(then_expr).is_never() + && cx.typeck_results().expr_ty(then.body).is_never() { len_comparison(bin_op.node, left, right)? } else if let Some((macro_call, bin_op)) = first_node_macro_backtrace(cx, expr).find_map(|macro_call| { diff --git a/clippy_lints/src/missing_fields_in_debug.rs b/clippy_lints/src/missing_fields_in_debug.rs index 18e2b384a46..8822b32b1c3 100644 --- a/clippy_lints/src/missing_fields_in_debug.rs +++ b/clippy_lints/src/missing_fields_in_debug.rs @@ -198,8 +198,8 @@ fn check_struct<'tcx>( impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { // is this an `impl Debug for X` block? - if let ItemKind::Impl(Impl { of_trait: Some(trait_ref), self_ty, .. }) = item.kind - && let Res::Def(DefKind::Trait, trait_def_id) = trait_ref.path.res + if let ItemKind::Impl(Impl { of_trait: Some(of_trait), self_ty, .. }) = item.kind + && let Res::Def(DefKind::Trait, trait_def_id) = of_trait.trait_ref.path.res && let TyKind::Path(QPath::Resolved(_, self_path)) = &self_ty.kind // make sure that the self type is either a struct, an enum or a union // this prevents ICEs such as when self is a type parameter or a primitive type diff --git a/clippy_lints/src/missing_inline.rs b/clippy_lints/src/missing_inline.rs index d02952eb487..b16924babd1 100644 --- a/clippy_lints/src/missing_inline.rs +++ b/clippy_lints/src/missing_inline.rs @@ -190,5 +190,5 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { /// and a rustc warning would be triggered, see #15301 fn fn_is_externally_exported(cx: &LateContext<'_>, def_id: DefId) -> bool { let attrs = cx.tcx.codegen_fn_attrs(def_id); - attrs.contains_extern_indicator() + attrs.contains_extern_indicator(cx.tcx, def_id) } diff --git a/clippy_lints/src/missing_trait_methods.rs b/clippy_lints/src/missing_trait_methods.rs index 399bf4e1806..9cc93bf0653 100644 --- a/clippy_lints/src/missing_trait_methods.rs +++ b/clippy_lints/src/missing_trait_methods.rs @@ -61,10 +61,10 @@ impl<'tcx> LateLintPass<'tcx> for MissingTraitMethods { if !is_lint_allowed(cx, MISSING_TRAIT_METHODS, item.hir_id()) && span_is_local(item.span) && let ItemKind::Impl(Impl { - of_trait: Some(trait_ref), + of_trait: Some(of_trait), .. }) = item.kind - && let Some(trait_id) = trait_ref.trait_def_id() + && let Some(trait_id) = of_trait.trait_ref.trait_def_id() { let trait_item_ids: DefIdSet = cx .tcx diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs index 96b238484f6..2fffc4244a7 100644 --- a/clippy_lints/src/non_copy_const.rs +++ b/clippy_lints/src/non_copy_const.rs @@ -778,7 +778,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { if let Node::Item(parent_item) = cx.tcx.parent_hir_node(item.hir_id()) && let ItemKind::Impl(impl_block) = parent_item.kind && let Some(of_trait) = impl_block.of_trait - && let Some(trait_id) = of_trait.trait_def_id() + && let Some(trait_id) = of_trait.trait_ref.trait_def_id() { // Replace all instances of `<Self as Trait>::AssocType` with the // unit type and check again. If the result is the same then the diff --git a/clippy_lints/src/non_send_fields_in_send_ty.rs b/clippy_lints/src/non_send_fields_in_send_ty.rs index 8ff78ec7c58..b810bc01fbd 100644 --- a/clippy_lints/src/non_send_fields_in_send_ty.rs +++ b/clippy_lints/src/non_send_fields_in_send_ty.rs @@ -83,10 +83,10 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy { if !item.span.in_external_macro(cx.tcx.sess.source_map()) && let Some(send_trait) = cx.tcx.get_diagnostic_item(sym::Send) && let ItemKind::Impl(hir_impl) = &item.kind - && let Some(trait_ref) = &hir_impl.of_trait - && let Some(trait_id) = trait_ref.trait_def_id() + && let Some(of_trait) = &hir_impl.of_trait + && let Some(trait_id) = of_trait.trait_ref.trait_def_id() && send_trait == trait_id - && hir_impl.polarity == ImplPolarity::Positive + && of_trait.polarity == ImplPolarity::Positive && let Some(ty_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id) && let self_ty = ty_trait_ref.instantiate_identity().self_ty() && let ty::Adt(adt_def, impl_trait_args) = self_ty.kind() diff --git a/clippy_lints/src/operators/assign_op_pattern.rs b/clippy_lints/src/operators/assign_op_pattern.rs index 9c6141d8222..7317c62df7f 100644 --- a/clippy_lints/src/operators/assign_op_pattern.rs +++ b/clippy_lints/src/operators/assign_op_pattern.rs @@ -1,6 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::msrvs::Msrv; -use clippy_utils::qualify_min_const_fn::is_stable_const_fn; use clippy_utils::source::SpanRangeExt; use clippy_utils::ty::implements_trait; use clippy_utils::visitors::for_each_expr_without_closures; @@ -21,7 +20,7 @@ pub(super) fn check<'tcx>( expr: &'tcx hir::Expr<'_>, assignee: &'tcx hir::Expr<'_>, e: &'tcx hir::Expr<'_>, - msrv: Msrv, + _msrv: Msrv, ) { if let hir::ExprKind::Binary(op, l, r) = &e.kind { let lint = |assignee: &hir::Expr<'_>, rhs: &hir::Expr<'_>| { @@ -45,10 +44,8 @@ pub(super) fn check<'tcx>( } // Skip if the trait is not stable in const contexts - if is_in_const_context(cx) - && let Some(binop_id) = cx.tcx.associated_item_def_ids(trait_id).first() - && !is_stable_const_fn(cx, *binop_id, msrv) - { + // FIXME: reintroduce a better check after this is merged back into Clippy + if is_in_const_context(cx) { return; } diff --git a/clippy_lints/src/operators/op_ref.rs b/clippy_lints/src/operators/op_ref.rs index 0a1f2625f4c..9c160ff680e 100644 --- a/clippy_lints/src/operators/op_ref.rs +++ b/clippy_lints/src/operators/op_ref.rs @@ -183,7 +183,7 @@ fn in_impl<'tcx>( && let item = cx.tcx.hir_expect_item(impl_def_id.expect_local()) && let ItemKind::Impl(item) = &item.kind && let Some(of_trait) = &item.of_trait - && let Some(seg) = of_trait.path.segments.last() + && let Some(seg) = of_trait.trait_ref.path.segments.last() && let Res::Def(_, trait_id) = seg.res && trait_id == bin_op && let Some(generic_args) = seg.args diff --git a/clippy_lints/src/partialeq_ne_impl.rs b/clippy_lints/src/partialeq_ne_impl.rs index 301b2cd4bf2..77751e75a8e 100644 --- a/clippy_lints/src/partialeq_ne_impl.rs +++ b/clippy_lints/src/partialeq_ne_impl.rs @@ -34,15 +34,15 @@ declare_lint_pass!(PartialEqNeImpl => [PARTIALEQ_NE_IMPL]); impl<'tcx> LateLintPass<'tcx> for PartialEqNeImpl { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if let ItemKind::Impl(Impl { - of_trait: Some(trait_ref), + of_trait: Some(of_trait), items: impl_items, .. }) = item.kind && !cx.tcx.is_automatically_derived(item.owner_id.to_def_id()) && let Some(eq_trait) = cx.tcx.lang_items().eq_trait() - && trait_ref.path.res.def_id() == eq_trait + && of_trait.trait_ref.path.res.def_id() == eq_trait { - for impl_item in *impl_items { + for impl_item in impl_items { if cx.tcx.item_name(impl_item.owner_id) == sym::ne { span_lint_hir( cx, diff --git a/clippy_lints/src/redundant_pub_crate.rs b/clippy_lints/src/redundant_pub_crate.rs index 3828aff4164..0c1c664f111 100644 --- a/clippy_lints/src/redundant_pub_crate.rs +++ b/clippy_lints/src/redundant_pub_crate.rs @@ -7,7 +7,6 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; use rustc_session::impl_lint_pass; use rustc_span::def_id::CRATE_DEF_ID; -use rustc_span::hygiene::MacroKind; declare_clippy_lint! { /// ### What it does @@ -89,8 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate { // We ignore macro exports. And `ListStem` uses, which aren't interesting. fn is_ignorable_export<'tcx>(item: &'tcx Item<'tcx>) -> bool { if let ItemKind::Use(path, kind) = item.kind { - let ignore = matches!(path.res.macro_ns, Some(Res::Def(DefKind::Macro(MacroKind::Bang), _))) - || kind == UseKind::ListStem; + let ignore = matches!(path.res.macro_ns, Some(Res::Def(DefKind::Macro(_), _))) || kind == UseKind::ListStem; if ignore { return true; } diff --git a/clippy_lints/src/same_name_method.rs b/clippy_lints/src/same_name_method.rs index 67eb71f7d07..b87751f4986 100644 --- a/clippy_lints/src/same_name_method.rs +++ b/clippy_lints/src/same_name_method.rs @@ -68,9 +68,9 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { let existing_name = map.get_mut(res).unwrap(); match of_trait { - Some(trait_ref) => { + Some(of_trait) => { let mut methods_in_trait: BTreeSet<Symbol> = if let Node::TraitRef(TraitRef { path, .. }) = - cx.tcx.hir_node(trait_ref.hir_ref_id) + cx.tcx.hir_node(of_trait.trait_ref.hir_ref_id) && let Res::Def(DefKind::Trait, did) = path.res { // FIXME: if diff --git a/clippy_lints/src/serde_api.rs b/clippy_lints/src/serde_api.rs index 2de22e4b6a3..01c7f394b9a 100644 --- a/clippy_lints/src/serde_api.rs +++ b/clippy_lints/src/serde_api.rs @@ -26,16 +26,16 @@ declare_lint_pass!(SerdeApi => [SERDE_API_MISUSE]); impl<'tcx> LateLintPass<'tcx> for SerdeApi { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if let ItemKind::Impl(Impl { - of_trait: Some(trait_ref), + of_trait: Some(of_trait), items, .. }) = item.kind { - let did = trait_ref.path.res.def_id(); + let did = of_trait.trait_ref.path.res.def_id(); if paths::SERDE_DE_VISITOR.matches(cx, did) { let mut seen_str = None; let mut seen_string = None; - for item in *items { + for item in items { match cx.tcx.item_name(item.owner_id) { sym::visit_str => seen_str = Some(cx.tcx.def_span(item.owner_id)), sym::visit_string => seen_string = Some(cx.tcx.def_span(item.owner_id)), diff --git a/clippy_lints/src/single_component_path_imports.rs b/clippy_lints/src/single_component_path_imports.rs index 38cf7e3822a..07a8eb5d886 100644 --- a/clippy_lints/src/single_component_path_imports.rs +++ b/clippy_lints/src/single_component_path_imports.rs @@ -1,6 +1,5 @@ use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg}; use rustc_ast::node_id::{NodeId, NodeMap}; -use rustc_ast::ptr::P; use rustc_ast::visit::{Visitor, walk_expr}; use rustc_ast::{Crate, Expr, ExprKind, Item, ItemKind, MacroDef, ModKind, Ty, TyKind, UseTreeKind}; use rustc_errors::Applicability; @@ -124,7 +123,7 @@ impl Visitor<'_> for ImportUsageVisitor { } impl SingleComponentPathImports { - fn check_mod(&mut self, items: &[P<Item>]) { + fn check_mod(&mut self, items: &[Box<Item>]) { // keep track of imports reused with `self` keyword, such as `self::crypto_hash` in the example // below. Removing the `use crypto_hash;` would make this a compile error // ``` diff --git a/clippy_lints/src/to_string_trait_impl.rs b/clippy_lints/src/to_string_trait_impl.rs index 9596b85664b..303f6028bd5 100644 --- a/clippy_lints/src/to_string_trait_impl.rs +++ b/clippy_lints/src/to_string_trait_impl.rs @@ -48,10 +48,10 @@ declare_lint_pass!(ToStringTraitImpl => [TO_STRING_TRAIT_IMPL]); impl<'tcx> LateLintPass<'tcx> for ToStringTraitImpl { fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx Item<'tcx>) { if let ItemKind::Impl(Impl { - of_trait: Some(trait_ref), + of_trait: Some(of_trait), .. }) = it.kind - && let Some(trait_did) = trait_ref.trait_def_id() + && let Some(trait_did) = of_trait.trait_ref.trait_def_id() && cx.tcx.is_diagnostic_item(sym::ToString, trait_did) { span_lint_and_help( diff --git a/clippy_lints/src/unconditional_recursion.rs b/clippy_lints/src/unconditional_recursion.rs index dcddff557d1..e843e169113 100644 --- a/clippy_lints/src/unconditional_recursion.rs +++ b/clippy_lints/src/unconditional_recursion.rs @@ -137,9 +137,9 @@ fn get_impl_trait_def_id(cx: &LateContext<'_>, method_def_id: LocalDefId) -> Opt // We exclude `impl` blocks generated from rustc's proc macros. && !cx.tcx.is_automatically_derived(owner_id.to_def_id()) // It is a implementation of a trait. - && let Some(trait_) = impl_.of_trait + && let Some(of_trait) = impl_.of_trait { - trait_.trait_def_id() + of_trait.trait_ref.trait_def_id() } else { None } @@ -242,8 +242,8 @@ fn check_to_string(cx: &LateContext<'_>, method_span: Span, method_def_id: Local // We exclude `impl` blocks generated from rustc's proc macros. && !cx.tcx.is_automatically_derived(owner_id.to_def_id()) // It is a implementation of a trait. - && let Some(trait_) = impl_.of_trait - && let Some(trait_def_id) = trait_.trait_def_id() + && let Some(of_trait) = impl_.of_trait + && let Some(trait_def_id) = of_trait.trait_ref.trait_def_id() // The trait is `ToString`. && cx.tcx.is_diagnostic_item(sym::ToString, trait_def_id) { diff --git a/clippy_lints/src/undocumented_unsafe_blocks.rs b/clippy_lints/src/undocumented_unsafe_blocks.rs index c031dbb8cc8..ba0d4de5f3b 100644 --- a/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -8,7 +8,7 @@ use clippy_utils::source::walk_span_to_context; use clippy_utils::visitors::{Descend, for_each_expr}; use hir::HirId; use rustc_hir as hir; -use rustc_hir::{Block, BlockCheckMode, ItemKind, Node, UnsafeSource}; +use rustc_hir::{Block, BlockCheckMode, Impl, ItemKind, Node, UnsafeSource}; use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::impl_lint_pass; @@ -202,79 +202,41 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { }; let item_has_safety_comment = item_has_safety_comment(cx, item); - match (&item.kind, item_has_safety_comment) { - // lint unsafe impl without safety comment - (ItemKind::Impl(impl_), HasSafetyComment::No) if impl_.safety.is_unsafe() => { - if !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, item.hir_id()) - && !is_unsafe_from_proc_macro(cx, item.span) - { - let source_map = cx.tcx.sess.source_map(); - let span = if source_map.is_multiline(item.span) { - source_map.span_until_char(item.span, '\n') - } else { - item.span - }; - - #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")] - span_lint_and_then( - cx, - UNDOCUMENTED_UNSAFE_BLOCKS, - span, - "unsafe impl missing a safety comment", - |diag| { - diag.help("consider adding a safety comment on the preceding line"); - }, - ); - } - }, - // lint safe impl with unnecessary safety comment - (ItemKind::Impl(impl_), HasSafetyComment::Yes(pos)) if impl_.safety.is_safe() => { - if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, item.hir_id()) { - let (span, help_span) = mk_spans(pos); - - span_lint_and_then( - cx, - UNNECESSARY_SAFETY_COMMENT, - span, - "impl has unnecessary safety comment", - |diag| { - diag.span_help(help_span, "consider removing the safety comment"); - }, - ); - } - }, - (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), HasSafetyComment::Yes(pos)) => { - if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, body.hir_id) { - let body = cx.tcx.hir_body(body); - if !matches!( - body.value.kind, hir::ExprKind::Block(block, _) - if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) - ) { - let (span, help_span) = mk_spans(pos); - - 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"); - }, - ); - } - } - }, - // Aside from unsafe impls and consts/statics with an unsafe block, items in general - // do not have safety invariants that need to be documented, so lint those. - (_, HasSafetyComment::Yes(pos)) => { - if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, item.hir_id()) { - let (span, help_span) = mk_spans(pos); + match item_has_safety_comment { + HasSafetyComment::Yes(pos) => check_has_safety_comment(cx, item, mk_spans(pos)), + HasSafetyComment::No => check_has_no_safety_comment(cx, item), + HasSafetyComment::Maybe => {}, + } + } +} +fn check_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>, (span, help_span): (Span, Span)) { + match &item.kind { + ItemKind::Impl(Impl { + of_trait: Some(of_trait), + .. + }) if of_trait.safety.is_safe() => { + if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, item.hir_id()) { + span_lint_and_then( + cx, + UNNECESSARY_SAFETY_COMMENT, + span, + "impl has unnecessary safety comment", + |diag| { + diag.span_help(help_span, "consider removing the safety comment"); + }, + ); + } + }, + 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) => { + if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, body.hir_id) { + let body = cx.tcx.hir_body(body); + if !matches!( + body.value.kind, hir::ExprKind::Block(block, _) + if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) + ) { span_lint_and_then( cx, UNNECESSARY_SAFETY_COMMENT, @@ -288,12 +250,56 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { }, ); } - }, - _ => (), - } + } + }, + // Aside from unsafe impls and consts/statics with an unsafe block, items in general + // do not have safety invariants that need to be documented, so lint those. + _ => { + if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, item.hir_id()) { + 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"); + }, + ); + } + }, } } +fn check_has_no_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>) { + if let ItemKind::Impl(Impl { + of_trait: Some(of_trait), + .. + }) = item.kind + && of_trait.safety.is_unsafe() + && !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, item.hir_id()) + && !is_unsafe_from_proc_macro(cx, item.span) + { + let source_map = cx.tcx.sess.source_map(); + let span = if source_map.is_multiline(item.span) { + source_map.span_until_char(item.span, '\n') + } else { + item.span + }; + #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")] + span_lint_and_then( + cx, + UNDOCUMENTED_UNSAFE_BLOCKS, + span, + "unsafe impl missing a safety comment", + |diag| { + diag.help("consider adding a safety comment on the preceding line"); + }, + ); + } +} fn expr_has_unnecessary_safety_comment<'tcx>( cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, diff --git a/clippy_lints/src/unnested_or_patterns.rs b/clippy_lints/src/unnested_or_patterns.rs index bd8420917f5..8b278d98a30 100644 --- a/clippy_lints/src/unnested_or_patterns.rs +++ b/clippy_lints/src/unnested_or_patterns.rs @@ -7,13 +7,14 @@ use clippy_utils::msrvs::{self, MsrvStack}; use clippy_utils::over; use rustc_ast::PatKind::*; use rustc_ast::mut_visit::*; -use rustc_ast::ptr::P; use rustc_ast::{self as ast, DUMMY_NODE_ID, Mutability, Pat, PatKind}; use rustc_ast_pretty::pprust; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::impl_lint_pass; use rustc_span::DUMMY_SP; +// import needed to shadow `PatKind::Box` glob-imported above +use std::boxed::Box; use std::cell::Cell; use std::mem; use thin_vec::{ThinVec, thin_vec}; @@ -97,7 +98,7 @@ fn lint_unnested_or_patterns(cx: &EarlyContext<'_>, pat: &Pat) { return; } - let mut pat = P(pat.clone()); + let mut pat = Box::new(pat.clone()); // Nix all the paren patterns everywhere so that they aren't in our way. remove_all_parens(&mut pat); @@ -119,7 +120,7 @@ fn lint_unnested_or_patterns(cx: &EarlyContext<'_>, pat: &Pat) { } /// Remove all `(p)` patterns in `pat`. -fn remove_all_parens(pat: &mut P<Pat>) { +fn remove_all_parens(pat: &mut Box<Pat>) { #[derive(Default)] struct Visitor { /// If is not in the outer most pattern. This is needed to avoid removing the outermost @@ -142,7 +143,7 @@ fn remove_all_parens(pat: &mut P<Pat>) { } /// Insert parens where necessary according to Rust's precedence rules for patterns. -fn insert_necessary_parens(pat: &mut P<Pat>) { +fn insert_necessary_parens(pat: &mut Box<Pat>) { struct Visitor; impl MutVisitor for Visitor { fn visit_pat(&mut self, pat: &mut Pat) { @@ -154,7 +155,7 @@ fn insert_necessary_parens(pat: &mut P<Pat>) { Ref(p, Mutability::Not) if matches!(p.kind, Ident(BindingMode::MUT, ..)) => p, // `&(mut x)` _ => return, }; - target.kind = Paren(P(take_pat(target))); + target.kind = Paren(Box::new(take_pat(target))); } } Visitor.visit_pat(pat); @@ -162,7 +163,7 @@ fn insert_necessary_parens(pat: &mut P<Pat>) { /// Unnest or-patterns `p0 | ... | p1` in the pattern `pat`. /// For example, this would transform `Some(0) | FOO | Some(2)` into `Some(0 | 2) | FOO`. -fn unnest_or_patterns(pat: &mut P<Pat>) -> bool { +fn unnest_or_patterns(pat: &mut Box<Pat>) -> bool { struct Visitor { changed: bool, } @@ -222,7 +223,7 @@ macro_rules! always_pat { /// Focus on `focus_idx` in `alternatives`, /// attempting to extend it with elements of the same constructor `C` /// in `alternatives[focus_idx + 1..]`. -fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: usize) -> bool { +fn transform_with_focus_on_idx(alternatives: &mut ThinVec<Box<Pat>>, focus_idx: usize) -> bool { // Extract the kind; we'll need to make some changes in it. let mut focus_kind = mem::replace(&mut alternatives[focus_idx].kind, Wild); // We'll focus on `alternatives[focus_idx]`, @@ -283,14 +284,14 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: us |k, ps1, idx| matches!( k, TupleStruct(qself2, path2, ps2) - if eq_maybe_qself(qself1.as_ref(), qself2.as_ref()) + if eq_maybe_qself(qself1.as_deref(), qself2.as_deref()) && eq_path(path1, path2) && eq_pre_post(ps1, ps2, idx) ), |k| always_pat!(k, TupleStruct(_, _, ps) => ps), ), // Transform a record pattern `S { fp_0, ..., fp_n }`. Struct(qself1, path1, fps1, rest1) => { - extend_with_struct_pat(qself1.as_ref(), path1, fps1, *rest1, start, alternatives) + extend_with_struct_pat(qself1.as_deref(), path1, fps1, *rest1, start, alternatives) }, }; @@ -303,12 +304,12 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: us /// So when we fixate on some `ident_k: pat_k`, we try to find `ident_k` in the other pattern /// and check that all `fp_i` where `i ∈ ((0...n) \ k)` between two patterns are equal. fn extend_with_struct_pat( - qself1: Option<&P<ast::QSelf>>, + qself1: Option<&ast::QSelf>, path1: &ast::Path, fps1: &mut [ast::PatField], rest1: ast::PatFieldsRest, start: usize, - alternatives: &mut ThinVec<P<Pat>>, + alternatives: &mut ThinVec<Box<Pat>>, ) -> bool { (0..fps1.len()).any(|idx| { let pos_in_2 = Cell::new(None); // The element `k`. @@ -318,7 +319,7 @@ fn extend_with_struct_pat( |k| { matches!(k, Struct(qself2, path2, fps2, rest2) if rest1 == *rest2 // If one struct pattern has `..` so must the other. - && eq_maybe_qself(qself1, qself2.as_ref()) + && eq_maybe_qself(qself1, qself2.as_deref()) && eq_path(path1, path2) && fps1.len() == fps2.len() && fps1.iter().enumerate().all(|(idx_1, fp1)| { @@ -346,11 +347,11 @@ fn extend_with_struct_pat( /// while also requiring `ps1[..n] ~ ps2[..n]` (pre) and `ps1[n + 1..] ~ ps2[n + 1..]` (post), /// where `~` denotes semantic equality. fn extend_with_matching_product( - targets: &mut [P<Pat>], + targets: &mut [Box<Pat>], start: usize, - alternatives: &mut ThinVec<P<Pat>>, - predicate: impl Fn(&PatKind, &[P<Pat>], usize) -> bool, - extract: impl Fn(PatKind) -> ThinVec<P<Pat>>, + alternatives: &mut ThinVec<Box<Pat>>, + predicate: impl Fn(&PatKind, &[Box<Pat>], usize) -> bool, + extract: impl Fn(PatKind) -> ThinVec<Box<Pat>>, ) -> bool { (0..targets.len()).any(|idx| { let tail_or = drain_matching( @@ -377,14 +378,14 @@ fn take_pat(from: &mut Pat) -> Pat { /// Extend `target` as an or-pattern with the alternatives /// in `tail_or` if there are any and return if there were. -fn extend_with_tail_or(target: &mut Pat, tail_or: ThinVec<P<Pat>>) -> bool { - fn extend(target: &mut Pat, mut tail_or: ThinVec<P<Pat>>) { +fn extend_with_tail_or(target: &mut Pat, tail_or: ThinVec<Box<Pat>>) -> bool { + fn extend(target: &mut Pat, mut tail_or: ThinVec<Box<Pat>>) { match target { // On an existing or-pattern in the target, append to it. Pat { kind: Or(ps), .. } => ps.append(&mut tail_or), // Otherwise convert the target to an or-pattern. target => { - let mut init_or = thin_vec![P(take_pat(target))]; + let mut init_or = thin_vec![Box::new(take_pat(target))]; init_or.append(&mut tail_or); target.kind = Or(init_or); }, @@ -403,10 +404,10 @@ fn extend_with_tail_or(target: &mut Pat, tail_or: ThinVec<P<Pat>>) -> bool { // Only elements beginning with `start` are considered for extraction. fn drain_matching( start: usize, - alternatives: &mut ThinVec<P<Pat>>, + alternatives: &mut ThinVec<Box<Pat>>, predicate: impl Fn(&PatKind) -> bool, - extract: impl Fn(PatKind) -> P<Pat>, -) -> ThinVec<P<Pat>> { + extract: impl Fn(PatKind) -> Box<Pat>, +) -> ThinVec<Box<Pat>> { let mut tail_or = ThinVec::new(); let mut idx = 0; @@ -438,15 +439,15 @@ fn drain_matching( fn extend_with_matching( target: &mut Pat, start: usize, - alternatives: &mut ThinVec<P<Pat>>, + alternatives: &mut ThinVec<Box<Pat>>, predicate: impl Fn(&PatKind) -> bool, - extract: impl Fn(PatKind) -> P<Pat>, + extract: impl Fn(PatKind) -> Box<Pat>, ) -> bool { extend_with_tail_or(target, drain_matching(start, alternatives, predicate, extract)) } /// Are the patterns in `ps1` and `ps2` equal save for `ps1[idx]` compared to `ps2[idx]`? -fn eq_pre_post(ps1: &[P<Pat>], ps2: &[P<Pat>], idx: usize) -> bool { +fn eq_pre_post(ps1: &[Box<Pat>], ps2: &[Box<Pat>], idx: usize) -> bool { ps1.len() == ps2.len() && ps1[idx].is_rest() == ps2[idx].is_rest() // Avoid `[x, ..] | [x, 0]` => `[x, .. | 0]`. && over(&ps1[..idx], &ps2[..idx], |l, r| eq_pat(l, r)) diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs index d9a007635ca..a15e4e42e71 100644 --- a/clippy_lints/src/write.rs +++ b/clippy_lints/src/write.rs @@ -347,10 +347,10 @@ impl<'tcx> LateLintPass<'tcx> for Write { fn is_debug_impl(cx: &LateContext<'_>, item: &Item<'_>) -> bool { if let ItemKind::Impl(Impl { - of_trait: Some(trait_ref), + of_trait: Some(of_trait), .. }) = &item.kind - && let Some(trait_id) = trait_ref.trait_def_id() + && let Some(trait_id) = of_trait.trait_ref.trait_def_id() { cx.tcx.is_diagnostic_item(sym::Debug, trait_id) } else { diff --git a/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs b/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs index 5e6a40ac2eb..0fd1e11b033 100644 --- a/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs +++ b/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs @@ -6,7 +6,8 @@ use rustc_hir::attrs::AttributeKind; use rustc_hir::def::Res; use rustc_hir::def_id::LocalDefId; use rustc_hir::{ - AttrArgs, AttrItem, AttrPath, Attribute, HirId, Impl, Item, ItemKind, Path, QPath, TraitRef, Ty, TyKind, find_attr, + AttrArgs, AttrItem, AttrPath, Attribute, HirId, Impl, Item, ItemKind, Path, QPath, TraitImplHeader, TraitRef, Ty, + TyKind, find_attr, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_lint_defs::declare_tool_lint; @@ -56,10 +57,14 @@ impl<'tcx> LateLintPass<'tcx> for DeriveDeserializeAllowingUnknown { // Is this an `impl` (of a certain form)? let ItemKind::Impl(Impl { of_trait: - Some(TraitRef { - path: - Path { - res: Res::Def(_, trait_def_id), + Some(TraitImplHeader { + trait_ref: + TraitRef { + path: + Path { + res: Res::Def(_, trait_def_id), + .. + }, .. }, .. diff --git a/clippy_utils/README.md b/clippy_utils/README.md index 6d8dd92d55d..2dfe28953d0 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: <!-- begin autogenerated nightly --> ``` -nightly-2025-08-07 +nightly-2025-08-22 ``` <!-- end autogenerated nightly --> diff --git a/clippy_utils/src/ast_utils/mod.rs b/clippy_utils/src/ast_utils/mod.rs index 7803f8c0d34..40c00568a3b 100644 --- a/clippy_utils/src/ast_utils/mod.rs +++ b/clippy_utils/src/ast_utils/mod.rs @@ -5,7 +5,6 @@ #![allow(clippy::wildcard_imports, clippy::enum_glob_use)] use crate::{both, over}; -use rustc_ast::ptr::P; use rustc_ast::{self as ast, *}; use rustc_span::symbol::Ident; use std::mem; @@ -42,21 +41,23 @@ pub fn eq_pat(l: &Pat, r: &Pat) -> bool { b1 == b2 && eq_id(*i1, *i2) && both(s1.as_deref(), s2.as_deref(), eq_pat) }, (Range(lf, lt, le), Range(rf, rt, re)) => { - eq_expr_opt(lf.as_ref(), rf.as_ref()) - && eq_expr_opt(lt.as_ref(), rt.as_ref()) + eq_expr_opt(lf.as_deref(), rf.as_deref()) + && 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), (Tuple(l), Tuple(r)) | (Slice(l), Slice(r)) => over(l, r, |l, r| eq_pat(l, r)), - (Path(lq, lp), Path(rq, rp)) => both(lq.as_ref(), rq.as_ref(), eq_qself) && eq_path(lp, rp), + (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)) => { - eq_maybe_qself(lqself.as_ref(), rqself.as_ref()) && eq_path(lp, rp) && over(lfs, rfs, |l, r| eq_pat(l, r)) + eq_maybe_qself(lqself.as_deref(), rqself.as_deref()) + && eq_path(lp, rp) + && over(lfs, rfs, |l, r| eq_pat(l, r)) }, (Struct(lqself, lp, lfs, lr), Struct(rqself, rp, rfs, rr)) => { lr == rr - && eq_maybe_qself(lqself.as_ref(), rqself.as_ref()) + && eq_maybe_qself(lqself.as_deref(), rqself.as_deref()) && eq_path(lp, rp) && unordered_over(lfs, rfs, eq_field_pat) }, @@ -83,11 +84,11 @@ pub fn eq_field_pat(l: &PatField, r: &PatField) -> bool { && over(&l.attrs, &r.attrs, eq_attr) } -pub fn eq_qself(l: &P<QSelf>, r: &P<QSelf>) -> bool { +pub fn eq_qself(l: &QSelf, r: &QSelf) -> bool { l.position == r.position && eq_ty(&l.ty, &r.ty) } -pub fn eq_maybe_qself(l: Option<&P<QSelf>>, r: Option<&P<QSelf>>) -> bool { +pub fn eq_maybe_qself(l: Option<&QSelf>, r: Option<&QSelf>) -> bool { match (l, r) { (Some(l), Some(r)) => eq_qself(l, r), (None, None) => true, @@ -130,8 +131,8 @@ pub fn eq_generic_arg(l: &GenericArg, r: &GenericArg) -> bool { } } -pub fn eq_expr_opt(l: Option<&P<Expr>>, r: Option<&P<Expr>>) -> bool { - both(l, r, |l, r| eq_expr(l, r)) +pub fn eq_expr_opt(l: Option<&Expr>, r: Option<&Expr>) -> bool { + both(l, r, eq_expr) } pub fn eq_struct_rest(l: &StructRest, r: &StructRest) -> bool { @@ -178,7 +179,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool { (Cast(l, lt), Cast(r, rt)) | (Type(l, lt), Type(r, rt)) => eq_expr(l, r) && eq_ty(lt, rt), (Let(lp, le, _, _), Let(rp, re, _, _)) => eq_pat(lp, rp) && eq_expr(le, re), (If(lc, lt, le), If(rc, rt, re)) => { - eq_expr(lc, rc) && eq_block(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()) + eq_expr(lc, rc) && eq_block(lt, rt) && eq_expr_opt(le.as_deref(), re.as_deref()) }, (While(lc, lt, ll), While(rc, rt, rl)) => { eq_label(ll.as_ref(), rl.as_ref()) && eq_expr(lc, rc) && eq_block(lt, rt) @@ -202,9 +203,11 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool { (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), - (Yield(l), Yield(r)) => eq_expr_opt(l.expr(), r.expr()) && l.same_kind(r), - (Ret(l), Ret(r)) => eq_expr_opt(l.as_ref(), r.as_ref()), - (Break(ll, le), Break(rl, re)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_expr_opt(le.as_ref(), re.as_ref()), + (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)) => { + eq_label(ll.as_ref(), rl.as_ref()) && eq_expr_opt(le.as_deref(), re.as_deref()) + }, (Continue(ll), Continue(rl)) => eq_label(ll.as_ref(), rl.as_ref()), (Assign(l1, l2, _), Assign(r1, r2, _)) | (Index(l1, l2, _), Index(r1, r2, _)) => { eq_expr(l1, r1) && eq_expr(l2, r2) @@ -241,13 +244,13 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool { }, (Gen(lc, lb, lk, _), Gen(rc, rb, rk, _)) => lc == rc && eq_block(lb, rb) && lk == rk, (Range(lf, lt, ll), Range(rf, rt, rl)) => { - ll == rl && eq_expr_opt(lf.as_ref(), rf.as_ref()) && eq_expr_opt(lt.as_ref(), rt.as_ref()) + ll == rl && eq_expr_opt(lf.as_deref(), rf.as_deref()) && eq_expr_opt(lt.as_deref(), rt.as_deref()) }, (AddrOf(lbk, lm, le), AddrOf(rbk, rm, re)) => lbk == rbk && lm == rm && eq_expr(le, re), - (Path(lq, lp), Path(rq, rp)) => both(lq.as_ref(), rq.as_ref(), eq_qself) && eq_path(lp, rp), + (Path(lq, lp), Path(rq, rp)) => both(lq.as_deref(), rq.as_deref(), eq_qself) && eq_path(lp, rp), (MacCall(l), MacCall(r)) => eq_mac_call(l, r), (Struct(lse), Struct(rse)) => { - eq_maybe_qself(lse.qself.as_ref(), rse.qself.as_ref()) + eq_maybe_qself(lse.qself.as_deref(), rse.qself.as_deref()) && eq_path(&lse.path, &rse.path) && eq_struct_rest(&lse.rest, &rse.rest) && unordered_over(&lse.fields, &rse.fields, eq_field) @@ -279,8 +282,8 @@ pub fn eq_field(l: &ExprField, r: &ExprField) -> bool { pub fn eq_arm(l: &Arm, r: &Arm) -> bool { l.is_placeholder == r.is_placeholder && eq_pat(&l.pat, &r.pat) - && eq_expr_opt(l.body.as_ref(), r.body.as_ref()) - && eq_expr_opt(l.guard.as_ref(), r.guard.as_ref()) + && eq_expr_opt(l.body.as_deref(), r.body.as_deref()) + && eq_expr_opt(l.guard.as_deref(), r.guard.as_deref()) && over(&l.attrs, &r.attrs, eq_attr) } @@ -348,7 +351,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { safety: rs, define_opaque: _, }), - ) => eq_id(*li, *ri) && lm == rm && ls == rs && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()), + ) => eq_id(*li, *ri) && lm == rm && ls == rs && eq_ty(lt, rt) && eq_expr_opt(le.as_deref(), re.as_deref()), ( Const(box ConstItem { defaultness: ld, @@ -371,7 +374,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_ref(), re.as_ref()) + && eq_expr_opt(le.as_deref(), re.as_deref()) }, ( Fn(box ast::Fn { @@ -404,7 +407,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { ls == rs && eq_id(*li, *ri) && match (lmk, rmk) { - (ModKind::Loaded(litems, linline, _, _), ModKind::Loaded(ritems, rinline, _, _)) => { + (ModKind::Loaded(litems, linline, _), ModKind::Loaded(ritems, rinline, _)) => { linline == rinline && over(litems, ritems, |l, r| eq_item(l, r, eq_item_kind)) }, (ModKind::Unloaded, ModKind::Unloaded) => true, @@ -474,33 +477,27 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { eq_id(*li, *ri) && eq_generics(lg, rg) && over(lb, rb, eq_generic_bound) }, ( - Impl(box ast::Impl { - safety: lu, - polarity: lp, - defaultness: ld, - constness: lc, + Impl(ast::Impl { generics: lg, of_trait: lot, self_ty: lst, items: li, }), - Impl(box ast::Impl { - safety: ru, - polarity: rp, - defaultness: rd, - constness: rc, + Impl(ast::Impl { generics: rg, of_trait: rot, self_ty: rst, items: ri, }), ) => { - matches!(lu, Safety::Default) == matches!(ru, Safety::Default) - && matches!(lp, ImplPolarity::Positive) == matches!(rp, ImplPolarity::Positive) - && eq_defaultness(*ld, *rd) - && matches!(lc, ast::Const::No) == matches!(rc, ast::Const::No) - && eq_generics(lg, rg) - && both(lot.as_ref(), rot.as_ref(), |l, r| eq_path(&l.path, &r.path)) + eq_generics(lg, rg) + && both(lot.as_deref(), rot.as_deref(), |l, r| { + matches!(l.safety, Safety::Default) == matches!(r.safety, Safety::Default) + && matches!(l.polarity, ImplPolarity::Positive) == matches!(r.polarity, ImplPolarity::Positive) + && eq_defaultness(l.defaultness, r.defaultness) + && matches!(l.constness, ast::Const::No) == matches!(r.constness, ast::Const::No) + && eq_path(&l.trait_ref.path, &r.trait_ref.path) + }) && eq_ty(lst, rst) && over(li, ri, |l, r| eq_item(l, r, eq_assoc_item_kind)) }, @@ -532,7 +529,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool { safety: rs, define_opaque: _, }), - ) => eq_id(*li, *ri) && eq_ty(lt, rt) && lm == rm && eq_expr_opt(le.as_ref(), re.as_ref()) && ls == rs, + ) => eq_id(*li, *ri) && eq_ty(lt, rt) && lm == rm && eq_expr_opt(le.as_deref(), re.as_deref()) && ls == rs, ( Fn(box ast::Fn { defaultness: ld, @@ -614,7 +611,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_ref(), re.as_ref()) + && eq_expr_opt(le.as_deref(), re.as_deref()) }, ( Fn(box ast::Fn { @@ -727,10 +724,11 @@ pub fn eq_fn_header(l: &FnHeader, r: &FnHeader) -> bool { } #[expect(clippy::ref_option, reason = "This is the type how it is stored in the AST")] -pub fn eq_opt_fn_contract(l: &Option<P<FnContract>>, r: &Option<P<FnContract>>) -> bool { +pub fn eq_opt_fn_contract(l: &Option<Box<FnContract>>, r: &Option<Box<FnContract>>) -> bool { match (l, r) { (Some(l), Some(r)) => { - eq_expr_opt(l.requires.as_ref(), r.requires.as_ref()) && eq_expr_opt(l.ensures.as_ref(), r.ensures.as_ref()) + eq_expr_opt(l.requires.as_deref(), r.requires.as_deref()) + && eq_expr_opt(l.ensures.as_deref(), r.ensures.as_deref()) }, (None, None) => true, (Some(_), None) | (None, Some(_)) => false, @@ -848,7 +846,7 @@ pub fn eq_ty(l: &Ty, r: &Ty) -> bool { && eq_fn_decl(&l.decl, &r.decl) }, (Tup(l), Tup(r)) => over(l, r, |l, r| eq_ty(l, r)), - (Path(lq, lp), Path(rq, rp)) => both(lq.as_ref(), rq.as_ref(), eq_qself) && eq_path(lp, rp), + (Path(lq, lp), Path(rq, rp)) => both(lq.as_deref(), rq.as_deref(), eq_qself) && eq_path(lp, rp), (TraitObject(lg, ls), TraitObject(rg, rs)) => ls == rs && over(lg, rg, eq_generic_bound), (ImplTrait(_, lg), ImplTrait(_, rg)) => over(lg, rg, eq_generic_bound), (Typeof(l), Typeof(r)) => eq_expr(&l.value, &r.value), diff --git a/clippy_utils/src/check_proc_macro.rs b/clippy_utils/src/check_proc_macro.rs index dc31ed08fb7..c4a759e919b 100644 --- a/clippy_utils/src/check_proc_macro.rs +++ b/clippy_utils/src/check_proc_macro.rs @@ -20,7 +20,7 @@ use rustc_hir::intravisit::FnKind; use rustc_hir::{ Block, BlockCheckMode, Body, Closure, Destination, Expr, ExprKind, FieldDef, FnHeader, FnRetTy, HirId, Impl, ImplItem, ImplItemKind, IsAuto, Item, ItemKind, Lit, LoopSource, MatchSource, MutTy, Node, Path, QPath, Safety, - TraitItem, TraitItemKind, Ty, TyKind, UnOp, UnsafeSource, Variant, VariantData, YieldSource, + TraitImplHeader, TraitItem, TraitItemKind, Ty, TyKind, UnOp, UnsafeSource, Variant, VariantData, YieldSource, }; use rustc_lint::{EarlyContext, LateContext, LintContext}; use rustc_middle::ty::TyCtxt; @@ -254,7 +254,10 @@ fn item_search_pat(item: &Item<'_>) -> (Pat, Pat) { ItemKind::Union(..) => (Pat::Str("union"), Pat::Str("}")), ItemKind::Trait(_, _, Safety::Unsafe, ..) | ItemKind::Impl(Impl { - safety: Safety::Unsafe, .. + of_trait: Some(TraitImplHeader { + safety: Safety::Unsafe, .. + }), + .. }) => (Pat::Str("unsafe"), Pat::Str("}")), ItemKind::Trait(_, IsAuto::Yes, ..) => (Pat::Str("auto"), Pat::Str("}")), ItemKind::Trait(..) => (Pat::Str("trait"), Pat::Str("}")), diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 0a269cf6f43..8533fa85541 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -545,8 +545,9 @@ pub fn path_def_id<'tcx>(cx: &LateContext<'_>, maybe_path: &impl MaybePath<'tcx> pub fn trait_ref_of_method<'tcx>(cx: &LateContext<'tcx>, owner: OwnerId) -> Option<&'tcx TraitRef<'tcx>> { if let Node::Item(item) = cx.tcx.hir_node(cx.tcx.hir_owner_parent(owner)) && let ItemKind::Impl(impl_) = &item.kind + && let Some(of_trait) = impl_.of_trait { - return impl_.of_trait.as_ref(); + return Some(&of_trait.trait_ref); } None } diff --git a/clippy_utils/src/macros.rs b/clippy_utils/src/macros.rs index 60473a26493..7cd5a16f5b4 100644 --- a/clippy_utils/src/macros.rs +++ b/clippy_utils/src/macros.rs @@ -250,18 +250,13 @@ impl<'a> PanicExpn<'a> { }; let name = path.segments.last().unwrap().ident.name; - // This has no argument - if name == sym::panic_cold_explicit { - return Some(Self::Empty); - } - let [arg, rest @ ..] = args else { return None; }; let result = match name { sym::panic if arg.span.eq_ctxt(expr.span) => Self::Empty, sym::panic | sym::panic_str => Self::Str(arg), - sym::panic_display | sym::panic_cold_display => { + sym::panic_display => { let ExprKind::AddrOf(_, _, e) = &arg.kind else { return None; }; diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index ce7cc9348fb..278101ac27f 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -241,9 +241,6 @@ generate! { or_insert, or_insert_with, outer_expn, - panic_cold_display, - panic_cold_explicit, - panic_display, panic_str, parse, partition, diff --git a/clippy_utils/src/visitors.rs b/clippy_utils/src/visitors.rs index ba5cbc73836..c9f5401ebe7 100644 --- a/clippy_utils/src/visitors.rs +++ b/clippy_utils/src/visitors.rs @@ -460,7 +460,8 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool { } fn visit_nested_item(&mut self, id: ItemId) -> Self::Result { if let ItemKind::Impl(i) = &self.cx.tcx.hir_item(id).kind - && i.safety.is_unsafe() + && let Some(of_trait) = i.of_trait + && of_trait.safety.is_unsafe() { ControlFlow::Break(()) } else { diff --git a/rust-toolchain.toml b/rust-toolchain.toml index ac51ec2d61b..5497e77e8ad 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,6 +1,6 @@ [toolchain] # begin autogenerated nightly -channel = "nightly-2025-08-07" +channel = "nightly-2025-08-22" # end autogenerated nightly components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] profile = "minimal" diff --git a/tests/missing-test-files.rs b/tests/missing-test-files.rs index 565dcd73f58..63f960c92fa 100644 --- a/tests/missing-test-files.rs +++ b/tests/missing-test-files.rs @@ -1,6 +1,6 @@ #![warn(rust_2018_idioms, unused_lifetimes)] #![allow(clippy::assertions_on_constants)] -#![feature(path_file_prefix)] +#![cfg_attr(bootstrap, feature(path_file_prefix))] use std::cmp::Ordering; use std::ffi::OsStr; diff --git a/tests/ui/bool_assert_comparison.fixed b/tests/ui/bool_assert_comparison.fixed index 721d8b2c2dc..ec76abbef05 100644 --- a/tests/ui/bool_assert_comparison.fixed +++ b/tests/ui/bool_assert_comparison.fixed @@ -1,7 +1,7 @@ #![allow(unused, clippy::assertions_on_constants, clippy::const_is_empty)] #![warn(clippy::bool_assert_comparison)] -use std::ops::Not; +use std::ops::{Add, Not}; macro_rules! a { () => { @@ -62,6 +62,14 @@ impl Not for ImplNotTraitWithBool { } } +impl Add for ImplNotTraitWithBool { + type Output = Self; + + fn add(self, other: Self) -> Self::Output { + self + } +} + #[derive(Debug)] struct NonCopy; @@ -94,7 +102,7 @@ fn main() { assert_eq!(a!(), "".is_empty()); assert_eq!("".is_empty(), b!()); assert_eq!(a, true); - assert!(b); + assert!(!!b); //~^ bool_assert_comparison assert_ne!("a".len(), 1); @@ -122,7 +130,7 @@ fn main() { debug_assert_eq!(a!(), "".is_empty()); debug_assert_eq!("".is_empty(), b!()); debug_assert_eq!(a, true); - debug_assert!(b); + debug_assert!(!!b); //~^ bool_assert_comparison debug_assert_ne!("a".len(), 1); @@ -167,7 +175,7 @@ fn main() { use debug_assert_eq as renamed; renamed!(a, true); - debug_assert!(b); + debug_assert!(!!b); //~^ bool_assert_comparison let non_copy = NonCopy; @@ -199,4 +207,12 @@ fn main() { //~^ bool_assert_comparison debug_assert!(!"requires negation".is_empty()); //~^ bool_assert_comparison + assert!(!b); + //~^ bool_assert_comparison + assert!(!(!b)); + //~^ bool_assert_comparison + assert!(!!(b + b)); + //~^ bool_assert_comparison + assert!(!(b + b)); + //~^ bool_assert_comparison } diff --git a/tests/ui/bool_assert_comparison.rs b/tests/ui/bool_assert_comparison.rs index 5ab4f475b06..40824a23c82 100644 --- a/tests/ui/bool_assert_comparison.rs +++ b/tests/ui/bool_assert_comparison.rs @@ -1,7 +1,7 @@ #![allow(unused, clippy::assertions_on_constants, clippy::const_is_empty)] #![warn(clippy::bool_assert_comparison)] -use std::ops::Not; +use std::ops::{Add, Not}; macro_rules! a { () => { @@ -62,6 +62,14 @@ impl Not for ImplNotTraitWithBool { } } +impl Add for ImplNotTraitWithBool { + type Output = Self; + + fn add(self, other: Self) -> Self::Output { + self + } +} + #[derive(Debug)] struct NonCopy; @@ -199,4 +207,12 @@ fn main() { //~^ bool_assert_comparison debug_assert_eq!("requires negation".is_empty(), false); //~^ bool_assert_comparison + assert_eq!(!b, true); + //~^ bool_assert_comparison + assert_eq!(!b, false); + //~^ bool_assert_comparison + assert_eq!(b + b, true); + //~^ bool_assert_comparison + assert_eq!(b + b, false); + //~^ bool_assert_comparison } diff --git a/tests/ui/bool_assert_comparison.stderr b/tests/ui/bool_assert_comparison.stderr index a1d0af54361..f823f08f31d 100644 --- a/tests/ui/bool_assert_comparison.stderr +++ b/tests/ui/bool_assert_comparison.stderr @@ -1,5 +1,5 @@ error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:87:5 + --> tests/ui/bool_assert_comparison.rs:95:5 | LL | assert_eq!("a".is_empty(), false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL + assert!(!"a".is_empty()); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:89:5 + --> tests/ui/bool_assert_comparison.rs:97:5 | LL | assert_eq!("".is_empty(), true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + assert!("".is_empty()); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:91:5 + --> tests/ui/bool_assert_comparison.rs:99:5 | LL | assert_eq!(true, "".is_empty()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + assert!("".is_empty()); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:97:5 + --> tests/ui/bool_assert_comparison.rs:105:5 | LL | assert_eq!(b, true); | ^^^^^^^^^^^^^^^^^^^ @@ -45,11 +45,11 @@ LL | assert_eq!(b, true); help: replace it with `assert!(..)` | LL - assert_eq!(b, true); -LL + assert!(b); +LL + assert!(!!b); | error: used `assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:101:5 + --> tests/ui/bool_assert_comparison.rs:109:5 | LL | assert_ne!("a".is_empty(), false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + assert!("a".is_empty()); | error: used `assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:103:5 + --> tests/ui/bool_assert_comparison.rs:111:5 | LL | assert_ne!("".is_empty(), true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL + assert!(!"".is_empty()); | error: used `assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:105:5 + --> tests/ui/bool_assert_comparison.rs:113:5 | LL | assert_ne!(true, "".is_empty()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + assert!(!"".is_empty()); | error: used `assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:111:5 + --> tests/ui/bool_assert_comparison.rs:119:5 | LL | assert_ne!(b, true); | ^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL + assert!(!b); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:115:5 + --> tests/ui/bool_assert_comparison.rs:123:5 | LL | debug_assert_eq!("a".is_empty(), false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL + debug_assert!(!"a".is_empty()); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:117:5 + --> tests/ui/bool_assert_comparison.rs:125:5 | LL | debug_assert_eq!("".is_empty(), true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL + debug_assert!("".is_empty()); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:119:5 + --> tests/ui/bool_assert_comparison.rs:127:5 | LL | debug_assert_eq!(true, "".is_empty()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL + debug_assert!("".is_empty()); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:125:5 + --> tests/ui/bool_assert_comparison.rs:133:5 | LL | debug_assert_eq!(b, true); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -141,11 +141,11 @@ LL | debug_assert_eq!(b, true); help: replace it with `debug_assert!(..)` | LL - debug_assert_eq!(b, true); -LL + debug_assert!(b); +LL + debug_assert!(!!b); | error: used `debug_assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:129:5 + --> tests/ui/bool_assert_comparison.rs:137:5 | LL | debug_assert_ne!("a".is_empty(), false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL + debug_assert!("a".is_empty()); | error: used `debug_assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:131:5 + --> tests/ui/bool_assert_comparison.rs:139:5 | LL | debug_assert_ne!("".is_empty(), true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -169,7 +169,7 @@ LL + debug_assert!(!"".is_empty()); | error: used `debug_assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:133:5 + --> tests/ui/bool_assert_comparison.rs:141:5 | LL | debug_assert_ne!(true, "".is_empty()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL + debug_assert!(!"".is_empty()); | error: used `debug_assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:139:5 + --> tests/ui/bool_assert_comparison.rs:147:5 | LL | debug_assert_ne!(b, true); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -193,7 +193,7 @@ LL + debug_assert!(!b); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:145:5 + --> tests/ui/bool_assert_comparison.rs:153:5 | LL | assert_eq!("a".is_empty(), false, "tadam {}", 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -205,7 +205,7 @@ LL + assert!(!"a".is_empty(), "tadam {}", 1); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:147:5 + --> tests/ui/bool_assert_comparison.rs:155:5 | LL | assert_eq!("a".is_empty(), false, "tadam {}", true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -217,7 +217,7 @@ LL + assert!(!"a".is_empty(), "tadam {}", true); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:149:5 + --> tests/ui/bool_assert_comparison.rs:157:5 | LL | assert_eq!(false, "a".is_empty(), "tadam {}", true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -229,7 +229,7 @@ LL + assert!(!"a".is_empty(), "tadam {}", true); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:155:5 + --> tests/ui/bool_assert_comparison.rs:163:5 | LL | debug_assert_eq!("a".is_empty(), false, "tadam {}", 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -241,7 +241,7 @@ LL + debug_assert!(!"a".is_empty(), "tadam {}", 1); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:157:5 + --> tests/ui/bool_assert_comparison.rs:165:5 | LL | debug_assert_eq!("a".is_empty(), false, "tadam {}", true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -253,7 +253,7 @@ LL + debug_assert!(!"a".is_empty(), "tadam {}", true); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:159:5 + --> tests/ui/bool_assert_comparison.rs:167:5 | LL | debug_assert_eq!(false, "a".is_empty(), "tadam {}", true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -265,31 +265,35 @@ LL + debug_assert!(!"a".is_empty(), "tadam {}", true); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:163:5 + --> tests/ui/bool_assert_comparison.rs:171:5 | LL | assert_eq!(a!(), true); | ^^^^^^^^^^^^^^^^^^^^^^ | help: replace it with `assert!(..)` | -LL - assert_eq!(a!(), true); -LL + assert!(a!()); +LL | true +... +LL | +LL ~ assert!(a!()); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:165:5 + --> tests/ui/bool_assert_comparison.rs:173:5 | LL | assert_eq!(true, b!()); | ^^^^^^^^^^^^^^^^^^^^^^ | help: replace it with `assert!(..)` | -LL - assert_eq!(true, b!()); -LL + assert!(b!()); +LL | true +... +LL | +LL ~ assert!(b!()); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:170:5 + --> tests/ui/bool_assert_comparison.rs:178:5 | LL | renamed!(b, true); | ^^^^^^^^^^^^^^^^^ @@ -297,11 +301,11 @@ LL | renamed!(b, true); help: replace it with `debug_assert!(..)` | LL - renamed!(b, true); -LL + debug_assert!(b); +LL + debug_assert!(!!b); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:185:5 + --> tests/ui/bool_assert_comparison.rs:193:5 | LL | assert_eq!("".is_empty(), true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -313,7 +317,7 @@ LL + assert!("".is_empty()); | error: used `assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:187:5 + --> tests/ui/bool_assert_comparison.rs:195:5 | LL | assert_ne!("".is_empty(), false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -325,7 +329,7 @@ LL + assert!("".is_empty()); | error: used `assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:189:5 + --> tests/ui/bool_assert_comparison.rs:197:5 | LL | assert_ne!("requires negation".is_empty(), true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -337,7 +341,7 @@ LL + assert!(!"requires negation".is_empty()); | error: used `assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:191:5 + --> tests/ui/bool_assert_comparison.rs:199:5 | LL | assert_eq!("requires negation".is_empty(), false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -349,7 +353,7 @@ LL + assert!(!"requires negation".is_empty()); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:194:5 + --> tests/ui/bool_assert_comparison.rs:202:5 | LL | debug_assert_eq!("".is_empty(), true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -361,7 +365,7 @@ LL + debug_assert!("".is_empty()); | error: used `debug_assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:196:5 + --> tests/ui/bool_assert_comparison.rs:204:5 | LL | debug_assert_ne!("".is_empty(), false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -373,7 +377,7 @@ LL + debug_assert!("".is_empty()); | error: used `debug_assert_ne!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:198:5 + --> tests/ui/bool_assert_comparison.rs:206:5 | LL | debug_assert_ne!("requires negation".is_empty(), true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -385,7 +389,7 @@ LL + debug_assert!(!"requires negation".is_empty()); | error: used `debug_assert_eq!` with a literal bool - --> tests/ui/bool_assert_comparison.rs:200:5 + --> tests/ui/bool_assert_comparison.rs:208:5 | LL | debug_assert_eq!("requires negation".is_empty(), false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -396,5 +400,53 @@ LL - debug_assert_eq!("requires negation".is_empty(), false); LL + debug_assert!(!"requires negation".is_empty()); | -error: aborting due to 33 previous errors +error: used `assert_eq!` with a literal bool + --> tests/ui/bool_assert_comparison.rs:210:5 + | +LL | assert_eq!(!b, true); + | ^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_eq!(!b, true); +LL + assert!(!b); + | + +error: used `assert_eq!` with a literal bool + --> tests/ui/bool_assert_comparison.rs:212:5 + | +LL | assert_eq!(!b, false); + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_eq!(!b, false); +LL + assert!(!(!b)); + | + +error: used `assert_eq!` with a literal bool + --> tests/ui/bool_assert_comparison.rs:214:5 + | +LL | assert_eq!(b + b, true); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_eq!(b + b, true); +LL + assert!(!!(b + b)); + | + +error: used `assert_eq!` with a literal bool + --> tests/ui/bool_assert_comparison.rs:216:5 + | +LL | assert_eq!(b + b, false); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_eq!(b + b, false); +LL + assert!(!(b + b)); + | + +error: aborting due to 37 previous errors diff --git a/tests/ui/checked_unwrap/simple_conditionals.stderr b/tests/ui/checked_unwrap/simple_conditionals.stderr index 26e360112b6..939b509d85c 100644 --- a/tests/ui/checked_unwrap/simple_conditionals.stderr +++ b/tests/ui/checked_unwrap/simple_conditionals.stderr @@ -330,7 +330,7 @@ LL | if X.is_some() { | = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html> = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives - = note: `#[deny(static_mut_refs)]` on by default + = note: `#[deny(static_mut_refs)]` (part of `#[deny(rust_2024_compatibility)]`) on by default error: aborting due to 36 previous errors diff --git a/tests/ui/const_is_empty.rs b/tests/ui/const_is_empty.rs index 8bb4f0e5d97..63c6342a323 100644 --- a/tests/ui/const_is_empty.rs +++ b/tests/ui/const_is_empty.rs @@ -196,6 +196,7 @@ fn issue_13106() { const { assert!(EMPTY_STR.is_empty()); + //~^ const_is_empty } const { diff --git a/tests/ui/const_is_empty.stderr b/tests/ui/const_is_empty.stderr index 2ba189058e8..9a42518698e 100644 --- a/tests/ui/const_is_empty.stderr +++ b/tests/ui/const_is_empty.stderr @@ -158,10 +158,16 @@ LL | let _ = val.is_empty(); | ^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:202:9 + --> tests/ui/const_is_empty.rs:198:17 + | +LL | assert!(EMPTY_STR.is_empty()); + | ^^^^^^^^^^^^^^^^^^^^ + +error: this expression always evaluates to true + --> tests/ui/const_is_empty.rs:203:9 | LL | EMPTY_STR.is_empty(); | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 27 previous errors +error: aborting due to 28 previous errors diff --git a/tests/ui/crashes/ice-6255.rs b/tests/ui/crashes/ice-6255.rs index ef1e01f80ef..5f31696c791 100644 --- a/tests/ui/crashes/ice-6255.rs +++ b/tests/ui/crashes/ice-6255.rs @@ -9,7 +9,7 @@ macro_rules! define_other_core { } fn main() { - core::panic!(); + core::panic!(); //~ ERROR: `core` is ambiguous } define_other_core!(); diff --git a/tests/ui/crashes/ice-6255.stderr b/tests/ui/crashes/ice-6255.stderr index 738e9d1bd5c..420e4af936f 100644 --- a/tests/ui/crashes/ice-6255.stderr +++ b/tests/ui/crashes/ice-6255.stderr @@ -9,5 +9,25 @@ LL | define_other_core!(); | = note: this error originates in the macro `define_other_core` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 1 previous error +error[E0659]: `core` is ambiguous + --> tests/ui/crashes/ice-6255.rs:12:5 + | +LL | core::panic!(); + | ^^^^ ambiguous name + | + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution + = note: `core` could refer to a built-in crate +note: `core` could also refer to the crate imported here + --> tests/ui/crashes/ice-6255.rs:6:9 + | +LL | extern crate std as core; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | define_other_core!(); + | -------------------- in this macro invocation + = help: use `crate::core` to refer to this crate unambiguously + = note: this error originates in the macro `define_other_core` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/crashes/ice-96721.stderr b/tests/ui/crashes/ice-96721.stderr index f0778a4b32b..23f7300178e 100644 --- a/tests/ui/crashes/ice-96721.stderr +++ b/tests/ui/crashes/ice-96721.stderr @@ -3,6 +3,8 @@ error: malformed `path` attribute input | LL | #[path = foo!()] | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[path = "file"]` + | + = note: for more information, visit <https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute> error: aborting due to 1 previous error diff --git a/tests/ui/incompatible_msrv.rs b/tests/ui/incompatible_msrv.rs index f7f21e1850d..882f909e30c 100644 --- a/tests/ui/incompatible_msrv.rs +++ b/tests/ui/incompatible_msrv.rs @@ -1,6 +1,6 @@ #![warn(clippy::incompatible_msrv)] #![feature(custom_inner_attributes)] -#![allow(stable_features)] +#![allow(stable_features, clippy::diverging_sub_expression)] #![feature(strict_provenance)] // For use in test #![clippy::msrv = "1.3.0"] |
