diff --git a/clippy_lints/src/blocks_in_conditions.rs b/clippy_lints/src/blocks_in_conditions.rs index 171f30318601..869ed332b9c9 100644 --- a/clippy_lints/src/blocks_in_conditions.rs +++ b/clippy_lints/src/blocks_in_conditions.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; use clippy_utils::source::snippet_block_with_applicability; use clippy_utils::ty::implements_trait; -use clippy_utils::visitors::{for_each_expr, Descend}; +use clippy_utils::visitors::{for_each_expr_without_closures, Descend}; use clippy_utils::{get_parent_expr, higher, is_from_proc_macro}; use core::ops::ControlFlow; use rustc_errors::Applicability; @@ -125,7 +125,7 @@ impl<'tcx> LateLintPass<'tcx> for BlocksInConditions { } } } else { - let _: Option = for_each_expr(cond, |e| { + let _: Option = for_each_expr_without_closures(cond, |e| { if let ExprKind::Closure(closure) = e.kind { // do not lint if the closure is called using an iterator (see #1141) if let Some(parent) = get_parent_expr(cx, e) diff --git a/clippy_lints/src/casts/cast_sign_loss.rs b/clippy_lints/src/casts/cast_sign_loss.rs index 864489ee3fcd..8bbd41b0db1e 100644 --- a/clippy_lints/src/casts/cast_sign_loss.rs +++ b/clippy_lints/src/casts/cast_sign_loss.rs @@ -3,7 +3,7 @@ use std::ops::ControlFlow; use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::span_lint; -use clippy_utils::visitors::{for_each_expr, Descend}; +use clippy_utils::visitors::{for_each_expr_without_closures, Descend}; use clippy_utils::{method_chain_args, sext}; use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::LateContext; @@ -266,7 +266,7 @@ fn expr_add_sign(cx: &LateContext<'_>, expr: &Expr<'_>) -> Sign { fn exprs_with_muldiv_binop_peeled<'e>(expr: &'e Expr<'_>) -> Vec<&'e Expr<'e>> { let mut res = vec![]; - for_each_expr(expr, |sub_expr| -> ControlFlow { + for_each_expr_without_closures(expr, |sub_expr| -> ControlFlow { // We don't check for mul/div/rem methods here, but we could. if let ExprKind::Binary(op, lhs, _rhs) = sub_expr.kind { if matches!(op.node, BinOpKind::Mul | BinOpKind::Div) { @@ -315,7 +315,7 @@ fn exprs_with_muldiv_binop_peeled<'e>(expr: &'e Expr<'_>) -> Vec<&'e Expr<'e>> { fn exprs_with_add_binop_peeled<'e>(expr: &'e Expr<'_>) -> Vec<&'e Expr<'e>> { let mut res = vec![]; - for_each_expr(expr, |sub_expr| -> ControlFlow { + for_each_expr_without_closures(expr, |sub_expr| -> ControlFlow { // We don't check for add methods here, but we could. if let ExprKind::Binary(op, _lhs, _rhs) = sub_expr.kind { if matches!(op.node, BinOpKind::Add) { diff --git a/clippy_lints/src/casts/unnecessary_cast.rs b/clippy_lints/src/casts/unnecessary_cast.rs index a7f7bf7854e6..fb0b0cba6a66 100644 --- a/clippy_lints/src/casts/unnecessary_cast.rs +++ b/clippy_lints/src/casts/unnecessary_cast.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::numeric_literal::NumericLiteral; use clippy_utils::source::snippet_opt; -use clippy_utils::visitors::{for_each_expr, Visitable}; +use clippy_utils::visitors::{for_each_expr_without_closures, Visitable}; use clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant, is_ty_alias, path_to_local}; use rustc_ast::{LitFloatType, LitIntType, LitKind}; use rustc_errors::Applicability; @@ -245,7 +245,7 @@ fn fp_ty_mantissa_nbits(typ: Ty<'_>) -> u32 { /// TODO: Maybe we should move this to `clippy_utils` so others won't need to go down this dark, /// dark path reimplementing this (or something similar). fn is_cast_from_ty_alias<'tcx>(cx: &LateContext<'tcx>, expr: impl Visitable<'tcx>, cast_from: Ty<'tcx>) -> bool { - for_each_expr(expr, |expr| { + for_each_expr_without_closures(expr, |expr| { // Calls are a `Path`, and usage of locals are a `Path`. So, this checks // - call() as i32 // - local as i32 diff --git a/clippy_lints/src/cognitive_complexity.rs b/clippy_lints/src/cognitive_complexity.rs index ee1bb63b50d3..e41abf422349 100644 --- a/clippy_lints/src/cognitive_complexity.rs +++ b/clippy_lints/src/cognitive_complexity.rs @@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::source::snippet_opt; use clippy_utils::ty::is_type_diagnostic_item; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{get_async_fn_body, is_async_fn, LimitStack}; use core::ops::ControlFlow; use rustc_ast::ast::Attribute; @@ -65,7 +65,7 @@ impl CognitiveComplexity { let mut cc = 1u64; let mut returns = 0u64; - let _: Option = for_each_expr(expr, |e| { + let _: Option = for_each_expr_without_closures(expr, |e| { match e.kind { ExprKind::If(_, _, _) => { cc += 1; diff --git a/clippy_lints/src/collection_is_never_read.rs b/clippy_lints/src/collection_is_never_read.rs index 70856b808810..28d9f68d504c 100644 --- a/clippy_lints/src/collection_is_never_read.rs +++ b/clippy_lints/src/collection_is_never_read.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint; use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item}; -use clippy_utils::visitors::{for_each_expr_with_closures, Visitable}; +use clippy_utils::visitors::{for_each_expr, Visitable}; use clippy_utils::{get_enclosing_block, path_to_local_id}; use core::ops::ControlFlow; use rustc_hir::{Body, ExprKind, HirId, LangItem, LetStmt, Node, PatKind}; @@ -82,7 +82,7 @@ fn has_no_read_access<'tcx, T: Visitable<'tcx>>(cx: &LateContext<'tcx>, id: HirI let mut has_read_access = false; // Inspect all expressions and sub-expressions in the block. - for_each_expr_with_closures(cx, block, |expr| { + for_each_expr(cx, block, |expr| { // Ignore expressions that are not simply `id`. if !path_to_local_id(expr, id) { return ControlFlow::Continue(()); diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index ccf1d9d6f8c0..480df675d754 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_then}; use clippy_utils::source::{first_line_of_span, indent_of, reindent_multiline, snippet, snippet_opt}; use clippy_utils::ty::{needs_ordered_drop, InteriorMut}; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{ capture_local_usage, eq_expr_value, find_binding_init, get_enclosing_block, hash_expr, hash_stmt, if_sequence, is_else_clause, is_lint_allowed, path_to_local, search_same, ContainsName, HirEqInterExpr, SpanlessEq, @@ -362,7 +362,7 @@ fn eq_binding_names(s: &Stmt<'_>, names: &[(HirId, Symbol)]) -> bool { /// Checks if the statement modifies or moves any of the given locals. fn modifies_any_local<'tcx>(cx: &LateContext<'tcx>, s: &'tcx Stmt<'_>, locals: &HirIdSet) -> bool { - for_each_expr(s, |e| { + for_each_expr_without_closures(s, |e| { if let Some(id) = path_to_local(e) && locals.contains(&id) && !capture_local_usage(cx, e).is_imm_ref() @@ -413,7 +413,7 @@ fn scan_block_for_eq<'tcx>( let mut cond_locals = HirIdSet::default(); for &cond in conds { - let _: Option = for_each_expr(cond, |e| { + let _: Option = for_each_expr_without_closures(cond, |e| { if let Some(id) = path_to_local(e) { cond_locals.insert(id); } diff --git a/clippy_lints/src/functions/must_use.rs b/clippy_lints/src/functions/must_use.rs index e7ec2b3151e6..cce8617821e2 100644 --- a/clippy_lints/src/functions/must_use.rs +++ b/clippy_lints/src/functions/must_use.rs @@ -14,7 +14,7 @@ use clippy_utils::attrs::is_proc_macro; use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then}; use clippy_utils::source::snippet_opt; use clippy_utils::ty::is_must_use_ty; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{return_ty, trait_ref_of_method}; use core::ops::ControlFlow; @@ -226,7 +226,7 @@ fn is_mutated_static(e: &hir::Expr<'_>) -> bool { } fn mutates_static<'tcx>(cx: &LateContext<'tcx>, body: &'tcx hir::Body<'_>) -> bool { - for_each_expr(body.value, |e| { + for_each_expr_without_closures(body.value, |e| { use hir::ExprKind::{AddrOf, Assign, AssignOp, Call, MethodCall}; match e.kind { diff --git a/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs b/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs index b44a5f20ef68..1aeefe73cf68 100644 --- a/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs +++ b/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs @@ -5,7 +5,7 @@ use rustc_span::def_id::LocalDefId; use clippy_utils::diagnostics::span_lint; use clippy_utils::ty::type_is_unsafe_function; -use clippy_utils::visitors::for_each_expr_with_closures; +use clippy_utils::visitors::for_each_expr; use clippy_utils::{iter_input_pats, path_to_local}; use core::ops::ControlFlow; @@ -49,7 +49,7 @@ fn check_raw_ptr<'tcx>( if !raw_ptrs.is_empty() { let typeck = cx.tcx.typeck_body(body.id()); - let _: Option = for_each_expr_with_closures(cx, body.value, |e| { + let _: Option = for_each_expr(cx, body.value, |e| { match e.kind { hir::ExprKind::Call(f, args) if type_is_unsafe_function(cx, typeck.expr_ty(f)) => { for arg in args { diff --git a/clippy_lints/src/implicit_return.rs b/clippy_lints/src/implicit_return.rs index cc342007ec61..2f543781c44c 100644 --- a/clippy_lints/src/implicit_return.rs +++ b/clippy_lints/src/implicit_return.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::source::{snippet_with_applicability, snippet_with_context, walk_span_to_context}; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{get_async_fn_body, is_async_fn}; use core::ops::ControlFlow; use rustc_errors::Applicability; @@ -153,7 +153,7 @@ fn lint_implicit_returns( ExprKind::Loop(block, ..) => { let mut add_return = false; - let _: Option = for_each_expr(block, |e| { + let _: Option = for_each_expr_without_closures(block, |e| { if let ExprKind::Break(dest, sub_expr) = e.kind { if dest.target_id.ok() == Some(expr.hir_id) { if call_site_span.is_none() && e.span.ctxt() == ctxt { diff --git a/clippy_lints/src/matches/redundant_guards.rs b/clippy_lints/src/matches/redundant_guards.rs index a75cf37945f7..c2c0fbf439d5 100644 --- a/clippy_lints/src/matches/redundant_guards.rs +++ b/clippy_lints/src/matches/redundant_guards.rs @@ -2,7 +2,7 @@ use clippy_config::msrvs::Msrv; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::matching_root_macro_call; use clippy_utils::source::snippet; -use clippy_utils::visitors::{for_each_expr, is_local_used}; +use clippy_utils::visitors::{for_each_expr_without_closures, is_local_used}; use clippy_utils::{in_constant, path_to_local}; use rustc_ast::{BorrowKind, LitKind}; use rustc_errors::Applicability; @@ -249,7 +249,7 @@ fn emit_redundant_guards<'tcx>( /// an error in the future, and rustc already actively warns against this (see rust#41620), /// so we don't consider those as usable within patterns for linting purposes. fn expr_can_be_pat(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - for_each_expr(expr, |expr| { + for_each_expr_without_closures(expr, |expr| { if match expr.kind { ExprKind::ConstBlock(..) => cx.tcx.features().inline_const_pat, ExprKind::Call(c, ..) if let ExprKind::Path(qpath) = c.kind => { diff --git a/clippy_lints/src/matches/redundant_pattern_match.rs b/clippy_lints/src/matches/redundant_pattern_match.rs index 78973984fb0b..0e4b2d9d34a0 100644 --- a/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/clippy_lints/src/matches/redundant_pattern_match.rs @@ -3,7 +3,7 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::source::{snippet, walk_span_to_context}; use clippy_utils::sugg::{make_unop, Sugg}; use clippy_utils::ty::{is_type_diagnostic_item, needs_ordered_drop}; -use clippy_utils::visitors::{any_temporaries_need_ordered_drop, for_each_expr}; +use clippy_utils::visitors::{any_temporaries_need_ordered_drop, for_each_expr_without_closures}; use clippy_utils::{higher, is_expn_of, is_trait_method}; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; @@ -283,7 +283,7 @@ pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op // to see that there aren't any let chains anywhere in the guard, as that would break // if we suggest `t.is_none() && (let X = y && z)` for: // `match t { None if let X = y && z => true, _ => false }` - let has_nested_let_chain = for_each_expr(guard, |expr| { + let has_nested_let_chain = for_each_expr_without_closures(guard, |expr| { if matches!(expr.kind, ExprKind::Let(..)) { ControlFlow::Break(()) } else { diff --git a/clippy_lints/src/methods/collapsible_str_replace.rs b/clippy_lints/src/methods/collapsible_str_replace.rs index 5409ede6008b..1fab6c0e499d 100644 --- a/clippy_lints/src/methods/collapsible_str_replace.rs +++ b/clippy_lints/src/methods/collapsible_str_replace.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{eq_expr_value, get_parent_expr}; use core::ops::ControlFlow; use rustc_errors::Applicability; @@ -46,7 +46,7 @@ fn collect_replace_calls<'tcx>( let mut methods = VecDeque::new(); let mut from_args = VecDeque::new(); - let _: Option<()> = for_each_expr(expr, |e| { + let _: Option<()> = for_each_expr_without_closures(expr, |e| { if let Some(("replace", _, [from, to], _, _)) = method_call(e) { if eq_expr_value(cx, to_arg, to) && cx.typeck_results().expr_ty(from).peel_refs().is_char() { methods.push_front(e); diff --git a/clippy_lints/src/methods/str_splitn.rs b/clippy_lints/src/methods/str_splitn.rs index e8c12bbeea0e..4f42fb73547a 100644 --- a/clippy_lints/src/methods/str_splitn.rs +++ b/clippy_lints/src/methods/str_splitn.rs @@ -3,7 +3,7 @@ use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::source::snippet_with_context; use clippy_utils::usage::local_used_after_expr; -use clippy_utils::visitors::{for_each_expr_with_closures, Descend}; +use clippy_utils::visitors::{for_each_expr, Descend}; use clippy_utils::{is_diag_item_method, match_def_path, path_to_local_id, paths}; use core::ops::ControlFlow; use rustc_errors::Applicability; @@ -209,7 +209,7 @@ fn indirect_usage<'tcx>( }) = stmt.kind { let mut path_to_binding = None; - let _: Option = for_each_expr_with_closures(cx, init_expr, |e| { + let _: Option = for_each_expr(cx, init_expr, |e| { if path_to_local_id(e, binding) { path_to_binding = Some(e); } diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs index daf99d986142..c9b9d98dbe60 100644 --- a/clippy_lints/src/methods/unnecessary_filter_map.rs +++ b/clippy_lints/src/methods/unnecessary_filter_map.rs @@ -2,7 +2,7 @@ use super::utils::clone_or_copy_needed; use clippy_utils::diagnostics::span_lint; use clippy_utils::ty::is_copy; use clippy_utils::usage::mutated_variables; -use clippy_utils::visitors::{for_each_expr, Descend}; +use clippy_utils::visitors::{for_each_expr_without_closures, Descend}; use clippy_utils::{is_res_lang_ctor, is_trait_method, path_res, path_to_local_id}; use core::ops::ControlFlow; use rustc_hir as hir; @@ -26,7 +26,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a let (mut found_mapping, mut found_filtering) = check_expression(cx, arg_id, body.value); - let _: Option = for_each_expr(body.value, |e| { + let _: Option = for_each_expr_without_closures(body.value, |e| { if let hir::ExprKind::Ret(Some(e)) = &e.kind { let (found_mapping_res, found_filtering_res) = check_expression(cx, arg_id, e); found_mapping |= found_mapping_res; diff --git a/clippy_lints/src/methods/unnecessary_iter_cloned.rs b/clippy_lints/src/methods/unnecessary_iter_cloned.rs index d1300dd43c28..70885e46e955 100644 --- a/clippy_lints/src/methods/unnecessary_iter_cloned.rs +++ b/clippy_lints/src/methods/unnecessary_iter_cloned.rs @@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::ForLoop; use clippy_utils::source::snippet_opt; use clippy_utils::ty::{get_iterator_item_ty, implements_trait}; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{can_mut_borrow_both, fn_def_id, get_parent_expr, path_to_local}; use core::ops::ControlFlow; use rustc_errors::Applicability; @@ -61,7 +61,7 @@ pub fn check_for_loop_iter( fn is_caller_or_fields_change(cx: &LateContext<'_>, body: &Expr<'_>, caller: &Expr<'_>) -> bool { let mut change = false; if let ExprKind::Block(block, ..) = body.kind { - for_each_expr(block, |e| { + for_each_expr_without_closures(block, |e| { match e.kind { ExprKind::Assign(assignee, _, _) | ExprKind::AssignOp(_, assignee, _) => { change |= !can_mut_borrow_both(cx, caller, assignee); diff --git a/clippy_lints/src/missing_asserts_for_indexing.rs b/clippy_lints/src/missing_asserts_for_indexing.rs index 752723a0c68e..94c91b095171 100644 --- a/clippy_lints/src/missing_asserts_for_indexing.rs +++ b/clippy_lints/src/missing_asserts_for_indexing.rs @@ -4,7 +4,7 @@ use std::ops::ControlFlow; use clippy_utils::comparisons::{normalize_comparison, Rel}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{eq_expr_value, hash_expr, higher}; use rustc_ast::{LitKind, RangeLimits}; use rustc_data_structures::packed::Pu128; @@ -405,7 +405,7 @@ impl LateLintPass<'_> for MissingAssertsForIndexing { fn check_body(&mut self, cx: &LateContext<'_>, body: &Body<'_>) { let mut map = UnhashMap::default(); - for_each_expr(body.value, |expr| { + for_each_expr_without_closures(body.value, |expr| { check_index(cx, expr, &mut map); check_assert(cx, expr, &mut map); ControlFlow::::Continue(()) diff --git a/clippy_lints/src/missing_fields_in_debug.rs b/clippy_lints/src/missing_fields_in_debug.rs index a64faa124f08..77595b121aad 100644 --- a/clippy_lints/src/missing_fields_in_debug.rs +++ b/clippy_lints/src/missing_fields_in_debug.rs @@ -110,7 +110,7 @@ fn should_lint<'tcx>( // Is there a call to `DebugStruct::debug_struct`? Do lint if there is. let mut has_debug_struct = false; - for_each_expr(block, |expr| { + for_each_expr(cx, block, |expr| { if let ExprKind::MethodCall(path, recv, ..) = &expr.kind { let recv_ty = typeck_results.expr_ty(recv).peel_refs(); @@ -165,7 +165,7 @@ fn check_struct<'tcx>( let mut has_direct_field_access = false; let mut field_accesses = FxHashSet::default(); - for_each_expr(block, |expr| { + for_each_expr(cx, block, |expr| { if let ExprKind::Field(target, ident) = expr.kind && let target_ty = typeck_results.expr_ty_adjusted(target).peel_refs() && target_ty == self_ty diff --git a/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/clippy_lints/src/multiple_unsafe_ops_per_block.rs index 5b4ef852f0d9..da74a7c7145a 100644 --- a/clippy_lints/src/multiple_unsafe_ops_per_block.rs +++ b/clippy_lints/src/multiple_unsafe_ops_per_block.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::visitors::{for_each_expr_with_closures, Descend, Visitable}; +use clippy_utils::visitors::{for_each_expr, Descend, Visitable}; use core::ops::ControlFlow::Continue; use hir::def::{DefKind, Res}; use hir::{BlockCheckMode, ExprKind, QPath, Safety, UnOp}; @@ -96,7 +96,7 @@ fn collect_unsafe_exprs<'tcx>( node: impl Visitable<'tcx>, unsafe_ops: &mut Vec<(&'static str, Span)>, ) { - for_each_expr_with_closures(cx, node, |expr| { + for_each_expr(cx, node, |expr| { match expr.kind { ExprKind::InlineAsm(_) => unsafe_ops.push(("inline assembly used here", expr.span)), diff --git a/clippy_lints/src/needless_late_init.rs b/clippy_lints/src/needless_late_init.rs index 5a0ae1a4d6d2..4bfc30fa5cf8 100644 --- a/clippy_lints/src/needless_late_init.rs +++ b/clippy_lints/src/needless_late_init.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::path_to_local; use clippy_utils::source::snippet_opt; use clippy_utils::ty::needs_ordered_drop; -use clippy_utils::visitors::{for_each_expr, for_each_expr_with_closures, is_local_used}; +use clippy_utils::visitors::{for_each_expr, for_each_expr_without_closures, is_local_used}; use core::ops::ControlFlow; use rustc_errors::{Applicability, MultiSpan}; use rustc_hir::{ @@ -63,7 +63,7 @@ declare_clippy_lint! { declare_lint_pass!(NeedlessLateInit => [NEEDLESS_LATE_INIT]); fn contains_assign_expr<'tcx>(cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'tcx>) -> bool { - for_each_expr_with_closures(cx, stmt, |e| { + for_each_expr(cx, stmt, |e| { if matches!(e.kind, ExprKind::Assign(..)) { ControlFlow::Break(()) } else { @@ -74,7 +74,7 @@ fn contains_assign_expr<'tcx>(cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'tcx>) -> } fn contains_let(cond: &Expr<'_>) -> bool { - for_each_expr(cond, |e| { + for_each_expr_without_closures(cond, |e| { if matches!(e.kind, ExprKind::Let(_)) { ControlFlow::Break(()) } else { diff --git a/clippy_lints/src/needless_pass_by_ref_mut.rs b/clippy_lints/src/needless_pass_by_ref_mut.rs index da6ed5fb96f1..57ba0da53319 100644 --- a/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -1,7 +1,7 @@ use super::needless_pass_by_value::requires_exact_signature; use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::source::snippet; -use clippy_utils::visitors::for_each_expr_with_closures; +use clippy_utils::visitors::for_each_expr; use clippy_utils::{inherits_cfg, is_from_proc_macro, is_self}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_errors::Applicability; @@ -205,7 +205,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { // We retrieve all the closures declared in the function because they will not be found // by `euv::Delegate`. let mut closures: FxHashSet = FxHashSet::default(); - for_each_expr_with_closures(cx, body, |expr| { + for_each_expr(cx, body, |expr| { if let ExprKind::Closure(closure) = expr.kind { closures.insert(closure.def_id); } diff --git a/clippy_lints/src/operators/assign_op_pattern.rs b/clippy_lints/src/operators/assign_op_pattern.rs index 910e584a7a0f..641d881d974b 100644 --- a/clippy_lints/src/operators/assign_op_pattern.rs +++ b/clippy_lints/src/operators/assign_op_pattern.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet_opt; use clippy_utils::ty::implements_trait; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{binop_traits, eq_expr_value, trait_ref_of_method}; use core::ops::ControlFlow; use rustc_errors::Applicability; @@ -62,7 +62,7 @@ pub(super) fn check<'tcx>( }; let mut found = false; - let found_multiple = for_each_expr(e, |e| { + let found_multiple = for_each_expr_without_closures(e, |e| { if eq_expr_value(cx, assignee, e) { if found { return ControlFlow::Break(()); diff --git a/clippy_lints/src/panic_in_result_fn.rs b/clippy_lints/src/panic_in_result_fn.rs index 806638c0505b..381975199d28 100644 --- a/clippy_lints/src/panic_in_result_fn.rs +++ b/clippy_lints/src/panic_in_result_fn.rs @@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for PanicInResultFn { fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, body: &'tcx hir::Body<'tcx>) { let mut panics = Vec::new(); - let _: Option = for_each_expr(body.value, |e| { + let _: Option = for_each_expr(cx, body.value, |e| { let Some(macro_call) = root_macro_call_first_node(cx, e) else { return ControlFlow::Continue(Descend::Yes); }; diff --git a/clippy_lints/src/redundant_async_block.rs b/clippy_lints/src/redundant_async_block.rs index 0ed957f1f2fb..313e4083256b 100644 --- a/clippy_lints/src/redundant_async_block.rs +++ b/clippy_lints/src/redundant_async_block.rs @@ -4,7 +4,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::peel_blocks; use clippy_utils::source::{snippet, walk_span_to_context}; use clippy_utils::ty::implements_trait; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use rustc_errors::Applicability; use rustc_hir::{ Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, MatchSource, @@ -107,7 +107,7 @@ fn desugar_await<'tcx>(expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> { if let ExprKind::Match(match_value, _, MatchSource::AwaitDesugar) = expr.kind && let ExprKind::Call(_, [into_future_arg]) = match_value.kind && let ctxt = expr.span.ctxt() - && for_each_expr(into_future_arg, |e| { + && for_each_expr_without_closures(into_future_arg, |e| { walk_span_to_context(e.span, ctxt).map_or(ControlFlow::Break(()), |_| ControlFlow::Continue(())) }) .is_none() diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index 48d6fb3c0378..c11da3147ef4 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then}; use clippy_utils::source::{snippet_opt, snippet_with_context}; use clippy_utils::sugg::has_enclosing_paren; -use clippy_utils::visitors::{for_each_expr_with_closures, Descend}; +use clippy_utils::visitors::{for_each_expr, Descend}; use clippy_utils::{ binary_expr_needs_parentheses, fn_def_id, is_from_proc_macro, is_inside_let_else, is_res_lang_ctor, path_res, path_to_local_id, span_contains_cfg, span_find_starting_semi, @@ -436,7 +436,7 @@ fn emit_return_lint( } fn last_statement_borrows<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool { - for_each_expr_with_closures(cx, expr, |e| { + for_each_expr(cx, expr, |e| { if let Some(def_id) = fn_def_id(cx, e) && cx .tcx diff --git a/clippy_lints/src/suspicious_trait_impl.rs b/clippy_lints/src/suspicious_trait_impl.rs index 3f030b803318..744d6392e065 100644 --- a/clippy_lints/src/suspicious_trait_impl.rs +++ b/clippy_lints/src/suspicious_trait_impl.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{binop_traits, trait_ref_of_method, BINOP_TRAITS, OP_ASSIGN_TRAITS}; use core::ops::ControlFlow; use rustc_hir as hir; @@ -95,7 +95,7 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl { fn count_binops(expr: &hir::Expr<'_>) -> u32 { let mut count = 0u32; - let _: Option = for_each_expr(expr, |e| { + let _: Option = for_each_expr_without_closures(expr, |e| { if matches!( e.kind, hir::ExprKind::Binary(..) diff --git a/clippy_lints/src/undocumented_unsafe_blocks.rs b/clippy_lints/src/undocumented_unsafe_blocks.rs index 6cf9229fdd08..93a1089a9707 100644 --- a/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -3,7 +3,7 @@ use std::ops::ControlFlow; use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::is_lint_allowed; use clippy_utils::source::walk_span_to_context; -use clippy_utils::visitors::{for_each_expr_with_closures, Descend}; +use clippy_utils::visitors::{for_each_expr, Descend}; use hir::HirId; use rustc_data_structures::sync::Lrc; use rustc_hir as hir; @@ -296,7 +296,7 @@ fn expr_has_unnecessary_safety_comment<'tcx>( } // this should roughly be the reverse of `block_parents_have_safety_comment` - if for_each_expr_with_closures(cx, expr, |expr| match expr.kind { + if for_each_expr(cx, expr, |expr| match expr.kind { hir::ExprKind::Block( Block { rules: BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided), diff --git a/clippy_lints/src/unused_self.rs b/clippy_lints/src/unused_self.rs index a67f53f00aee..3e6102f5982f 100644 --- a/clippy_lints/src/unused_self.rs +++ b/clippy_lints/src/unused_self.rs @@ -59,7 +59,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedSelf { let parent_item = cx.tcx.hir().expect_item(parent); let assoc_item = cx.tcx.associated_item(impl_item.owner_id); let contains_todo = |cx, body: &'_ Body<'_>| -> bool { - clippy_utils::visitors::for_each_expr(body.value, |e| { + clippy_utils::visitors::for_each_expr_without_closures(body.value, |e| { if let Some(macro_call) = root_macro_call_first_node(cx, e) { if cx.tcx.item_name(macro_call.def_id).as_str() == "todo" { ControlFlow::Break(()) diff --git a/clippy_lints/src/unwrap_in_result.rs b/clippy_lints/src/unwrap_in_result.rs index 197ab0f173bd..f77badd97b7a 100644 --- a/clippy_lints/src/unwrap_in_result.rs +++ b/clippy_lints/src/unwrap_in_result.rs @@ -77,7 +77,7 @@ fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_item: &'tc let body = cx.tcx.hir().body(body_id); let typeck = cx.tcx.typeck(impl_item.owner_id.def_id); let mut result = Vec::new(); - let _: Option = for_each_expr(body.value, |e| { + let _: Option = for_each_expr(cx, body.value, |e| { // check for `expect` if let Some(arglists) = method_chain_args(e, &["expect"]) { let receiver_ty = typeck.expr_ty(arglists[0].0).peel_refs(); diff --git a/clippy_lints/src/zero_repeat_side_effects.rs b/clippy_lints/src/zero_repeat_side_effects.rs index 143fecdd237d..da198b78d2e7 100644 --- a/clippy_lints/src/zero_repeat_side_effects.rs +++ b/clippy_lints/src/zero_repeat_side_effects.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::higher::VecArgs; use clippy_utils::source::snippet; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use rustc_ast::LitKind; use rustc_errors::Applicability; use rustc_hir::{ExprKind, Node}; @@ -66,7 +66,7 @@ impl LateLintPass<'_> for ZeroRepeatSideEffects { fn inner_check(cx: &LateContext<'_>, expr: &'_ rustc_hir::Expr<'_>, inner_expr: &'_ rustc_hir::Expr<'_>, is_vec: bool) { // check if expr is a call or has a call inside it - if for_each_expr(inner_expr, |x| { + if for_each_expr_without_closures(inner_expr, |x| { if let ExprKind::Call(_, _) | ExprKind::MethodCall(_, _, _, _) = x.kind { std::ops::ControlFlow::Break(()) } else { diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 6d6c4ffbe5d6..49776bf5a5b4 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -126,7 +126,7 @@ use visitors::Visitable; use crate::consts::{constant, mir_to_const, Constant}; use crate::higher::Range; use crate::ty::{adt_and_variant_of_res, can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type}; -use crate::visitors::for_each_expr; +use crate::visitors::for_each_expr_without_closures; use rustc_middle::hir::nested_filter; @@ -1322,7 +1322,7 @@ pub fn contains_name<'tcx>(name: Symbol, expr: &'tcx Expr<'_>, cx: &LateContext< /// Returns `true` if `expr` contains a return expression pub fn contains_return<'tcx>(expr: impl Visitable<'tcx>) -> bool { - for_each_expr(expr, |e| { + for_each_expr_without_closures(expr, |e| { if matches!(e.kind, ExprKind::Ret(..)) { ControlFlow::Break(()) } else { diff --git a/clippy_utils/src/macros.rs b/clippy_utils/src/macros.rs index 8daab9b0d92c..455239cc37f3 100644 --- a/clippy_utils/src/macros.rs +++ b/clippy_utils/src/macros.rs @@ -1,6 +1,6 @@ #![allow(clippy::similar_names)] // `expr` and `expn` -use crate::visitors::{for_each_expr, Descend}; +use crate::visitors::{for_each_expr_without_closures, Descend}; use arrayvec::ArrayVec; use rustc_ast::{FormatArgs, FormatArgument, FormatPlaceholder}; @@ -323,7 +323,7 @@ fn find_assert_args_inner<'a, const N: usize>( Some(inner_name) => find_assert_within_debug_assert(cx, expr, expn, Symbol::intern(inner_name))?, }; let mut args = ArrayVec::new(); - let panic_expn = for_each_expr(expr, |e| { + let panic_expn = for_each_expr_without_closures(expr, |e| { if args.is_full() { match PanicExpn::parse(e) { Some(expn) => ControlFlow::Break(expn), @@ -349,7 +349,7 @@ fn find_assert_within_debug_assert<'a>( expn: ExpnId, assert_name: Symbol, ) -> Option<(&'a Expr<'a>, ExpnId)> { - for_each_expr(expr, |e| { + for_each_expr_without_closures(expr, |e| { if !e.span.from_expansion() { return ControlFlow::Continue(Descend::No); } @@ -397,7 +397,7 @@ impl FormatArgsStorage { /// /// See also [`find_format_arg_expr`] pub fn get(&self, cx: &LateContext<'_>, start: &Expr<'_>, expn_id: ExpnId) -> Option<&FormatArgs> { - let format_args_expr = for_each_expr(start, |expr| { + let format_args_expr = for_each_expr_without_closures(start, |expr| { let ctxt = expr.span.ctxt(); if ctxt.outer_expn().is_descendant_of(expn_id) { if macro_backtrace(expr.span) @@ -439,7 +439,7 @@ pub fn find_format_arg_expr<'hir, 'ast>( parent: _, } = target.expr.span.data(); - for_each_expr(start, |expr| { + for_each_expr_without_closures(start, |expr| { // When incremental compilation is enabled spans gain a parent during AST to HIR lowering, // since we're comparing an AST span to a HIR one we need to ignore the parent field let data = expr.span.data(); diff --git a/clippy_utils/src/ptr.rs b/clippy_utils/src/ptr.rs index 88837d8a143e..991ea428dc33 100644 --- a/clippy_utils/src/ptr.rs +++ b/clippy_utils/src/ptr.rs @@ -1,5 +1,5 @@ use crate::source::snippet; -use crate::visitors::{for_each_expr, Descend}; +use crate::visitors::{for_each_expr_without_closures, Descend}; use crate::{path_to_local_id, strip_pat_refs}; use core::ops::ControlFlow; use rustc_hir::{Body, BodyId, ExprKind, HirId, PatKind}; @@ -31,7 +31,7 @@ fn extract_clone_suggestions<'tcx>( body: &'tcx Body<'_>, ) -> Option)>> { let mut spans = Vec::new(); - for_each_expr(body, |e| { + for_each_expr_without_closures(body, |e| { if let ExprKind::MethodCall(seg, recv, [], _) = e.kind && path_to_local_id(recv, id) { diff --git a/clippy_utils/src/usage.rs b/clippy_utils/src/usage.rs index 2a25d51d8e50..fbf3d95365ac 100644 --- a/clippy_utils/src/usage.rs +++ b/clippy_utils/src/usage.rs @@ -1,4 +1,4 @@ -use crate::visitors::{for_each_expr, for_each_expr_with_closures, Descend, Visitable}; +use crate::visitors::{for_each_expr, for_each_expr_without_closures, Descend, Visitable}; use crate::{self as utils, get_enclosing_loop_or_multi_call_closure}; use core::ops::ControlFlow; use hir::def::Res; @@ -145,7 +145,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BindingUsageFinder<'a, 'tcx> { } pub fn contains_return_break_continue_macro(expression: &Expr<'_>) -> bool { - for_each_expr(expression, |e| { + for_each_expr_without_closures(expression, |e| { match e.kind { ExprKind::Ret(..) | ExprKind::Break(..) | ExprKind::Continue(..) => ControlFlow::Break(()), // Something special could be done here to handle while or for loop @@ -159,7 +159,7 @@ pub fn contains_return_break_continue_macro(expression: &Expr<'_>) -> bool { } pub fn local_used_in<'tcx>(cx: &LateContext<'tcx>, local_id: HirId, v: impl Visitable<'tcx>) -> bool { - for_each_expr_with_closures(cx, v, |e| { + for_each_expr(cx, v, |e| { if utils::path_to_local_id(e, local_id) { ControlFlow::Break(()) } else { @@ -184,7 +184,7 @@ pub fn local_used_after_expr(cx: &LateContext<'_>, local_id: HirId, after: &Expr let loop_start = get_enclosing_loop_or_multi_call_closure(cx, after).map(|e| e.hir_id); let mut past_expr = false; - for_each_expr_with_closures(cx, block, |e| { + for_each_expr(cx, block, |e| { if past_expr { if utils::path_to_local_id(e, local_id) { ControlFlow::Break(()) diff --git a/clippy_utils/src/visitors.rs b/clippy_utils/src/visitors.rs index 90b56297bb55..3a39e178515d 100644 --- a/clippy_utils/src/visitors.rs +++ b/clippy_utils/src/visitors.rs @@ -100,7 +100,7 @@ visitable_ref!(Stmt, visit_stmt); /// Calls the given function once for each expression contained. This does not enter any bodies or /// nested items. -pub fn for_each_expr<'tcx, B, C: Continue>( +pub fn for_each_expr_without_closures<'tcx, B, C: Continue>( node: impl Visitable<'tcx>, f: impl FnMut(&'tcx Expr<'tcx>) -> ControlFlow, ) -> Option { @@ -134,7 +134,7 @@ pub fn for_each_expr<'tcx, B, C: Continue>( /// Calls the given function once for each expression contained. This will enter bodies, but not /// nested items. -pub fn for_each_expr_with_closures<'tcx, B, C: Continue>( +pub fn for_each_expr<'tcx, B, C: Continue>( cx: &LateContext<'tcx>, node: impl Visitable<'tcx>, f: impl FnMut(&'tcx Expr<'tcx>) -> ControlFlow, @@ -181,7 +181,7 @@ pub fn for_each_expr_with_closures<'tcx, B, C: Continue>( /// returns `true` if expr contains match expr desugared from try fn contains_try(expr: &Expr<'_>) -> bool { - for_each_expr(expr, |e| { + for_each_expr_without_closures(expr, |e| { if matches!(e.kind, ExprKind::Match(_, _, hir::MatchSource::TryDesugar(_))) { ControlFlow::Break(()) } else { @@ -286,7 +286,7 @@ where /// Checks if the given resolved path is used in the given body. pub fn is_res_used(cx: &LateContext<'_>, res: Res, body: BodyId) -> bool { - for_each_expr_with_closures(cx, cx.tcx.hir().body(body).value, |e| { + for_each_expr(cx, cx.tcx.hir().body(body).value, |e| { if let ExprKind::Path(p) = &e.kind { if cx.qpath_res(p, e.hir_id) == res { return ControlFlow::Break(()); @@ -299,7 +299,7 @@ pub fn is_res_used(cx: &LateContext<'_>, res: Res, body: BodyId) -> bool { /// Checks if the given local is used. pub fn is_local_used<'tcx>(cx: &LateContext<'tcx>, visitable: impl Visitable<'tcx>, id: HirId) -> bool { - for_each_expr_with_closures(cx, visitable, |e| { + for_each_expr(cx, visitable, |e| { if path_to_local_id(e, id) { ControlFlow::Break(()) } else { @@ -757,7 +757,7 @@ pub fn for_each_local_assignment<'tcx, B>( } pub fn contains_break_or_continue(expr: &Expr<'_>) -> bool { - for_each_expr(expr, |e| { + for_each_expr_without_closures(expr, |e| { if matches!(e.kind, ExprKind::Break(..) | ExprKind::Continue(..)) { ControlFlow::Break(()) } else { @@ -776,7 +776,7 @@ pub fn local_used_once<'tcx>( ) -> Option<&'tcx Expr<'tcx>> { let mut expr = None; - let cf = for_each_expr_with_closures(cx, visitable, |e| { + let cf = for_each_expr(cx, visitable, |e| { if path_to_local_id(e, id) && expr.replace(e).is_some() { ControlFlow::Break(()) } else { diff --git a/tests/ui/missing_fields_in_debug.rs b/tests/ui/missing_fields_in_debug.rs index e91e8ab7f475..68867ec819d1 100644 --- a/tests/ui/missing_fields_in_debug.rs +++ b/tests/ui/missing_fields_in_debug.rs @@ -4,6 +4,7 @@ use std::fmt; use std::marker::PhantomData; use std::ops::Deref; +use std::thread::LocalKey; struct NamedStruct1Ignored { data: u8, @@ -191,4 +192,21 @@ impl fmt::Debug for WithPD { } } +struct InClosure { + a: u8, + b: String, +} + +impl fmt::Debug for InClosure { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut d = f.debug_struct("InClosure"); + d.field("a", &self.a); + let mut c = || { + d.field("b", &self.b); + }; + c(); + d.finish() + } +} + fn main() {} diff --git a/tests/ui/missing_fields_in_debug.stderr b/tests/ui/missing_fields_in_debug.stderr index 6f8a9abe9228..8c1810909dd8 100644 --- a/tests/ui/missing_fields_in_debug.stderr +++ b/tests/ui/missing_fields_in_debug.stderr @@ -1,5 +1,5 @@ error: manual `Debug` impl does not include all fields - --> tests/ui/missing_fields_in_debug.rs:13:1 + --> tests/ui/missing_fields_in_debug.rs:14:1 | LL | / impl fmt::Debug for NamedStruct1Ignored { LL | | @@ -11,7 +11,7 @@ LL | | } | |_^ | note: this field is unused - --> tests/ui/missing_fields_in_debug.rs:10:5 + --> tests/ui/missing_fields_in_debug.rs:11:5 | LL | hidden: u32, | ^^^^^^^^^^^ @@ -21,7 +21,7 @@ LL | hidden: u32, = help: to override `-D warnings` add `#[allow(clippy::missing_fields_in_debug)]` error: manual `Debug` impl does not include all fields - --> tests/ui/missing_fields_in_debug.rs:32:1 + --> tests/ui/missing_fields_in_debug.rs:33:1 | LL | / impl fmt::Debug for NamedStructMultipleIgnored { LL | | @@ -33,17 +33,17 @@ LL | | } | |_^ | note: this field is unused - --> tests/ui/missing_fields_in_debug.rs:26:5 + --> tests/ui/missing_fields_in_debug.rs:27:5 | LL | hidden: u32, | ^^^^^^^^^^^ note: this field is unused - --> tests/ui/missing_fields_in_debug.rs:27:5 + --> tests/ui/missing_fields_in_debug.rs:28:5 | LL | hidden2: String, | ^^^^^^^^^^^^^^^ note: this field is unused - --> tests/ui/missing_fields_in_debug.rs:29:5 + --> tests/ui/missing_fields_in_debug.rs:30:5 | LL | hidden4: ((((u8), u16), u32), u64), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL | hidden4: ((((u8), u16), u32), u64), = help: consider calling `.finish_non_exhaustive()` if you intend to ignore fields error: manual `Debug` impl does not include all fields - --> tests/ui/missing_fields_in_debug.rs:94:1 + --> tests/ui/missing_fields_in_debug.rs:95:1 | LL | / impl fmt::Debug for MultiExprDebugImpl { LL | | @@ -63,7 +63,7 @@ LL | | } | |_^ | note: this field is unused - --> tests/ui/missing_fields_in_debug.rs:90:5 + --> tests/ui/missing_fields_in_debug.rs:91:5 | LL | b: String, | ^^^^^^^^^ diff --git a/tests/ui/panic_in_result_fn.rs b/tests/ui/panic_in_result_fn.rs index 41e2f5226899..aaaf9a109acb 100644 --- a/tests/ui/panic_in_result_fn.rs +++ b/tests/ui/panic_in_result_fn.rs @@ -56,6 +56,11 @@ fn function_result_with_panic() -> Result // should emit lint panic!("error"); } +fn in_closure() -> Result { + let c = || panic!(); + c() +} + fn todo() { println!("something"); } diff --git a/tests/ui/panic_in_result_fn.stderr b/tests/ui/panic_in_result_fn.stderr index cd2234bdfb13..2d49b5ab1b8f 100644 --- a/tests/ui/panic_in_result_fn.stderr +++ b/tests/ui/panic_in_result_fn.stderr @@ -34,5 +34,21 @@ note: return Err() instead of panicking LL | panic!("error"); | ^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: used `panic!()` or assertion in a function that returns `Result` + --> tests/ui/panic_in_result_fn.rs:59:1 + | +LL | / fn in_closure() -> Result { +LL | | let c = || panic!(); +LL | | c() +LL | | } + | |_^ + | + = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing +note: return Err() instead of panicking + --> tests/ui/panic_in_result_fn.rs:60:16 + | +LL | let c = || panic!(); + | ^^^^^^^^ + +error: aborting due to 3 previous errors diff --git a/tests/ui/unwrap_in_result.rs b/tests/ui/unwrap_in_result.rs index a19db46c667d..62c6d959c84b 100644 --- a/tests/ui/unwrap_in_result.rs +++ b/tests/ui/unwrap_in_result.rs @@ -38,6 +38,11 @@ impl A { } None } + + fn in_closure(a: Option) -> Option { + let c = || a.unwrap(); + Some(c()) + } } fn main() { diff --git a/tests/ui/unwrap_in_result.stderr b/tests/ui/unwrap_in_result.stderr index 29c7a9373aa7..752177aaca57 100644 --- a/tests/ui/unwrap_in_result.stderr +++ b/tests/ui/unwrap_in_result.stderr @@ -38,5 +38,21 @@ note: potential non-recoverable error(s) LL | let i = i_str.parse::().expect("not a number"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: used unwrap or expect in a function that returns result or option + --> tests/ui/unwrap_in_result.rs:42:5 + | +LL | / fn in_closure(a: Option) -> Option { +LL | | let c = || a.unwrap(); +LL | | Some(c()) +LL | | } + | |_____^ + | + = help: unwrap and expect should not be used in a function that returns result or option +note: potential non-recoverable error(s) + --> tests/ui/unwrap_in_result.rs:43:20 + | +LL | let c = || a.unwrap(); + | ^^^^^^^^^^ + +error: aborting due to 3 previous errors