1
Fork 0

Use E0665 for missing #[default] error

Use orphaned error code for the same error it belonged to before.

```
error[E0665]: `#[derive(Default)]` on enum with no `#[default]`
  --> $DIR/macros-nonfatal-errors.rs:42:10
   |
LL |   #[derive(Default)]
   |            ^^^^^^^
LL | / enum NoDeclaredDefault {
LL | |     Foo,
LL | |     Bar,
LL | | }
   | |_- this enum needs a unit variant marked with `#[default]`
   |
   = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
help: make this unit variant default by placing `#[default]` on it
   |
LL |     #[default] Foo,
   |     ~~~~~~~~~~~~~~
help: make this unit variant default by placing `#[default]` on it
   |
LL |     #[default] Bar,
   |     ~~~~~~~~~~~~~~
```
This commit is contained in:
Esteban Küber 2024-12-21 02:43:09 +00:00
parent d520b18316
commit 94812f1c8f
6 changed files with 84 additions and 53 deletions

View file

@ -249,9 +249,9 @@ builtin_macros_naked_functions_testing_attribute =
.label = function marked with testing attribute here .label = function marked with testing attribute here
.naked_attribute = `#[naked]` is incompatible with testing attributes .naked_attribute = `#[naked]` is incompatible with testing attributes
builtin_macros_no_default_variant = no default declared builtin_macros_no_default_variant = `#[derive(Default)]` on enum with no `#[default]`
.help = make a unit variant default by placing `#[default]` above it .label = this enum needs a unit variant marked with `#[default]`
.suggestion = make `{$ident}` default .suggestion = make this unit variant default by placing `#[default]` on it
builtin_macros_non_abi = at least one abi must be provided as an argument to `clobber_abi` builtin_macros_non_abi = at least one abi must be provided as an argument to `clobber_abi`

View file

@ -42,7 +42,9 @@ pub(crate) fn expand_deriving_default(
StaticStruct(_, fields) => { StaticStruct(_, fields) => {
default_struct_substructure(cx, trait_span, substr, fields) default_struct_substructure(cx, trait_span, substr, fields)
} }
StaticEnum(enum_def, _) => default_enum_substructure(cx, trait_span, enum_def), StaticEnum(enum_def, _) => {
default_enum_substructure(cx, trait_span, enum_def, item.span())
}
_ => cx.dcx().span_bug(trait_span, "method in `derive(Default)`"), _ => cx.dcx().span_bug(trait_span, "method in `derive(Default)`"),
} }
})), })),
@ -96,9 +98,10 @@ fn default_enum_substructure(
cx: &ExtCtxt<'_>, cx: &ExtCtxt<'_>,
trait_span: Span, trait_span: Span,
enum_def: &EnumDef, enum_def: &EnumDef,
item_span: Span,
) -> BlockOrExpr { ) -> BlockOrExpr {
let expr = match try { let expr = match try {
let default_variant = extract_default_variant(cx, enum_def, trait_span)?; let default_variant = extract_default_variant(cx, enum_def, trait_span, item_span)?;
validate_default_attribute(cx, default_variant)?; validate_default_attribute(cx, default_variant)?;
default_variant default_variant
} { } {
@ -146,6 +149,7 @@ fn extract_default_variant<'a>(
cx: &ExtCtxt<'_>, cx: &ExtCtxt<'_>,
enum_def: &'a EnumDef, enum_def: &'a EnumDef,
trait_span: Span, trait_span: Span,
item_span: Span,
) -> Result<&'a rustc_ast::Variant, ErrorGuaranteed> { ) -> Result<&'a rustc_ast::Variant, ErrorGuaranteed> {
let default_variants: SmallVec<[_; 1]> = enum_def let default_variants: SmallVec<[_; 1]> = enum_def
.variants .variants
@ -163,9 +167,10 @@ fn extract_default_variant<'a>(
.filter(|variant| !attr::contains_name(&variant.attrs, sym::non_exhaustive)); .filter(|variant| !attr::contains_name(&variant.attrs, sym::non_exhaustive));
let suggs = possible_defaults let suggs = possible_defaults
.map(|v| errors::NoDefaultVariantSugg { span: v.span, ident: v.ident }) .map(|v| errors::NoDefaultVariantSugg { span: v.span.shrink_to_lo() })
.collect(); .collect();
let guar = cx.dcx().emit_err(errors::NoDefaultVariant { span: trait_span, suggs }); let guar =
cx.dcx().emit_err(errors::NoDefaultVariant { span: trait_span, item_span, suggs });
return Err(guar); return Err(guar);
} }

View file

@ -369,26 +369,21 @@ pub(crate) struct DerivePathArgsValue {
} }
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(builtin_macros_no_default_variant)] #[diag(builtin_macros_no_default_variant, code = E0665)]
#[help]
pub(crate) struct NoDefaultVariant { pub(crate) struct NoDefaultVariant {
#[primary_span] #[primary_span]
pub(crate) span: Span, pub(crate) span: Span,
#[label]
pub(crate) item_span: Span,
#[subdiagnostic] #[subdiagnostic]
pub(crate) suggs: Vec<NoDefaultVariantSugg>, pub(crate) suggs: Vec<NoDefaultVariantSugg>,
} }
#[derive(Subdiagnostic)] #[derive(Subdiagnostic)]
#[suggestion( #[suggestion(builtin_macros_suggestion, code = "#[default] ", applicability = "maybe-incorrect")]
builtin_macros_suggestion,
code = "#[default] {ident}",
applicability = "maybe-incorrect",
style = "tool-only"
)]
pub(crate) struct NoDefaultVariantSugg { pub(crate) struct NoDefaultVariantSugg {
#[primary_span] #[primary_span]
pub(crate) span: Span, pub(crate) span: Span,
pub(crate) ident: Ident,
} }
#[derive(Diagnostic)] #[derive(Diagnostic)]

