When looking for `Default` impls that could be derived, we look at the
body of their `fn default()` and if it is an fn call or literal we check
if they are equivalent to what `#[derive(Default)]` would have used.
Now, when checking those fn calls in the `fn default()` body, we also
compare against the corresponding type's `Default::default` body to see
if our call is equivalent to that one.
For example, given
```rust
struct S;
impl S {
fn new() -> S { S }
}
impl Default for S {
fn default() -> S { S::new() }
}
```
`<S as Default>::default()` and `S::new()` are considered equivalent.
Given that, if the user also writes
```rust
struct R {
s: S,
}
impl Default for R {
fn default() -> R {
R { s: S::new() }
}
}
```
the `derivable_impls` lint will now trigger.
187 lines
4.5 KiB
Text
187 lines
4.5 KiB
Text
error: this `impl` can be derived
|
|
--> tests/ui/derivable_impls.rs:20:1
|
|
|
|
|
LL | / impl std::default::Default for FooDefault<'_> {
|
|
LL | | fn default() -> Self {
|
|
LL | | Self {
|
|
LL | | a: false,
|
|
... |
|
|
LL | | }
|
|
| |_^
|
|
|
|
|
= note: `-D clippy::derivable-impls` implied by `-D warnings`
|
|
= help: to override `-D warnings` add `#[allow(clippy::derivable_impls)]`
|
|
help: replace the manual implementation with a derive attribute
|
|
|
|
|
LL + #[derive(Default)]
|
|
LL ~ struct FooDefault<'a> {
|
|
|
|
|
|
|
error: this `impl` can be derived
|
|
--> tests/ui/derivable_impls.rs:41:1
|
|
|
|
|
LL | / impl std::default::Default for TupleDefault {
|
|
LL | | fn default() -> Self {
|
|
LL | | Self(false, 0, 0u64)
|
|
LL | | }
|
|
LL | | }
|
|
| |_^
|
|
|
|
|
help: replace the manual implementation with a derive attribute
|
|
|
|
|
LL + #[derive(Default)]
|
|
LL ~ struct TupleDefault(bool, i32, u64);
|
|
|
|
|
|
|
error: this `impl` can be derived
|
|
--> tests/ui/derivable_impls.rs:93:1
|
|
|
|
|
LL | / impl Default for StrDefault<'_> {
|
|
LL | | fn default() -> Self {
|
|
LL | | Self("")
|
|
LL | | }
|
|
LL | | }
|
|
| |_^
|
|
|
|
|
help: replace the manual implementation with a derive attribute
|
|
|
|
|
LL + #[derive(Default)]
|
|
LL ~ struct StrDefault<'a>(&'a str);
|
|
|
|
|
|
|
error: this `impl` can be derived
|
|
--> tests/ui/derivable_impls.rs:119:1
|
|
|
|
|
LL | / impl Default for Y {
|
|
LL | | fn default() -> Self {
|
|
LL | | Self(mac!())
|
|
LL | | }
|
|
LL | | }
|
|
| |_^
|
|
|
|
|
help: replace the manual implementation with a derive attribute
|
|
|
|
|
LL + #[derive(Default)]
|
|
LL ~ struct Y(u32);
|
|
|
|
|
|
|
error: this `impl` can be derived
|
|
--> tests/ui/derivable_impls.rs:158:1
|
|
|
|
|
LL | / impl Default for WithoutSelfCurly {
|
|
LL | | fn default() -> Self {
|
|
LL | | WithoutSelfCurly { a: false }
|
|
LL | | }
|
|
LL | | }
|
|
| |_^
|
|
|
|
|
help: replace the manual implementation with a derive attribute
|
|
|
|
|
LL + #[derive(Default)]
|
|
LL ~ struct WithoutSelfCurly {
|
|
|
|
|
|
|
error: this `impl` can be derived
|
|
--> tests/ui/derivable_impls.rs:166:1
|
|
|
|
|
LL | / impl Default for WithoutSelfParan {
|
|
LL | | fn default() -> Self {
|
|
LL | | WithoutSelfParan(false)
|
|
LL | | }
|
|
LL | | }
|
|
| |_^
|
|
|
|
|
help: replace the manual implementation with a derive attribute
|
|
|
|
|
LL + #[derive(Default)]
|
|
LL ~ struct WithoutSelfParan(bool);
|
|
|
|
|
|
|
error: this `impl` can be derived
|
|
--> tests/ui/derivable_impls.rs:188:1
|
|
|
|
|
LL | / impl Default for DirectDefaultDefaultCall {
|
|
LL | | fn default() -> Self {
|
|
LL | | // When calling `Default::default()` in all fields, we know it is the same as deriving.
|
|
LL | | Self { v: Default::default() }
|
|
LL | | }
|
|
LL | | }
|
|
| |_^
|
|
|
|
|
help: replace the manual implementation with a derive attribute
|
|
|
|
|
LL + #[derive(Default)]
|
|
LL ~ pub struct DirectDefaultDefaultCall {
|
|
|
|
|
|
|
error: this `impl` can be derived
|
|
--> tests/ui/derivable_impls.rs:199:1
|
|
|
|
|
LL | / impl Default for EquivalentToDefaultDefaultCallVec {
|
|
LL | | fn default() -> Self {
|
|
LL | | // The body of `<Vec as Default>::default()` is `Vec::new()`, so they are equivalent.
|
|
LL | | Self { v: Vec::new() }
|
|
LL | | }
|
|
LL | | }
|
|
| |_^
|
|
|
|
|
help: replace the manual implementation with a derive attribute
|
|
|
|
|
LL + #[derive(Default)]
|
|
LL ~ pub struct EquivalentToDefaultDefaultCallVec {
|
|
|
|
|
|
|
error: this `impl` can be derived
|
|
--> tests/ui/derivable_impls.rs:226:1
|
|
|
|
|
LL | / impl Default for EquivalentToDefaultDefaultCallLocal {
|
|
LL | | fn default() -> Self {
|
|
LL | | // The body of `<S as Default>::default()` is `S::new()`, so they are equivalent.
|
|
LL | | Self { v: S::new() }
|
|
LL | | }
|
|
LL | | }
|
|
| |_^
|
|
|
|
|
help: replace the manual implementation with a derive attribute
|
|
|
|
|
LL + #[derive(Default)]
|
|
LL ~ pub struct EquivalentToDefaultDefaultCallLocal {
|
|
|
|
|
|
|
error: this `impl` can be derived
|
|
--> tests/ui/derivable_impls.rs:265:1
|
|
|
|
|
LL | / impl Default for RepeatDefault1 {
|
|
LL | | fn default() -> Self {
|
|
LL | | RepeatDefault1 { a: [0; 32] }
|
|
LL | | }
|
|
LL | | }
|
|
| |_^
|
|
|
|
|
help: replace the manual implementation with a derive attribute
|
|
|
|
|
LL + #[derive(Default)]
|
|
LL ~ pub struct RepeatDefault1 {
|
|
|
|
|
|
|
error: this `impl` can be derived
|
|
--> tests/ui/derivable_impls.rs:299:1
|
|
|
|
|
LL | / impl Default for SimpleEnum {
|
|
LL | | fn default() -> Self {
|
|
LL | | SimpleEnum::Bar
|
|
LL | | }
|
|
LL | | }
|
|
| |_^
|
|
|
|
|
help: replace the manual implementation with a derive attribute and mark the default variant
|
|
|
|
|
LL + #[derive(Default)]
|
|
LL ~ pub enum SimpleEnum {
|
|
LL | Foo,
|
|
LL ~ #[default]
|
|
LL ~ Bar,
|
|
|
|
|
|
|
error: aborting due to 11 previous errors
|
|
|