From a8e7fed17264bd269c55e8224991d5bf0249472c Mon Sep 17 00:00:00 2001 From: ThibsG Date: Sun, 28 Nov 2021 09:50:34 +0100 Subject: [PATCH] Add a note about type annotation on closure param --- clippy_utils/src/sugg.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs index e1d0920590b..872942685f0 100644 --- a/clippy_utils/src/sugg.rs +++ b/clippy_utils/src/sugg.rs @@ -737,12 +737,14 @@ pub struct DerefClosure { /// such as explicit deref and borrowing cases. /// Returns `None` if no such use cases have been triggered in closure body /// -/// note: this only works on single line immutable closures with one 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 { if let hir::ExprKind::Closure(_, fn_decl, body_id, ..) = closure.kind { let closure_body = cx.tcx.hir().body(body_id); - // is closure arg a double reference (i.e.: `|x: &&i32| ...`) - let closure_arg_is_double_ref = if let TyKind::Rptr(_, MutTy { ty, .. }) = fn_decl.inputs[0].kind { + // 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` + let closure_arg_is_type_annotated_double_ref = if let TyKind::Rptr(_, MutTy { ty, .. }) = fn_decl.inputs[0].kind + { matches!(ty.kind, TyKind::Rptr(_, MutTy { .. })) } else { false @@ -751,7 +753,7 @@ pub fn deref_closure_args<'tcx>(cx: &LateContext<'_>, closure: &'tcx hir::Expr<' let mut visitor = DerefDelegate { cx, closure_span: closure.span, - closure_arg_is_double_ref, + closure_arg_is_type_annotated_double_ref, next_pos: closure.span.lo(), suggestion_start: String::new(), applicability: Applicability::MaybeIncorrect, @@ -780,8 +782,8 @@ struct DerefDelegate<'a, 'tcx> { cx: &'a LateContext<'tcx>, /// The span of the input closure to adapt closure_span: Span, - /// Indicates if the arg of the closure is a double reference - closure_arg_is_double_ref: bool, + /// Indicates if the arg of the closure is a type annotated double reference + closure_arg_is_type_annotated_double_ref: bool, /// last position of the span to gradually build the suggestion next_pos: BytePos, /// starting part of the gradually built suggestion @@ -799,7 +801,7 @@ pub fn finish(&mut self) -> String { let end_span = Span::new(self.next_pos, self.closure_span.hi(), self.closure_span.ctxt(), None); let end_snip = snippet_with_applicability(self.cx, end_span, "..", &mut self.applicability); let sugg = format!("{}{}", self.suggestion_start, end_snip); - if self.closure_arg_is_double_ref { + if self.closure_arg_is_type_annotated_double_ref { sugg.replacen('&', "", 1) } else { sugg @@ -889,7 +891,7 @@ fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) { // and if the item is already a double ref let ident_sugg = if !call_args.is_empty() && !takes_arg_by_double_ref - && (self.closure_arg_is_double_ref || has_field_or_index_projection) + && (self.closure_arg_is_type_annotated_double_ref || has_field_or_index_projection) { let ident = if has_field_or_index_projection { ident_str_with_proj