From be50a5f266a16515a561186be6e9c318be3c75e5 Mon Sep 17 00:00:00 2001 From: Alessio Cosenza Date: Fri, 19 May 2023 17:46:32 +0200 Subject: [PATCH] Add support to returned refs from `MethodCall` --- .../src/redundant_type_annotations.rs | 23 ++++--- tests/ui/redundant_type_annotations.rs | 60 ++++++++++++------- tests/ui/redundant_type_annotations.stderr | 46 ++++++++------ 3 files changed, 83 insertions(+), 46 deletions(-) diff --git a/clippy_lints/src/redundant_type_annotations.rs b/clippy_lints/src/redundant_type_annotations.rs index 79f30baa4c58..dc48f821f9d8 100644 --- a/clippy_lints/src/redundant_type_annotations.rs +++ b/clippy_lints/src/redundant_type_annotations.rs @@ -59,10 +59,8 @@ fn func_hir_id_to_func_ty<'tcx>(cx: &LateContext<'tcx>, hir_id: hir::hir_id::Hir } fn func_ty_to_return_type<'tcx>(cx: &LateContext<'tcx>, func_ty: Ty<'tcx>) -> Option> { - if func_ty.is_fn() - && let Some(return_type) = func_ty.fn_sig(cx.tcx).output().no_bound_vars() - { - Some(return_type) + if func_ty.is_fn() { + Some(func_ty.fn_sig(cx.tcx).output().skip_binder()) } else { None } @@ -142,12 +140,23 @@ impl LateLintPass<'_> for RedundantTypeAnnotations { } }, hir::ExprKind::MethodCall(_, _, _, _) => { - if let hir::TyKind::Path(ty_path) = &ty.kind - && let hir::QPath::Resolved(_, resolved_path_ty) = ty_path + let mut is_ref = false; + let mut ty_kind = &ty.kind; + // If the annotation is a ref we "peel" it + if let hir::TyKind::Ref(_, mut_ty) = &ty.kind { + is_ref = true; + ty_kind = &mut_ty.ty.kind; + } + + if let hir::TyKind::Path(ty_path) = ty_kind + && let hir::QPath::Resolved(_, resolved_path_ty) = ty_path && let Some(func_ty) = func_hir_id_to_func_ty(cx, init.hir_id) && let Some(return_type) = func_ty_to_return_type(cx, func_ty) - && is_same_type(cx, resolved_path_ty.res, return_type) + && is_same_type(cx, resolved_path_ty.res, match is_ref { + true => return_type.peel_refs(), + false => return_type, + }) { span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, "redundant type annotation"); } diff --git a/tests/ui/redundant_type_annotations.rs b/tests/ui/redundant_type_annotations.rs index 5722621e83a1..cc507b8d658c 100644 --- a/tests/ui/redundant_type_annotations.rs +++ b/tests/ui/redundant_type_annotations.rs @@ -18,8 +18,15 @@ fn plus_one>(val: T) -> T { val + 1 } +#[derive(Default)] +struct Slice { + inner: u32, +} + +#[derive(Default)] struct Pie { inner: u32, + inner_struct: Slice, } enum Pizza { @@ -32,7 +39,7 @@ fn return_a_string() -> String { } fn return_a_struct() -> Pie { - Pie { inner: 5 } + Pie::default() } fn return_an_enum() -> Pizza { @@ -48,12 +55,20 @@ impl Pie { self.inner } + fn return_a_ref(&self) -> &u32 { + &self.inner + } + + fn return_a_ref_to_struct(&self) -> &Slice { + &self.inner_struct + } + fn associated_return_an_int() -> u32 { 5 } fn new() -> Self { - Self { inner: 5 } + Self::default() } fn associated_return_a_string() -> String { @@ -61,7 +76,11 @@ impl Pie { } fn test_method_call(&self) { - let v: u32 = self.return_an_int(); // Should lint + // Everything here should be lint + + let v: u32 = self.return_an_int(); + let v: &u32 = self.return_a_ref(); + let v: &Slice = self.return_a_ref_to_struct(); } } @@ -72,21 +91,24 @@ fn test_generics() { // The type annotation is needed to determine the topic let _c: Cake = make_cake(); - // This should lint (doesn't) + // This could be lint, but currently doesn't let _c: Cake = make_cake::(); - // This should lint (doesn't) + // This could be lint, but currently doesn't let _c: u8 = make_something::(); - // This should lint (doesn't) + // This could be lint, but currently doesn't let _c: u8 = plus_one(5_u8); // Annotation needed otherwise T is i32 let _c: u8 = plus_one(5); + + // This could be lint, but currently doesn't + let _return: String = String::from("test"); } fn test_non_locals() { - // This shouldn't lint + // This shouldn't be lint fn _arg(x: u32) -> u32 { x } @@ -96,27 +118,27 @@ fn test_non_locals() { } fn test_complex_types() { - // Shouldn't lint, since the literal will be i32 otherwise + // Shouldn't be lint, since the literal will be i32 otherwise let _u8: u8 = 128; - // Should lint (doesn't) + // This could be lint, but currently doesn't let _tuple_i32: (i32, i32) = (12, 13); - // Shouldn't lint, since the tuple will be i32 otherwise + // Shouldn't be lint, since the tuple will be i32 otherwise let _tuple_u32: (u32, u32) = (1, 2); - // Should lint, since the type is determined by the init value (doesn't) + // Should be lint, since the type is determined by the init value, but currently doesn't let _tuple_u32: (u32, u32) = (3_u32, 4_u32); - // Should lint (doesn't) + // This could be lint, but currently doesn't let _array: [i32; 3] = [5, 6, 7]; - // Shouldn't lint + // Shouldn't be lint let _array: [u32; 2] = [8, 9]; } fn test_functions() { - // Everything here should lint + // Everything here should be lint let _return: String = return_a_string(); @@ -132,29 +154,23 @@ fn test_functions() { let _return: u32 = new_pie.return_an_int(); - let _return: String = String::from("test"); - let _return: u32 = Pie::associated_return_an_int(); let _return: String = Pie::associated_return_a_string(); } fn test_simple_types() { + // Everything here should be lint + let _var: u32 = u32::MAX; - // Should lint let _var: u32 = 5_u32; - // Should lint let _var: &str = "test"; - // Should lint let _var: &[u8] = b"test"; - // Should lint let _var: bool = false; } fn main() {} - -// TODO: test refs diff --git a/tests/ui/redundant_type_annotations.stderr b/tests/ui/redundant_type_annotations.stderr index 3356f4808608..e8b2fe5c3847 100644 --- a/tests/ui/redundant_type_annotations.stderr +++ b/tests/ui/redundant_type_annotations.stderr @@ -1,94 +1,106 @@ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:64:9 + --> $DIR/redundant_type_annotations.rs:81:9 | -LL | let v: u32 = self.return_an_int(); // Should lint +LL | let v: u32 = self.return_an_int(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::redundant-type-annotations` implied by `-D warnings` error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:121:5 + --> $DIR/redundant_type_annotations.rs:82:9 + | +LL | let v: &u32 = self.return_a_ref(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant type annotation + --> $DIR/redundant_type_annotations.rs:83:9 + | +LL | let v: &Slice = self.return_a_ref_to_struct(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant type annotation + --> $DIR/redundant_type_annotations.rs:143:5 | LL | let _return: String = return_a_string(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:123:5 + --> $DIR/redundant_type_annotations.rs:145:5 | LL | let _return: Pie = return_a_struct(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:125:5 + --> $DIR/redundant_type_annotations.rs:147:5 | LL | let _return: Pizza = return_an_enum(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:127:5 + --> $DIR/redundant_type_annotations.rs:149:5 | LL | let _return: u32 = return_an_int(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:129:5 + --> $DIR/redundant_type_annotations.rs:151:5 | LL | let _return: String = String::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:131:5 + --> $DIR/redundant_type_annotations.rs:153:5 | LL | let new_pie: Pie = Pie::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:133:5 + --> $DIR/redundant_type_annotations.rs:155:5 | LL | let _return: u32 = new_pie.return_an_int(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:137:5 + --> $DIR/redundant_type_annotations.rs:157:5 | LL | let _return: u32 = Pie::associated_return_an_int(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:139:5 + --> $DIR/redundant_type_annotations.rs:159:5 | LL | let _return: String = Pie::associated_return_a_string(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:143:5 + --> $DIR/redundant_type_annotations.rs:165:5 | LL | let _var: u32 = u32::MAX; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:146:5 + --> $DIR/redundant_type_annotations.rs:167:5 | LL | let _var: u32 = 5_u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:149:5 + --> $DIR/redundant_type_annotations.rs:169:5 | LL | let _var: &str = "test"; | ^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:152:5 + --> $DIR/redundant_type_annotations.rs:171:5 | LL | let _var: &[u8] = b"test"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:155:5 + --> $DIR/redundant_type_annotations.rs:173:5 | LL | let _var: bool = false; | ^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 15 previous errors +error: aborting due to 17 previous errors