Auto merge of #99231 - Dylan-DPC:rollup-0tl8c0o, r=Dylan-DPC

Rollup of 5 pull requests

Successful merges:

 - #97720 (Always create elided lifetime parameters for functions)
 - #98315 (Stabilize `core::ffi:c_*` and rexport in `std::ffi`)
 - #98705 (Implement `for<>` lifetime binder for closures)
 - #99126 (remove allow(rustc::potential_query_instability) in rustc_span)
 - #99139 (Give a better error when `x dist` fails for an optional tool)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-07-14 11:00:30 +00:00
commit c9a78ee274
35 changed files with 83 additions and 69 deletions

View File

@ -6,7 +6,7 @@
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{BlockCheckMode, Expr, ExprKind}; use rustc_hir::{BlockCheckMode, Closure, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
@ -51,7 +51,7 @@ struct ExVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for ExVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for ExVisitor<'a, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
if let ExprKind::Closure { body, .. } = expr.kind { if let ExprKind::Closure(&Closure { body, .. }) = expr.kind {
// do not lint if the closure is called using an iterator (see #1141) // do not lint if the closure is called using an iterator (see #1141)
if_chain! { if_chain! {
if let Some(parent) = get_parent_expr(self.cx, expr); if let Some(parent) = get_parent_expr(self.cx, expr);

View File

@ -5,7 +5,7 @@
use clippy_utils::{path_to_local_id, paths, peel_blocks, peel_ref_operators, 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, Closure, Expr, ExprKind, PatKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, UintTy}; use rustc_middle::ty::{self, UintTy};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
@ -51,7 +51,7 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
if count.ident.name == sym::count; if count.ident.name == sym::count;
if let ExprKind::MethodCall(filter, [filter_recv, filter_arg], _) = count_recv.kind; if let ExprKind::MethodCall(filter, [filter_recv, filter_arg], _) = count_recv.kind;
if filter.ident.name == sym!(filter); if filter.ident.name == sym!(filter);
if let ExprKind::Closure { body, .. } = filter_arg.kind; if let ExprKind::Closure(&Closure { body, .. }) = filter_arg.kind;
let body = cx.tcx.hir().body(body); let body = cx.tcx.hir().body(body);
if let [param] = body.params; if let [param] = body.params;
if let PatKind::Binding(_, arg_id, _, _) = strip_pat_refs(param.pat).kind; if let PatKind::Binding(_, arg_id, _, _) = strip_pat_refs(param.pat).kind;

View File

@ -7,7 +7,7 @@
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::{Expr, ExprKind, Param, PatKind, Unsafety}; use rustc_hir::{Closure, Expr, ExprKind, Param, PatKind, Unsafety};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
use rustc_middle::ty::binding::BindingMode; use rustc_middle::ty::binding::BindingMode;
@ -78,7 +78,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
return; return;
} }
let body = match expr.kind { let body = match expr.kind {
ExprKind::Closure { body, .. } => cx.tcx.hir().body(body), ExprKind::Closure(&Closure { body, .. }) => cx.tcx.hir().body(body),
_ => return, _ => return,
}; };
if body.value.span.from_expansion() { if body.value.span.from_expansion() {

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint; use clippy_utils::diagnostics::span_lint;
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item}; use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
use clippy_utils::{higher, match_def_path, path_def_id, paths}; use clippy_utils::{higher, match_def_path, path_def_id, paths};
use rustc_hir::{BorrowKind, Expr, ExprKind}; use rustc_hir::{BorrowKind, Closure, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{sym, Symbol};
@ -159,7 +159,7 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
} }
} }
if method.ident.name == sym!(flat_map) && args.len() == 2 { if method.ident.name == sym!(flat_map) && args.len() == 2 {
if let ExprKind::Closure { body, .. } = args[1].kind { if let ExprKind::Closure(&Closure { body, .. }) = args[1].kind {
let body = cx.tcx.hir().body(body); let body = cx.tcx.hir().body(body);
return is_infinite(cx, &body.value); return is_infinite(cx, &body.value);
} }

View File

@ -2,7 +2,7 @@
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item}; use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
use clippy_utils::{get_trait_def_id, paths, return_ty, trait_ref_of_method}; use clippy_utils::{get_trait_def_id, paths, return_ty, trait_ref_of_method};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_hir::{ImplItem, ImplItemKind}; use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym; use rustc_span::sym;
@ -102,7 +102,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<
let decl = &signature.decl; let decl = &signature.decl;
if decl.implicit_self.has_implicit_self(); if decl.implicit_self.has_implicit_self();
if decl.inputs.len() == 1; if decl.inputs.len() == 1;
if impl_item.generics.params.is_empty(); if impl_item.generics.params.iter().all(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }));
// Check if return type is String // Check if return type is String
if is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id()), sym::String); if is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id()), sym::String);

View File

