Auto merge of #6939 - ThibsG:suggNewWithoutDefault, r=llogiq

Fix bad suggestion for generics in `new_without_default` lint

Fixes bad suggestion where a type parameter was missing for `new_without_default` lint.

Fixes #6933

changelog: none
This commit is contained in:
bors 2021-03-20 17:20:34 +00:00
commit 478f2581b1
3 changed files with 61 additions and 7 deletions

View file

@ -1,5 +1,6 @@
use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::paths; use clippy_utils::paths;
use clippy_utils::source::snippet;
use clippy_utils::sugg::DiagnosticBuilderExt; use clippy_utils::sugg::DiagnosticBuilderExt;
use clippy_utils::{get_trait_def_id, return_ty}; use clippy_utils::{get_trait_def_id, return_ty};
use if_chain::if_chain; use if_chain::if_chain;
@ -62,7 +63,10 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
if let hir::ItemKind::Impl(hir::Impl { if let hir::ItemKind::Impl(hir::Impl {
of_trait: None, items, .. of_trait: None,
ref generics,
items,
..
}) = item.kind }) = item.kind
{ {
for assoc_item in items { 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( span_lint_hir_and_then(
cx, cx,
NEW_WITHOUT_DEFAULT, NEW_WITHOUT_DEFAULT,
@ -140,7 +145,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
cx, cx,
item.span, item.span,
"try this", "try this",
&create_new_without_default_suggest_msg(self_ty), &create_new_without_default_suggest_msg(self_ty, &generics_sugg),
Applicability::MaybeIncorrect, 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] #[rustfmt::skip]
format!( format!(
"impl Default for {} {{ "impl{} Default for {} {{
fn default() -> Self {{ fn default() -> Self {{
Self::new() Self::new()
}} }}
}}", ty) }}", generics_sugg, ty)
} }

View file

@ -159,4 +159,19 @@ impl NewNotEqualToDerive {
} }
} }
// see #6933
pub struct FooGenerics<T>(std::marker::PhantomData<T>);
impl<T> FooGenerics<T> {
pub fn new() -> Self {
Self(Default::default())
}
}
pub struct BarGenerics<T>(std::marker::PhantomData<T>);
impl<T: Copy> BarGenerics<T> {
pub fn new() -> Self {
Self(Default::default())
}
}
fn main() {} fn main() {}

View file

@ -43,7 +43,7 @@ LL | | }
| |
help: try this help: try this
| |
LL | impl Default for LtKo<'c> { LL | impl<'c> Default for LtKo<'c> {
LL | fn default() -> Self { LL | fn default() -> Self {
LL | Self::new() LL | Self::new()
LL | } LL | }
@ -67,5 +67,39 @@ LL | }
LL | } LL | }
| |
error: aborting due to 4 previous errors error: you should consider adding a `Default` implementation for `FooGenerics<T>`
--> $DIR/new_without_default.rs:165:5
|
LL | / pub fn new() -> Self {
LL | | Self(Default::default())
LL | | }
| |_____^
|
help: try this
|
LL | impl<T> Default for FooGenerics<T> {
LL | fn default() -> Self {
LL | Self::new()
LL | }
LL | }
|
error: you should consider adding a `Default` implementation for `BarGenerics<T>`
--> $DIR/new_without_default.rs:172:5
|
LL | / pub fn new() -> Self {
LL | | Self(Default::default())
LL | | }
| |_____^
|
help: try this
|
LL | impl<T: Copy> Default for BarGenerics<T> {
LL | fn default() -> Self {
LL | Self::new()
LL | }
LL | }
|
error: aborting due to 6 previous errors