Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 25 additions & 5 deletions clippy_lints/src/new_without_default.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::return_ty;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::source::{indent_of, reindent_multiline, snippet_with_applicability};
use clippy_utils::sugg::DiagExt;
use rustc_errors::Applicability;
use rustc_hir as hir;
Expand Down Expand Up @@ -57,6 +57,7 @@ pub struct NewWithoutDefault {
impl_lint_pass!(NewWithoutDefault => [NEW_WITHOUT_DEFAULT]);

impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
#[expect(clippy::too_many_lines)]
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
let hir::ItemKind::Impl(hir::Impl {
of_trait: None,
Expand Down Expand Up @@ -140,10 +141,29 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
};
let generics_sugg = snippet_with_applicability(cx, generics.span, "", &mut app);
let where_clause_sugg = if generics.has_where_clause_predicates {
format!(
"\n{}\n",
snippet_with_applicability(cx, generics.where_clause_span, "", &mut app)
)
let where_clause_sugg =
snippet_with_applicability(cx, generics.where_clause_span, "", &mut app).to_string();
let mut where_clause_sugg = reindent_multiline(&where_clause_sugg, true, Some(4));
if impl_item.generics.has_where_clause_predicates {
if !where_clause_sugg.ends_with(',') {
where_clause_sugg.push(',');
}

let additional_where_preds =
snippet_with_applicability(cx, impl_item.generics.where_clause_span, "", &mut app);
let ident = indent_of(cx, generics.where_clause_span).unwrap_or(0);
// Remove the leading `where ` keyword
let additional_where_preds = additional_where_preds.trim_start_matches("where").trim_start();
where_clause_sugg.push('\n');
where_clause_sugg.extend(std::iter::repeat_n(' ', ident));
where_clause_sugg.push_str(additional_where_preds);
}
format!("\n{where_clause_sugg}\n")
} else if impl_item.generics.has_where_clause_predicates {
let where_clause_sugg =
snippet_with_applicability(cx, impl_item.generics.where_clause_span, "", &mut app);
let where_clause_sugg = reindent_multiline(&where_clause_sugg, true, Some(4));
format!("\n{}\n", where_clause_sugg.trim_start())
} else {
String::new()
};
Expand Down
55 changes: 55 additions & 0 deletions tests/ui/new_without_default.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -409,3 +409,58 @@ mod issue15778 {
}
}
}

pub mod issue16255 {
use std::fmt::Display;
use std::marker::PhantomData;

pub struct Foo<T> {
marker: PhantomData<T>,
}

impl<T> Default for Foo<T>
where
T: Display,
T: Clone,
{
fn default() -> Self {
Self::new()
}
}

impl<T> Foo<T>
where
T: Display,
{
pub fn new() -> Self
//~^ new_without_default
where
T: Clone,
{
Self { marker: PhantomData }
}
}

pub struct Bar<T> {
marker: PhantomData<T>,
}

impl<T> Default for Bar<T>
where
T: Clone,
{
fn default() -> Self {
Self::new()
}
}

impl<T> Bar<T> {
pub fn new() -> Self
//~^ new_without_default
where
T: Clone,
{
Self { marker: PhantomData }
}
}
}
36 changes: 36 additions & 0 deletions tests/ui/new_without_default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,3 +324,39 @@ mod issue15778 {
}
}
}

pub mod issue16255 {
use std::fmt::Display;
use std::marker::PhantomData;

pub struct Foo<T> {
marker: PhantomData<T>,
}

impl<T> Foo<T>
where
T: Display,
{
pub fn new() -> Self
//~^ new_without_default
where
T: Clone,
{
Self { marker: PhantomData }
}
}

pub struct Bar<T> {
marker: PhantomData<T>,
}

impl<T> Bar<T> {
pub fn new() -> Self
//~^ new_without_default
where
T: Clone,
{
Self { marker: PhantomData }
}
}
}
55 changes: 54 additions & 1 deletion tests/ui/new_without_default.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -250,5 +250,58 @@ LL + }
LL + }
|

error: aborting due to 13 previous errors
error: you should consider adding a `Default` implementation for `Foo<T>`
--> tests/ui/new_without_default.rs:340:9
|
LL | / pub fn new() -> Self
LL | |
LL | | where
LL | | T: Clone,
LL | | {
LL | | Self { marker: PhantomData }
LL | | }
| |_________^
|
help: try adding this
|
LL ~ impl<T> Default for Foo<T>
LL + where
LL + T: Display,
LL + T: Clone,
LL + {
LL + fn default() -> Self {
LL + Self::new()
LL + }
LL + }
LL +
LL ~ impl<T> Foo<T>
|

error: you should consider adding a `Default` implementation for `Bar<T>`
--> tests/ui/new_without_default.rs:354:9
|
LL | / pub fn new() -> Self
LL | |
LL | | where
LL | | T: Clone,
LL | | {
LL | | Self { marker: PhantomData }
LL | | }
| |_________^
|
help: try adding this
|
LL ~ impl<T> Default for Bar<T>
LL + where
LL + T: Clone,
LL + {
LL + fn default() -> Self {
LL + Self::new()
LL + }
LL + }
LL +
LL ~ impl<T> Bar<T> {
|

error: aborting due to 15 previous errors