Rename remove_blocks to peel_blocks

This commit is contained in:
Cameron Steffen 2021-04-01 10:31:11 -05:00
parent 9e0852705e
commit 284b63a687
9 changed files with 38 additions and 34 deletions

View File

@ -2,7 +2,7 @@
use clippy_utils::source::snippet_with_applicability; use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::match_type; use clippy_utils::ty::match_type;
use clippy_utils::visitors::is_local_used; use clippy_utils::visitors::is_local_used;
use clippy_utils::{path_to_local_id, paths, peel_ref_operators, remove_blocks, strip_pat_refs}; use clippy_utils::{path_to_local_id, paths, peel_blocks, peel_ref_operators, strip_pat_refs};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Expr, ExprKind, PatKind}; use rustc_hir::{BinOpKind, Expr, ExprKind, PatKind};
@ -55,7 +55,7 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
cx.typeck_results().expr_ty(filter_recv).peel_refs(), cx.typeck_results().expr_ty(filter_recv).peel_refs(),
&paths::SLICE_ITER); &paths::SLICE_ITER);
let operand_is_arg = |expr| { let operand_is_arg = |expr| {
let expr = peel_ref_operators(cx, remove_blocks(expr)); let expr = peel_ref_operators(cx, peel_blocks(expr));
path_to_local_id(expr, arg_id) path_to_local_id(expr, arg_id)
}; };
let needle = if operand_is_arg(l) { let needle = if operand_is_arg(l) {

View File

@ -1,5 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::{is_automatically_derived, is_default_equivalent, remove_blocks}; use clippy_utils::{is_automatically_derived, is_default_equivalent, peel_blocks};
use rustc_hir::{ use rustc_hir::{
def::{DefKind, Res}, def::{DefKind, Res},
Body, Expr, ExprKind, GenericArg, Impl, ImplItemKind, Item, ItemKind, Node, PathSegment, QPath, TyKind, Body, Expr, ExprKind, GenericArg, Impl, ImplItemKind, Item, ItemKind, Node, PathSegment, QPath, TyKind,
@ -95,7 +95,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
} }
} }
} }
let should_emit = match remove_blocks(func_expr).kind { let should_emit = match peel_blocks(func_expr).kind {
ExprKind::Tup(fields) => fields.iter().all(|e| is_default_equivalent(cx, e)), ExprKind::Tup(fields) => fields.iter().all(|e| is_default_equivalent(cx, e)),
ExprKind::Call(callee, args) ExprKind::Call(callee, args)
if is_path_self(callee) => args.iter().all(|e| is_default_equivalent(cx, e)), if is_path_self(callee) => args.iter().all(|e| is_default_equivalent(cx, e)),

View File

@ -1,8 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::is_trait_method;
use clippy_utils::remove_blocks;
use clippy_utils::source::snippet_with_applicability; use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::{is_copy, is_type_diagnostic_item}; use clippy_utils::ty::{is_copy, is_type_diagnostic_item};
use clippy_utils::{is_trait_method, peel_blocks};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
@ -60,7 +59,7 @@ fn check_expr(&mut self, cx: &LateContext<'_>, e: &hir::Expr<'_>) {
if let hir::ExprKind::Closure(_, _, body_id, _, _) = args[1].kind; if let hir::ExprKind::Closure(_, _, body_id, _, _) = args[1].kind;
then { then {
let closure_body = cx.tcx.hir().body(body_id); let closure_body = cx.tcx.hir().body(body_id);
let closure_expr = remove_blocks(&closure_body.value); let closure_expr = peel_blocks(&closure_body.value);
match closure_body.params[0].pat.kind { match closure_body.params[0].pat.kind {
hir::PatKind::Ref(inner, hir::Mutability::Not) => if let hir::PatKind::Binding( hir::PatKind::Ref(inner, hir::Mutability::Not) => if let hir::PatKind::Binding(
hir::BindingAnnotation::Unannotated, .., name, None hir::BindingAnnotation::Unannotated, .., name, None

View File

@ -9,7 +9,7 @@
use clippy_utils::visitors::is_local_used; use clippy_utils::visitors::is_local_used;
use clippy_utils::{ use clippy_utils::{
get_parent_expr, is_expn_of, is_lang_ctor, is_lint_allowed, is_refutable, is_unit_expr, is_wild, meets_msrv, msrvs, get_parent_expr, is_expn_of, is_lang_ctor, is_lint_allowed, is_refutable, is_unit_expr, is_wild, meets_msrv, msrvs,
path_to_local, path_to_local_id, peel_hir_pat_refs, peel_n_hir_expr_refs, recurse_or_patterns, remove_blocks, path_to_local, path_to_local_id, peel_blocks, peel_hir_pat_refs, peel_n_hir_expr_refs, recurse_or_patterns,
strip_pat_refs, strip_pat_refs,
}; };
use clippy_utils::{paths, search_same, SpanlessEq, SpanlessHash}; use clippy_utils::{paths, search_same, SpanlessEq, SpanlessHash};
@ -659,7 +659,7 @@ fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'_>) {
QPath::Resolved(None, variant_name), args, _) = arms[0].pat.kind; QPath::Resolved(None, variant_name), args, _) = arms[0].pat.kind;
if args.len() == 1; if args.len() == 1;
if let PatKind::Binding(_, arg, ..) = strip_pat_refs(&args[0]).kind; if let PatKind::Binding(_, arg, ..) = strip_pat_refs(&args[0]).kind;
let body = remove_blocks(arms[0].body); let body = peel_blocks(arms[0].body);
if path_to_local_id(body, arg); if path_to_local_id(body, arg);
then { then {
@ -724,7 +724,7 @@ fn check_single_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], exp
return; return;
} }
let els = arms[1].body; let els = arms[1].body;
let els = if is_unit_expr(remove_blocks(els)) { let els = if is_unit_expr(peel_blocks(els)) {
None None
} else if let ExprKind::Block(Block { stmts, expr: block_expr, .. }, _) = els.kind { } else if let ExprKind::Block(Block { stmts, expr: block_expr, .. }, _) = els.kind {
if stmts.len() == 1 && block_expr.is_none() || stmts.is_empty() && block_expr.is_some() { if stmts.len() == 1 && block_expr.is_none() || stmts.is_empty() && block_expr.is_some() {
@ -1482,7 +1482,7 @@ fn check_match_single_binding<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[A
let matched_vars = ex.span; let matched_vars = ex.span;
let bind_names = arms[0].pat.span; let bind_names = arms[0].pat.span;
let match_body = remove_blocks(arms[0].body); let match_body = peel_blocks(arms[0].body);
let mut snippet_body = if match_body.span.from_expansion() { let mut snippet_body = if match_body.span.from_expansion() {
Sugg::hir_with_macro_callsite(cx, match_body, "..").to_string() Sugg::hir_with_macro_callsite(cx, match_body, "..").to_string()
} else { } else {
@ -1679,7 +1679,7 @@ fn is_ref_some_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> Option<BindingAnnotat
if is_lang_ctor(cx, qpath, OptionSome); if is_lang_ctor(cx, qpath, OptionSome);
if let PatKind::Binding(rb, .., ident, _) = first_pat.kind; if let PatKind::Binding(rb, .., ident, _) = first_pat.kind;
if rb == BindingAnnotation::Ref || rb == BindingAnnotation::RefMut; if rb == BindingAnnotation::Ref || rb == BindingAnnotation::RefMut;
if let ExprKind::Call(e, args) = remove_blocks(arm.body).kind; if let ExprKind::Call(e, args) = peel_blocks(arm.body).kind;
if let ExprKind::Path(ref some_path) = e.kind; if let ExprKind::Path(ref some_path) = e.kind;
if is_lang_ctor(cx, some_path, OptionSome) && args.len() == 1; if is_lang_ctor(cx, some_path, OptionSome) && args.len() == 1;
if let ExprKind::Path(QPath::Resolved(_, path2)) = args[0].kind; if let ExprKind::Path(QPath::Resolved(_, path2)) = args[0].kind;

View File

@ -1,7 +1,7 @@
use super::{contains_return, BIND_INSTEAD_OF_MAP}; use super::{contains_return, BIND_INSTEAD_OF_MAP};
use clippy_utils::diagnostics::{multispan_sugg_with_applicability, span_lint_and_sugg, span_lint_and_then}; use clippy_utils::diagnostics::{multispan_sugg_with_applicability, span_lint_and_sugg, span_lint_and_then};
use clippy_utils::source::{snippet, snippet_with_macro_callsite}; use clippy_utils::source::{snippet, snippet_with_macro_callsite};
use clippy_utils::{remove_blocks, visitors::find_all_ret_expressions}; use clippy_utils::{peel_blocks, visitors::find_all_ret_expressions};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
@ -152,7 +152,7 @@ fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg:
match arg.kind { match arg.kind {
hir::ExprKind::Closure(_, _, body_id, closure_args_span, _) => { hir::ExprKind::Closure(_, _, body_id, closure_args_span, _) => {
let closure_body = cx.tcx.hir().body(body_id); let closure_body = cx.tcx.hir().body(body_id);
let closure_expr = remove_blocks(&closure_body.value); let closure_expr = peel_blocks(&closure_body.value);
if Self::lint_closure_autofixable(cx, expr, recv, closure_expr, closure_args_span) { if Self::lint_closure_autofixable(cx, expr, recv, closure_expr, closure_args_span) {
true true

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::{indent_of, reindent_multiline, snippet}; use clippy_utils::source::{indent_of, reindent_multiline, snippet};
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{is_trait_method, path_to_local_id, remove_blocks, SpanlessEq}; use clippy_utils::{is_trait_method, path_to_local_id, peel_blocks, SpanlessEq};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
@ -25,7 +25,7 @@ fn is_method<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, method_name: Sy
}, },
hir::ExprKind::Closure(_, _, c, _, _) => { hir::ExprKind::Closure(_, _, c, _, _) => {
let body = cx.tcx.hir().body(*c); let body = cx.tcx.hir().body(*c);
let closure_expr = remove_blocks(&body.value); let closure_expr = peel_blocks(&body.value);
let arg_id = body.params[0].pat.hir_id; let arg_id = body.params[0].pat.hir_id;
match closure_expr.kind { match closure_expr.kind {
hir::ExprKind::MethodCall(hir::PathSegment { ident, .. }, _, args, _) => { hir::ExprKind::MethodCall(hir::PathSegment { ident, .. }, _, args, _) => {

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet; use clippy_utils::source::snippet;
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{match_def_path, meets_msrv, msrvs, path_to_local_id, paths, remove_blocks}; use clippy_utils::{match_def_path, meets_msrv, msrvs, path_to_local_id, paths, peel_blocks};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
@ -53,7 +53,7 @@ pub(super) fn check<'tcx>(
}), }),
hir::ExprKind::Closure(_, _, body_id, _, _) => { hir::ExprKind::Closure(_, _, body_id, _, _) => {
let closure_body = cx.tcx.hir().body(body_id); let closure_body = cx.tcx.hir().body(body_id);
let closure_expr = remove_blocks(&closure_body.value); let closure_expr = peel_blocks(&closure_body.value);
match &closure_expr.kind { match &closure_expr.kind {
hir::ExprKind::MethodCall(_, _, args, _) => { hir::ExprKind::MethodCall(_, _, args, _) => {

View File

@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability; use clippy_utils::source::snippet_with_applicability;
use clippy_utils::{is_trait_method, path_to_local_id, remove_blocks, strip_pat_refs}; use clippy_utils::{is_trait_method, path_to_local_id, peel_blocks, strip_pat_refs};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::ast; use rustc_ast::ast;
use rustc_errors::Applicability; use rustc_errors::Applicability;
@ -31,7 +31,7 @@ fn check_fold_with_op(
// Extract the body of the closure passed to fold // Extract the body of the closure passed to fold
if let hir::ExprKind::Closure(_, _, body_id, _, _) = acc.kind; if let hir::ExprKind::Closure(_, _, body_id, _, _) = acc.kind;
let closure_body = cx.tcx.hir().body(body_id); let closure_body = cx.tcx.hir().body(body_id);
let closure_expr = remove_blocks(&closure_body.value); let closure_expr = peel_blocks(&closure_body.value);
// Check if the closure body is of the form `acc <op> some_expr(x)` // Check if the closure body is of the form `acc <op> some_expr(x)`
if let hir::ExprKind::Binary(ref bin_op, left_expr, right_expr) = closure_expr.kind; if let hir::ExprKind::Binary(ref bin_op, left_expr, right_expr) = closure_expr.kind;

View File

@ -1224,6 +1224,25 @@ pub fn get_parent_as_impl(tcx: TyCtxt<'_>, id: HirId) -> Option<&Impl<'_>> {
} }
} }
/// Removes blocks around an expression, only if the block contains just one expression
/// and no statements.
///
/// Examples:
/// * `{}` -> `{}`
/// * `{ x }` -> `x`
/// * `{{ x }}` -> `x`
/// * `{ x; }` -> `{ x; }`
/// * `{ x; y }` -> `{ x; y }`
pub fn peel_blocks<'tcx>(mut expr: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {
while let ExprKind::Block(block, ..) = expr.kind {
match (block.stmts.is_empty(), block.expr.as_ref()) {
(true, Some(e)) => expr = e,
_ => break,
}
}
expr
}
/// Checks if the given expression is the else clause of either an `if` or `if let` expression. /// Checks if the given expression is the else clause of either an `if` or `if let` expression.
pub fn is_else_clause(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool { pub fn is_else_clause(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {
let mut iter = tcx.hir().parent_iter(expr.hir_id); let mut iter = tcx.hir().parent_iter(expr.hir_id);
@ -1405,20 +1424,6 @@ pub fn is_automatically_derived(attrs: &[ast::Attribute]) -> bool {
has_attr(attrs, sym::automatically_derived) has_attr(attrs, sym::automatically_derived)
} }
/// Remove blocks around an expression.
///
/// Ie. `x`, `{ x }` and `{{{{ x }}}}` all give `x`. `{ x; y }` and `{}` return
/// themselves.
pub fn remove_blocks<'tcx>(mut expr: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {
while let ExprKind::Block(block, ..) = expr.kind {
match (block.stmts.is_empty(), block.expr.as_ref()) {
(true, Some(e)) => expr = e,
_ => break,
}
}
expr
}
pub fn is_self(slf: &Param<'_>) -> bool { pub fn is_self(slf: &Param<'_>) -> bool {
if let PatKind::Binding(.., name, _) = slf.pat.kind { if let PatKind::Binding(.., name, _) = slf.pat.kind {
name.name == kw::SelfLower name.name == kw::SelfLower