@ -9,8 +9,8 @@
use rustc_hir::FnRetTy::Return; use rustc_hir::FnRetTy::Return;
use rustc_hir::{ use rustc_hir::{
BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, Impl, ImplItem, BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, Impl, ImplItem,
ImplItemKind, Item, ItemKind, LangItem, Lifetime, LifetimeName, ParamName, PolyTraitRef, PredicateOrigin, ImplItemKind, Item, ItemKind, LangItem, Lifetime, LifetimeName, LifetimeParamKind, ParamName, PolyTraitRef,
TraitBoundModifier, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate, PredicateOrigin, TraitBoundModifier, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate,
}; };
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter as middle_nested_filter; use rustc_middle::hir::nested_filter as middle_nested_filter;
@ -338,7 +338,10 @@ fn could_use_elision<'tcx>(
fn allowed_lts_from(named_generics: &[GenericParam<'_>]) -> FxHashSet<RefLt> { fn allowed_lts_from(named_generics: &[GenericParam<'_>]) -> FxHashSet<RefLt> {
let mut allowed_lts = FxHashSet::default(); let mut allowed_lts = FxHashSet::default();
for par in named_generics.iter() { for par in named_generics.iter() {
if let GenericParamKind::Lifetime { .. } = par.kind { if let GenericParamKind::Lifetime {
kind: LifetimeParamKind::Explicit,
} = par.kind
{
allowed_lts.insert(RefLt::Named(par.name.ident().name)); allowed_lts.insert(RefLt::Named(par.name.ident().name));
} }
} }
@ -379,6 +382,7 @@ fn record(&mut self, lifetime: &Option<Lifetime>) {
self.lts.push(RefLt::Static); self.lts.push(RefLt::Static);
} else if let LifetimeName::Param(_, ParamName::Fresh) = lt.name { } else if let LifetimeName::Param(_, ParamName::Fresh) = lt.name {
// Fresh lifetimes generated should be ignored. // Fresh lifetimes generated should be ignored.
self.lts.push(RefLt::Unnamed);
} else if lt.is_elided() { } else if lt.is_elided() {
self.lts.push(RefLt::Unnamed); self.lts.push(RefLt::Unnamed);
} else { } else {

View File

@ -9,7 +9,7 @@
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, HirId, Mutability, Pat, PatKind, QPath}; use rustc_hir::{BinOpKind, BorrowKind, Closure, Expr, ExprKind, HirId, Mutability, Pat, PatKind, QPath};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::middle::region; use rustc_middle::middle::region;
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty};
@ -369,7 +369,7 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
self.visit_expr(expr); self.visit_expr(expr);
} }
}, },
ExprKind::Closure { body, .. } => { ExprKind::Closure(&Closure { body, .. }) => {
let body = self.cx.tcx.hir().body(body); let body = self.cx.tcx.hir().body(body);
self.visit_expr(&body.value); self.visit_expr(&body.value);
}, },

View File

