Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lint against manual impl Default that could have been derived #134175

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1b36289
Make some manual `impl Default` derived
estebank Dec 11, 2024
75f1249
Introduce `default_could_be_derived` lint
estebank Dec 11, 2024
476fe03
Use `derive(Default)`
estebank Dec 11, 2024
9b209dc
Detect `impl Default` where fields are literals and `Default::default…
estebank Dec 11, 2024
3ec241b
Explicitly consider fields set to `None` as `Default` derivable
estebank Dec 11, 2024
9ef798c
Detect when user uses default unit variant in default impl
estebank Dec 11, 2024
9ab4f0c
Use `#[derive(Default)]` for `std::option::Option`
estebank Dec 11, 2024
2c7e43f
Also lint enums with type parameters with unit variant default
estebank Dec 11, 2024
c35fd36
Lint against manual `Default` impl if all fields are defaulted
estebank Dec 11, 2024
e5a4a88
Lint structs with default field values and manual `Default`
estebank Dec 11, 2024
34ecbb9
Extend `Default` lint to tuple-structs
estebank Dec 11, 2024
e39edf7
Extend support to unit-structs and add comments
estebank Dec 12, 2024
5558821
Rework logic to make it work x-crate and remove special cases
estebank Dec 12, 2024
da449e2
update test output
estebank Dec 12, 2024
132b49d
Add test for `const` "equivalent"
estebank Dec 12, 2024
f10d560
`#[derive(Default)] struct FixupContext`
estebank Dec 12, 2024
7c8b801
Tweak lint output
estebank Dec 12, 2024
4c421be
Split lints
estebank Dec 12, 2024
64c4938
Fix clippy tests
estebank Dec 12, 2024
810a245
Use `derive(Default)` in rustfmt
estebank Dec 12, 2024
448d80d
Derive `Default` in `tests::hash`
estebank Dec 12, 2024
433947b
Make lint deny-by-default (for crater run)
estebank Dec 12, 2024
32b933e
`allow(default_could_be_derived)` in `Default` examples
estebank Dec 13, 2024
814146c
Mention `#[default]` in E0655 code index
estebank Dec 13, 2024
c666eae
Fix lint example
estebank Dec 14, 2024
6fa30b6
fix rebase
estebank Dec 15, 2024
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
19 changes: 3 additions & 16 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic};
pub use rustc_span::AttrId;
use rustc_span::source_map::{Spanned, respan};
use rustc_span::symbol::{Ident, Symbol, kw, sym};
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
use rustc_span::{ErrorGuaranteed, Span};
use thin_vec::{ThinVec, thin_vec};

pub use crate::format::*;
Expand Down Expand Up @@ -388,22 +388,15 @@ impl GenericParam {

/// Represents lifetime, type and const parameters attached to a declaration of
/// a function, enum, trait, etc.
#[derive(Clone, Encodable, Decodable, Debug)]
#[derive(Clone, Encodable, Decodable, Debug, Default)]
pub struct Generics {
pub params: ThinVec<GenericParam>,
pub where_clause: WhereClause,
pub span: Span,
}

impl Default for Generics {
/// Creates an instance of `Generics`.
fn default() -> Generics {
Generics { params: ThinVec::new(), where_clause: Default::default(), span: DUMMY_SP }
}
}

/// A where-clause in a definition.
#[derive(Clone, Encodable, Decodable, Debug)]
#[derive(Clone, Encodable, Decodable, Debug, Default)]
pub struct WhereClause {
/// `true` if we ate a `where` token.
///
Expand All @@ -420,12 +413,6 @@ impl WhereClause {
}
}

impl Default for WhereClause {
fn default() -> WhereClause {
WhereClause { has_where_token: false, predicates: ThinVec::new(), span: DUMMY_SP }
}
}

/// A single predicate in a where-clause.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct WherePredicate {
Expand Down
18 changes: 3 additions & 15 deletions compiler/rustc_ast_pretty/src/pprust/state/fixup.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use rustc_ast::Expr;
use rustc_ast::util::{classify, parser};

#[derive(Copy, Clone, Debug)]
// The default amount of fixing is minimal fixing. Fixups should be turned on
// in a targeted fashion where needed.
#[derive(Copy, Clone, Debug, Default)]
pub(crate) struct FixupContext {
/// Print expression such that it can be parsed back as a statement
/// consisting of the original expression.
Expand Down Expand Up @@ -93,20 +95,6 @@ pub(crate) struct FixupContext {
parenthesize_exterior_struct_lit: bool,
}

/// The default amount of fixing is minimal fixing. Fixups should be turned on
/// in a targeted fashion where needed.
impl Default for FixupContext {
fn default() -> Self {
FixupContext {
stmt: false,
leftmost_subexpression_in_stmt: false,
match_arm: false,
leftmost_subexpression_in_match_arm: false,
parenthesize_exterior_struct_lit: false,
}
}
}

impl FixupContext {
/// Create the initial fixup for printing an expression in statement
/// position.
Expand Down
18 changes: 15 additions & 3 deletions compiler/rustc_error_codes/src/error_codes/E0665.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,30 @@ The `Default` cannot be derived on an enum for the simple reason that the
compiler doesn't know which value to pick by default whereas it can for a
struct as long as all its fields implement the `Default` trait as well.

If you still want to implement `Default` on your enum, you'll have to do it "by
hand":
For the case where the desired default variant has no data, you can annotate
it with `#[default]` to derive it:

```
#[derive(Default)]
enum Food {
#[default]
Sweet,
Salty,
}
```

In the case where the default variant does have data, you will have to
implement `Default` on your enum "by hand":

```
enum Food {
Sweet(i32),
Salty,
}

impl Default for Food {
fn default() -> Food {
Food::Sweet
Food::Sweet(1)
}
}
```
Loading
Loading