Auto merge of #12822 - Alexendoo:for-each-expr, r=dswij
Make `for_each_expr` visit closures by default, rename the old version `for_each_expr_without_closures` A lot of the time `for_each_expr` is picked when closures should be visited so I think it makes sense for this to be the default with the alternative available for when you don't need to visit them. The first commit renames `for_each_expr` to `for_each_expr_without_closures` and `for_each_expr_with_closures` to `for_each_expr` The second commit switches a few uses that I caught over to include closures to fix a few bugs changelog: none
This commit is contained in:
commit
0f87a81882
@ -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)
|
||||
|
@ -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<Infallible, Descend> {
|
||||
for_each_expr_without_closures(expr, |sub_expr| -> ControlFlow<Infallible, Descend> {
|
||||
// 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<Infallible, Descend> {
|
||||
for_each_expr_without_closures(expr, |sub_expr| -> ControlFlow<Infallible, Descend> {
|
||||
// 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) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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(());
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 => {
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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(())
|
||||
|
@ -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
|
||||
|
@ -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)),
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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<LocalDefId> = 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);
|
||||
}
|
||||
|
@ -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(());
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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(..)
|
||||
|
@ -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),
|
||||
|
@ -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(())
|
||||
|
@ -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();
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
@ -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<Vec<(Span, Cow<'static, str>)>> {
|
||||
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)
|
||||
{
|
||||
|
@ -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(())
|
||||
|
@ -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<B, C>,
|
||||
) -> Option<B> {
|
||||
@ -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<B, C>,
|
||||
@ -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 {
|
||||
|
@ -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() {}
|
||||
|
@ -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,
|
||||
| ^^^^^^^^^
|
||||
|
@ -56,6 +56,11 @@ fn function_result_with_panic() -> Result<bool, String> // should emit lint
|
||||
panic!("error");
|
||||
}
|
||||
|
||||
fn in_closure() -> Result<bool, String> {
|
||||
let c = || panic!();
|
||||
c()
|
||||
}
|
||||
|
||||
fn todo() {
|
||||
println!("something");
|
||||
}
|
||||
|
@ -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<bool, String> {
|
||||
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
|
||||
|
||||
|
@ -38,6 +38,11 @@ impl A {
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn in_closure(a: Option<bool>) -> Option<bool> {
|
||||
let c = || a.unwrap();
|
||||
Some(c())
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -38,5 +38,21 @@ note: potential non-recoverable error(s)
|
||||
LL | let i = i_str.parse::<i32>().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<bool>) -> Option<bool> {
|
||||
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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user