Skip to content

Commit e828c32

Browse files
committed
fix: new_without_default misses where clause in new
1 parent 34fab5c commit e828c32

File tree

4 files changed

+169
-6
lines changed

4 files changed

+169
-6
lines changed

clippy_lints/src/new_without_default.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::span_lint_hir_and_then;
22
use clippy_utils::return_ty;
3-
use clippy_utils::source::snippet_with_applicability;
3+
use clippy_utils::source::{indent_of, reindent_multiline, snippet_with_applicability};
44
use clippy_utils::sugg::DiagExt;
55
use rustc_errors::Applicability;
66
use rustc_hir as hir;
@@ -140,10 +140,29 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
140140
};
141141
let generics_sugg = snippet_with_applicability(cx, generics.span, "", &mut app);
142142
let where_clause_sugg = if generics.has_where_clause_predicates {
143-
format!(
144-
"\n{}\n",
145-
snippet_with_applicability(cx, generics.where_clause_span, "", &mut app)
146-
)
143+
let where_clause_sugg =
144+
snippet_with_applicability(cx, generics.where_clause_span, "", &mut app).to_string();
145+
let mut where_clause_sugg = reindent_multiline(&where_clause_sugg, true, Some(4));
146+
if impl_item.generics.has_where_clause_predicates {
147+
if !where_clause_sugg.ends_with(',') {
148+
where_clause_sugg.push(',');
149+
}
150+
151+
let additional_where_preds =
152+
snippet_with_applicability(cx, impl_item.generics.where_clause_span, "", &mut app);
153+
let ident = indent_of(cx, generics.where_clause_span).unwrap_or(0);
154+
// Remove the leading `where ` keyword
155+
let additional_where_preds = additional_where_preds.trim_start_matches("where").trim_start();
156+
where_clause_sugg.push('\n');
157+
where_clause_sugg.push_str(&" ".repeat(ident));
158+
where_clause_sugg.push_str(additional_where_preds);
159+
}
160+
format!("\n{}\n", where_clause_sugg)
161+
} else if impl_item.generics.has_where_clause_predicates {
162+
let where_clause_sugg =
163+
snippet_with_applicability(cx, impl_item.generics.where_clause_span, "", &mut app);
164+
let where_clause_sugg = reindent_multiline(&where_clause_sugg, true, Some(4));
165+
format!("\n{}\n", where_clause_sugg.trim_start())
147166
} else {
148167
String::new()
149168
};

tests/ui/new_without_default.fixed

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,3 +409,58 @@ mod issue15778 {
409409
}
410410
}
411411
}
412+
413+
pub mod issue16255 {
414+
use std::fmt::Display;
415+
use std::marker::PhantomData;
416+
417+
pub struct Foo<T> {
418+
marker: PhantomData<T>,
419+
}
420+
421+
impl<T> Default for Foo<T>
422+
where
423+
T: Display,
424+
T: Clone,
425+
{
426+
fn default() -> Self {
427+
Self::new()
428+
}
429+
}
430+
431+
impl<T> Foo<T>
432+
where
433+
T: Display,
434+
{
435+
pub fn new() -> Self
436+
//~^ new_without_default
437+
where
438+
T: Clone,
439+
{
440+
Self { marker: PhantomData }
441+
}
442+
}
443+
444+
pub struct Bar<T> {
445+
marker: PhantomData<T>,
446+
}
447+
448+
impl<T> Default for Bar<T>
449+
where
450+
T: Clone,
451+
{
452+
fn default() -> Self {
453+
Self::new()
454+
}
455+
}
456+
457+
impl<T> Bar<T> {
458+
pub fn new() -> Self
459+
//~^ new_without_default
460+
where
461+
T: Clone,
462+
{
463+
Self { marker: PhantomData }
464+
}
465+
}
466+
}

tests/ui/new_without_default.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,3 +324,39 @@ mod issue15778 {
324324
}
325325
}
326326
}
327+
328+
pub mod issue16255 {
329+
use std::fmt::Display;
330+
use std::marker::PhantomData;
331+
332+
pub struct Foo<T> {
333+
marker: PhantomData<T>,
334+
}
335+
336+
impl<T> Foo<T>
337+
where
338+
T: Display,
339+
{
340+
pub fn new() -> Self
341+
//~^ new_without_default
342+
where
343+
T: Clone,
344+
{
345+
Self { marker: PhantomData }
346+
}
347+
}
348+
349+
pub struct Bar<T> {
350+
marker: PhantomData<T>,
351+
}
352+
353+
impl<T> Bar<T> {
354+
pub fn new() -> Self
355+
//~^ new_without_default
356+
where
357+
T: Clone,
358+
{
359+
Self { marker: PhantomData }
360+
}
361+
}
362+
}

tests/ui/new_without_default.stderr

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,5 +250,58 @@ LL + }
250250
LL + }
251251
|
252252

253-
error: aborting due to 13 previous errors
253+
error: you should consider adding a `Default` implementation for `Foo<T>`
254+
--> tests/ui/new_without_default.rs:340:9
255+
|
256+
LL | / pub fn new() -> Self
257+
LL | |
258+
LL | | where
259+
LL | | T: Clone,
260+
LL | | {
261+
LL | | Self { marker: PhantomData }
262+
LL | | }
263+
| |_________^
264+
|
265+
help: try adding this
266+
|
267+
LL ~ impl<T> Default for Foo<T>
268+
LL + where
269+
LL + T: Display,
270+
LL + T: Clone,
271+
LL + {
272+
LL + fn default() -> Self {
273+
LL + Self::new()
274+
LL + }
275+
LL + }
276+
LL +
277+
LL ~ impl<T> Foo<T>
278+
|
279+
280+
error: you should consider adding a `Default` implementation for `Bar<T>`
281+
--> tests/ui/new_without_default.rs:354:9
282+
|
283+
LL | / pub fn new() -> Self
284+
LL | |
285+
LL | | where
286+
LL | | T: Clone,
287+
LL | | {
288+
LL | | Self { marker: PhantomData }
289+
LL | | }
290+
| |_________^
291+
|
292+
help: try adding this
293+
|
294+
LL ~ impl<T> Default for Bar<T>
295+
LL + where
296+
LL + T: Clone,
297+
LL + {
298+
LL + fn default() -> Self {
299+
LL + Self::new()
300+
LL + }
301+
LL + }
302+
LL +
303+
LL ~ impl<T> Bar<T> {
304+
|
305+
306+
error: aborting due to 15 previous errors
254307

0 commit comments

Comments
 (0)