about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-07-28 05:59:30 +0000
committerbors <bors@rust-lang.org>2021-07-28 05:59:30 +0000
commitaea2e446f09b923d513013743b37b43fca7282dc (patch)
treeac53a52123dd478795393e478e43608b98871609 /src
parent8b50cc9a2c408caef30a1cf950c948509b2f648e (diff)
parent72465b0a32e689cd6a61120479c13b38281108a7 (diff)
downloadrust-aea2e446f09b923d513013743b37b43fca7282dc.tar.gz
rust-aea2e446f09b923d513013743b37b43fca7282dc.zip
Auto merge of #86735 - jhpratt:rfc-3107, r=petrochenkov
Implement RFC 3107: `#[derive(Default)]` on enums with a `#[default]` attribute

This PR implements RFC 3107, which permits `#[derive(Default)]` on enums where a unit variant has a `#[default]` attribute. See comments for current status.
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/deriving/deriving-default-enum.rs19
-rw-r--r--src/test/ui/deriving/deriving-with-helper.rs5
-rw-r--r--src/test/ui/error-codes/E0665.rs8
-rw-r--r--src/test/ui/error-codes/E0665.stderr11
-rw-r--r--src/test/ui/feature-gates/feature-gate-derive_default_enum.rs7
-rw-r--r--src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr13
-rw-r--r--src/test/ui/macros/macros-nonfatal-errors.rs89
-rw-r--r--src/test/ui/macros/macros-nonfatal-errors.stderr155
-rw-r--r--src/test/ui/resolve/issue-2356.rs2
9 files changed, 267 insertions, 42 deletions
diff --git a/src/test/ui/deriving/deriving-default-enum.rs b/src/test/ui/deriving/deriving-default-enum.rs
new file mode 100644
index 00000000000..931ff1a5847
--- /dev/null
+++ b/src/test/ui/deriving/deriving-default-enum.rs
@@ -0,0 +1,19 @@
+// run-pass
+
+#![feature(derive_default_enum)]
+
+// nb: does not impl Default
+#[derive(Debug, PartialEq)]
+struct NotDefault;
+
+#[derive(Debug, Default, PartialEq)]
+enum Foo {
+    #[default]
+    Alpha,
+    #[allow(dead_code)]
+    Beta(NotDefault),
+}
+
+fn main() {
+    assert_eq!(Foo::default(), Foo::Alpha);
+}
diff --git a/src/test/ui/deriving/deriving-with-helper.rs b/src/test/ui/deriving/deriving-with-helper.rs
index ea74a15624c..d8f0b27a2e5 100644
--- a/src/test/ui/deriving/deriving-with-helper.rs
+++ b/src/test/ui/deriving/deriving-with-helper.rs
@@ -5,6 +5,7 @@
 #![feature(lang_items)]
 #![feature(no_core)]
 #![feature(rustc_attrs)]
+#![feature(derive_default_enum)]
 
 #![no_core]
 