View file

@ -1,10 +1,9 @@
#### Note: this error code is no longer emitted by the compiler. The `Default` trait was derived on an enum without specifying the default
variant.
The `Default` trait was derived on an enum.
Erroneous code example: Erroneous code example:
```compile_fail ```compile_fail,E0665
#[derive(Default)] #[derive(Default)]
enum Food { enum Food {
Sweet, Sweet,
@ -16,8 +15,8 @@ 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 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. struct as long as all its fields implement the `Default` trait as well.
For the case where the desired default variant has no data, you can annotate For the case where the desired default variant has no payload, you can
it with `#[default]` to derive it: annotate it with `#[default]` to derive it:
``` ```
#[derive(Default)] #[derive(Default)]
@ -28,8 +27,8 @@ enum Food {
} }
``` ```
In the case where the default variant does have data, you will have to In the case where the default variant does have a payload, you will have to
implement `Default` on your enum "by hand": implement `Default` on your enum manually:
``` ```
enum Food { enum Food {

View file

@ -39,12 +39,18 @@ enum AttrOnInnerExpression {
Baz, Baz,
} }
#[derive(Default)] //~ ERROR no default declared #[derive(Default)] //~ ERROR `#[derive(Default)]` on enum with no `#[default]`
enum NoDeclaredDefault { enum NoDeclaredDefault {
Foo, Foo,
Bar, Bar,
} }
#[derive(Default)] //~ ERROR `#[derive(Default)]` on enum with no `#[default]`
enum NoDeclaredDefaultWithoutUnitVariant {
Foo(i32),
Bar(i32),
}
#[derive(Default)] //~ ERROR multiple declared defaults #[derive(Default)] //~ ERROR multiple declared defaults
enum MultipleDefaults { enum MultipleDefaults {
#[default] #[default]

View file

@ -46,17 +46,42 @@ LL | Bar([u8; #[default] 1]),
| |
= help: consider a manual implementation of `Default` = help: consider a manual implementation of `Default`
error: no default declared error[E0665]: `#[derive(Default)]` on enum with no `#[default]`
--> $DIR/macros-nonfatal-errors.rs:42:10 --> $DIR/macros-nonfatal-errors.rs:42:10
| |
LL | #[derive(Default)] LL | #[derive(Default)]
| ^^^^^^^ | ^^^^^^^
LL | / enum NoDeclaredDefault {
LL | | Foo,
LL | | Bar,
LL | | }
| |_- this enum needs a unit variant marked with `#[default]`
|
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
help: make this unit variant default by placing `#[default]` on it
|
LL | #[default] Foo,
| ++++++++++
help: make this unit variant default by placing `#[default]` on it
|
LL | #[default] Bar,
| ++++++++++
error[E0665]: `#[derive(Default)]` on enum with no `#[default]`
--> $DIR/macros-nonfatal-errors.rs:48:10
|
LL | #[derive(Default)]
| ^^^^^^^
LL | / enum NoDeclaredDefaultWithoutUnitVariant {
LL | | Foo(i32),
LL | | Bar(i32),
LL | | }
| |_- this enum needs a unit variant marked with `#[default]`
| |
= help: make a unit variant default by placing `#[default]` above it
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
error: multiple declared defaults error: multiple declared defaults
--> $DIR/macros-nonfatal-errors.rs:48:10 --> $DIR/macros-nonfatal-errors.rs:54:10
| |
LL | #[derive(Default)] LL | #[derive(Default)]
| ^^^^^^^ | ^^^^^^^
@ -74,7 +99,7 @@ LL | Baz,
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
error: `#[default]` attribute does not accept a value error: `#[default]` attribute does not accept a value
--> $DIR/macros-nonfatal-errors.rs:60:5 --> $DIR/macros-nonfatal-errors.rs:66:5
| |
LL | #[default = 1] LL | #[default = 1]
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
@ -82,7 +107,7 @@ LL | #[default = 1]
= help: try using `#[default]` = help: try using `#[default]`
error: multiple `#[default]` attributes error: multiple `#[default]` attributes
--> $DIR/macros-nonfatal-errors.rs:68:5 --> $DIR/macros-nonfatal-errors.rs:74:5
| |
LL | #[default] LL | #[default]
| ---------- `#[default]` used here | ---------- `#[default]` used here
@ -93,13 +118,13 @@ LL | Foo,
| |
= note: only one `#[default]` attribute is needed = note: only one `#[default]` attribute is needed
help: try removing this help: try removing this
--> $DIR/macros-nonfatal-errors.rs:67:5 --> $DIR/macros-nonfatal-errors.rs:73:5
| |
LL | #[default] LL | #[default]
| ^^^^^^^^^^ | ^^^^^^^^^^
error: multiple `#[default]` attributes error: multiple `#[default]` attributes
--> $DIR/macros-nonfatal-errors.rs:78:5 --> $DIR/macros-nonfatal-errors.rs:84:5
| |
LL | #[default] LL | #[default]
| ---------- `#[default]` used here | ---------- `#[default]` used here
@ -111,7 +136,7 @@ LL | Foo,
| |
= note: only one `#[default]` attribute is needed = note: only one `#[default]` attribute is needed
help: try removing these help: try removing these
--> $DIR/macros-nonfatal-errors.rs:75:5 --> $DIR/macros-nonfatal-errors.rs:81:5
| |
LL | #[default] LL | #[default]
| ^^^^^^^^^^ | ^^^^^^^^^^
@ -121,7 +146,7 @@ LL | #[default]
| ^^^^^^^^^^ | ^^^^^^^^^^
error: the `#[default]` attribute may only be used on unit enum variants error: the `#[default]` attribute may only be used on unit enum variants
--> $DIR/macros-nonfatal-errors.rs:85:5 --> $DIR/macros-nonfatal-errors.rs:91:5
| |
LL | Foo {}, LL | Foo {},
| ^^^ | ^^^
@ -129,7 +154,7 @@ LL | Foo {},
= help: consider a manual implementation of `Default` = help: consider a manual implementation of `Default`
error: default variant must be exhaustive error: default variant must be exhaustive
--> $DIR/macros-nonfatal-errors.rs:93:5 --> $DIR/macros-nonfatal-errors.rs:99:5
| |
LL | #[non_exhaustive] LL | #[non_exhaustive]
| ----------------- declared `#[non_exhaustive]` here | ----------------- declared `#[non_exhaustive]` here
@ -139,37 +164,37 @@ LL | Foo,
= help: consider a manual implementation of `Default` = help: consider a manual implementation of `Default`
error: asm template must be a string literal error: asm template must be a string literal
--> $DIR/macros-nonfatal-errors.rs:98:10 --> $DIR/macros-nonfatal-errors.rs:104:10
| |
LL | asm!(invalid); LL | asm!(invalid);
| ^^^^^^^ | ^^^^^^^
error: `concat_idents!()` requires ident args error: `concat_idents!()` requires ident args
--> $DIR/macros-nonfatal-errors.rs:101:5 --> $DIR/macros-nonfatal-errors.rs:107:5
| |
LL | concat_idents!("not", "idents"); LL | concat_idents!("not", "idents");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: argument must be a string literal error: argument must be a string literal
--> $DIR/macros-nonfatal-errors.rs:103:17 --> $DIR/macros-nonfatal-errors.rs:109:17
| |
LL | option_env!(invalid); LL | option_env!(invalid);
| ^^^^^^^ | ^^^^^^^
error: expected string literal error: expected string literal
--> $DIR/macros-nonfatal-errors.rs:104:10 --> $DIR/macros-nonfatal-errors.rs:110:10
| |
LL | env!(invalid); LL | env!(invalid);
| ^^^^^^^ | ^^^^^^^
error: `env!()` takes 1 or 2 arguments error: `env!()` takes 1 or 2 arguments
--> $DIR/macros-nonfatal-errors.rs:105:5 --> $DIR/macros-nonfatal-errors.rs:111:5
| |
LL | env!(foo, abr, baz); LL | env!(foo, abr, baz);
| ^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^
error: environment variable `RUST_HOPEFULLY_THIS_DOESNT_EXIST` not defined at compile time error: environment variable `RUST_HOPEFULLY_THIS_DOESNT_EXIST` not defined at compile time
--> $DIR/macros-nonfatal-errors.rs:106:5 --> $DIR/macros-nonfatal-errors.rs:112:5
| |
LL | env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST"); LL | env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -178,7 +203,7 @@ LL | env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST");
= note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
error: format argument must be a string literal error: format argument must be a string literal
--> $DIR/macros-nonfatal-errors.rs:108:13 --> $DIR/macros-nonfatal-errors.rs:114:13
| |
LL | format!(invalid); LL | format!(invalid);
| ^^^^^^^ | ^^^^^^^
@ -189,19 +214,19 @@ LL | format!("{}", invalid);
| +++++ | +++++
error: argument must be a string literal error: argument must be a string literal
--> $DIR/macros-nonfatal-errors.rs:110:14 --> $DIR/macros-nonfatal-errors.rs:116:14
| |
LL | include!(invalid); LL | include!(invalid);
| ^^^^^^^ | ^^^^^^^
error: argument must be a string literal error: argument must be a string literal
--> $DIR/macros-nonfatal-errors.rs:112:18 --> $DIR/macros-nonfatal-errors.rs:118:18
| |
LL | include_str!(invalid); LL | include_str!(invalid);
| ^^^^^^^ | ^^^^^^^
error: couldn't read `$DIR/i'd be quite surprised if a file with this name existed`: $FILE_NOT_FOUND_MSG error: couldn't read `$DIR/i'd be quite surprised if a file with this name existed`: $FILE_NOT_FOUND_MSG
--> $DIR/macros-nonfatal-errors.rs:113:5 --> $DIR/macros-nonfatal-errors.rs:119:5
| |
LL | include_str!("i'd be quite surprised if a file with this name existed"); LL | include_str!("i'd be quite surprised if a file with this name existed");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -209,13 +234,13 @@ LL | include_str!("i'd be quite surprised if a file with this name existed")
= note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info)
error: argument must be a string literal error: argument must be a string literal
--> $DIR/macros-nonfatal-errors.rs:114:20 --> $DIR/macros-nonfatal-errors.rs:120:20
| |
LL | include_bytes!(invalid); LL | include_bytes!(invalid);
| ^^^^^^^ | ^^^^^^^
error: couldn't read `$DIR/i'd be quite surprised if a file with this name existed`: $FILE_NOT_FOUND_MSG error: couldn't read `$DIR/i'd be quite surprised if a file with this name existed`: $FILE_NOT_FOUND_MSG
--> $DIR/macros-nonfatal-errors.rs:115:5 --> $DIR/macros-nonfatal-errors.rs:121:5
| |
LL | include_bytes!("i'd be quite surprised if a file with this name existed"); LL | include_bytes!("i'd be quite surprised if a file with this name existed");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -223,13 +248,13 @@ LL | include_bytes!("i'd be quite surprised if a file with this name existed
= note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: trace_macros! accepts only `true` or `false` error: trace_macros! accepts only `true` or `false`
--> $DIR/macros-nonfatal-errors.rs:117:5 --> $DIR/macros-nonfatal-errors.rs:123:5
| |
LL | trace_macros!(invalid); LL | trace_macros!(invalid);
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
error: default variant must be exhaustive error: default variant must be exhaustive
--> $DIR/macros-nonfatal-errors.rs:127:9 --> $DIR/macros-nonfatal-errors.rs:133:9
| |
LL | #[non_exhaustive] LL | #[non_exhaustive]
| ----------------- declared `#[non_exhaustive]` here | ----------------- declared `#[non_exhaustive]` here
@ -239,10 +264,11 @@ LL | Foo,
= help: consider a manual implementation of `Default` = help: consider a manual implementation of `Default`
error: cannot find macro `llvm_asm` in this scope error: cannot find macro `llvm_asm` in this scope
--> $DIR/macros-nonfatal-errors.rs:99:5 --> $DIR/macros-nonfatal-errors.rs:105:5
| |
LL | llvm_asm!(invalid); LL | llvm_asm!(invalid);
| ^^^^^^^^ | ^^^^^^^^
error: aborting due to 28 previous errors error: aborting due to 29 previous errors
For more information about this error, try `rustc --explain E0665`.