diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index 821528d7ab9..1c19a9e0e60 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then}; use clippy_utils::source::{snippet_with_applicability, snippet_with_context}; use clippy_utils::sugg::has_enclosing_paren; -use clippy_utils::ty::{expr_sig, peel_mid_ty_refs, variant_of_res}; +use clippy_utils::ty::{expr_sig, peel_mid_ty_refs, ty_sig, variant_of_res}; use clippy_utils::{get_parent_expr, is_lint_allowed, path_to_local, walk_to_expr_usage}; use rustc_ast::util::parser::{PREC_POSTFIX, PREC_PREFIX}; use rustc_data_structures::fx::FxIndexMap; @@ -704,24 +704,13 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, & let owner_id = cx.tcx.hir().body_owner(cx.enclosing_body.unwrap()); Some( if let Node::Expr( - closure @ Expr { - kind: ExprKind::Closure(&Closure { fn_decl, .. }), + closure_expr @ Expr { + kind: ExprKind::Closure(closure), .. }, ) = cx.tcx.hir().get(owner_id) { - match fn_decl.output { - FnRetTy::Return(ty) => { - if let Some(sig) = expr_sig(cx, closure) - && let Some(output) = sig.output() - { - binding_ty_auto_deref_stability(cx, ty, precedence, output.bound_vars()) - } else { - Position::Other(precedence) - } - }, - FnRetTy::DefaultReturn(_) => Position::Other(precedence), - } + closure_result_position(cx, closure, cx.typeck_results().expr_ty(closure_expr), precedence) } else { let output = cx .tcx @@ -730,6 +719,12 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, & }, ) }, + ExprKind::Closure(closure) => Some(closure_result_position( + cx, + closure, + cx.typeck_results().expr_ty(parent), + precedence, + )), ExprKind::Call(func, _) if func.hir_id == child_id => { (child_id == e.hir_id).then_some(Position::Callee) }, @@ -825,6 +820,26 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, & (position, adjustments) } +fn closure_result_position<'tcx>( + cx: &LateContext<'tcx>, + closure: &'tcx Closure<'_>, + ty: Ty<'tcx>, + precedence: i8, +) -> Position { + match closure.fn_decl.output { + FnRetTy::Return(hir_ty) => { + if let Some(sig) = ty_sig(cx, ty) + && let Some(output) = sig.output() + { + binding_ty_auto_deref_stability(cx, hir_ty, precedence, output.bound_vars()) + } else { + Position::Other(precedence) + } + }, + FnRetTy::DefaultReturn(_) => Position::Other(precedence), + } +} + // Checks the stability of auto-deref when assigned to a binding with the given explicit type. // // e.g. diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs index d394360fc67..e7d670766a0 100644 --- a/clippy_utils/src/ty.rs +++ b/clippy_utils/src/ty.rs @@ -572,7 +572,8 @@ pub fn expr_sig<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option> { +/// If the type is function like, get the signature for it. +pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option> { if ty.is_box() { return ty_sig(cx, ty.boxed_ty()); } diff --git a/tests/ui/explicit_auto_deref.fixed b/tests/ui/explicit_auto_deref.fixed index 27bc7fbfae3..d1d35e5c0eb 100644 --- a/tests/ui/explicit_auto_deref.fixed +++ b/tests/ui/explicit_auto_deref.fixed @@ -257,13 +257,13 @@ fn main() { let x = S7([0]); let _: &[u32] = &*x; - let c1 = |x: &Vec<&u32>| {}; + let c1 = |_: &Vec<&u32>| {}; let x = &&vec![&1u32]; c1(x); let _ = for<'a, 'b> |x: &'a &'a Vec<&'b u32>, b: bool| -> &'a Vec<&'b u32> { if b { return x; } - *x + x }; } diff --git a/tests/ui/explicit_auto_deref.rs b/tests/ui/explicit_auto_deref.rs index 64aea9f464e..deedafad153 100644 --- a/tests/ui/explicit_auto_deref.rs +++ b/tests/ui/explicit_auto_deref.rs @@ -257,7 +257,7 @@ fn main() { let x = S7([0]); let _: &[u32] = &*x; - let c1 = |x: &Vec<&u32>| {}; + let c1 = |_: &Vec<&u32>| {}; let x = &&vec![&1u32]; c1(*x); let _ = for<'a, 'b> |x: &'a &'a Vec<&'b u32>, b: bool| -> &'a Vec<&'b u32> { diff --git a/tests/ui/explicit_auto_deref.stderr b/tests/ui/explicit_auto_deref.stderr index 12db0c6f87f..91863abcc5d 100644 --- a/tests/ui/explicit_auto_deref.stderr +++ b/tests/ui/explicit_auto_deref.stderr @@ -228,5 +228,11 @@ error: deref which would be done by auto-deref LL | return *x; | ^^ help: try this: `x` -error: aborting due to 38 previous errors +error: deref which would be done by auto-deref + --> $DIR/explicit_auto_deref.rs:267:9 + | +LL | *x + | ^^ help: try this: `x` + +error: aborting due to 39 previous errors