@@ -30,7 +31,7 @@ mod default {
 trait Sized {}
 
 #[derive(Default)]
-struct S {
+enum S {
     #[default] // OK
-    field: u8,
+    Foo,
 }
diff --git a/src/test/ui/error-codes/E0665.rs b/src/test/ui/error-codes/E0665.rs
deleted file mode 100644
index cfd42bd9aac..00000000000
--- a/src/test/ui/error-codes/E0665.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-#[derive(Default)] //~ ERROR E0665
-enum Food {
-    Sweet,
-    Salty,
-}
-
-fn main() {
-}
diff --git a/src/test/ui/error-codes/E0665.stderr b/src/test/ui/error-codes/E0665.stderr
deleted file mode 100644
index bb8b3906ca6..00000000000
--- a/src/test/ui/error-codes/E0665.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0665]: `Default` cannot be derived for enums, only structs
-  --> $DIR/E0665.rs:1:10
-   |
-LL | #[derive(Default)]
-   |          ^^^^^^^
-   |
-   = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0665`.
diff --git a/src/test/ui/feature-gates/feature-gate-derive_default_enum.rs b/src/test/ui/feature-gates/feature-gate-derive_default_enum.rs
new file mode 100644
index 00000000000..05a5d4e1422
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-derive_default_enum.rs
@@ -0,0 +1,7 @@
+#[derive(Default)] //~ ERROR deriving `Default` on enums is experimental
+enum Foo {
+    #[default]
+    Alpha,
+}
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr b/src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr
new file mode 100644
index 00000000000..58dd4d508a7
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr
@@ -0,0 +1,13 @@
+error[E0658]: deriving `Default` on enums is experimental
+  --> $DIR/feature-gate-derive_default_enum.rs:1:10
+   |
+LL | #[derive(Default)]
+   |          ^^^^^^^
+   |
+   = note: see issue #86985 <https://github.com/rust-lang/rust/issues/86985> for more information
+   = help: add `#![feature(derive_default_enum)]` to the crate attributes to enable
+   = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/macros/macros-nonfatal-errors.rs b/src/test/ui/macros/macros-nonfatal-errors.rs
index 0a496c9dc3d..faacc6f081d 100644
--- a/src/test/ui/macros/macros-nonfatal-errors.rs
+++ b/src/test/ui/macros/macros-nonfatal-errors.rs
@@ -5,9 +5,94 @@
 
 #![feature(asm, llvm_asm)]
 #![feature(trace_macros, concat_idents)]
+#![feature(stmt_expr_attributes, arbitrary_enum_discriminant)]
+#![feature(derive_default_enum)]
 
-#[derive(Default)] //~ ERROR
-enum OrDeriveThis {}
+#[derive(Default)]
+struct DefaultInnerAttrStruct {
+    #[default] //~ ERROR the `#[default]` attribute may only be used on unit enum variants
+    foo: (),
+}
+
+#[derive(Default)]
+struct DefaultInnerAttrTupleStruct(#[default] ());
+//~^ ERROR the `#[default]` attribute may only be used on unit enum variants
+
+#[derive(Default)]
+#[default] //~ ERROR the `#[default]` attribute may only be used on unit enum variants
+struct DefaultOuterAttrStruct {}
+
+#[derive(Default)]
+#[default] //~ ERROR the `#[default]` attribute may only be used on unit enum variants
+enum DefaultOuterAttrEnum {
+    #[default]
+    Foo,
+}
+
+#[rustfmt::skip] // needs some work to handle this case
+#[repr(u8)]
+#[derive(Default)]
+enum AttrOnInnerExpression {
+    Foo = #[default] 0, //~ ERROR the `#[default]` attribute may only be used on unit enum variants
+    Bar([u8; #[default] 1]), //~ ERROR the `#[default]` attribute may only be used on unit enum variants
+    #[default]
+    Baz,
+}
+
+#[derive(Default)] //~ ERROR no default declared
+enum NoDeclaredDefault {
+    Foo,
+    Bar,
+}
+
+#[derive(Default)] //~ ERROR multiple declared defaults
+enum MultipleDefaults {
+    #[default]
+    Foo,
+    #[default]
+    Bar,
+    #[default]
+    Baz,
+}
+
+#[derive(Default)]
+enum ExtraDeriveTokens {
+    #[default = 1] //~ ERROR `#[default]` attribute does not accept a value
+    Foo,
+}
+
+#[derive(Default)]
+enum TwoDefaultAttrs {
+    #[default]
+    #[default]
+    Foo, //~ERROR multiple `#[default]` attributes
+    Bar,
+}
+
+#[derive(Default)]
+enum ManyDefaultAttrs {
+    #[default]
+    #[default]
+    #[default]
+    #[default]
+    Foo, //~ERROR multiple `#[default]` attributes
+    Bar,
+}
+
+#[derive(Default)]
+enum DefaultHasFields {
+    #[default]
+    Foo {}, //~ ERROR the `#[default]` attribute may only be used on unit enum variants
+    Bar,
+}
+
+#[derive(Default)]
+enum NonExhaustiveDefault {
+    #[default]
+    #[non_exhaustive]
+    Foo, //~ ERROR default variant must be exhaustive
+    Bar,
+}
 
 fn main() {
     asm!(invalid); //~ ERROR
diff --git a/src/test/ui/macros/macros-nonfatal-errors.stderr b/src/test/ui/macros/macros-nonfatal-errors.stderr
index 14058f86639..e0ed8522bf6 100644
--- a/src/test/ui/macros/macros-nonfatal-errors.stderr
+++ b/src/test/ui/macros/macros-nonfatal-errors.stderr
@@ -1,49 +1,169 @@
-error[E0665]: `Default` cannot be derived for enums, only structs
-  --> $DIR/macros-nonfatal-errors.rs:9:10
+error: the `#[default]` attribute may only be used on unit enum variants
+  --> $DIR/macros-nonfatal-errors.rs:13:5
+   |
+LL |     #[default]
+   |     ^^^^^^^^^^
+
+error: the `#[default]` attribute may only be used on unit enum variants
+  --> $DIR/macros-nonfatal-errors.rs:18:36
+   |
+LL | struct DefaultInnerAttrTupleStruct(#[default] ());
+   |                                    ^^^^^^^^^^
+
+error: the `#[default]` attribute may only be used on unit enum variants
+  --> $DIR/macros-nonfatal-errors.rs:22:1
+   |
+LL | #[default]
+   | ^^^^^^^^^^
+
+error: the `#[default]` attribute may only be used on unit enum variants
+  --> $DIR/macros-nonfatal-errors.rs:26:1
+   |
+LL | #[default]
+   | ^^^^^^^^^^
+
+error: the `#[default]` attribute may only be used on unit enum variants
+  --> $DIR/macros-nonfatal-errors.rs:36:11
+   |
+LL |     Foo = #[default] 0,
+   |           ^^^^^^^^^^
+
+error: the `#[default]` attribute may only be used on unit enum variants
+  --> $DIR/macros-nonfatal-errors.rs:37:14
+   |
+LL |     Bar([u8; #[default] 1]),
+   |              ^^^^^^^^^^
+
+error: no default declared
+  --> $DIR/macros-nonfatal-errors.rs:42:10
    |
 LL | #[derive(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)
+
+error: multiple declared defaults
+  --> $DIR/macros-nonfatal-errors.rs:48:10
+   |
+LL | #[derive(Default)]
+   |          ^^^^^^^
+...
+LL |     Foo,
+   |     --- first default
+LL |     #[default]
+LL |     Bar,
+   |     --- additional default
+LL |     #[default]
+LL |     Baz,
+   |     --- additional default
+   |
+   = note: only one variant can be default
    = 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
+   |
+LL |     #[default = 1]
+   |     ^^^^^^^^^^^^^^
+   |
+   = help: try using `#[default]`
+
+error: multiple `#[default]` attributes
+  --> $DIR/macros-nonfatal-errors.rs:68:5
+   |
+LL |     #[default]
+   |     ---------- `#[default]` used here
+LL |     #[default]
+   |     ---------- `#[default]` used again here
+LL |     Foo,
+   |     ^^^
+   |
+   = note: only one `#[default]` attribute is needed
+help: try removing this
+  --> $DIR/macros-nonfatal-errors.rs:67:5
+   |
+LL |     #[default]
+   |     ^^^^^^^^^^
+
+error: multiple `#[default]` attributes
+  --> $DIR/macros-nonfatal-errors.rs:78:5
+   |
+LL |     #[default]
+   |     ---------- `#[default]` used here
+LL |     #[default]
+   |     ---------- `#[default]` used again here
+...
+LL |     Foo,
+   |     ^^^
+   |
+   = note: only one `#[default]` attribute is needed
+help: try removing these
+  --> $DIR/macros-nonfatal-errors.rs:75:5
+   |
+LL |     #[default]
+   |     ^^^^^^^^^^
+LL |     #[default]
+   |     ^^^^^^^^^^
+LL |     #[default]
+   |     ^^^^^^^^^^
+
+error: the `#[default]` attribute may only be used on unit enum variants
+  --> $DIR/macros-nonfatal-errors.rs:85:5
+   |
+LL |     Foo {},
+   |     ^^^
+   |
+   = help: consider a manual implementation of `Default`
+
+error: default variant must be exhaustive
+  --> $DIR/macros-nonfatal-errors.rs:93:5
+   |
+LL |     #[non_exhaustive]
+   |     ----------------- declared `#[non_exhaustive]` here
+LL |     Foo,
+   |     ^^^
+   |
+   = help: consider a manual implementation of `Default`
+
 error: asm template must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:13:10
+  --> $DIR/macros-nonfatal-errors.rs:98:10
    |
 LL |     asm!(invalid);
    |          ^^^^^^^
 
 error: inline assembly must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:14:15
+  --> $DIR/macros-nonfatal-errors.rs:99:15
    |
 LL |     llvm_asm!(invalid);
    |               ^^^^^^^
 
 error: concat_idents! requires ident args.
-  --> $DIR/macros-nonfatal-errors.rs:16:5
+  --> $DIR/macros-nonfatal-errors.rs:101:5
    |
 LL |     concat_idents!("not", "idents");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: argument must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:18:17
+  --> $DIR/macros-nonfatal-errors.rs:103:17
    |
 LL |     option_env!(invalid);
    |                 ^^^^^^^
 
 error: expected string literal
-  --> $DIR/macros-nonfatal-errors.rs:19:10
+  --> $DIR/macros-nonfatal-errors.rs:104:10
    |
 LL |     env!(invalid);
    |          ^^^^^^^
 
 error: expected string literal
-  --> $DIR/macros-nonfatal-errors.rs:20:10
+  --> $DIR/macros-nonfatal-errors.rs:105:10
    |
 LL |     env!(foo, abr, baz);
    |          ^^^
 
 error: environment variable `RUST_HOPEFULLY_THIS_DOESNT_EXIST` not defined
-  --> $DIR/macros-nonfatal-errors.rs:21:5
+  --> $DIR/macros-nonfatal-errors.rs:106:5
    |
 LL |     env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -51,7 +171,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:23:13
+  --> $DIR/macros-nonfatal-errors.rs:108:13
    |
 LL |     format!(invalid);
    |             ^^^^^^^
@@ -62,19 +182,19 @@ LL |     format!("{}", invalid);
    |             ^^^^^
 
 error: argument must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:25:14
+  --> $DIR/macros-nonfatal-errors.rs:110:14
    |
 LL |     include!(invalid);
    |              ^^^^^^^
 
 error: argument must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:27:18
+  --> $DIR/macros-nonfatal-errors.rs:112: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 (os error 2)
-  --> $DIR/macros-nonfatal-errors.rs:28:5
+  --> $DIR/macros-nonfatal-errors.rs:113:5
    |
 LL |     include_str!("i'd be quite surprised if a file with this name existed");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -82,13 +202,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)
 
 error: argument must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:29:20
+  --> $DIR/macros-nonfatal-errors.rs:114: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 (os error 2)
-  --> $DIR/macros-nonfatal-errors.rs:30:5
+  --> $DIR/macros-nonfatal-errors.rs:115:5
    |
 LL |     include_bytes!("i'd be quite surprised if a file with this name existed");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -96,11 +216,10 @@ 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:32:5
+  --> $DIR/macros-nonfatal-errors.rs:117:5
    |
 LL |     trace_macros!(invalid);
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 15 previous errors
+error: aborting due to 27 previous errors
 
-For more information about this error, try `rustc --explain E0665`.
diff --git a/src/test/ui/resolve/issue-2356.rs b/src/test/ui/resolve/issue-2356.rs
index f7b2dd13dcb..fe9bf4d443e 100644
--- a/src/test/ui/resolve/issue-2356.rs
+++ b/src/test/ui/resolve/issue-2356.rs
@@ -29,7 +29,7 @@ impl Clone for Cat {
 impl Default for Cat {
   fn default() -> Self {
     default();
-    //~^ ERROR cannot find function `default`
+    //~^ ERROR cannot find function `default` in this scope [E0425]
     loop {}
   }
 }