@ -8,7 +8,7 @@
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{def::Res, Expr, ExprKind, HirId, Local, Mutability, PatKind, QPath, UnOp}; use rustc_hir::{Closure, def::Res, Expr, ExprKind, HirId, Local, Mutability, PatKind, QPath, UnOp};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::adjustment::Adjust; use rustc_middle::ty::adjustment::Adjust;
use rustc_span::{symbol::sym, Symbol}; use rustc_span::{symbol::sym, Symbol};
@ -220,7 +220,7 @@ fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
if let Some(e) = e { if let Some(e) = e {
self.visit_expr(e); self.visit_expr(e);
} }
} else if let ExprKind::Closure { body: id, .. } = e.kind { } else if let ExprKind::Closure(&Closure { body: id, .. }) = e.kind {
if is_res_used(self.cx, self.iter_expr.path, id) { if is_res_used(self.cx, self.iter_expr.path, id) {
self.uses_iter = true; self.uses_iter = true;
} }
@ -260,7 +260,7 @@ fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
if let Some(e) = e { if let Some(e) = e {
self.visit_expr(e); self.visit_expr(e);
} }
} else if let ExprKind::Closure { body: id, .. } = e.kind { } else if let ExprKind::Closure(&Closure { body: id, .. }) = e.kind {
self.used_iter = is_res_used(self.cx, self.iter_expr.path, id); self.used_iter = is_res_used(self.cx, self.iter_expr.path, id);
} else { } else {
walk_expr(self, e); walk_expr(self, e);
@ -307,7 +307,7 @@ fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
if let Some(e) = e { if let Some(e) = e {
self.visit_expr(e); self.visit_expr(e);
} }
} else if let ExprKind::Closure { body: id, .. } = e.kind { } else if let ExprKind::Closure(&Closure { body: id, .. }) = e.kind {
self.used_after = is_res_used(self.cx, self.iter_expr.path, id); self.used_after = is_res_used(self.cx, self.iter_expr.path, id);
} else { } else {
walk_expr(self, e); walk_expr(self, e);

View File

@ -6,7 +6,7 @@
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::intravisit::FnKind; use rustc_hir::intravisit::FnKind;
use rustc_hir::{ use rustc_hir::{
AsyncGeneratorKind, Block, Body, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound, HirId, AsyncGeneratorKind, Block, Body, Closure, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound, HirId,
IsAsync, ItemKind, LifetimeName, Term, TraitRef, Ty, TyKind, TypeBindingKind, IsAsync, ItemKind, LifetimeName, Term, TraitRef, Ty, TyKind, TypeBindingKind,
}; };
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
@ -177,7 +177,7 @@ fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>)
if let Some(block_expr) = block.expr; if let Some(block_expr) = block.expr;
if let Some(args) = match_function_call(cx, block_expr, &FUTURE_FROM_GENERATOR); if let Some(args) = match_function_call(cx, block_expr, &FUTURE_FROM_GENERATOR);
if args.len() == 1; if args.len() == 1;
if let Expr{kind: ExprKind::Closure { body, .. }, ..} = args[0]; if let Expr{kind: ExprKind::Closure(&Closure { body, .. }), ..} = args[0];
let closure_body = cx.tcx.hir().body(body); let closure_body = cx.tcx.hir().body(body);
if closure_body.generator_kind == Some(GeneratorKind::Async(AsyncGeneratorKind::Block)); if closure_body.generator_kind == Some(GeneratorKind::Async(AsyncGeneratorKind::Block));
then { then {

View File

@ -5,7 +5,7 @@
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::LangItem::{ResultErr, ResultOk}; use rustc_hir::LangItem::{ResultErr, ResultOk};
use rustc_hir::{Expr, ExprKind, PatKind}; use rustc_hir::{Closure, Expr, ExprKind, PatKind};
use rustc_lint::LintContext; use rustc_lint::LintContext;
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
@ -88,7 +88,7 @@ fn is_ok_wrapping(cx: &LateContext<'_>, map_expr: &Expr<'_>) -> bool {
} }
} }
if_chain! { if_chain! {
if let ExprKind::Closure { body, .. } = map_expr.kind; if let ExprKind::Closure(&Closure { body, .. }) = map_expr.kind;
let body = cx.tcx.hir().body(body); let body = cx.tcx.hir().body(body);
if let PatKind::Binding(_, param_id, ..) = body.params[0].pat.kind; if let PatKind::Binding(_, param_id, ..) = body.params[0].pat.kind;
if let ExprKind::Call(Expr { kind: ExprKind::Path(ok_path), .. }, &[ref ok_arg]) = body.value.kind; if let ExprKind::Call(Expr { kind: ExprKind::Path(ok_path), .. }, &[ref ok_arg]) = body.value.kind;

View File

@ -148,7 +148,7 @@ fn check_to_owned(
fn suggest(cx: &LateContext<'_>, parent_expr: &hir::Expr<'_>, left_expr: &hir::Expr<'_>, filter_expr: &hir::Expr<'_>) { fn suggest(cx: &LateContext<'_>, parent_expr: &hir::Expr<'_>, left_expr: &hir::Expr<'_>, filter_expr: &hir::Expr<'_>) {
if let hir::ExprKind::MethodCall(_, [_, closure], _) = filter_expr.kind if let hir::ExprKind::MethodCall(_, [_, closure], _) = filter_expr.kind
&& let hir::ExprKind::Closure{ body, ..} = closure.kind && let hir::ExprKind::Closure(&hir::Closure { body, ..}) = closure.kind
&& let filter_body = cx.tcx.hir().body(body) && let filter_body = cx.tcx.hir().body(body)
&& let [filter_params] = filter_body.params && let [filter_params] = filter_body.params
&& let Some(sugg) = match filter_params.pat.kind { && let Some(sugg) = match filter_params.pat.kind {

View File

@ -67,7 +67,7 @@ fn check_expr(&mut self, cx: &LateContext<'_>, e: &hir::Expr<'_>) {
if method.ident.name == sym::map; if method.ident.name == sym::map;
let ty = cx.typeck_results().expr_ty(&args[0]); let ty = cx.typeck_results().expr_ty(&args[0]);
if is_type_diagnostic_item(cx, ty, sym::Option) || is_trait_method(cx, e, sym::Iterator); if is_type_diagnostic_item(cx, ty, sym::Option) || is_trait_method(cx, e, sym::Iterator);
if let hir::ExprKind::Closure { body, .. } = args[1].kind; if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = args[1].kind;
then { then {
let closure_body = cx.tcx.hir().body(body); let closure_body = cx.tcx.hir().body(body);
let closure_expr = peel_blocks(&closure_body.value); let closure_expr = peel_blocks(&closure_body.value);

View File

@ -1,5 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::diagnostics::span_lint_and_help;
use rustc_hir::{CaptureBy, Expr, ExprKind, PatKind}; use rustc_hir::{CaptureBy, Closure, Expr, ExprKind, PatKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
@ -119,12 +119,12 @@ fn check_expr(&mut self, cx: &LateContext<'_>, e: &Expr<'_>) {
if method.ident.as_str() == "map_err" && args.len() == 2 { if method.ident.as_str() == "map_err" && args.len() == 2 {
// make sure the first argument is a closure, and grab the CaptureRef, BodyId, and fn_decl_span // make sure the first argument is a closure, and grab the CaptureRef, BodyId, and fn_decl_span
// fields // fields
if let ExprKind::Closure { if let ExprKind::Closure(&Closure {
capture_clause, capture_clause,
body, body,
fn_decl_span, fn_decl_span,
.. ..
} = args[1].kind }) = args[1].kind
{ {
// check if this is by Reference (meaning there's no move statement) // check if this is by Reference (meaning there's no move statement)
if capture_clause == CaptureBy::Ref { if capture_clause == CaptureBy::Ref {

View File

@ -169,7 +169,7 @@ fn unit_closure<'tcx>(
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
) -> Option<(&'tcx hir::Param<'tcx>, &'tcx hir::Expr<'tcx>)> { ) -> Option<(&'tcx hir::Param<'tcx>, &'tcx hir::Expr<'tcx>)> {
if_chain! { if_chain! {
if let hir::ExprKind::Closure { fn_decl, body, .. } = expr.kind; if let hir::ExprKind::Closure(&hir::Closure { fn_decl, body, .. }) = expr.kind;
let body = cx.tcx.hir().body(body); let body = cx.tcx.hir().body(body);
let body_expr = &body.value; let body_expr = &body.value;
if fn_decl.inputs.len() == 1; if fn_decl.inputs.len() == 1;

View File

@ -150,7 +150,7 @@ fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg:
} }
match arg.kind { match arg.kind {
hir::ExprKind::Closure { body, fn_decl_span, .. } => { hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }) => {
let closure_body = cx.tcx.hir().body(body); let closure_body = cx.tcx.hir().body(body);
let closure_expr = peel_blocks(&closure_body.value); let closure_expr = peel_blocks(&closure_body.value);

View File

@ -6,7 +6,7 @@
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::Res; use rustc_hir::def::Res;
use rustc_hir::{Expr, ExprKind, PatKind, PathSegment, QPath, UnOp}; use rustc_hir::{Closure, Expr, ExprKind, PatKind, PathSegment, QPath, UnOp};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{sym, Symbol};
@ -22,8 +22,8 @@ fn is_method<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, method_name: Sy
hir::ExprKind::Path(QPath::Resolved(_, segments)) => { hir::ExprKind::Path(QPath::Resolved(_, segments)) => {
segments.segments.last().unwrap().ident.name == method_name segments.segments.last().unwrap().ident.name == method_name
}, },
hir::ExprKind::Closure { body, .. } => { hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
let body = cx.tcx.hir().body(*body); let body = cx.tcx.hir().body(body);
let closure_expr = peel_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 {
@ -106,7 +106,7 @@ pub(super) fn check<'tcx>(
if is_trait_method(cx, map_recv, sym::Iterator); if is_trait_method(cx, map_recv, sym::Iterator);
// filter(|x| ...is_some())... // filter(|x| ...is_some())...
if let ExprKind::Closure { body: filter_body_id, .. } = filter_arg.kind; if let ExprKind::Closure(&Closure { body: filter_body_id, .. }) = filter_arg.kind;
let filter_body = cx.tcx.hir().body(filter_body_id); let filter_body = cx.tcx.hir().body(filter_body_id);
if let [filter_param] = filter_body.params; if let [filter_param] = filter_body.params;
// optional ref pattern: `filter(|&x| ..)` // optional ref pattern: `filter(|&x| ..)`
@ -129,7 +129,7 @@ pub(super) fn check<'tcx>(
if path.ident.name.as_str() == if is_result { "is_ok" } else { "is_some" }; if path.ident.name.as_str() == if is_result { "is_ok" } else { "is_some" };
// ...map(|x| ...unwrap()) // ...map(|x| ...unwrap())
if let ExprKind::Closure { body: map_body_id, .. } = map_arg.kind; if let ExprKind::Closure(&Closure { body: map_body_id, .. }) = map_arg.kind;
let map_body = cx.tcx.hir().body(map_body_id); let map_body = cx.tcx.hir().body(map_body_id);
if let [map_param] = map_body.params; if let [map_param] = map_body.params;
if let PatKind::Binding(_, map_param_id, map_param_ident, None) = map_param.pat.kind; if let PatKind::Binding(_, map_param_id, map_param_ident, None) = map_param.pat.kind;

View File

@ -51,7 +51,7 @@ pub(super) fn check<'tcx>(
.map_or(false, |fun_def_id| { .map_or(false, |fun_def_id| {
deref_aliases.iter().any(|path| match_def_path(cx, fun_def_id, path)) deref_aliases.iter().any(|path| match_def_path(cx, fun_def_id, path))
}), }),
hir::ExprKind::Closure { body, .. } => { hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
let closure_body = cx.tcx.hir().body(body); let closure_body = cx.tcx.hir().body(body);
let closure_expr = peel_blocks(&closure_body.value); let closure_expr = peel_blocks(&closure_body.value);

View File

@ -71,7 +71,7 @@ pub(super) fn check<'tcx>(
if is_option { if is_option {
let self_snippet = snippet(cx, recv.span, ".."); let self_snippet = snippet(cx, recv.span, "..");
if_chain! { if_chain! {
if let hir::ExprKind::Closure { body, fn_decl_span, .. } = map_arg.kind; if let hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }) = map_arg.kind;
let arg_snippet = snippet(cx, fn_decl_span, ".."); let arg_snippet = snippet(cx, fn_decl_span, "..");
let body = cx.tcx.hir().body(body); let body = cx.tcx.hir().body(body);
if let Some((func, [arg_char])) = reduce_unit_expression(&body.value); if let Some((func, [arg_char])) = reduce_unit_expression(&body.value);

View File

@ -41,7 +41,7 @@ pub(super) fn check<'tcx>(
let mut applicability = Applicability::MachineApplicable; let mut applicability = Applicability::MachineApplicable;
let any_search_snippet = if_chain! { let any_search_snippet = if_chain! {
if search_method == "find"; if search_method == "find";
if let hir::ExprKind::Closure { body, .. } = search_arg.kind; if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = search_arg.kind;
let closure_body = cx.tcx.hir().body(body); let closure_body = cx.tcx.hir().body(body);
if let Some(closure_arg) = closure_body.params.get(0); if let Some(closure_arg) = closure_body.params.get(0);
then { then {

View File

@ -18,7 +18,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<
return; return;
} }
if let hir::ExprKind::Closure { body, .. } = arg.kind { if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = arg.kind {
let body = cx.tcx.hir().body(body); let body = cx.tcx.hir().body(body);
let arg_id = body.params[0].pat.hir_id; let arg_id = body.params[0].pat.hir_id;
let mutates_arg = let mutates_arg =

View File

@ -29,7 +29,7 @@ fn check_fold_with_op(
) { ) {
if_chain! { if_chain! {
// Extract the body of the closure passed to fold // Extract the body of the closure passed to fold
if let hir::ExprKind::Closure { body, .. } = acc.kind; if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = acc.kind;
let closure_body = cx.tcx.hir().body(body); let closure_body = cx.tcx.hir().body(body);
let closure_expr = peel_blocks(&closure_body.value); let closure_expr = peel_blocks(&closure_body.value);

View File

@ -22,7 +22,7 @@ pub(super) fn check<'tcx>(
let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result); let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result);
if is_option || is_result { if is_option || is_result {
if let hir::ExprKind::Closure { body, .. } = arg.kind { if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = arg.kind {
let body = cx.tcx.hir().body(body); let body = cx.tcx.hir().body(body);
let body_expr = &body.value; let body_expr = &body.value;

View File

@ -1,7 +1,7 @@
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{ use rustc_hir::{
intravisit::{walk_expr, Visitor}, intravisit::{walk_expr, Visitor},
Expr, ExprKind, Stmt, StmtKind, Closure, Expr, ExprKind, Stmt, StmtKind,
}; };
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
@ -72,7 +72,7 @@ fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
if has_iter_method(cx, cx.typeck_results().expr_ty(iter_recv)).is_some(); if has_iter_method(cx, cx.typeck_results().expr_ty(iter_recv)).is_some();
// Skip the lint if the body is not block because this is simpler than `for` loop. // Skip the lint if the body is not block because this is simpler than `for` loop.
// e.g. `v.iter().for_each(f)` is simpler and clearer than using `for` loop. // e.g. `v.iter().for_each(f)` is simpler and clearer than using `for` loop.
if let ExprKind::Closure { body, .. } = for_each_arg.kind; if let ExprKind::Closure(&Closure { body, .. }) = for_each_arg.kind;
let body = cx.tcx.hir().body(body); let body = cx.tcx.hir().body(body);
if let ExprKind::Block(..) = body.value.kind; if let ExprKind::Block(..) = body.value.kind;
then { then {

View File

@ -11,7 +11,7 @@
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
use rustc_hir::intravisit::{walk_expr, walk_stmt, FnKind, Visitor}; use rustc_hir::intravisit::{walk_expr, walk_stmt, FnKind, Visitor};
use rustc_hir::{ use rustc_hir::{
Arm, Block, Body, Expr, ExprKind, Guard, HirId, ImplicitSelfKind, Let, Local, Pat, PatKind, Path, PathSegment, Arm, Closure, Block, Body, Expr, ExprKind, Guard, HirId, ImplicitSelfKind, Let, Local, Pat, PatKind, Path, PathSegment,
QPath, Stmt, StmtKind, TyKind, UnOp, QPath, Stmt, StmtKind, TyKind, UnOp,
}; };
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
@ -298,7 +298,7 @@ fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
}, },
ExprKind::Match(expr, arms, _) => self.visit_match(expr, arms), ExprKind::Match(expr, arms, _) => self.visit_match(expr, arms),
// since analysing the closure is not easy, just set all variables in it to side-effect // since analysing the closure is not easy, just set all variables in it to side-effect
ExprKind::Closure { body, .. } => { ExprKind::Closure(&Closure { body, .. }) => {
let body = self.tcx.hir().body(body); let body = self.tcx.hir().body(body);
self.visit_body(body); self.visit_body(body);
let vars = std::mem::take(&mut self.ret_vars); let vars = std::mem::take(&mut self.ret_vars);

View File

@ -495,12 +495,13 @@ fn check_mut_from_ref<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Optio
if let FnRetTy::Return(ty) = sig.decl.output if let FnRetTy::Return(ty) = sig.decl.output
&& let Some((out, Mutability::Mut, _)) = get_rptr_lm(ty) && let Some((out, Mutability::Mut, _)) = get_rptr_lm(ty)
{ {
let out_region = cx.tcx.named_region(out.hir_id);
let args: Option<Vec<_>> = sig let args: Option<Vec<_>> = sig
.decl .decl
.inputs .inputs
.iter() .iter()
.filter_map(get_rptr_lm) .filter_map(get_rptr_lm)
.filter(|&(lt, _, _)| lt.name == out.name) .filter(|&(lt, _, _)| cx.tcx.named_region(lt.hir_id) == out_region)
.map(|(_, mutability, span)| (mutability == Mutability::Not).then(|| span)) .map(|(_, mutability, span)| (mutability == Mutability::Not).then(|| span))
.collect(); .collect();
if let Some(args) = args if let Some(args) = args

View File

@ -69,7 +69,7 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
if_chain! { if_chain! {
if let ast::ExprKind::Call(ref paren, _) = expr.kind; if let ast::ExprKind::Call(ref paren, _) = expr.kind;
if let ast::ExprKind::Paren(ref closure) = paren.kind; if let ast::ExprKind::Paren(ref closure) = paren.kind;
if let ast::ExprKind::Closure(_, _, _, ref decl, ref block, _) = closure.kind; if let ast::ExprKind::Closure(_, _, _, _, ref decl, ref block, _) = closure.kind;
then { then {
let mut visitor = ReturnVisitor::new(); let mut visitor = ReturnVisitor::new();
visitor.visit_expr(block); visitor.visit_expr(block);

View File

@ -582,7 +582,7 @@ fn ident_difference_expr_with_base_location(
| (Await(_), Await(_)) | (Await(_), Await(_))
| (Async(_, _, _), Async(_, _, _)) | (Async(_, _, _), Async(_, _, _))
| (Block(_, _), Block(_, _)) | (Block(_, _), Block(_, _))
| (Closure(_, _, _, _, _, _), Closure(_, _, _, _, _, _)) | (Closure(_, _, _, _, _, _, _), Closure(_, _, _, _, _, _, _))
| (Match(_, _), Match(_, _)) | (Match(_, _), Match(_, _))
| (Loop(_, _), Loop(_, _)) | (Loop(_, _), Loop(_, _))
| (ForLoop(_, _, _, _), ForLoop(_, _, _, _)) | (ForLoop(_, _, _, _), ForLoop(_, _, _, _))

View File

@ -31,7 +31,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
return false; return false;
} }
let ltopt = if lt.is_elided() { let ltopt = if lt.name.is_anonymous() {
String::new() String::new()
} else { } else {
format!("{} ", lt.name.ident().as_str()) format!("{} ", lt.name.ident().as_str())

View File

@ -2,7 +2,7 @@
use clippy_utils::{get_trait_def_id, paths}; use clippy_utils::{get_trait_def_id, paths};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::{Expr, ExprKind, StmtKind}; use rustc_hir::{Closure, Expr, ExprKind, StmtKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty; use rustc_middle::ty;
use rustc_middle::ty::{GenericPredicates, PredicateKind, ProjectionPredicate, TraitPredicate}; use rustc_middle::ty::{GenericPredicates, PredicateKind, ProjectionPredicate, TraitPredicate};
@ -116,7 +116,7 @@ fn get_args_to_check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Ve
fn check_arg<'tcx>(cx: &LateContext<'tcx>, arg: &'tcx Expr<'tcx>) -> Option<(Span, Option<Span>)> { fn check_arg<'tcx>(cx: &LateContext<'tcx>, arg: &'tcx Expr<'tcx>) -> Option<(Span, Option<Span>)> {
if_chain! { if_chain! {
if let ExprKind::Closure { body, fn_decl_span, .. } = arg.kind; if let ExprKind::Closure(&Closure { body, fn_decl_span, .. }) = arg.kind;
if let ty::Closure(_def_id, substs) = &cx.typeck_results().node_type(arg.hir_id).kind(); if let ty::Closure(_def_id, substs) = &cx.typeck_results().node_type(arg.hir_id).kind();
let ret_ty = substs.as_closure().sig().output(); let ret_ty = substs.as_closure().sig().output();
let ty = cx.tcx.erase_late_bound_regions(ret_ty); let ty = cx.tcx.erase_late_bound_regions(ret_ty);

View File

@ -3,7 +3,7 @@
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item}; use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, Mutability, Param, Pat, PatKind, Path, PathSegment, QPath}; use rustc_hir::{Closure, Expr, ExprKind, Mutability, Param, Pat, PatKind, Path, PathSegment, QPath};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, subst::GenericArgKind}; use rustc_middle::ty::{self, subst::GenericArgKind};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
@ -155,7 +155,7 @@ fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<LintTrigger> {
if let ExprKind::MethodCall(name_ident, args, _) = &expr.kind; if let ExprKind::MethodCall(name_ident, args, _) = &expr.kind;
if let name = name_ident.ident.name.to_ident_string(); if let name = name_ident.ident.name.to_ident_string();
if name == "sort_by" || name == "sort_unstable_by"; if name == "sort_by" || name == "sort_unstable_by";
if let [vec, Expr { kind: ExprKind::Closure{ body: closure_body_id, .. }, .. }] = args; if let [vec, Expr { kind: ExprKind::Closure(Closure { body: closure_body_id, .. }), .. }] = args;
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(vec), sym::Vec); if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(vec), sym::Vec);
if let closure_body = cx.tcx.hir().body(*closure_body_id); if let closure_body = cx.tcx.hir().body(*closure_body_id);
if let &[ if let &[

View File

@ -6,7 +6,7 @@
use rustc_ast::LitIntType; use rustc_ast::LitIntType;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::{ArrayLen, ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind}; use rustc_hir::{ArrayLen, Closure, ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind};
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::{Ident, Symbol}; use rustc_span::symbol::{Ident, Symbol};
@ -466,13 +466,13 @@ macro_rules! kind {
self.expr(scrutinee); self.expr(scrutinee);
self.slice(arms, |arm| self.arm(arm)); self.slice(arms, |arm| self.arm(arm));
}, },
ExprKind::Closure { ExprKind::Closure(&Closure {
capture_clause, capture_clause,
fn_decl, fn_decl,
body: body_id, body: body_id,
movability, movability,
.. ..
} => { }) => {
let movability = OptionPat::new(movability.map(|m| format!("Movability::{m:?}"))); let movability = OptionPat::new(movability.map(|m| format!("Movability::{m:?}")));
let ret_ty = match fn_decl.output { let ret_ty = match fn_decl.output {

View File

@ -168,8 +168,8 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
(AssignOp(lo, lp, lv), AssignOp(ro, rp, rv)) => lo.node == ro.node && eq_expr(lp, rp) && eq_expr(lv, rv), (AssignOp(lo, lp, lv), AssignOp(ro, rp, rv)) => lo.node == ro.node && eq_expr(lp, rp) && eq_expr(lv, rv),
(Field(lp, lf), Field(rp, rf)) => eq_id(*lf, *rf) && eq_expr(lp, rp), (Field(lp, lf), Field(rp, rf)) => eq_id(*lf, *rf) && eq_expr(lp, rp),
(Match(ls, la), Match(rs, ra)) => eq_expr(ls, rs) && over(la, ra, eq_arm), (Match(ls, la), Match(rs, ra)) => eq_expr(ls, rs) && over(la, ra, eq_arm),
(Closure(lc, la, lm, lf, lb, _), Closure(rc, ra, rm, rf, rb, _)) => { (Closure(lb, lc, la, lm, lf, le, _), Closure(rb, rc, ra, rm, rf, re, _)) => {
lc == rc && la.is_async() == ra.is_async() && lm == rm && eq_fn_decl(lf, rf) && eq_expr(lb, rb) eq_closure_binder(lb, rb) && lc == rc && la.is_async() == ra.is_async() && lm == rm && eq_fn_decl(lf, rf) && eq_expr(le, re)
}, },
(Async(lc, _, lb), Async(rc, _, rb)) => lc == rc && eq_block(lb, rb), (Async(lc, _, lb), Async(rc, _, rb)) => lc == rc && eq_block(lb, rb),
(Range(lf, lt, ll), Range(rf, rt, rl)) => ll == rl && eq_expr_opt(lf, rf) && eq_expr_opt(lt, rt), (Range(lf, lt, ll), Range(rf, rt, rl)) => ll == rl && eq_expr_opt(lf, rf) && eq_expr_opt(lt, rt),
@ -561,6 +561,15 @@ pub fn eq_fn_decl(l: &FnDecl, r: &FnDecl) -> bool {
}) })
} }
pub fn eq_closure_binder(l: &ClosureBinder, r: &ClosureBinder) -> bool {
match (l, r) {
(ClosureBinder::NotPresent, ClosureBinder::NotPresent) => true,
(ClosureBinder::For { generic_params: lp, .. }, ClosureBinder::For { generic_params: rp, .. }) =>
lp.len() == rp.len() && std::iter::zip(lp.iter(), rp.iter()).all(|(l, r)| eq_generic_param(l, r)),
_ => false,
}
}
pub fn eq_fn_ret_ty(l: &FnRetTy, r: &FnRetTy) -> bool { pub fn eq_fn_ret_ty(l: &FnRetTy, r: &FnRetTy) -> bool {
match (l, r) { match (l, r) {
(FnRetTy::Default(_), FnRetTy::Default(_)) => true, (FnRetTy::Default(_), FnRetTy::Default(_)) => true,

View File

@ -6,7 +6,7 @@
use rustc_hir::def::Res; use rustc_hir::def::Res;
use rustc_hir::HirIdMap; use rustc_hir::HirIdMap;
use rustc_hir::{ use rustc_hir::{
ArrayLen, BinOpKind, Block, BodyId, Expr, ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, Guard, HirId, ArrayLen, BinOpKind, Closure, Block, BodyId, Expr, ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, Guard, HirId,
InlineAsmOperand, Let, Lifetime, LifetimeName, ParamName, Pat, PatField, PatKind, Path, PathSegment, QPath, Stmt, InlineAsmOperand, Let, Lifetime, LifetimeName, ParamName, Pat, PatField, PatKind, Path, PathSegment, QPath, Stmt,
StmtKind, Ty, TyKind, TypeBinding, StmtKind, Ty, TyKind, TypeBinding,
}; };
@ -663,9 +663,9 @@ pub fn hash_expr(&mut self, e: &Expr<'_>) {
self.hash_expr(e); self.hash_expr(e);
self.hash_ty(ty); self.hash_ty(ty);
}, },
ExprKind::Closure { ExprKind::Closure(&Closure {
capture_clause, body, .. capture_clause, body, ..
} => { }) => {
std::mem::discriminant(&capture_clause).hash(&mut self.s); std::mem::discriminant(&capture_clause).hash(&mut self.s);
// closures inherit TypeckResults // closures inherit TypeckResults
self.hash_expr(&self.cx.tcx.hir().body(body).value); self.hash_expr(&self.cx.tcx.hir().body(body).value);

View File

@ -79,10 +79,10 @@
use rustc_hir::intravisit::{walk_expr, FnKind, Visitor}; use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
use rustc_hir::LangItem::{OptionNone, ResultErr, ResultOk}; use rustc_hir::LangItem::{OptionNone, ResultErr, ResultOk};
use rustc_hir::{ use rustc_hir::{
def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Constness, Destination, Expr, ExprKind, FnDecl, def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Constness, Destination, Expr,
HirId, Impl, ImplItem, ImplItemKind, IsAsync, Item, ItemKind, LangItem, Local, MatchSource, Mutability, Node, ExprKind, FnDecl, HirId, Impl, ImplItem, ImplItemKind, IsAsync, Item, ItemKind, LangItem, Local, MatchSource,
Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitRef, TyKind, Mutability, Node, Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind,
UnOp, TraitRef, TyKind, UnOp,
}; };
use rustc_lint::{LateContext, Level, Lint, LintContext}; use rustc_lint::{LateContext, Level, Lint, LintContext};
use rustc_middle::hir::place::PlaceBase; use rustc_middle::hir::place::PlaceBase;
@ -1699,7 +1699,7 @@ pub fn get_async_fn_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Option<&'t
_, _,
&[ &[
Expr { Expr {
kind: ExprKind::Closure { body, .. }, kind: ExprKind::Closure(&Closure { body, .. }),
.. ..
}, },
], ],
@ -1786,7 +1786,7 @@ fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool {
} }
match expr.kind { match expr.kind {
ExprKind::Closure { body, .. } => is_body_identity_function(cx, cx.tcx.hir().body(body)), ExprKind::Closure(&Closure { body, .. }) => is_body_identity_function(cx, cx.tcx.hir().body(body)),
_ => path_def_id(cx, expr).map_or(false, |id| match_def_path(cx, id, &paths::CONVERT_IDENTITY)), _ => path_def_id(cx, expr).map_or(false, |id| match_def_path(cx, id, &paths::CONVERT_IDENTITY)),
} }
} }

View File

@ -8,7 +8,7 @@
use rustc_ast_pretty::pprust::token_kind_to_string; use rustc_ast_pretty::pprust::token_kind_to_string;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::{ExprKind, HirId, MutTy, TyKind}; use rustc_hir::{Closure, ExprKind, HirId, MutTy, TyKind};
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{EarlyContext, LateContext, LintContext}; use rustc_lint::{EarlyContext, LateContext, LintContext};
use rustc_middle::hir::place::ProjectionKind; use rustc_middle::hir::place::ProjectionKind;
@ -790,7 +790,7 @@ pub struct DerefClosure {
/// ///
/// note: this only works on single line immutable closures with exactly one input parameter. /// note: this only works on single line immutable closures with exactly one input parameter.
pub fn deref_closure_args<'tcx>(cx: &LateContext<'_>, closure: &'tcx hir::Expr<'_>) -> Option<DerefClosure> { pub fn deref_closure_args<'tcx>(cx: &LateContext<'_>, closure: &'tcx hir::Expr<'_>) -> Option<DerefClosure> {
if let hir::ExprKind::Closure { fn_decl, body, .. } = closure.kind { if let hir::ExprKind::Closure(&Closure { fn_decl, body, .. }) = closure.kind {
let closure_body = cx.tcx.hir().body(body); let closure_body = cx.tcx.hir().body(body);
// is closure arg a type annotated double reference (i.e.: `|x: &&i32| ...`) // is closure arg a type annotated double reference (i.e.: `|x: &&i32| ...`)
// a type annotation is present if param `kind` is different from `TyKind::Infer` // a type annotation is present if param `kind` is different from `TyKind::Infer`