diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs index 502e5e4bf37..3789572ad43 100644 --- a/clippy_lints/src/new_without_default.rs +++ b/clippy_lints/src/new_without_default.rs @@ -1,5 +1,6 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::paths; +use clippy_utils::source::snippet; use clippy_utils::sugg::DiagnosticBuilderExt; use clippy_utils::{get_trait_def_id, return_ty}; use if_chain::if_chain; @@ -62,7 +63,10 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { #[allow(clippy::too_many_lines)] fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { if let hir::ItemKind::Impl(hir::Impl { - of_trait: None, items, .. + of_trait: None, + ref generics, + items, + .. }) = item.kind { for assoc_item in items { @@ -126,6 +130,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { } } + let generics_sugg = snippet(cx, generics.span, ""); span_lint_hir_and_then( cx, NEW_WITHOUT_DEFAULT, @@ -140,7 +145,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { cx, item.span, "try this", - &create_new_without_default_suggest_msg(self_ty), + &create_new_without_default_suggest_msg(self_ty, &generics_sugg), Applicability::MaybeIncorrect, ); }, @@ -155,12 +160,12 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { } } -fn create_new_without_default_suggest_msg(ty: Ty<'_>) -> String { +fn create_new_without_default_suggest_msg(ty: Ty<'_>, generics_sugg: &str) -> String { #[rustfmt::skip] format!( -"impl Default for {} {{ +"impl{} Default for {} {{ fn default() -> Self {{ Self::new() }} -}}", ty) +}}", generics_sugg, ty) } diff --git a/tests/ui/new_without_default.rs b/tests/ui/new_without_default.rs index 3b6041823d8..64659b63f46 100644 --- a/tests/ui/new_without_default.rs +++ b/tests/ui/new_without_default.rs @@ -159,4 +159,19 @@ impl NewNotEqualToDerive { } } +// see #6933 +pub struct FooGenerics(std::marker::PhantomData); +impl FooGenerics { + pub fn new() -> Self { + Self(Default::default()) + } +} + +pub struct BarGenerics(std::marker::PhantomData); +impl BarGenerics { + pub fn new() -> Self { + Self(Default::default()) + } +} + fn main() {} diff --git a/tests/ui/new_without_default.stderr b/tests/ui/new_without_default.stderr index e529e441eb7..973836f75a9 100644 --- a/tests/ui/new_without_default.stderr +++ b/tests/ui/new_without_default.stderr @@ -43,7 +43,7 @@ LL | | } | help: try this | -LL | impl Default for LtKo<'c> { +LL | impl<'c> Default for LtKo<'c> { LL | fn default() -> Self { LL | Self::new() LL | } @@ -67,5 +67,39 @@ LL | } LL | } | -error: aborting due to 4 previous errors +error: you should consider adding a `Default` implementation for `FooGenerics` + --> $DIR/new_without_default.rs:165:5 + | +LL | / pub fn new() -> Self { +LL | | Self(Default::default()) +LL | | } + | |_____^ + | +help: try this + | +LL | impl Default for FooGenerics { +LL | fn default() -> Self { +LL | Self::new() +LL | } +LL | } + | + +error: you should consider adding a `Default` implementation for `BarGenerics` + --> $DIR/new_without_default.rs:172:5 + | +LL | / pub fn new() -> Self { +LL | | Self(Default::default()) +LL | | } + | |_____^ + | +help: try this + | +LL | impl Default for BarGenerics { +LL | fn default() -> Self { +LL | Self::new() +LL | } +LL | } + | + +error: aborting due to 6 previous errors