diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 6e0154875..099206763 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -966,6 +966,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { } } + // if return type is mutable pointer + if let TyKind::RawPtr(ty::TypeAndMut{ty: ret_type, ..}) = ret_ty.sty { + // then the pointer must point to Self + 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 777311496..b267a3aec 100644 --- a/tests/ui/new_ret_no_self.rs +++ b/tests/ui/new_ret_no_self.rs @@ -119,3 +119,24 @@ impl TupleReturnerBad { // should trigger lint pub fn new() -> (u32, u32) { unimplemented!(); } } + +struct MutPointerReturnerOk; + +impl MutPointerReturnerOk { + // should not trigger lint + pub fn new() -> *mut Self { unimplemented!(); } +} + +struct MutPointerReturnerOk2; + +impl MutPointerReturnerOk2 { + // should not trigger lint + pub fn new() -> *const Self { unimplemented!(); } +} + +struct MutPointerReturnerBad; + +impl MutPointerReturnerBad { + // should trigger lint + pub fn new() -> *mut V { unimplemented!(); } +} diff --git a/tests/ui/new_ret_no_self.stderr b/tests/ui/new_ret_no_self.stderr index 6f8e2d136..20f0dbbe8 100644 --- a/tests/ui/new_ret_no_self.stderr +++ b/tests/ui/new_ret_no_self.stderr @@ -30,5 +30,11 @@ error: methods called `new` usually return `Self` 120 | pub fn new() -> (u32, u32) { unimplemented!(); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: methods called `new` usually return `Self` + --> $DIR/new_ret_no_self.rs:141:5 + | +141 | pub fn new() -> *mut V { unimplemented!(); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors