fix: new_without_default misses where clause in new
This commit is contained in:
parent
34fab5cd37
commit
a2102a528c
4 changed files with 170 additions and 6 deletions
|
|
@ -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;
|
||||
|
|
@ -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,
|
||||
|
|
@ -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()
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue