Skip to content

Commit b443d1e

Browse files
committed
Tweak lint output
1 parent 1db7d91 commit b443d1e

File tree

4 files changed

+69
-22
lines changed

4 files changed

+69
-22
lines changed

compiler/rustc_lint/src/default_could_be_derived.rs

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived {
180180
item.span,
181181
|diag| {
182182
diag.primary_message("`impl Default` that could be derived");
183+
diag.span_label(
184+
expr.span,
185+
"this enum variant has no fields, so it's trivially derivable",
186+
);
183187
diag.multipart_suggestion_verbose(
184188
"you don't need to manually `impl Default`, you can derive it",
185189
vec![
@@ -198,7 +202,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived {
198202
},
199203
);
200204
}
201-
hir::ExprKind::Struct(_qpath, fields, _tail) => {
205+
hir::ExprKind::Struct(_qpath, fields, tail) => {
202206
// We have a struct literal
203207
//
204208
// struct Foo {
@@ -218,13 +222,44 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived {
218222
// - `val` matches the `Default::default()` body for that type
219223
// - `val` is `0`
220224
// - `val` is `false`
225+
if let hir::StructTailExpr::Base(_) = tail {
226+
// This is *very* niche. We'd only get here if someone wrote
227+
// impl Default for Ty {
228+
// fn default() -> Ty {
229+
// Ty { ..something() }
230+
// }
231+
// }
232+
// where `something()` would have to be a call or path.
233+
return;
234+
}
221235
if fields.iter().all(|f| check_expr(cx, f.expr)) {
222236
cx.tcx.node_span_lint(
223237
DEFAULT_COULD_BE_DERIVED,
224238
item.hir_id(),
225239
item.span,
226240
|diag| {
227241
diag.primary_message("`impl Default` that could be derived");
242+
for (i, field) in fields.iter().enumerate() {
243+
let msg = if i == fields.len() - 1 {
244+
if fields.len() == 1 {
245+
"this is the same value the expansion of \
246+
`#[derive(Default)]` would use"
247+
} else {
248+
"these are the same values the expansion of \
249+
`#[derive(Default)]` would use"
250+
}
251+
} else {
252+
""
253+
};
254+
diag.span_label(field.expr.span, msg);
255+
}
256+
if let hir::StructTailExpr::DefaultFields(span) = tail {
257+
diag.span_label(
258+
span,
259+
"all remaining fields will use the same default field \
260+
values that the `#[derive(Default)]` would use",
261+
);
262+
}
228263
diag.multipart_suggestion_verbose(
229264
"you don't need to manually `impl Default`, you can derive it",
230265
vec![
@@ -268,6 +303,20 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived {
268303
item.span,
269304
|diag| {
270305
diag.primary_message("`impl Default` that could be derived");
306+
for (i, field) in args.iter().enumerate() {
307+
let msg = if i == args.len() - 1 {
308+
if args.len() == 1 {
309+
"this is the same value the expansion of \
310+
`#[derive(Default)]` would use"
311+
} else {
312+
"these are the same values the expansion of \
313+
`#[derive(Default)]` would use"
314+
}
315+
} else {
316+
""
317+
};
318+
diag.span_label(field.span, msg);
319+
}
271320
diag.multipart_suggestion_verbose(
272321
"you don't need to manually `impl Default`, you can derive it",
273322
vec![
@@ -305,6 +354,10 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived {
305354
item.span,
306355
|diag| {
307356
diag.primary_message("`impl Default` that could be derived");
357+
diag.span_label(
358+
expr.span,
359+
"this type has no fields, so it's trivially derivable",
360+
);
308361
diag.multipart_suggestion_verbose(
309362
"you don't need to manually `impl Default`, you can derive it",
310363
vec![

tests/ui/lint/lint-unconditional-recursion.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ pub struct Point {
182182
pub y: f32,
183183
}
184184

185-
impl Default for Point { //~ WARN
185+
impl Default for Point {
186186
fn default() -> Self { //~ ERROR function cannot return without recursing
187187
Point {
188188
x: Default::default(),

tests/ui/lint/lint-unconditional-recursion.stderr

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -197,23 +197,5 @@ LL | ..Default::default()
197197
|
198198
= help: a `loop` may express intention better if this is on purpose
199199

200-
warning: `impl Default` that could be derived
201-
--> $DIR/lint-unconditional-recursion.rs:185:1
202-
|
203-
LL | / impl Default for Point {
204-
LL | | fn default() -> Self {
205-
LL | | Point {
206-
LL | | x: Default::default(),
207-
... |
208-
LL | | }
209-
LL | | }
210-
| |_^
211-
|
212-
= note: `#[warn(default_could_be_derived)]` on by default
213-
help: you don't need to manually `impl Default`, you can derive it
214-
|
215-
LL ~ #[derive(Default)] pub struct Point {
216-
|
217-
218-
error: aborting due to 18 previous errors; 1 warning emitted
200+
error: aborting due to 18 previous errors
219201

tests/ui/structs/manual-default-impl-could-be-derived.stderr

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ error: `impl Default` that could be derived
33
|
44
LL | / impl Default for A {
55
LL | | fn default() -> Self { A }
6+
| | - this type has no fields, so it's trivially derivable
67
LL | | }
78
| |_^
89
|
@@ -22,6 +23,7 @@ error: `impl Default` that could be derived
2223
|
2324
LL | / impl Default for B {
2425
LL | | fn default() -> Self { B(Default::default()) }
26+
| | ------------------ this is the same value the expansion of `#[derive(Default)]` would use
2527
LL | | }
2628
| |_^
2729
|
@@ -36,6 +38,7 @@ error: `impl Default` that could be derived
3638
|
3739
LL | / impl Default for C {
3840
LL | | fn default() -> Self { C(None) }
41+
| | ---- this is the same value the expansion of `#[derive(Default)]` would use
3942
LL | | }
4043
| |_^
4144
|
@@ -52,7 +55,10 @@ LL | / impl Default for D {
5255
LL | | fn default() -> Self {
5356
LL | | D {
5457
LL | | x: Default::default(),
55-
... |
58+
| | ------------------
59+
LL | | y: 0,
60+
| | - these are the same values the expansion of `#[derive(Default)]` would use
61+
LL | | }
5662
LL | | }
5763
LL | | }
5864
| |_^
@@ -69,6 +75,7 @@ LL | / impl Default for E {
6975
LL | | fn default() -> Self {
7076
LL | | E {
7177
LL | | x: None,
78+
| | ---- this is the same value the expansion of `#[derive(Default)]` would use
7279
LL | | }
7380
LL | | }
7481
LL | | }
@@ -85,6 +92,7 @@ error: `impl Default` that could be derived
8592
LL | / impl<T> Default for F<T> {
8693
LL | | fn default() -> Self {
8794
LL | | F::Unit
95+
| | ------- this enum variant has no fields, so it's trivially derivable
8896
LL | | }
8997
LL | | }
9098
| |_^
@@ -102,6 +110,7 @@ LL | / impl Default for G {
102110
LL | | fn default() -> Self {
103111
LL | | G {
104112
LL | | f: F::Unit,
113+
| | ------- this is the same value the expansion of `#[derive(Default)]` would use
105114
LL | | }
106115
LL | | }
107116
LL | | }
@@ -165,6 +174,7 @@ LL | / impl Default for J {
165174
LL | | fn default() -> Self {
166175
LL | | J {
167176
LL | | x: foo(), // fn call that isn't an assoc fn
177+
| | ----- this is the same value the expansion of `#[derive(Default)]` would use
168178
LL | | }
169179
LL | | }
170180
LL | | }
@@ -182,6 +192,7 @@ LL | / impl Default for L {
182192
LL | | fn default() -> Self {
183193
LL | | L {
184194
LL | | x: Vec::new(), // `<Vec as Default>::default()` just calls `Vec::new()`
195+
| | ---------- this is the same value the expansion of `#[derive(Default)]` would use
185196
LL | | }
186197
LL | | }
187198
LL | | }
@@ -199,6 +210,7 @@ LL | / impl Default for M {
199210
LL | | fn default() -> Self {
200211
LL | | M {
201212
LL | | x: N_CONST,
213+
| | ------- this is the same value the expansion of `#[derive(Default)]` would use
202214
LL | | }
203215
LL | | }
204216
LL | | }

0 commit comments

Comments
 (0)