diff --git a/Cargo.toml b/Cargo.toml index f6084a462726..eda20531e40f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy" -version = "0.1.76" +version = "0.1.77" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/clippy_config/Cargo.toml b/clippy_config/Cargo.toml index 20f313201276..74b8e5eaa1c4 100644 --- a/clippy_config/Cargo.toml +++ b/clippy_config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_config" -version = "0.1.76" +version = "0.1.77" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 67ea0af07e6f..a4f368397ced 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -636,11 +636,12 @@ impl Conf { match path { Ok((_, warnings)) => { for warning in warnings { - sess.warn(warning.clone()); + sess.dcx().warn(warning.clone()); } }, Err(error) => { - sess.err(format!("error finding Clippy's configuration file: {error}")); + sess.dcx() + .err(format!("error finding Clippy's configuration file: {error}")); }, } @@ -652,7 +653,7 @@ impl Conf { Ok((Some(path), _)) => match sess.source_map().load_file(path) { Ok(file) => deserialize(&file), Err(error) => { - sess.err(format!("failed to read `{}`: {error}", path.display())); + sess.dcx().err(format!("failed to read `{}`: {error}", path.display())); TryConf::default() }, }, @@ -663,14 +664,14 @@ impl Conf { // all conf errors are non-fatal, we just use the default conf in case of error for error in errors { - sess.span_err( + sess.dcx().span_err( error.span, format!("error reading Clippy's configuration file: {}", error.message), ); } for warning in warnings { - sess.span_warn( + sess.dcx().span_warn( warning.span, format!("error reading Clippy's configuration file: {}", warning.message), ); diff --git a/clippy_config/src/msrvs.rs b/clippy_config/src/msrvs.rs index 8dec477cfdd6..471ad73e2074 100644 --- a/clippy_config/src/msrvs.rs +++ b/clippy_config/src/msrvs.rs @@ -84,7 +84,7 @@ impl Msrv { (None, Some(cargo_msrv)) => self.stack = vec![cargo_msrv], (Some(clippy_msrv), Some(cargo_msrv)) => { if clippy_msrv != cargo_msrv { - sess.warn(format!( + sess.dcx().warn(format!( "the MSRV in `clippy.toml` and `Cargo.toml` differ; using `{clippy_msrv}` from `clippy.toml`" )); } @@ -107,7 +107,8 @@ impl Msrv { if let Some(msrv_attr) = msrv_attrs.next() { if let Some(duplicate) = msrv_attrs.last() { - sess.struct_span_err(duplicate.span, "`clippy::msrv` is defined multiple times") + sess.dcx() + .struct_span_err(duplicate.span, "`clippy::msrv` is defined multiple times") .span_note(msrv_attr.span, "first definition found here") .emit(); } @@ -117,9 +118,10 @@ impl Msrv { return Some(version); } - sess.span_err(msrv_attr.span, format!("`{msrv}` is not a valid Rust version")); + sess.dcx() + .span_err(msrv_attr.span, format!("`{msrv}` is not a valid Rust version")); } else { - sess.span_err(msrv_attr.span, "bad clippy attribute"); + sess.dcx().span_err(msrv_attr.span, "bad clippy attribute"); } } diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index ad8b7ded46b9..8cba35f3d871 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_lints" -version = "0.1.76" +version = "0.1.77" 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/async_yields_async.rs b/clippy_lints/src/async_yields_async.rs index 3e5a01c45df1..bb08ac7508bc 100644 --- a/clippy_lints/src/async_yields_async.rs +++ b/clippy_lints/src/async_yields_async.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::source::snippet; use clippy_utils::ty::implements_trait; use rustc_errors::Applicability; -use rustc_hir::{Body, BodyId, CoroutineKind, CoroutineSource, ExprKind, QPath}; +use rustc_hir::{Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, QPath}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; @@ -44,16 +44,22 @@ declare_clippy_lint! { declare_lint_pass!(AsyncYieldsAsync => [ASYNC_YIELDS_ASYNC]); impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync { - fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) { - use CoroutineSource::{Block, Closure}; + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { // For functions, with explicitly defined types, don't warn. // XXXkhuey maybe we should? - if let Some(CoroutineKind::Async(Block | Closure)) = body.coroutine_kind { + if let ExprKind::Closure(Closure { + kind: + ClosureKind::Coroutine(CoroutineKind::Desugared( + CoroutineDesugaring::Async, + CoroutineSource::Block | CoroutineSource::Closure, + )), + body: body_id, + .. + }) = expr.kind + { if let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() { - let body_id = BodyId { - hir_id: body.value.hir_id, - }; - let typeck_results = cx.tcx.typeck_body(body_id); + let typeck_results = cx.tcx.typeck_body(*body_id); + let body = cx.tcx.hir().body(*body_id); let expr_ty = typeck_results.expr_ty(body.value); if implements_trait(cx, expr_ty, future_trait_def_id, &[]) { diff --git a/clippy_lints/src/await_holding_invalid.rs b/clippy_lints/src/await_holding_invalid.rs index 9894a1639618..765cc7c0a54f 100644 --- a/clippy_lints/src/await_holding_invalid.rs +++ b/clippy_lints/src/await_holding_invalid.rs @@ -2,8 +2,8 @@ use clippy_config::types::DisallowedPath; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::{match_def_path, paths}; use rustc_data_structures::fx::FxHashMap; +use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_hir::{Body, CoroutineKind, CoroutineSource}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::CoroutineLayout; use rustc_session::impl_lint_pass; @@ -183,8 +183,8 @@ impl AwaitHolding { } } -impl LateLintPass<'_> for AwaitHolding { - fn check_crate(&mut self, cx: &LateContext<'_>) { +impl<'tcx> LateLintPass<'tcx> for AwaitHolding { + fn check_crate(&mut self, cx: &LateContext<'tcx>) { for conf in &self.conf_invalid_types { let segs: Vec<_> = conf.path().split("::").collect(); for id in clippy_utils::def_path_def_ids(cx, &segs) { @@ -193,11 +193,14 @@ impl LateLintPass<'_> for AwaitHolding { } } - fn check_body(&mut self, cx: &LateContext<'_>, body: &'_ Body<'_>) { - use CoroutineSource::{Block, Closure, Fn}; - if let Some(CoroutineKind::Async(Block | Closure | Fn)) = body.coroutine_kind { - let def_id = cx.tcx.hir().body_owner_def_id(body.id()); - if let Some(coroutine_layout) = cx.tcx.mir_coroutine_witnesses(def_id) { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { + if let hir::ExprKind::Closure(hir::Closure { + kind: hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)), + def_id, + .. + }) = expr.kind + { + if let Some(coroutine_layout) = cx.tcx.mir_coroutine_witnesses(*def_id) { self.check_interior_types(cx, coroutine_layout); } } diff --git a/clippy_lints/src/doc/needless_doctest_main.rs b/clippy_lints/src/doc/needless_doctest_main.rs index e019523e6098..c639813a3f9a 100644 --- a/clippy_lints/src/doc/needless_doctest_main.rs +++ b/clippy_lints/src/doc/needless_doctest_main.rs @@ -6,7 +6,7 @@ use clippy_utils::diagnostics::span_lint; use rustc_ast::{CoroutineKind, Fn, FnRetTy, Item, ItemKind}; use rustc_data_structures::sync::Lrc; use rustc_errors::emitter::EmitterWriter; -use rustc_errors::Handler; +use rustc_errors::DiagCtxt; use rustc_lint::LateContext; use rustc_parse::maybe_new_parser_from_source_str; use rustc_parse::parser::ForceCollect; @@ -45,10 +45,10 @@ pub fn check( let fallback_bundle = rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), false); let emitter = EmitterWriter::new(Box::new(io::sink()), fallback_bundle); - let handler = Handler::with_emitter(Box::new(emitter)).disable_warnings(); - #[expect(clippy::arc_with_non_send_sync)] // `Lrc` is expected by with_span_handler + let dcx = DiagCtxt::with_emitter(Box::new(emitter)).disable_warnings(); + #[expect(clippy::arc_with_non_send_sync)] // `Lrc` is expected by with_dcx let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sess = ParseSess::with_span_handler(handler, sm); + let sess = ParseSess::with_dcx(dcx, sm); let mut parser = match maybe_new_parser_from_source_str(&sess, filename, code) { Ok(p) => p, diff --git a/clippy_lints/src/item_name_repetitions.rs b/clippy_lints/src/item_name_repetitions.rs index b6aacba2517a..a9f1612ff05e 100644 --- a/clippy_lints/src/item_name_repetitions.rs +++ b/clippy_lints/src/item_name_repetitions.rs @@ -436,7 +436,7 @@ impl LateLintPass<'_> for ItemNameRepetitions { { match item.kind { ItemKind::Enum(def, _) => check_variant(cx, self.enum_threshold, &def, item_name, item.span), - ItemKind::Struct(VariantData::Struct(fields, _), _) => { + ItemKind::Struct(VariantData::Struct { fields, .. }, _) => { check_fields(cx, self.struct_threshold, item, fields); }, _ => (), diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index 83af551fcd3c..c09d3d1862b0 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -8,8 +8,8 @@ use rustc_hir::def::Res; use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_hir::{ AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, ImplItem, ImplItemKind, - ImplicitSelfKind, Item, ItemKind, LangItem, Mutability, Node, PatKind, PathSegment, PrimTy, QPath, TraitItemRef, - TyKind, TypeBindingKind, + ImplicitSelfKind, Item, ItemKind, Mutability, Node, OpaqueTyOrigin, PatKind, PathSegment, PrimTy, QPath, + TraitItemRef, TyKind, TypeBindingKind, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, AssocKind, FnSig, Ty}; @@ -289,8 +289,10 @@ fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<& kind: ItemKind::OpaqueTy(opaque), .. } = item - && opaque.bounds.len() == 1 - && let GenericBound::LangItemTrait(LangItem::Future, _, _, generic_args) = &opaque.bounds[0] + && let OpaqueTyOrigin::AsyncFn(_) = opaque.origin + && let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds + && let Some(segment) = trait_ref.trait_ref.path.segments.last() + && let Some(generic_args) = segment.args && generic_args.bindings.len() == 1 && let TypeBindingKind::Equality { term: diff --git a/clippy_lints/src/manual_async_fn.rs b/clippy_lints/src/manual_async_fn.rs index eaaaea0be9f8..4cd5f3b81e52 100644 --- a/clippy_lints/src/manual_async_fn.rs +++ b/clippy_lints/src/manual_async_fn.rs @@ -3,8 +3,9 @@ use clippy_utils::source::{position_before_rarrow, snippet_block, snippet_opt}; use rustc_errors::Applicability; use rustc_hir::intravisit::FnKind; use rustc_hir::{ - Block, Body, Closure, CoroutineKind, CoroutineSource, Expr, ExprKind, FnDecl, FnRetTy, GenericArg, GenericBound, - ImplItem, Item, ItemKind, LifetimeName, Node, Term, TraitRef, Ty, TyKind, TypeBindingKind, + Block, Body, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, FnDecl, + FnRetTy, GenericArg, GenericBound, ImplItem, Item, ItemKind, LifetimeName, Node, Term, TraitRef, Ty, TyKind, + TypeBindingKind, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; @@ -172,15 +173,14 @@ fn captures_all_lifetimes(inputs: &[Ty<'_>], output_lifetimes: &[LifetimeName]) } fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) -> Option<&'tcx Body<'tcx>> { - if let Some(block_expr) = block.expr - && let Expr { - kind: ExprKind::Closure(&Closure { body, .. }), - .. - } = block_expr - && let closure_body = cx.tcx.hir().body(body) - && closure_body.coroutine_kind == Some(CoroutineKind::Async(CoroutineSource::Block)) + if let Some(Expr { + kind: ExprKind::Closure(&Closure { kind, body, .. }), + .. + }) = block.expr + && let ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Block)) = + kind { - return Some(closure_body); + return Some(cx.tcx.hir().body(body)); } None diff --git a/clippy_lints/src/manual_non_exhaustive.rs b/clippy_lints/src/manual_non_exhaustive.rs index 545b122930e5..d2ac0ad8363e 100644 --- a/clippy_lints/src/manual_non_exhaustive.rs +++ b/clippy_lints/src/manual_non_exhaustive.rs @@ -103,7 +103,7 @@ impl EarlyLintPass for ManualNonExhaustiveStruct { if let ast::ItemKind::Struct(variant_data, _) = &item.kind { let (fields, delimiter) = match variant_data { - ast::VariantData::Struct(fields, _) => (&**fields, '{'), + ast::VariantData::Struct { fields, .. } => (&**fields, '{'), ast::VariantData::Tuple(fields, _) => (&**fields, '('), ast::VariantData::Unit(_) => return, }; diff --git a/clippy_lints/src/methods/iter_kv_map.rs b/clippy_lints/src/methods/iter_kv_map.rs index e1b934d36ea8..6394f35f8604 100644 --- a/clippy_lints/src/methods/iter_kv_map.rs +++ b/clippy_lints/src/methods/iter_kv_map.rs @@ -32,7 +32,6 @@ pub(super) fn check<'tcx>( && let Body { params: [p], value: body_expr, - coroutine_kind: _, } = cx.tcx.hir().body(c.body) && let PatKind::Tuple([key_pat, val_pat], _) = p.pat.kind && let (replacement_kind, annotation, bound_ident) = match (&key_pat.kind, &val_pat.kind) { diff --git a/clippy_lints/src/missing_const_for_fn.rs b/clippy_lints/src/missing_const_for_fn.rs index acaa6be30092..9ba19e0a8658 100644 --- a/clippy_lints/src/missing_const_for_fn.rs +++ b/clippy_lints/src/missing_const_for_fn.rs @@ -153,7 +153,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { if let Err((span, err)) = is_min_const_fn(cx.tcx, mir, &self.msrv) { if cx.tcx.is_const_fn_raw(def_id.to_def_id()) { - cx.tcx.sess.span_err(span, err); + cx.tcx.dcx().span_err(span, err); } } else { span_lint(cx, MISSING_CONST_FOR_FN, span, "this could be a `const fn`"); diff --git a/clippy_lints/src/needless_continue.rs b/clippy_lints/src/needless_continue.rs index 4b9ab50e4fd7..ff72b5e69ef1 100644 --- a/clippy_lints/src/needless_continue.rs +++ b/clippy_lints/src/needless_continue.rs @@ -220,7 +220,11 @@ where F: FnMut(&ast::Block, Option<&ast::Label>), { if let ast::ExprKind::While(_, loop_block, label) - | ast::ExprKind::ForLoop(_, _, loop_block, label) + | ast::ExprKind::ForLoop { + body: loop_block, + label, + .. + } | ast::ExprKind::Loop(loop_block, label, ..) = &expr.kind { func(loop_block, label.as_ref()); diff --git a/clippy_lints/src/needless_question_mark.rs b/clippy_lints/src/needless_question_mark.rs index a4d3aaf0de98..d7adf22ff32a 100644 --- a/clippy_lints/src/needless_question_mark.rs +++ b/clippy_lints/src/needless_question_mark.rs @@ -3,7 +3,7 @@ use clippy_utils::path_res; use clippy_utils::source::snippet; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{Block, Body, CoroutineKind, CoroutineSource, Expr, ExprKind, LangItem, MatchSource, QPath}; +use rustc_hir::{Block, Body, Expr, ExprKind, LangItem, MatchSource, QPath}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; @@ -86,22 +86,20 @@ impl LateLintPass<'_> for NeedlessQuestionMark { } fn check_body(&mut self, cx: &LateContext<'_>, body: &'_ Body<'_>) { - if let Some(CoroutineKind::Async(CoroutineSource::Fn)) = body.coroutine_kind { - if let ExprKind::Block( - Block { - expr: - Some(Expr { - kind: ExprKind::DropTemps(async_body), - .. - }), - .. - }, - _, - ) = body.value.kind - { - if let ExprKind::Block(Block { expr: Some(expr), .. }, ..) = async_body.kind { - check(cx, expr); - } + if let ExprKind::Block( + Block { + expr: + Some(Expr { + kind: ExprKind::DropTemps(async_body), + .. + }), + .. + }, + _, + ) = body.value.kind + { + if let ExprKind::Block(Block { expr: Some(expr), .. }, ..) = async_body.kind { + check(cx, expr.peel_blocks()); } } else { check(cx, body.value.peel_blocks()); diff --git a/clippy_lints/src/redundant_async_block.rs b/clippy_lints/src/redundant_async_block.rs index 11007450a161..0ed957f1f2fb 100644 --- a/clippy_lints/src/redundant_async_block.rs +++ b/clippy_lints/src/redundant_async_block.rs @@ -6,7 +6,9 @@ use clippy_utils::source::{snippet, walk_span_to_context}; use clippy_utils::ty::implements_trait; use clippy_utils::visitors::for_each_expr; use rustc_errors::Applicability; -use rustc_hir::{Closure, CoroutineKind, CoroutineSource, Expr, ExprKind, MatchSource}; +use rustc_hir::{ + Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, MatchSource, +}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::UpvarCapture; @@ -73,9 +75,15 @@ impl<'tcx> LateLintPass<'tcx> for RedundantAsyncBlock { /// If `expr` is a desugared `async` block, return the original expression if it does not capture /// any variable by ref. fn desugar_async_block<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> { - if let ExprKind::Closure(Closure { body, def_id, .. }) = expr.kind + if let ExprKind::Closure(Closure { body, def_id, kind, .. }) = expr.kind && let body = cx.tcx.hir().body(*body) - && matches!(body.coroutine_kind, Some(CoroutineKind::Async(CoroutineSource::Block))) + && matches!( + kind, + ClosureKind::Coroutine(CoroutineKind::Desugared( + CoroutineDesugaring::Async, + CoroutineSource::Block + )) + ) { cx.typeck_results() .closure_min_captures diff --git a/clippy_lints/src/redundant_closure_call.rs b/clippy_lints/src/redundant_closure_call.rs index 8bac2e40e012..cde08dfcc748 100644 --- a/clippy_lints/src/redundant_closure_call.rs +++ b/clippy_lints/src/redundant_closure_call.rs @@ -5,7 +5,7 @@ use clippy_utils::sugg::Sugg; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::intravisit::{Visitor as HirVisitor, Visitor}; -use rustc_hir::{intravisit as hir_visit, CoroutineKind, CoroutineSource, Node}; +use rustc_hir::{intravisit as hir_visit, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Node}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; use rustc_middle::lint::in_external_macro; @@ -63,11 +63,11 @@ impl<'tcx> Visitor<'tcx> for ReturnVisitor { /// Checks if the body is owned by an async closure. /// Returns true for `async || whatever_expression`, but false for `|| async { whatever_expression /// }`. -fn is_async_closure(cx: &LateContext<'_>, body: &hir::Body<'_>) -> bool { +fn is_async_closure(body: &hir::Body<'_>) -> bool { if let hir::ExprKind::Closure(innermost_closure_generated_by_desugar) = body.value.kind - && let desugared_inner_closure_body = cx.tcx.hir().body(innermost_closure_generated_by_desugar.body) // checks whether it is `async || whatever_expression` - && let Some(CoroutineKind::Async(CoroutineSource::Closure)) = desugared_inner_closure_body.coroutine_kind + && let ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure)) + = innermost_closure_generated_by_desugar.kind { true } else { @@ -103,7 +103,7 @@ fn find_innermost_closure<'tcx>( data = Some(( body.value, closure.fn_decl, - if is_async_closure(cx, body) { + if is_async_closure(body) { ty::Asyncness::Yes } else { ty::Asyncness::No diff --git a/clippy_lints/src/redundant_else.rs b/clippy_lints/src/redundant_else.rs index 001686c84f81..fb434fb7450a 100644 --- a/clippy_lints/src/redundant_else.rs +++ b/clippy_lints/src/redundant_else.rs @@ -111,7 +111,7 @@ impl<'ast> Visitor<'ast> for BreakVisitor { ExprKind::If(_, ref then, Some(ref els)) => self.check_block(then) && self.check_expr(els), ExprKind::If(_, _, None) // ignore loops for simplicity - | ExprKind::While(..) | ExprKind::ForLoop(..) | ExprKind::Loop(..) => false, + | ExprKind::While(..) | ExprKind::ForLoop { .. } | ExprKind::Loop(..) => false, _ => { walk_expr(self, expr); return; diff --git a/clippy_lints/src/suspicious_operation_groupings.rs b/clippy_lints/src/suspicious_operation_groupings.rs index 8b9d9bade915..60e9d262e7e0 100644 --- a/clippy_lints/src/suspicious_operation_groupings.rs +++ b/clippy_lints/src/suspicious_operation_groupings.rs @@ -554,7 +554,7 @@ fn ident_difference_expr_with_base_location( | (Closure(_), Closure(_)) | (Match(_, _), Match(_, _)) | (Loop(_, _, _), Loop(_, _, _)) - | (ForLoop(_, _, _, _), ForLoop(_, _, _, _)) + | (ForLoop { .. }, ForLoop { .. }) | (While(_, _, _), While(_, _, _)) | (If(_, _, _), If(_, _, _)) | (Let(_, _, _, _), Let(_, _, _, _)) diff --git a/clippy_lints/src/unnested_or_patterns.rs b/clippy_lints/src/unnested_or_patterns.rs index 65600009c1d7..77adcdd0e6bf 100644 --- a/clippy_lints/src/unnested_or_patterns.rs +++ b/clippy_lints/src/unnested_or_patterns.rs @@ -293,7 +293,7 @@ fn extend_with_struct_pat( qself1: &Option
>, path1: &ast::Path, fps1: &mut [ast::PatField], - rest1: bool, + rest1: ast::PatFieldsRest, start: usize, alternatives: &mut ThinVec
>,
) -> bool {
diff --git a/clippy_lints/src/unused_async.rs b/clippy_lints/src/unused_async.rs
index 9c8c44c0a16d..1d42375ba8e5 100644
--- a/clippy_lints/src/unused_async.rs
+++ b/clippy_lints/src/unused_async.rs
@@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::is_def_id_trait_method;
use rustc_hir::def::DefKind;
-use rustc_hir::intravisit::{walk_body, walk_expr, walk_fn, FnKind, Visitor};
+use rustc_hir::intravisit::{walk_expr, walk_fn, FnKind, Visitor};
use rustc_hir::{Body, Expr, ExprKind, FnDecl, Node, YieldSource};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter;
@@ -78,26 +78,32 @@ impl<'a, 'tcx> Visitor<'tcx> for AsyncFnVisitor<'a, 'tcx> {
self.await_in_async_block = Some(ex.span);
}
}
- walk_expr(self, ex);
- }
-
- fn nested_visit_map(&mut self) -> Self::Map {
- self.cx.tcx.hir()
- }
- fn visit_body(&mut self, b: &'tcx Body<'tcx>) {
- let is_async_block = matches!(b.coroutine_kind, Some(rustc_hir::CoroutineKind::Async(_)));
+ let is_async_block = matches!(
+ ex.kind,
+ ExprKind::Closure(rustc_hir::Closure {
+ kind: rustc_hir::ClosureKind::Coroutine(rustc_hir::CoroutineKind::Desugared(
+ rustc_hir::CoroutineDesugaring::Async,
+ _
+ )),
+ ..
+ })
+ );
if is_async_block {
self.async_depth += 1;
}
- walk_body(self, b);
+ walk_expr(self, ex);
if is_async_block {
self.async_depth -= 1;
}
}
+
+ fn nested_visit_map(&mut self) -> Self::Map {
+ self.cx.tcx.hir()
+ }
}
impl<'tcx> LateLintPass<'tcx> for UnusedAsync {
diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs
index a8bf142f5d53..8817e46b3c8c 100644
--- a/clippy_lints/src/utils/author.rs
+++ b/clippy_lints/src/utils/author.rs
@@ -7,7 +7,8 @@ use rustc_ast::LitIntType;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir;
use rustc_hir::{
- ArrayLen, BindingAnnotation, CaptureBy, Closure, ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind,
+ ArrayLen, BindingAnnotation, CaptureBy, Closure, ClosureKind, CoroutineKind, ExprKind, FnRetTy, HirId, Lit,
+ PatKind, QPath, StmtKind, TyKind,
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_session::declare_lint_pass;
@@ -477,7 +478,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
capture_clause,
fn_decl,
body: body_id,
- movability,
+ kind,
..
}) => {
let capture_clause = match capture_clause {
@@ -485,7 +486,17 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
CaptureBy::Ref => "Ref",
};
- let movability = OptionPat::new(movability.map(|m| format!("Movability::{m:?}")));
+ let closure_kind = match kind {
+ ClosureKind::Closure => "ClosureKind::Closure".to_string(),
+ ClosureKind::Coroutine(coroutine_kind) => match coroutine_kind {
+ CoroutineKind::Desugared(desugaring, source) => format!(
+ "ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::{desugaring:?}, CoroutineSource::{source:?}))"
+ ),
+ CoroutineKind::Coroutine(movability) => {
+ format!("ClosureKind::Coroutine(CoroutineKind::Coroutine(Movability::{movability:?})")
+ },
+ },
+ };
let ret_ty = match fn_decl.output {
FnRetTy::DefaultReturn(_) => "FnRetTy::DefaultReturn(_)",
@@ -493,7 +504,9 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
};
bind!(self, fn_decl, body_id);
- kind!("Closure(CaptureBy::{capture_clause}, {fn_decl}, {body_id}, _, {movability})");
+ kind!(
+ "Closure {{ capture_clause: CaptureBy::{capture_clause}, fn_decl: {fn_decl}, body: {body_id}, closure_kind: {closure_kind}, .. }}"
+ );
chain!(self, "let {ret_ty} = {fn_decl}.output");
self.body(body_id);
},
diff --git a/clippy_utils/Cargo.toml b/clippy_utils/Cargo.toml
index 5d23326cec89..b8869eedf52c 100644
--- a/clippy_utils/Cargo.toml
+++ b/clippy_utils/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "clippy_utils"
-version = "0.1.76"
+version = "0.1.77"
edition = "2021"
publish = false
diff --git a/clippy_utils/src/ast_utils.rs b/clippy_utils/src/ast_utils.rs
index e36f2fa87a72..adc35bd82ae3 100644
--- a/clippy_utils/src/ast_utils.rs
+++ b/clippy_utils/src/ast_utils.rs
@@ -134,6 +134,7 @@ pub fn eq_struct_rest(l: &StructRest, r: &StructRest) -> bool {
}
}
+#[allow(clippy::too_many_lines)] // Just a big match statement
pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
use ExprKind::*;
if !over(&l.attrs, &r.attrs, eq_attr) {
@@ -169,9 +170,22 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
(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, re),
(While(lc, lt, ll), While(rc, rt, rl)) => eq_label(ll, rl) && eq_expr(lc, rc) && eq_block(lt, rt),
- (ForLoop(lp, li, lt, ll), ForLoop(rp, ri, rt, rl)) => {
- eq_label(ll, rl) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt)
- },
+ (
+ ForLoop {
+ pat: lp,
+ iter: li,
+ body: lt,
+ label: ll,
+ kind: lk,
+ },
+ ForLoop {
+ pat: rp,
+ iter: ri,
+ body: rt,
+ label: rl,
+ kind: rk,
+ },
+ ) => eq_label(ll, rl) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt) && lk == rk,
(Loop(lt, ll, _), Loop(rt, rl, _)) => eq_label(ll, rl) && eq_block(lt, rt),
(Block(lb, ll), Block(rb, rl)) => eq_label(ll, rl) && eq_block(lb, rb),
(TryBlock(l), TryBlock(r)) => eq_block(l, r),
@@ -546,7 +560,9 @@ pub fn eq_variant_data(l: &VariantData, r: &VariantData) -> bool {
use VariantData::*;
match (l, r) {
(Unit(_), Unit(_)) => true,
- (Struct(l, _), Struct(r, _)) | (Tuple(l, _), Tuple(r, _)) => over(l, r, eq_struct_field),
+ (Struct { fields: l, .. }, Struct { fields: r, .. }) | (Tuple(l, _), Tuple(r, _)) => {
+ over(l, r, eq_struct_field)
+ },
_ => false,
}
}
diff --git a/clippy_utils/src/attrs.rs b/clippy_utils/src/attrs.rs
index 51771f78d4ff..db80e07ca1c4 100644
--- a/clippy_utils/src/attrs.rs
+++ b/clippy_utils/src/attrs.rs
@@ -76,12 +76,14 @@ pub fn get_attr<'a>(
})
.map_or_else(
|| {
- sess.span_err(attr_segments[1].ident.span, "usage of unknown attribute");
+ sess.dcx()
+ .span_err(attr_segments[1].ident.span, "usage of unknown attribute");
false
},
|deprecation_status| {
- let mut diag =
- sess.struct_span_err(attr_segments[1].ident.span, "usage of deprecated attribute");
+ let mut diag = sess
+ .dcx()
+ .struct_span_err(attr_segments[1].ident.span, "usage of deprecated attribute");
match *deprecation_status {
DeprecationStatus::Deprecated => {
diag.emit();
@@ -116,10 +118,10 @@ fn parse_attrs