diff options
| author | Philipp Krones <hello@philkrones.com> | 2025-06-26 17:34:27 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-26 17:34:27 +0000 |
| commit | c950602c01b2a68b7502388d440270d4e3ee64aa (patch) | |
| tree | 69d3177d81af95c7c8c162af72befe4eb2fa2b8a | |
| parent | 8050e591b6db92d8c1df55994415b1acfaf1d150 (diff) | |
| parent | 32fcff8aa8a5c6092917ac8c87da4341a7ed2d0b (diff) | |
| download | rust-c950602c01b2a68b7502388d440270d4e3ee64aa.tar.gz rust-c950602c01b2a68b7502388d440270d4e3ee64aa.zip | |
Rustup (#15148)
r? @ghost changelog: none
54 files changed, 277 insertions, 213 deletions
diff --git a/Cargo.toml b/Cargo.toml index 8cd648cf9f0..8cbdcf45693 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy" -version = "0.1.89" +version = "0.1.90" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" @@ -59,6 +59,7 @@ rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" } [features] integration = ["dep:tempfile"] internal = ["dep:clippy_lints_internal", "dep:tempfile"] +jemalloc = [] [package.metadata.rust-analyzer] # This package uses #[feature(rustc_private)] diff --git a/clippy_config/Cargo.toml b/clippy_config/Cargo.toml index 0606245f990..858366c8a5c 100644 --- a/clippy_config/Cargo.toml +++ b/clippy_config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_config" -version = "0.1.89" +version = "0.1.90" edition = "2024" publish = false diff --git a/clippy_dev/src/update_lints.rs b/clippy_dev/src/update_lints.rs index 6dbee33ffca..5f6e874ffe2 100644 --- a/clippy_dev/src/update_lints.rs +++ b/clippy_dev/src/update_lints.rs @@ -386,17 +386,13 @@ pub fn read_deprecated_lints() -> (Vec<DeprecatedLint>, Vec<RenamedLint>) { /// Removes the line splices and surrounding quotes from a string literal fn parse_str_lit(s: &str) -> String { - let (s, mode) = if let Some(s) = s.strip_prefix("r") { - (s.trim_matches('#'), rustc_literal_escaper::Mode::RawStr) - } else { - (s, rustc_literal_escaper::Mode::Str) - }; + let s = s.strip_prefix("r").unwrap_or(s).trim_matches('#'); let s = s .strip_prefix('"') .and_then(|s| s.strip_suffix('"')) .unwrap_or_else(|| panic!("expected quoted string, found `{s}`")); let mut res = String::with_capacity(s.len()); - rustc_literal_escaper::unescape_unicode(s, mode, &mut |_, ch| { + rustc_literal_escaper::unescape_str(s, &mut |_, ch| { if let Ok(ch) = ch { res.push(ch); } diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index 37b554fd0d8..c03cc99b581 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_lints" -version = "0.1.89" +version = "0.1.90" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/clippy_lints/src/attrs/inline_always.rs b/clippy_lints/src/attrs/inline_always.rs index cb63fadb4e2..b8f93ee5e2c 100644 --- a/clippy_lints/src/attrs/inline_always.rs +++ b/clippy_lints/src/attrs/inline_always.rs @@ -1,29 +1,22 @@ use super::INLINE_ALWAYS; -use super::utils::is_word; use clippy_utils::diagnostics::span_lint; +use rustc_attr_data_structures::{AttributeKind, InlineAttr, find_attr}; use rustc_hir::Attribute; use rustc_lint::LateContext; +use rustc_span::Span; use rustc_span::symbol::Symbol; -use rustc_span::{Span, sym}; pub(super) fn check(cx: &LateContext<'_>, span: Span, name: Symbol, attrs: &[Attribute]) { if span.from_expansion() { return; } - for attr in attrs { - if let Some(values) = attr.meta_item_list() { - if values.len() != 1 || !attr.has_name(sym::inline) { - continue; - } - if is_word(&values[0], sym::always) { - span_lint( - cx, - INLINE_ALWAYS, - attr.span(), - format!("you have declared `#[inline(always)]` on `{name}`. This is usually a bad idea"), - ); - } - } + if let Some(span) = find_attr!(attrs, AttributeKind::Inline(InlineAttr::Always, span) => *span) { + span_lint( + cx, + INLINE_ALWAYS, + span, + format!("you have declared `#[inline(always)]` on `{name}`. This is usually a bad idea"), + ); } } diff --git a/clippy_lints/src/bool_assert_comparison.rs b/clippy_lints/src/bool_assert_comparison.rs index ae36bb76117..8f95e44bf85 100644 --- a/clippy_lints/src/bool_assert_comparison.rs +++ b/clippy_lints/src/bool_assert_comparison.rs @@ -56,7 +56,7 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) - .and_then(|trait_id| { cx.tcx.associated_items(trait_id).find_by_ident_and_kind( cx.tcx, - Ident::from_str("Output"), + Ident::with_dummy_span(sym::Output), ty::AssocTag::Type, trait_id, ) diff --git a/clippy_lints/src/casts/manual_dangling_ptr.rs b/clippy_lints/src/casts/manual_dangling_ptr.rs index 61dfc0fc042..d9e88d6a401 100644 --- a/clippy_lints/src/casts/manual_dangling_ptr.rs +++ b/clippy_lints/src/casts/manual_dangling_ptr.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::SpanRangeExt; -use clippy_utils::{expr_or_init, path_def_id, paths, std_or_core}; +use clippy_utils::{expr_or_init, is_path_diagnostic_item, std_or_core, sym}; use rustc_ast::LitKind; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, GenericArg, Mutability, QPath, Ty, TyKind}; @@ -53,8 +53,7 @@ fn is_expr_const_aligned(cx: &LateContext<'_>, expr: &Expr<'_>, to: &Ty<'_>) -> fn is_align_of_call(cx: &LateContext<'_>, fun: &Expr<'_>, to: &Ty<'_>) -> bool { if let ExprKind::Path(QPath::Resolved(_, path)) = fun.kind - && let Some(fun_id) = path_def_id(cx, fun) - && paths::ALIGN_OF.matches(cx, fun_id) + && is_path_diagnostic_item(cx, fun, sym::mem_align_of) && let Some(args) = path.segments.last().and_then(|seg| seg.args) && let [GenericArg::Type(generic_ty)] = args.args { diff --git a/clippy_lints/src/casts/unnecessary_cast.rs b/clippy_lints/src/casts/unnecessary_cast.rs index 8e8c55cf383..010f09d4c1d 100644 --- a/clippy_lints/src/casts/unnecessary_cast.rs +++ b/clippy_lints/src/casts/unnecessary_cast.rs @@ -185,7 +185,7 @@ pub(super) fn check<'tcx>( Node::Expr(parent) if is_borrow_expr(cx, parent) && !is_in_allowed_macro(cx, parent) => { MaybeParenOrBlock::Block }, - Node::Expr(parent) if cast_expr.precedence() < parent.precedence() => MaybeParenOrBlock::Paren, + Node::Expr(parent) if cx.precedence(cast_expr) < cx.precedence(parent) => MaybeParenOrBlock::Paren, _ => MaybeParenOrBlock::Nothing, }; diff --git a/clippy_lints/src/coerce_container_to_any.rs b/clippy_lints/src/coerce_container_to_any.rs index 8c12a42ba4e..2b659253763 100644 --- a/clippy_lints/src/coerce_container_to_any.rs +++ b/clippy_lints/src/coerce_container_to_any.rs @@ -42,7 +42,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.88.0"] pub COERCE_CONTAINER_TO_ANY, - suspicious, + nursery, "coercing to `&dyn Any` when dereferencing could produce a `dyn Any` without coercion is usually not intended" } declare_lint_pass!(CoerceContainerToAny => [COERCE_CONTAINER_TO_ANY]); diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index cde9528cd87..7463d7b5c3b 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -972,7 +972,7 @@ fn report<'tcx>( "&" }; - let expr_str = if !expr_is_macro_call && is_ufcs && expr.precedence() < ExprPrecedence::Prefix { + let expr_str = if !expr_is_macro_call && is_ufcs && cx.precedence(expr) < ExprPrecedence::Prefix { Cow::Owned(format!("({expr_str})")) } else { expr_str @@ -1015,10 +1015,10 @@ fn report<'tcx>( Node::Expr(e) => match e.kind { ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => false, ExprKind::Call(..) => { - expr.precedence() < ExprPrecedence::Unambiguous + cx.precedence(expr) < ExprPrecedence::Unambiguous || matches!(expr.kind, ExprKind::Field(..)) }, - _ => expr.precedence() < e.precedence(), + _ => cx.precedence(expr) < cx.precedence(e), }, _ => false, }; @@ -1066,7 +1066,7 @@ fn report<'tcx>( Mutability::Not => "&", Mutability::Mut => "&mut ", }; - (prefix, expr.precedence() < ExprPrecedence::Prefix) + (prefix, cx.precedence(expr) < ExprPrecedence::Prefix) }, None if !ty.is_ref() && data.adjusted_ty.is_ref() => ("&", false), _ => ("", false), @@ -1172,7 +1172,7 @@ impl<'tcx> Dereferencing<'tcx> { }, Some(parent) if !parent.span.from_expansion() => { // Double reference might be needed at this point. - if parent.precedence() == ExprPrecedence::Unambiguous { + if cx.precedence(parent) == ExprPrecedence::Unambiguous { // Parentheses would be needed here, don't lint. *outer_pat = None; } else { diff --git a/clippy_lints/src/doc/doc_suspicious_footnotes.rs b/clippy_lints/src/doc/doc_suspicious_footnotes.rs index 289b6b915d4..3330cc5defd 100644 --- a/clippy_lints/src/doc/doc_suspicious_footnotes.rs +++ b/clippy_lints/src/doc/doc_suspicious_footnotes.rs @@ -1,4 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_then; +use rustc_ast::attr::AttributeExt as _; use rustc_ast::token::CommentKind; use rustc_errors::Applicability; use rustc_hir::{AttrStyle, Attribute}; @@ -43,13 +44,15 @@ pub fn check(cx: &LateContext<'_>, doc: &str, range: Range<usize>, fragments: &F "looks like a footnote ref, but has no matching footnote", |diag| { if this_fragment.kind == DocFragmentKind::SugaredDoc { - let (doc_attr, (_, doc_attr_comment_kind)) = attrs + let (doc_attr, (_, doc_attr_comment_kind), attr_style) = attrs .iter() .filter(|attr| attr.span().overlaps(this_fragment.span)) .rev() - .find_map(|attr| Some((attr, attr.doc_str_and_comment_kind()?))) + .find_map(|attr| { + Some((attr, attr.doc_str_and_comment_kind()?, attr.doc_resolution_scope()?)) + }) .unwrap(); - let (to_add, terminator) = match (doc_attr_comment_kind, doc_attr.style()) { + let (to_add, terminator) = match (doc_attr_comment_kind, attr_style) { (CommentKind::Line, AttrStyle::Outer) => ("\n///\n/// ", ""), (CommentKind::Line, AttrStyle::Inner) => ("\n//!\n//! ", ""), (CommentKind::Block, AttrStyle::Outer) => ("\n/** ", " */"), diff --git a/clippy_lints/src/doc/needless_doctest_main.rs b/clippy_lints/src/doc/needless_doctest_main.rs index 4bf545bb9f4..74283d7ba86 100644 --- a/clippy_lints/src/doc/needless_doctest_main.rs +++ b/clippy_lints/src/doc/needless_doctest_main.rs @@ -42,9 +42,8 @@ pub fn check( let mut test_attr_spans = vec![]; let filename = FileName::anon_source_code(&code); - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), false); - let emitter = HumanEmitter::new(Box::new(io::sink()), fallback_bundle); + let translator = rustc_driver::default_translator(); + let emitter = HumanEmitter::new(Box::new(io::sink()), translator); let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings(); #[expect(clippy::arc_with_non_send_sync)] // `Arc` is expected by with_dcx let sm = Arc::new(SourceMap::new(FilePathMapping::empty())); diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index fe85ae77b26..0288747d6f3 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -7,6 +7,7 @@ use clippy_utils::{ get_path_from_caller_to_method_type, is_adjusted, is_no_std_crate, path_to_local, path_to_local_id, }; use rustc_abi::ExternAbi; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_errors::Applicability; use rustc_hir::{BindingMode, Expr, ExprKind, FnRetTy, GenericArgs, Param, PatKind, QPath, Safety, TyKind}; use rustc_infer::infer::TyCtxtInferExt; @@ -161,7 +162,7 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx let sig = match callee_ty_adjusted.kind() { ty::FnDef(def, _) => { // Rewriting `x(|| f())` to `x(f)` where f is marked `#[track_caller]` moves the `Location` - if cx.tcx.has_attr(*def, sym::track_caller) { + if find_attr!(cx.tcx.get_all_attrs(*def), AttributeKind::TrackCaller(..)) { return; } @@ -249,7 +250,7 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx }, ExprKind::MethodCall(path, self_, args, _) if check_inputs(typeck, body.params, Some(self_), args) => { if let Some(method_def_id) = typeck.type_dependent_def_id(body.value.hir_id) - && !cx.tcx.has_attr(method_def_id, sym::track_caller) + && !find_attr!(cx.tcx.get_all_attrs(method_def_id), AttributeKind::TrackCaller(..)) && check_sig(closure_sig, cx.tcx.fn_sig(method_def_id).skip_binder().skip_binder()) { let mut app = Applicability::MachineApplicable; diff --git a/clippy_lints/src/functions/must_use.rs b/clippy_lints/src/functions/must_use.rs index 70655838b6a..d959981a83c 100644 --- a/clippy_lints/src/functions/must_use.rs +++ b/clippy_lints/src/functions/must_use.rs @@ -14,6 +14,8 @@ use clippy_utils::source::SpanRangeExt; use clippy_utils::ty::is_must_use_ty; use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{return_ty, trait_ref_of_method}; +use rustc_attr_data_structures::{AttributeKind, find_attr}; +use rustc_span::Symbol; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use core::ops::ControlFlow; @@ -22,7 +24,7 @@ use super::{DOUBLE_MUST_USE, MUST_USE_CANDIDATE, MUST_USE_UNIT}; pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { let attrs = cx.tcx.hir_attrs(item.hir_id()); - let attr = cx.tcx.get_attr(item.owner_id, sym::must_use); + let attr = find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::MustUse { span, reason } => (span, reason)); if let hir::ItemKind::Fn { ref sig, body: ref body_id, @@ -31,9 +33,19 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_> { let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id); let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); - if let Some(attr) = attr { - check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig); - } else if is_public && !is_proc_macro(attrs) && !attrs.iter().any(|a| a.has_name(sym::no_mangle)) { + if let Some((attr_span, reason)) = attr { + check_needless_must_use( + cx, + sig.decl, + item.owner_id, + item.span, + fn_header_span, + *attr_span, + *reason, + attrs, + sig, + ); + } else if is_public && !is_proc_macro(attrs) && !find_attr!(attrs, AttributeKind::NoMangle(..)) { check_must_use_candidate( cx, sig.decl, @@ -52,9 +64,20 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id); let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); let attrs = cx.tcx.hir_attrs(item.hir_id()); - let attr = cx.tcx.get_attr(item.owner_id, sym::must_use); - if let Some(attr) = attr { - check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig); + let attr = + find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::MustUse { span, reason } => (span, reason)); + if let Some((attr_span, reason)) = attr { + check_needless_must_use( + cx, + sig.decl, + item.owner_id, + item.span, + fn_header_span, + *attr_span, + *reason, + attrs, + sig, + ); } else if is_public && !is_proc_macro(attrs) && trait_ref_of_method(cx, item.owner_id).is_none() { check_must_use_candidate( cx, @@ -75,9 +98,20 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); let attrs = cx.tcx.hir_attrs(item.hir_id()); - let attr = cx.tcx.get_attr(item.owner_id, sym::must_use); - if let Some(attr) = attr { - check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig); + let attr = + find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::MustUse { span, reason } => (span, reason)); + if let Some((attr_span, reason)) = attr { + check_needless_must_use( + cx, + sig.decl, + item.owner_id, + item.span, + fn_header_span, + *attr_span, + *reason, + attrs, + sig, + ); } else if let hir::TraitFn::Provided(eid) = *eid { let body = cx.tcx.hir_body(eid); if attr.is_none() && is_public && !is_proc_macro(attrs) { @@ -103,7 +137,8 @@ fn check_needless_must_use( item_id: hir::OwnerId, item_span: Span, fn_header_span: Span, - attr: &Attribute, + attr_span: Span, + reason: Option<Symbol>, attrs: &[Attribute], sig: &FnSig<'_>, ) { @@ -118,12 +153,7 @@ fn check_needless_must_use( fn_header_span, "this unit-returning function has a `#[must_use]` attribute", |diag| { - diag.span_suggestion( - attr.span(), - "remove the attribute", - "", - Applicability::MachineApplicable, - ); + diag.span_suggestion(attr_span, "remove the attribute", "", Applicability::MachineApplicable); }, ); } else { @@ -137,11 +167,11 @@ fn check_needless_must_use( MUST_USE_UNIT, fn_header_span, "this unit-returning function has a `#[must_use]` attribute", - Some(attr.span()), + Some(attr_span), "remove `must_use`", ); } - } else if attr.value_str().is_none() && is_must_use_ty(cx, return_ty(cx, item_id)) { + } else if reason.is_none() && is_must_use_ty(cx, return_ty(cx, item_id)) { // Ignore async functions unless Future::Output type is a must_use type if sig.header.is_async() { let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode()); diff --git a/clippy_lints/src/inline_fn_without_body.rs b/clippy_lints/src/inline_fn_without_body.rs index da5ca5e6772..ffe6ad14f63 100644 --- a/clippy_lints/src/inline_fn_without_body.rs +++ b/clippy_lints/src/inline_fn_without_body.rs @@ -1,10 +1,10 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::sugg::DiagExt; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_errors::Applicability; use rustc_hir::{TraitFn, TraitItem, TraitItemKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; -use rustc_span::sym; declare_clippy_lint! { /// ### What it does @@ -32,15 +32,19 @@ declare_lint_pass!(InlineFnWithoutBody => [INLINE_FN_WITHOUT_BODY]); impl<'tcx> LateLintPass<'tcx> for InlineFnWithoutBody { fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { if let TraitItemKind::Fn(_, TraitFn::Required(_)) = item.kind - && let Some(attr) = cx.tcx.hir_attrs(item.hir_id()).iter().find(|a| a.has_name(sym::inline)) + && let Some(attr_span) = find_attr!(cx + .tcx + .hir_attrs(item.hir_id()), + AttributeKind::Inline(_, span) => *span + ) { span_lint_and_then( cx, INLINE_FN_WITHOUT_BODY, - attr.span(), + attr_span, format!("use of `#[inline]` on trait method `{}` which has no body", item.ident), |diag| { - diag.suggest_remove_item(cx, attr.span(), "remove", Applicability::MachineApplicable); + diag.suggest_remove_item(cx, attr_span, "remove", Applicability::MachineApplicable); }, ); } diff --git a/clippy_lints/src/loops/single_element_loop.rs b/clippy_lints/src/loops/single_element_loop.rs index 12719c4f94b..d66771a8b5b 100644 --- a/clippy_lints/src/loops/single_element_loop.rs +++ b/clippy_lints/src/loops/single_element_loop.rs @@ -84,7 +84,7 @@ pub(super) fn check<'tcx>( if !prefix.is_empty() && ( // Precedence of internal expression is less than or equal to precedence of `&expr`. - arg_expression.precedence() <= ExprPrecedence::Prefix || is_range_literal(arg_expression) + cx.precedence(arg_expression) <= ExprPrecedence::Prefix || is_range_literal(arg_expression) ) { arg_snip = format!("({arg_snip})").into(); diff --git a/clippy_lints/src/manual_option_as_slice.rs b/clippy_lints/src/manual_option_as_slice.rs index b55c11f2d5b..922db174e3d 100644 --- a/clippy_lints/src/manual_option_as_slice.rs +++ b/clippy_lints/src/manual_option_as_slice.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; use clippy_utils::msrvs::Msrv; -use clippy_utils::{is_none_arm, msrvs, paths, peel_hir_expr_refs, sym}; +use clippy_utils::{is_none_arm, msrvs, peel_hir_expr_refs, sym}; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{Arm, Expr, ExprKind, LangItem, Pat, PatKind, QPath, is_range_literal}; @@ -220,5 +220,5 @@ fn is_empty_slice(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { } fn is_slice_from_ref(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - paths::SLICE_FROM_REF.matches_path(cx, expr) + clippy_utils::is_path_diagnostic_item(cx, expr, sym::slice_from_ref) } diff --git a/clippy_lints/src/matches/manual_utils.rs b/clippy_lints/src/matches/manual_utils.rs index d0905733ab5..dbae71bbb1b 100644 --- a/clippy_lints/src/matches/manual_utils.rs +++ b/clippy_lints/src/matches/manual_utils.rs @@ -117,7 +117,7 @@ where // it's being passed by value. let scrutinee = peel_hir_expr_refs(scrutinee).0; let (scrutinee_str, _) = snippet_with_context(cx, scrutinee.span, expr_ctxt, "..", &mut app); - let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence() < ExprPrecedence::Unambiguous { + let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && cx.precedence(scrutinee) < ExprPrecedence::Unambiguous { format!("({scrutinee_str})") } else { scrutinee_str.into() diff --git a/clippy_lints/src/methods/io_other_error.rs b/clippy_lints/src/methods/io_other_error.rs index ec4b9c7ae2e..9276261606e 100644 --- a/clippy_lints/src/methods/io_other_error.rs +++ b/clippy_lints/src/methods/io_other_error.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::{expr_or_init, paths}; +use clippy_utils::{expr_or_init, is_path_diagnostic_item, sym}; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, QPath}; use rustc_lint::LateContext; @@ -10,8 +10,11 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, path: &Expr<'_>, args && !expr.span.from_expansion() && !error_kind.span.from_expansion() && let ExprKind::Path(QPath::TypeRelative(_, new_segment)) = path.kind - && paths::IO_ERROR_NEW.matches_path(cx, path) - && paths::IO_ERRORKIND_OTHER_CTOR.matches_path(cx, expr_or_init(cx, error_kind)) + && is_path_diagnostic_item(cx, path, sym::io_error_new) + && let ExprKind::Path(QPath::Resolved(_, init_path)) = &expr_or_init(cx, error_kind).kind + && let [.., error_kind_ty, error_kind_variant] = init_path.segments + && cx.tcx.is_diagnostic_item(sym::io_errorkind, error_kind_ty.res.def_id()) + && error_kind_variant.ident.name == sym::Other && msrv.meets(cx, msrvs::IO_ERROR_OTHER) { span_lint_and_then( diff --git a/clippy_lints/src/methods/unnecessary_to_owned.rs b/clippy_lints/src/methods/unnecessary_to_owned.rs index fdccf1fb33d..769526d131b 100644 --- a/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -388,9 +388,11 @@ fn check_other_call_arg<'tcx>( && let (input, n_refs) = peel_middle_ty_refs(*input) && let (trait_predicates, _) = get_input_traits_and_projections(cx, callee_def_id, input) && let Some(sized_def_id) = cx.tcx.lang_items().sized_trait() + && let Some(meta_sized_def_id) = cx.tcx.lang_items().meta_sized_trait() && let [trait_predicate] = trait_predicates .iter() .filter(|trait_predicate| trait_predicate.def_id() != sized_def_id) + .filter(|trait_predicate| trait_predicate.def_id() != meta_sized_def_id) .collect::<Vec<_>>()[..] && let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref) && let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef) diff --git a/clippy_lints/src/missing_inline.rs b/clippy_lints/src/missing_inline.rs index 1f613171b46..25c95d23436 100644 --- a/clippy_lints/src/missing_inline.rs +++ b/clippy_lints/src/missing_inline.rs @@ -1,10 +1,11 @@ use clippy_utils::diagnostics::span_lint; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_hir as hir; use rustc_hir::Attribute; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty::AssocItemContainer; use rustc_session::declare_lint_pass; -use rustc_span::{Span, sym}; +use rustc_span::Span; declare_clippy_lint! { /// ### What it does @@ -64,8 +65,7 @@ declare_clippy_lint! { } fn check_missing_inline_attrs(cx: &LateContext<'_>, attrs: &[Attribute], sp: Span, desc: &'static str) { - let has_inline = attrs.iter().any(|a| a.has_name(sym::inline)); - if !has_inline { + if !find_attr!(attrs, AttributeKind::Inline(..)) { span_lint( cx, MISSING_INLINE_IN_PUBLIC_ITEMS, diff --git a/clippy_lints/src/needless_borrows_for_generic_args.rs b/clippy_lints/src/needless_borrows_for_generic_args.rs index 2efb55b9880..17d251a7bbb 100644 --- a/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -161,7 +161,7 @@ fn path_has_args(p: &QPath<'_>) -> bool { /// - `Copy` itself, or /// - the only use of a mutable reference, or /// - not a variable (created by a function call) -#[expect(clippy::too_many_arguments)] +#[expect(clippy::too_many_arguments, clippy::too_many_lines)] fn needless_borrow_count<'tcx>( cx: &LateContext<'tcx>, possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>, @@ -174,6 +174,7 @@ fn needless_borrow_count<'tcx>( ) -> usize { let destruct_trait_def_id = cx.tcx.lang_items().destruct_trait(); let sized_trait_def_id = cx.tcx.lang_items().sized_trait(); + let meta_sized_trait_def_id = cx.tcx.lang_items().meta_sized_trait(); let drop_trait_def_id = cx.tcx.lang_items().drop_trait(); let fn_sig = cx.tcx.fn_sig(fn_id).instantiate_identity().skip_binder(); @@ -209,6 +210,7 @@ fn needless_borrow_count<'tcx>( .all(|trait_def_id| { Some(trait_def_id) == destruct_trait_def_id || Some(trait_def_id) == sized_trait_def_id + || Some(trait_def_id) == meta_sized_trait_def_id || cx.tcx.is_diagnostic_item(sym::Any, trait_def_id) }) { @@ -230,11 +232,11 @@ fn needless_borrow_count<'tcx>( let mut args_with_referent_ty = callee_args.to_vec(); let mut check_reference_and_referent = |reference: &Expr<'tcx>, referent: &Expr<'tcx>| { - if let ExprKind::Field(base, _) = &referent.kind { - let base_ty = cx.typeck_results().expr_ty(base); - if drop_trait_def_id.is_some_and(|id| implements_trait(cx, base_ty, id, &[])) { - return false; - } + if let ExprKind::Field(base, _) = &referent.kind + && let base_ty = cx.typeck_results().expr_ty(base) + && drop_trait_def_id.is_some_and(|id| implements_trait(cx, base_ty, id, &[])) + { + return false; } let referent_ty = cx.typeck_results().expr_ty(referent); diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index 95623467b81..c97ecce75b4 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -116,13 +116,18 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { ]; let sized_trait = need!(cx.tcx.lang_items().sized_trait()); + let meta_sized_trait = need!(cx.tcx.lang_items().meta_sized_trait()); let preds = traits::elaborate(cx.tcx, cx.param_env.caller_bounds().iter()) .filter(|p| !p.is_global()) .filter_map(|pred| { // Note that we do not want to deal with qualified predicates here. match pred.kind().no_bound_vars() { - Some(ty::ClauseKind::Trait(pred)) if pred.def_id() != sized_trait => Some(pred), + Some(ty::ClauseKind::Trait(pred)) + if pred.def_id() != sized_trait && pred.def_id() != meta_sized_trait => + { + Some(pred) + }, _ => None, } }) diff --git a/clippy_lints/src/neg_multiply.rs b/clippy_lints/src/neg_multiply.rs index 74c8142787e..442280f9998 100644 --- a/clippy_lints/src/neg_multiply.rs +++ b/clippy_lints/src/neg_multiply.rs @@ -64,7 +64,7 @@ fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) { { let mut applicability = Applicability::MachineApplicable; let (snip, from_macro) = snippet_with_context(cx, exp.span, span.ctxt(), "..", &mut applicability); - let suggestion = if !from_macro && exp.precedence() < ExprPrecedence::Prefix && !has_enclosing_paren(&snip) { + let suggestion = if !from_macro && cx.precedence(exp) < ExprPrecedence::Prefix && !has_enclosing_paren(&snip) { format!("-({snip})") } else { format!("-{snip}") diff --git a/clippy_lints/src/no_mangle_with_rust_abi.rs b/clippy_lints/src/no_mangle_with_rust_abi.rs index b71dde90691..dee8efeb291 100644 --- a/clippy_lints/src/no_mangle_with_rust_abi.rs +++ b/clippy_lints/src/no_mangle_with_rust_abi.rs @@ -1,8 +1,9 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::{snippet, snippet_with_applicability}; use rustc_abi::ExternAbi; +use rustc_attr_data_structures::AttributeKind; use rustc_errors::Applicability; -use rustc_hir::{Item, ItemKind}; +use rustc_hir::{Attribute, Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; use rustc_span::{BytePos, Pos}; @@ -44,8 +45,7 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi { let mut app = Applicability::MaybeIncorrect; let fn_snippet = snippet_with_applicability(cx, fn_sig.span.with_hi(ident.span.lo()), "..", &mut app); for attr in attrs { - if let Some(ident) = attr.ident() - && ident.name == rustc_span::sym::no_mangle + if let Attribute::Parsed(AttributeKind::NoMangle(attr_span)) = attr && fn_sig.header.abi == ExternAbi::Rust && let Some((fn_attrs, _)) = fn_snippet.rsplit_once("fn") && !fn_attrs.contains("extern") @@ -54,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi { .span .with_lo(fn_sig.span.lo() + BytePos::from_usize(fn_attrs.len())) .shrink_to_lo(); - let attr_snippet = snippet(cx, attr.span(), ".."); + let attr_snippet = snippet(cx, *attr_span, ".."); span_lint_and_then( cx, diff --git a/clippy_lints/src/pass_by_ref_or_value.rs b/clippy_lints/src/pass_by_ref_or_value.rs index dadf49b64e5..b8005dfd6f8 100644 --- a/clippy_lints/src/pass_by_ref_or_value.rs +++ b/clippy_lints/src/pass_by_ref_or_value.rs @@ -5,7 +5,7 @@ use clippy_utils::ty::{for_each_top_level_late_bound_region, is_copy}; use clippy_utils::{is_self, is_self_ty}; use core::ops::ControlFlow; use rustc_abi::ExternAbi; -use rustc_ast::attr; +use rustc_attr_data_structures::{AttributeKind, InlineAttr, find_attr}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; use rustc_hir as hir; @@ -270,11 +270,13 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue { return; } let attrs = cx.tcx.hir_attrs(hir_id); + if find_attr!(attrs, AttributeKind::Inline(InlineAttr::Always, _)) { + return; + } + for a in attrs { - if let Some(meta_items) = a.meta_item_list() - && (a.has_name(sym::proc_macro_derive) - || (a.has_name(sym::inline) && attr::list_contains_name(&meta_items, sym::always))) - { + // FIXME(jdonszelmann): make part of the find_attr above + if a.has_name(sym::proc_macro_derive) { return; } } diff --git a/clippy_lints/src/redundant_slicing.rs b/clippy_lints/src/redundant_slicing.rs index 1117dea703c..324a05cdcc0 100644 --- a/clippy_lints/src/redundant_slicing.rs +++ b/clippy_lints/src/redundant_slicing.rs @@ -86,7 +86,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing { let (indexed_ty, indexed_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(indexed)); let parent_expr = get_parent_expr(cx, expr); let needs_parens_for_prefix = - parent_expr.is_some_and(|parent| parent.precedence() > ExprPrecedence::Prefix); + parent_expr.is_some_and(|parent| cx.precedence(parent) > ExprPrecedence::Prefix); if expr_ty == indexed_ty { if expr_ref_count > indexed_ref_count { diff --git a/clippy_lints/src/return_self_not_must_use.rs b/clippy_lints/src/return_self_not_must_use.rs index 07ae92fa984..25929b853af 100644 --- a/clippy_lints/src/return_self_not_must_use.rs +++ b/clippy_lints/src/return_self_not_must_use.rs @@ -1,12 +1,13 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::ty::is_must_use_ty; use clippy_utils::{nth_arg, return_ty}; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::FnKind; use rustc_hir::{Body, FnDecl, OwnerId, TraitItem, TraitItemKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::declare_lint_pass; -use rustc_span::{Span, sym}; +use rustc_span::Span; declare_clippy_lint! { /// ### What it does @@ -74,7 +75,10 @@ fn check_method(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_def: LocalDefId, spa // We only show this warning for public exported methods. && cx.effective_visibilities.is_exported(fn_def) // We don't want to emit this lint if the `#[must_use]` attribute is already there. - && !cx.tcx.hir_attrs(owner_id.into()).iter().any(|attr| attr.has_name(sym::must_use)) + && !find_attr!( + cx.tcx.hir_attrs(owner_id.into()), + AttributeKind::MustUse { .. } + ) && cx.tcx.visibility(fn_def.to_def_id()).is_public() && let ret_ty = return_ty(cx, owner_id) && let self_arg = nth_arg(cx, owner_id, 0) diff --git a/clippy_lints/src/single_range_in_vec_init.rs b/clippy_lints/src/single_range_in_vec_init.rs index 54d09ff9ee4..dda2f8cc1d0 100644 --- a/clippy_lints/src/single_range_in_vec_init.rs +++ b/clippy_lints/src/single_range_in_vec_init.rs @@ -3,7 +3,7 @@ use clippy_utils::higher::VecArgs; use clippy_utils::macros::root_macro_call_first_node; use clippy_utils::source::SpanRangeExt; use clippy_utils::ty::implements_trait; -use clippy_utils::{is_no_std_crate, paths}; +use clippy_utils::{is_no_std_crate, sym}; use rustc_ast::{LitIntType, LitKind, UintTy}; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, LangItem, QPath, StructTailExpr}; @@ -100,7 +100,7 @@ impl LateLintPass<'_> for SingleRangeInVecInit { && let Some(start_snippet) = start.span.get_source_text(cx) && let Some(end_snippet) = end.span.get_source_text(cx) { - let should_emit_every_value = if let Some(step_def_id) = paths::ITER_STEP.only(cx) + let should_emit_every_value = if let Some(step_def_id) = cx.tcx.get_diagnostic_item(sym::range_step) && implements_trait(cx, ty, step_def_id, &[]) { true diff --git a/clippy_lints/src/to_digit_is_some.rs b/clippy_lints/src/to_digit_is_some.rs index 7d7d74f27b3..3e847543e1c 100644 --- a/clippy_lints/src/to_digit_is_some.rs +++ b/clippy_lints/src/to_digit_is_some.rs @@ -2,7 +2,7 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; -use clippy_utils::{is_in_const_context, paths, sym}; +use clippy_utils::{is_in_const_context, is_path_diagnostic_item, sym}; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; @@ -62,7 +62,7 @@ impl<'tcx> LateLintPass<'tcx> for ToDigitIsSome { } }, hir::ExprKind::Call(to_digits_call, [char_arg, radix_arg]) => { - if paths::CHAR_TO_DIGIT.matches_path(cx, to_digits_call) { + if is_path_diagnostic_item(cx, to_digits_call, sym::char_to_digit) { Some((false, char_arg, radix_arg)) } else { None diff --git a/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs b/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs index 0d5cf45a5e6..18897fbb5b8 100644 --- a/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs +++ b/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs @@ -44,7 +44,7 @@ pub(super) fn check<'tcx>( }; if let Node::Expr(parent) = cx.tcx.parent_hir_node(e.hir_id) - && parent.precedence() > ExprPrecedence::Cast + && cx.precedence(parent) > ExprPrecedence::Cast { sugg = format!("({sugg})"); } diff --git a/clippy_lints/src/unnested_or_patterns.rs b/clippy_lints/src/unnested_or_patterns.rs index b839b6f5672..bd8420917f5 100644 --- a/clippy_lints/src/unnested_or_patterns.rs +++ b/clippy_lints/src/unnested_or_patterns.rs @@ -128,7 +128,7 @@ fn remove_all_parens(pat: &mut P<Pat>) { } impl MutVisitor for Visitor { - fn visit_pat(&mut self, pat: &mut P<Pat>) { + fn visit_pat(&mut self, pat: &mut Pat) { let is_inner = mem::replace(&mut self.is_inner, true); walk_pat(self, pat); let inner = match &mut pat.kind { @@ -145,7 +145,7 @@ fn remove_all_parens(pat: &mut P<Pat>) { fn insert_necessary_parens(pat: &mut P<Pat>) { struct Visitor; impl MutVisitor for Visitor { - fn visit_pat(&mut self, pat: &mut P<Pat>) { + fn visit_pat(&mut self, pat: &mut Pat) { use ast::BindingMode; walk_pat(self, pat); let target = match &mut pat.kind { @@ -167,7 +167,7 @@ fn unnest_or_patterns(pat: &mut P<Pat>) -> bool { changed: bool, } impl MutVisitor for Visitor { - fn visit_pat(&mut self, p: &mut P<Pat>) { + fn visit_pat(&mut self, p: &mut Pat) { // This is a bottom up transformation, so recurse first. walk_pat(self, p); diff --git a/clippy_lints/src/useless_concat.rs b/clippy_lints/src/useless_concat.rs index 1ed1fbb3b9c..96845adb04a 100644 --- a/clippy_lints/src/useless_concat.rs +++ b/clippy_lints/src/useless_concat.rs @@ -1,8 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::macros::macro_backtrace; -use clippy_utils::paths::CONCAT; use clippy_utils::source::snippet_opt; -use clippy_utils::tokenize_with_text; +use clippy_utils::{sym, tokenize_with_text}; use rustc_ast::LitKind; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; @@ -43,7 +42,7 @@ impl LateLintPass<'_> for UselessConcat { // Get the direct parent of the expression. && let Some(macro_call) = macro_backtrace(expr.span).next() // Check if the `concat` macro from the `core` library. - && CONCAT.matches(cx, macro_call.def_id) + && cx.tcx.is_diagnostic_item(sym::macro_concat, macro_call.def_id) // We get the original code to parse it. && let Some(original_code) = snippet_opt(cx, macro_call.span) // This check allows us to ensure that the code snippet: diff --git a/clippy_utils/Cargo.toml b/clippy_utils/Cargo.toml index 615c0995e8b..73291aa8cdf 100644 --- a/clippy_utils/Cargo.toml +++ b/clippy_utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_utils" -version = "0.1.89" +version = "0.1.90" edition = "2024" description = "Helpful tools for writing lints, provided as they are used in Clippy" repository = "https://github.com/rust-lang/rust-clippy" diff --git a/clippy_utils/README.md b/clippy_utils/README.md index 1aa16e3943c..649748d1534 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-06-12 +nightly-2025-06-26 ``` <!-- end autogenerated nightly --> diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 7fa52229fef..a8b33418c8c 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -1886,7 +1886,7 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { _ => None, }; - did.is_some_and(|did| cx.tcx.has_attr(did, sym::must_use)) + did.is_some_and(|did| find_attr!(cx.tcx.get_all_attrs(did), AttributeKind::MustUse { .. })) } /// Checks if a function's body represents the identity function. Looks for bodies of the form: diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index f37a609497e..8bbcb220210 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -126,15 +126,6 @@ path_macros! { macro_path: PathNS::Macro, } -// Paths in `core`/`alloc`/`std`. This should be avoided and cleaned up by adding diagnostic items. -pub static ALIGN_OF: PathLookup = value_path!(core::mem::align_of); -pub static CHAR_TO_DIGIT: PathLookup = value_path!(char::to_digit); -pub static CONCAT: PathLookup = macro_path!(core::concat); -pub static IO_ERROR_NEW: PathLookup = value_path!(std::io::Error::new); -pub static IO_ERRORKIND_OTHER_CTOR: PathLookup = value_path!(std::io::ErrorKind::Other); -pub static ITER_STEP: PathLookup = type_path!(core::iter::Step); -pub static SLICE_FROM_REF: PathLookup = value_path!(core::slice::from_ref); - // Paths in external crates pub static FUTURES_IO_ASYNCREADEXT: PathLookup = type_path!(futures_util::AsyncReadExt); pub static FUTURES_IO_ASYNCWRITEEXT: PathLookup = type_path!(futures_util::AsyncWriteExt); diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index 05c24d7339f..be93f275fab 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -34,10 +34,12 @@ pub fn is_min_const_fn<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, msrv: Ms } if !msrv.meets(cx, msrvs::CONST_FN_TRAIT_BOUND) && let Some(sized_did) = cx.tcx.lang_items().sized_trait() + && let Some(meta_sized_did) = cx.tcx.lang_items().meta_sized_trait() && cx.tcx.param_env(def_id).caller_bounds().iter().any(|bound| { - bound - .as_trait_clause() - .is_some_and(|clause| clause.def_id() != sized_did) + bound.as_trait_clause().is_some_and(|clause| { + let did = clause.def_id(); + did != sized_did && did != meta_sized_did + }) }) { return Err(( diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index 60582ee6f85..8a8218c6976 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -46,7 +46,6 @@ generate! { DOUBLE_QUOTE: "\"", Deserialize, EarlyLintPass, - ErrorKind, IntoIter, Itertools, LF: "\n", @@ -65,7 +64,6 @@ generate! { RegexBuilder, RegexSet, Start, - Step, Symbol, SyntaxContext, TBD, @@ -76,7 +74,6 @@ generate! { Visitor, Weak, abs, - align_of, ambiguous_glob_reexports, append, arg, @@ -159,7 +156,6 @@ generate! { from_ne_bytes, from_ptr, from_raw, - from_ref, from_str, from_str_radix, fs, @@ -218,7 +214,6 @@ generate! { max_by_key, max_value, maximum, - mem, min, min_by, min_by_key, diff --git a/clippy_utils/src/ty/mod.rs b/clippy_utils/src/ty/mod.rs index 1f0a0f2b02a..bffbcf073ab 100644 --- a/clippy_utils/src/ty/mod.rs +++ b/clippy_utils/src/ty/mod.rs @@ -6,6 +6,7 @@ use core::ops::ControlFlow; use itertools::Itertools; use rustc_abi::VariantIdx; use rustc_ast::ast::Mutability; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; @@ -20,8 +21,8 @@ use rustc_middle::traits::EvaluationResult; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::{ self, AdtDef, AliasTy, AssocItem, AssocTag, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind, GenericArgsRef, - GenericParamDefKind, IntTy, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, - TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr, + GenericParamDefKind, IntTy, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, + TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr, }; use rustc_span::symbol::Ident; use rustc_span::{DUMMY_SP, Span, Symbol, sym}; @@ -326,8 +327,8 @@ pub fn has_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { // Returns whether the type has #[must_use] attribute pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { match ty.kind() { - ty::Adt(adt, _) => cx.tcx.has_attr(adt.did(), sym::must_use), - ty::Foreign(did) => cx.tcx.has_attr(*did, sym::must_use), + ty::Adt(adt, _) => find_attr!(cx.tcx.get_all_attrs(adt.did()), AttributeKind::MustUse { .. }), + ty::Foreign(did) => find_attr!(cx.tcx.get_all_attrs(*did), AttributeKind::MustUse { .. }), ty::Slice(ty) | ty::Array(ty, _) | ty::RawPtr(ty, _) | ty::Ref(_, ty, _) => { // for the Array case we don't need to care for the len == 0 case // because we don't want to lint functions returning empty arrays @@ -337,7 +338,10 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { ty::Alias(ty::Opaque, AliasTy { def_id, .. }) => { for (predicate, _) in cx.tcx.explicit_item_self_bounds(def_id).skip_binder() { if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() - && cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use) + && find_attr!( + cx.tcx.get_all_attrs(trait_predicate.trait_ref.def_id), + AttributeKind::MustUse { .. } + ) { return true; } @@ -347,7 +351,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { ty::Dynamic(binder, _, _) => { for predicate in *binder { if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() - && cx.tcx.has_attr(trait_ref.def_id, sym::must_use) + && find_attr!(cx.tcx.get_all_attrs(trait_ref.def_id), AttributeKind::MustUse { .. }) { return true; } @@ -853,7 +857,7 @@ pub fn for_each_top_level_late_bound_region<B>( ControlFlow::Continue(()) } } - fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) -> Self::Result { + fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) -> Self::Result { self.index += 1; let res = t.super_visit_with(self); self.index -= 1; diff --git a/declare_clippy_lint/Cargo.toml b/declare_clippy_lint/Cargo.toml index c8a9b13e6ce..bd6b4dfdee4 100644 --- a/declare_clippy_lint/Cargo.toml +++ b/declare_clippy_lint/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "declare_clippy_lint" -version = "0.1.89" +version = "0.1.90" edition = "2024" repository = "https://github.com/rust-lang/rust-clippy" license = "MIT OR Apache-2.0" diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 3fc5a1224a8..124756a3600 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,6 +1,6 @@ [toolchain] # begin autogenerated nightly -channel = "nightly-2025-06-12" +channel = "nightly-2025-06-26" # 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 202c74413cf..c4076cbaa77 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -13,6 +13,11 @@ 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. +#[cfg(feature = "jemalloc")] +extern crate tikv_jemalloc_sys as jemalloc_sys; + use clippy_utils::sym; use declare_clippy_lint::LintListBuilder; use rustc_interface::interface; @@ -187,6 +192,36 @@ const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/ne #[allow(clippy::too_many_lines)] #[allow(clippy::ignored_unit_patterns)] 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 5f8a4ce2363..49595e2fec2 100644 --- a/tests/ui/author/macro_in_closure.stdout +++ b/tests/ui/author/macro_in_closure.stdout @@ -9,28 +9,35 @@ if let StmtKind::Let(local) = stmt.kind && let ExprKind::Call(func, args) = e.kind && paths::STD_IO_STDIO__PRINT.matches_path(cx, func) // Add the path to `clippy_utils::paths` if needed && args.len() == 1 - && let ExprKind::Call(func1, args1) = args[0].kind - && paths::CORE_FMT_RT_NEW_V1.matches_path(cx, func1) // Add the path to `clippy_utils::paths` if needed - && args1.len() == 2 + && let ExprKind::Block(block1, None) = args[0].kind + && block1.stmts.len() == 1 + && let StmtKind::Let(local1) = block1.stmts[0].kind + && let Some(init1) = local1.init + && let ExprKind::Array(elements) = init1.kind + && elements.len() == 1 + && let ExprKind::Call(func1, args1) = elements[0].kind + && paths::CORE_FMT_RT_ARGUMENT_NEW_DISPLAY.matches_path(cx, func1) // Add the path to `clippy_utils::paths` if needed + && args1.len() == 1 && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = args1[0].kind - && let ExprKind::Array(elements) = inner.kind - && elements.len() == 2 - && let ExprKind::Lit(ref lit) = elements[0].kind + && let PatKind::Binding(BindingMode::NONE, _, name, None) = local1.pat.kind + && name.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 + && args2.len() == 2 + && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args2[0].kind + && let ExprKind::Array(elements1) = inner1.kind + && elements1.len() == 2 + && let ExprKind::Lit(ref lit) = elements1[0].kind && let LitKind::Str(s, _) = lit.node && s.as_str() == "" - && let ExprKind::Lit(ref lit1) = elements[1].kind + && let ExprKind::Lit(ref lit1) = elements1[1].kind && let LitKind::Str(s1, _) = lit1.node && s1.as_str() == "\n" - && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args1[1].kind - && let ExprKind::Array(elements1) = inner1.kind - && elements1.len() == 1 - && let ExprKind::Call(func2, args2) = elements1[0].kind - && paths::CORE_FMT_RT_ARGUMENT_NEW_DISPLAY.matches_path(cx, func2) // Add the path to `clippy_utils::paths` if needed - && args2.len() == 1 - && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[0].kind + && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[1].kind && block.expr.is_none() - && let PatKind::Binding(BindingMode::NONE, _, name, None) = local.pat.kind - && name.as_str() == "print_text" + && let PatKind::Binding(BindingMode::NONE, _, name1, None) = local.pat.kind + && name1.as_str() == "print_text" { // report your lint here } diff --git a/tests/ui/author/macro_in_loop.stdout b/tests/ui/author/macro_in_loop.stdout index ecc25254311..4fc7b49464d 100644 --- a/tests/ui/author/macro_in_loop.stdout +++ b/tests/ui/author/macro_in_loop.stdout @@ -19,25 +19,32 @@ if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::Fo && let ExprKind::Call(func, args) = e1.kind && paths::STD_IO_STDIO__PRINT.matches_path(cx, func) // Add the path to `clippy_utils::paths` if needed && args.len() == 1 - && let ExprKind::Call(func1, args1) = args[0].kind - && paths::CORE_FMT_RT_NEW_V1.matches_path(cx, func1) // Add the path to `clippy_utils::paths` if needed - && args1.len() == 2 + && let ExprKind::Block(block2, None) = args[0].kind + && block2.stmts.len() == 1 + && let StmtKind::Let(local) = block2.stmts[0].kind + && let Some(init) = local.init + && let ExprKind::Array(elements) = init.kind + && elements.len() == 1 + && let ExprKind::Call(func1, args1) = elements[0].kind + && paths::CORE_FMT_RT_ARGUMENT_NEW_DISPLAY.matches_path(cx, func1) // Add the path to `clippy_utils::paths` if needed + && args1.len() == 1 && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = args1[0].kind - && let ExprKind::Array(elements) = inner.kind - && elements.len() == 2 - && let ExprKind::Lit(ref lit2) = elements[0].kind + && let PatKind::Binding(BindingMode::NONE, _, name1, None) = local.pat.kind + && name1.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 + && args2.len() == 2 + && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args2[0].kind + && let ExprKind::Array(elements1) = inner1.kind + && elements1.len() == 2 + && let ExprKind::Lit(ref lit2) = elements1[0].kind && let LitKind::Str(s, _) = lit2.node && s.as_str() == "" - && let ExprKind::Lit(ref lit3) = elements[1].kind + && let ExprKind::Lit(ref lit3) = elements1[1].kind && let LitKind::Str(s1, _) = lit3.node && s1.as_str() == "\n" - && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args1[1].kind - && let ExprKind::Array(elements1) = inner1.kind - && elements1.len() == 1 - && let ExprKind::Call(func2, args2) = elements1[0].kind - && paths::CORE_FMT_RT_ARGUMENT_NEW_DISPLAY.matches_path(cx, func2) // Add the path to `clippy_utils::paths` if needed - && args2.len() == 1 - && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[0].kind + && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[1].kind && block1.expr.is_none() && block.expr.is_none() { diff --git a/tests/ui/def_id_nocore.rs b/tests/ui/def_id_nocore.rs index 40f40f7ea09..5c13d862276 100644 --- a/tests/ui/def_id_nocore.rs +++ b/tests/ui/def_id_nocore.rs @@ -7,8 +7,14 @@ #[link(name = "c")] unsafe extern "C" {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} #[lang = "freeze"] diff --git a/tests/ui/def_id_nocore.stderr b/tests/ui/def_id_nocore.stderr index 2718217313f..175dd075408 100644 --- a/tests/ui/def_id_nocore.stderr +++ b/tests/ui/def_id_nocore.stderr @@ -1,5 +1,5 @@ error: methods called `as_*` usually take `self` by reference or `self` by mutable reference - --> tests/ui/def_id_nocore.rs:27:19 + --> tests/ui/def_id_nocore.rs:33:19 | LL | pub fn as_ref(self) -> &'static str { | ^^^^ diff --git a/tests/ui/large_stack_frames.rs b/tests/ui/large_stack_frames.rs index 3ed124f69ef..132f1450b6d 100644 --- a/tests/ui/large_stack_frames.rs +++ b/tests/ui/large_stack_frames.rs @@ -1,8 +1,7 @@ //@ normalize-stderr-test: "\b10000(08|16|32)\b" -> "100$$PTR" //@ normalize-stderr-test: "\b2500(060|120)\b" -> "250$$PTR" -#![allow(unused, incomplete_features)] +#![allow(unused)] #![warn(clippy::large_stack_frames)] -#![feature(unsized_locals)] use std::hint::black_box; @@ -11,11 +10,6 @@ fn generic<T: Default>() { black_box(&x); } -fn unsized_local() { - let x: dyn std::fmt::Display = *(Box::new(1) as Box<dyn std::fmt::Display>); - black_box(&x); -} - struct ArrayDefault<const N: usize>([u8; N]); impl<const N: usize> Default for ArrayDefault<N> { diff --git a/tests/ui/large_stack_frames.stderr b/tests/ui/large_stack_frames.stderr index 0ff49e9f5b3..79482e65c3e 100644 --- a/tests/ui/large_stack_frames.stderr +++ b/tests/ui/large_stack_frames.stderr @@ -1,5 +1,5 @@ error: this function may allocate 250$PTR bytes on the stack - --> tests/ui/large_stack_frames.rs:27:4 + --> tests/ui/large_stack_frames.rs:21:4 | LL | fn many_small_arrays() { | ^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | let x5 = [0u8; 500_000]; = help: to override `-D warnings` add `#[allow(clippy::large_stack_frames)]` error: this function may allocate 1000000 bytes on the stack - --> tests/ui/large_stack_frames.rs:38:4 + --> tests/ui/large_stack_frames.rs:32:4 | LL | fn large_return_value() -> ArrayDefault<1_000_000> { | ^^^^^^^^^^^^^^^^^^ ----------------------- this is the largest part, at 1000000 bytes for type `ArrayDefault<1000000>` @@ -21,7 +21,7 @@ LL | fn large_return_value() -> ArrayDefault<1_000_000> { = note: 1000000 bytes is larger than Clippy's configured `stack-size-threshold` of 512000 error: this function may allocate 100$PTR bytes on the stack - --> tests/ui/large_stack_frames.rs:44:4 + --> tests/ui/large_stack_frames.rs:38:4 | LL | fn large_fn_arg(x: ArrayDefault<1_000_000>) { | ^^^^^^^^^^^^ - `x` is the largest part, at 1000000 bytes for type `ArrayDefault<1000000>` @@ -29,7 +29,7 @@ LL | fn large_fn_arg(x: ArrayDefault<1_000_000>) { = note: 100$PTR bytes is larger than Clippy's configured `stack-size-threshold` of 512000 error: this function may allocate 100$PTR bytes on the stack - --> tests/ui/large_stack_frames.rs:51:13 + --> tests/ui/large_stack_frames.rs:45:13 | LL | let f = || black_box(&[0u8; 1_000_000]); | ^^^^^^^^^^^^^^----------------^ diff --git a/tests/ui/manual_inspect.fixed b/tests/ui/manual_inspect.fixed index 9b768dbad70..00a19155a51 100644 --- a/tests/ui/manual_inspect.fixed +++ b/tests/ui/manual_inspect.fixed @@ -154,7 +154,6 @@ fn main() { }); let _ = [0] - //~^ suspicious_map .into_iter() .inspect(|&x| { //~^ manual_inspect diff --git a/tests/ui/manual_inspect.rs b/tests/ui/manual_inspect.rs index e679636201e..b3b17139cde 100644 --- a/tests/ui/manual_inspect.rs +++ b/tests/ui/manual_inspect.rs @@ -165,7 +165,6 @@ fn main() { }); let _ = [0] - //~^ suspicious_map .into_iter() .map(|x| { //~^ manual_inspect diff --git a/tests/ui/manual_inspect.stderr b/tests/ui/manual_inspect.stderr index 78b085fdfca..70c00c1f755 100644 --- a/tests/ui/manual_inspect.stderr +++ b/tests/ui/manual_inspect.stderr @@ -157,25 +157,8 @@ LL | LL ~ println!("{}", x); | -error: this call to `map()` won't have an effect on the call to `count()` - --> tests/ui/manual_inspect.rs:167:13 - | -LL | let _ = [0] - | _____________^ -LL | | -LL | | .into_iter() -LL | | .map(|x| { -... | -LL | | }) -LL | | .count(); - | |________________^ - | - = help: make sure you did not confuse `map` with `filter`, `for_each` or `inspect` - = note: `-D clippy::suspicious-map` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::suspicious_map)]` - error: using `map` over `inspect` - --> tests/ui/manual_inspect.rs:170:10 + --> tests/ui/manual_inspect.rs:169:10 | LL | .map(|x| { | ^^^ @@ -188,7 +171,7 @@ LL ~ println!("{}", x); | error: using `map` over `inspect` - --> tests/ui/manual_inspect.rs:203:30 + --> tests/ui/manual_inspect.rs:202:30 | LL | if let Some(x) = Some(1).map(|x| { println!("{x}"); | ^^^ @@ -200,5 +183,5 @@ LL | // Do not collapse code into this comment LL ~ }) { | -error: aborting due to 14 previous errors +error: aborting due to 13 previous errors diff --git a/tests/ui/single_range_in_vec_init.rs b/tests/ui/single_range_in_vec_init.rs index 25884450b08..0888019e101 100644 --- a/tests/ui/single_range_in_vec_init.rs +++ b/tests/ui/single_range_in_vec_init.rs @@ -2,7 +2,6 @@ //@no-rustfix: overlapping suggestions #![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::useless_vec, unused)] #![warn(clippy::single_range_in_vec_init)] -#![feature(generic_arg_infer)] #[macro_use] extern crate proc_macros; diff --git a/tests/ui/single_range_in_vec_init.stderr b/tests/ui/single_range_in_vec_init.stderr index a99127a7606..b21338e38a3 100644 --- a/tests/ui/single_range_in_vec_init.stderr +++ b/tests/ui/single_range_in_vec_init.stderr @@ -1,5 +1,5 @@ error: an array of `Range` that is only one element - --> tests/ui/single_range_in_vec_init.rs:26:5 + --> tests/ui/single_range_in_vec_init.rs:25:5 | LL | [0..200]; | ^^^^^^^^ @@ -18,7 +18,7 @@ LL + [0; 200]; | error: a `Vec` of `Range` that is only one element - --> tests/ui/single_range_in_vec_init.rs:28:5 + --> tests/ui/single_range_in_vec_init.rs:27:5 | LL | vec![0..200]; | ^^^^^^^^^^^^ @@ -35,7 +35,7 @@ LL + vec![0; 200]; | error: an array of `Range` that is only one element - --> tests/ui/single_range_in_vec_init.rs:30:5 + --> tests/ui/single_range_in_vec_init.rs:29:5 | LL | [0u8..200]; | ^^^^^^^^^^ @@ -52,7 +52,7 @@ LL + [0u8; 200]; | error: an array of `Range` that is only one element - --> tests/ui/single_range_in_vec_init.rs:32:5 + --> tests/ui/single_range_in_vec_init.rs:31:5 | LL | [0usize..200]; | ^^^^^^^^^^^^^ @@ -69,7 +69,7 @@ LL + [0usize; 200]; | error: an array of `Range` that is only one element - --> tests/ui/single_range_in_vec_init.rs:34:5 + --> tests/ui/single_range_in_vec_init.rs:33:5 | LL | [0..200usize]; | ^^^^^^^^^^^^^ @@ -86,7 +86,7 @@ LL + [0; 200usize]; | error: a `Vec` of `Range` that is only one element - --> tests/ui/single_range_in_vec_init.rs:36:5 + --> tests/ui/single_range_in_vec_init.rs:35:5 | LL | vec![0u8..200]; | ^^^^^^^^^^^^^^ @@ -103,7 +103,7 @@ LL + vec![0u8; 200]; | error: a `Vec` of `Range` that is only one element - --> tests/ui/single_range_in_vec_init.rs:38:5 + --> tests/ui/single_range_in_vec_init.rs:37:5 | LL | vec![0usize..200]; | ^^^^^^^^^^^^^^^^^ @@ -120,7 +120,7 @@ LL + vec![0usize; 200]; | error: a `Vec` of `Range` that is only one element - --> tests/ui/single_range_in_vec_init.rs:40:5 + --> tests/ui/single_range_in_vec_init.rs:39:5 | LL | vec![0..200usize]; | ^^^^^^^^^^^^^^^^^ @@ -137,7 +137,7 @@ LL + vec![0; 200usize]; | error: an array of `Range` that is only one element - --> tests/ui/single_range_in_vec_init.rs:43:5 + --> tests/ui/single_range_in_vec_init.rs:42:5 | LL | [0..200isize]; | ^^^^^^^^^^^^^ @@ -149,7 +149,7 @@ LL + (0..200isize).collect::<std::vec::Vec<isize>>(); | error: a `Vec` of `Range` that is only one element - --> tests/ui/single_range_in_vec_init.rs:45:5 + --> tests/ui/single_range_in_vec_init.rs:44:5 | LL | vec![0..200isize]; | ^^^^^^^^^^^^^^^^^ |
