Skip to content

Commit

Permalink
Use E0665 for missing #[default] error
Browse files Browse the repository at this point in the history
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,
   |     ~~~~~~~~~~~~~~
```
  • Loading branch information
estebank committed Dec 21, 2024
1 parent d520b18 commit 4bf8948
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 53 deletions.
6 changes: 3 additions & 3 deletions compiler/rustc_builtin_macros/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,9 @@ builtin_macros_naked_functions_testing_attribute =
.label = function marked with testing attribute here
.naked_attribute = `#[naked]` is incompatible with testing attributes
builtin_macros_no_default_variant = no default declared
.help = make a unit variant default by placing `#[default]` above it
.suggestion = make `{$ident}` default
builtin_macros_no_default_variant = `#[derive(Default)]` on enum with no `#[default]`
.label = this enum needs a unit variant marked with `#[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`
Expand Down
13 changes: 9 additions & 4 deletions compiler/rustc_builtin_macros/src/deriving/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ pub(crate) fn expand_deriving_default(
StaticStruct(_, 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)`"),
}
})),
Expand Down Expand Up @@ -96,9 +98,10 @@ fn default_enum_substructure(
cx: &ExtCtxt<'_>,
trait_span: Span,
enum_def: &EnumDef,
item_span: Span,
) -> BlockOrExpr {
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)?;
default_variant
} {
Expand Down Expand Up @@ -146,6 +149,7 @@ fn extract_default_variant<'a>(
cx: &ExtCtxt<'_>,
enum_def: &'a EnumDef,
trait_span: Span,
item_span: Span,
) -> Result<&'a rustc_ast::Variant, ErrorGuaranteed> {
let default_variants: SmallVec<[_; 1]> = enum_def
.variants
Expand All @@ -163,9 +167,10 @@ fn extract_default_variant<'a>(
.filter(|variant| !attr::contains_name(&variant.attrs, sym::non_exhaustive));

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();
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);
}
Expand Down
13 changes: 4 additions & 9 deletions compiler/rustc_builtin_macros/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,26 +369,21 @@ pub(crate) struct DerivePathArgsValue {
}

#[derive(Diagnostic)]
#[diag(builtin_macros_no_default_variant)]
#[help]
#[diag(builtin_macros_no_default_variant, code = E0665)]
pub(crate) struct NoDefaultVariant {
#[primary_span]
pub(crate) span: Span,
#[label]
pub(crate) item_span: Span,
#[subdiagnostic]
pub(crate) suggs: Vec<NoDefaultVariantSugg>,
}

#[derive(Subdiagnostic)]
#[suggestion(
builtin_macros_suggestion,
code = "#[default] {ident}",
applicability = "maybe-incorrect",
style = "tool-only"
)]
#[suggestion(builtin_macros_suggestion, code = "#[default] ", applicability = "maybe-incorrect")]
pub(crate) struct NoDefaultVariantSugg {
#[primary_span]
pub(crate) span: Span,
pub(crate) ident: Ident,
}

#[derive(Diagnostic)]
Expand Down
15 changes: 7 additions & 8 deletions compiler/rustc_error_codes/src/error_codes/E0665.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
#### Note: this error code is no longer emitted by the compiler.

The `Default` trait was derived on an enum.
The `Default` trait was derived on an enum without specifying the default
variant.

Erroneous code example:

```compile_fail
```compile_fail,ignore
#[derive(Default)]
enum Food {
Sweet,
Expand All @@ -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
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
it with `#[default]` to derive it:
For the case where the desired default variant has no payload, you can
annotate it with `#[default]` to derive it:

```
#[derive(Default)]
Expand All @@ -28,8 +27,8 @@ enum Food {
}
```

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

```
enum Food {
Expand Down
8 changes: 7 additions & 1 deletion tests/ui/macros/macros-nonfatal-errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,18 @@ enum AttrOnInnerExpression {
Baz,
}

#[derive(Default)] //~ ERROR no default declared
#[derive(Default)] //~ ERROR `#[derive(Default)]` on enum with no `#[default]`
enum NoDeclaredDefault {
Foo,
Bar,
}

#[derive(Default)] //~ ERROR `#[derive(Default)]` on enum with no `#[default]`
enum NoDeclaredDefaultWithoutUnitVariant {
Foo(i32),
Bar(i32),
}

#[derive(Default)] //~ ERROR multiple declared defaults
enum MultipleDefaults {
#[default]
Expand Down
82 changes: 54 additions & 28 deletions tests/ui/macros/macros-nonfatal-errors.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,43 @@ LL | Bar([u8; #[default] 1]),
|
= 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
|
LL | #[derive(Default)]
| ^^^^^^^
LL | #[derive(Default)]
| ^^^^^^^
LL | / enum NoDeclaredDefault {
LL | | Foo,
LL | | Bar,
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)
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: multiple declared defaults
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]`
|
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)

error: multiple declared defaults
--> $DIR/macros-nonfatal-errors.rs:54:10
|
LL | #[derive(Default)]
| ^^^^^^^
...
Expand All @@ -74,15 +99,15 @@ LL | Baz,
= 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
--> $DIR/macros-nonfatal-errors.rs:60:5
--> $DIR/macros-nonfatal-errors.rs:66:5
|
LL | #[default = 1]
| ^^^^^^^^^^^^^^
|
= help: try using `#[default]`

error: multiple `#[default]` attributes
--> $DIR/macros-nonfatal-errors.rs:68:5
--> $DIR/macros-nonfatal-errors.rs:74:5
|
LL | #[default]
| ---------- `#[default]` used here
Expand All @@ -93,13 +118,13 @@ LL | Foo,
|
= note: only one `#[default]` attribute is needed
help: try removing this
--> $DIR/macros-nonfatal-errors.rs:67:5
--> $DIR/macros-nonfatal-errors.rs:73:5
|
LL | #[default]
| ^^^^^^^^^^

error: multiple `#[default]` attributes
--> $DIR/macros-nonfatal-errors.rs:78:5
--> $DIR/macros-nonfatal-errors.rs:84:5
|
LL | #[default]
| ---------- `#[default]` used here
Expand All @@ -111,7 +136,7 @@ LL | Foo,
|
= note: only one `#[default]` attribute is needed
help: try removing these
--> $DIR/macros-nonfatal-errors.rs:75:5
--> $DIR/macros-nonfatal-errors.rs:81:5
|
LL | #[default]
| ^^^^^^^^^^
Expand All @@ -121,15 +146,15 @@ LL | #[default]
| ^^^^^^^^^^

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 {},
| ^^^
|
= help: consider a manual implementation of `Default`

error: default variant must be exhaustive
--> $DIR/macros-nonfatal-errors.rs:93:5
--> $DIR/macros-nonfatal-errors.rs:99:5
|
LL | #[non_exhaustive]
| ----------------- declared `#[non_exhaustive]` here
Expand All @@ -139,37 +164,37 @@ LL | Foo,
= help: consider a manual implementation of `Default`

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);
| ^^^^^^^

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");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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);
| ^^^^^^^

error: expected string literal
--> $DIR/macros-nonfatal-errors.rs:104:10
--> $DIR/macros-nonfatal-errors.rs:110:10
|
LL | env!(invalid);
| ^^^^^^^

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);
| ^^^^^^^^^^^^^^^^^^^

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");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -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)

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);
| ^^^^^^^
Expand All @@ -189,47 +214,47 @@ LL | format!("{}", invalid);
| +++++

error: argument must be a string literal
--> $DIR/macros-nonfatal-errors.rs:110:14
--> $DIR/macros-nonfatal-errors.rs:116:14
|
LL | include!(invalid);
| ^^^^^^^

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);
| ^^^^^^^

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");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= 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
--> $DIR/macros-nonfatal-errors.rs:114:20
--> $DIR/macros-nonfatal-errors.rs:120:20
|
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
--> $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");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= 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`
--> $DIR/macros-nonfatal-errors.rs:117:5
--> $DIR/macros-nonfatal-errors.rs:123:5
|
LL | trace_macros!(invalid);
| ^^^^^^^^^^^^^^^^^^^^^^

error: default variant must be exhaustive
--> $DIR/macros-nonfatal-errors.rs:127:9
--> $DIR/macros-nonfatal-errors.rs:133:9
|
LL | #[non_exhaustive]
| ----------------- declared `#[non_exhaustive]` here
Expand All @@ -239,10 +264,11 @@ LL | Foo,
= help: consider a manual implementation of `Default`

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);
| ^^^^^^^^

error: aborting due to 28 previous errors
error: aborting due to 29 previous errors

For more information about this error, try `rustc --explain E0665`.

0 comments on commit 4bf8948

Please sign in to comment.