mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-27 15:11:30 +00:00
Add support to returned refs from MethodCall
This commit is contained in:
parent
6f26df1c9a
commit
29ab954a2b
3 changed files with 85 additions and 47 deletions
|
@ -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<Ty<'tcx>> {
|
||||
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
|
||||
}
|
||||
|
@ -111,7 +109,7 @@ fn is_redundant_in_func_call<'tcx>(
|
|||
false
|
||||
}
|
||||
|
||||
fn extract_primty<'tcx>(ty_kind: &hir::TyKind<'tcx>) -> Option<hir::PrimTy> {
|
||||
fn extract_primty(ty_kind: &hir::TyKind<'_>) -> Option<hir::PrimTy> {
|
||||
if let hir::TyKind::Path(ty_path) = ty_kind
|
||||
&& let hir::QPath::Resolved(_, resolved_path_ty) = ty_path
|
||||
&& let hir::def::Res::PrimTy(primty) = resolved_path_ty.res
|
||||
|
@ -142,12 +140,24 @@ 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, if is_ref {
|
||||
return_type.peel_refs()
|
||||
} else {
|
||||
return_type
|
||||
})
|
||||
{
|
||||
span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, "redundant type annotation");
|
||||
}
|
||||
|
|
|
@ -18,8 +18,15 @@ fn plus_one<T: std::ops::Add<u8, Output = T>>(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<u8> = make_cake();
|
||||
|
||||
// This should lint (doesn't)
|
||||
// This could be lint, but currently doesn't
|
||||
let _c: Cake<u8> = make_cake::<u8>();
|
||||
|
||||
// This should lint (doesn't)
|
||||
// This could be lint, but currently doesn't
|
||||
let _c: u8 = make_something::<u8>();
|
||||
|
||||
// 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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue