diff options
| author | bors <bors@rust-lang.org> | 2022-04-15 01:57:52 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-04-15 01:57:52 +0000 |
| commit | 0bc93b67f55ed04de7b462af69f06407844c6531 (patch) | |
| tree | 1544ba68bd9a4a11f91b8a64e592ef71d09999a1 /clippy_utils/src | |
| parent | 80bcd9bc6e91cc00fbf7c9bf7aab13c0a4ec2367 (diff) | |
| parent | 70f7c624e442c3049d440cd20f8d77b66580105c (diff) | |
| download | rust-0bc93b67f55ed04de7b462af69f06407844c6531.tar.gz rust-0bc93b67f55ed04de7b462af69f06407844c6531.zip | |
Auto merge of #8563 - Jarcho:let_unit_1502, r=Jarcho
Don't lint `let_unit_value` when needed for type inferenece fixes: #1502 Pinging `@dtolnay.` I think this is enough to fix the issue. Do you have a good list crates to test this on? changelog: Don't lint `let_unit_value` when needed for type inference
Diffstat (limited to 'clippy_utils/src')
| -rw-r--r-- | clippy_utils/src/visitors.rs | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/clippy_utils/src/visitors.rs b/clippy_utils/src/visitors.rs index 3db64b25353..c00bc2bd213 100644 --- a/clippy_utils/src/visitors.rs +++ b/clippy_utils/src/visitors.rs @@ -1,4 +1,5 @@ use crate::path_to_local_id; +use core::ops::ControlFlow; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{self, walk_block, walk_expr, Visitor}; @@ -402,3 +403,36 @@ pub fn contains_unsafe_block<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) v.visit_expr(e); v.found_unsafe } + +/// Runs the given function for each sub-expression producing the final value consumed by the parent +/// of the give expression. +/// +/// e.g. for the following expression +/// ```rust,ignore +/// if foo { +/// f(0) +/// } else { +/// 1 + 1 +/// } +/// ``` +/// this will pass both `f(0)` and `1+1` to the given function. +pub fn for_each_value_source<'tcx, B>( + e: &'tcx Expr<'tcx>, + f: &mut impl FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>, +) -> ControlFlow<B> { + match e.kind { + ExprKind::Block(Block { expr: Some(e), .. }, _) => for_each_value_source(e, f), + ExprKind::Match(_, arms, _) => { + for arm in arms { + for_each_value_source(arm.body, f)?; + } + ControlFlow::Continue(()) + }, + ExprKind::If(_, if_expr, Some(else_expr)) => { + for_each_value_source(if_expr, f)?; + for_each_value_source(else_expr, f) + }, + ExprKind::DropTemps(e) => for_each_value_source(e, f), + _ => f(e), + } +} |
