Skip to content

Commit

Permalink
Unrolled build for rust-lang#134364
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#134364 - estebank:derive-docs, r=fmease

Use E0665 for missing `#[default]` on enum and update doc

The docs for E0665 when doing `#[derive(Default]` on an `enum` previously didn't mention `#[default]` at all, or made a distinction between unit variants, that can be annotated, and tuple or struct variants, which cannot.

E0665 was not being emitted, we now use it 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
rust-timer authored Dec 22, 2024
2 parents c113247 + 94812f1 commit 5bc0dd3
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 52 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
25 changes: 18 additions & 7 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,E0665
#[derive(Default)]
enum Food {
Sweet,
Expand All @@ -16,18 +15,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 payload, 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 a payload, you will have to
implement `Default` on your enum manually:

```
enum Food {
Sweet(i32),
Salty,
}
impl Default for Food {
fn default() -> Food {
Food::Sweet
Food::Sweet(1)
}
}
```
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 5bc0dd3

Please sign in to comment.