From 6e75050be07d5f457c8854e9392fd756ef211a06 Mon Sep 17 00:00:00 2001 From: Josh Mcguigan Date: Fri, 19 Oct 2018 04:55:06 -0700 Subject: [PATCH] new_ret_no_self correct linting of tuple return types --- clippy_lints/src/methods/mod.rs | 11 +++++++++++ tests/ui/new_ret_no_self.rs | 28 ++++++++++++++++++++++++++++ tests/ui/new_ret_no_self.stderr | 8 +++++++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 6d22abf2d33..6e015487561 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -936,6 +936,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { if let hir::ImplItemKind::Method(_, _) = implitem.node { let ret_ty = return_ty(cx, implitem.id); +// println!("ret_ty: {:?}", ret_ty); +// println!("ret_ty.sty {:?}", ret_ty.sty); + // if return type is impl trait if let TyKind::Opaque(def_id, _) = ret_ty.sty { @@ -955,6 +958,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { } } + // if return type is tuple + if let TyKind::Tuple(list) = ret_ty.sty { + // then at least one of the types in the tuple must be Self + for ret_type in list { + if same_tys(cx, ty, ret_type) { return; } + } + } + if name == "new" && !same_tys(cx, ret_ty, ty) { span_lint(cx, NEW_RET_NO_SELF, diff --git a/tests/ui/new_ret_no_self.rs b/tests/ui/new_ret_no_self.rs index 1a4b91cc9da..77731149678 100644 --- a/tests/ui/new_ret_no_self.rs +++ b/tests/ui/new_ret_no_self.rs @@ -91,3 +91,31 @@ impl V { unimplemented!(); } } + +struct TupleReturnerOk; + +impl TupleReturnerOk { + // should not trigger lint + pub fn new() -> (Self, u32) { unimplemented!(); } +} + +struct TupleReturnerOk2; + +impl TupleReturnerOk2 { + // should not trigger lint (it doesn't matter which element in the tuple is Self) + pub fn new() -> (u32, Self) { unimplemented!(); } +} + +struct TupleReturnerOk3; + +impl TupleReturnerOk3 { + // should not trigger lint (tuple can contain multiple Self) + pub fn new() -> (Self, Self) { unimplemented!(); } +} + +struct TupleReturnerBad; + +impl TupleReturnerBad { + // should trigger lint + pub fn new() -> (u32, u32) { unimplemented!(); } +} diff --git a/tests/ui/new_ret_no_self.stderr b/tests/ui/new_ret_no_self.stderr index ad26438d4ef..6f8e2d136a7 100644 --- a/tests/ui/new_ret_no_self.stderr +++ b/tests/ui/new_ret_no_self.stderr @@ -24,5 +24,11 @@ error: methods called `new` usually return `Self` 92 | | } | |_____^ -error: aborting due to 3 previous errors +error: methods called `new` usually return `Self` + --> $DIR/new_ret_no_self.rs:120:5 + | +120 | pub fn new() -> (u32, u32) { unimplemented!(); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors