summaryrefslogtreecommitdiffstats
path: root/src/test/ui/deriving
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/test/ui/deriving/auxiliary/derive-no-std.rs29
-rw-r--r--src/test/ui/deriving/derive-no-std.rs12
-rw-r--r--src/test/ui/deriving/derive-partialord-correctness.rs9
-rw-r--r--src/test/ui/deriving/deriving-all-codegen.rs106
-rw-r--r--src/test/ui/deriving/deriving-all-codegen.stdout1113
-rw-r--r--src/test/ui/deriving/deriving-associated-types.rs199
-rw-r--r--src/test/ui/deriving/deriving-bounds.rs5
-rw-r--r--src/test/ui/deriving/deriving-clone-array.rs10
-rw-r--r--src/test/ui/deriving/deriving-clone-enum.rs14
-rw-r--r--src/test/ui/deriving/deriving-clone-generic-enum.rs14
-rw-r--r--src/test/ui/deriving/deriving-clone-generic-struct.rs15
-rw-r--r--src/test/ui/deriving/deriving-clone-generic-tuple-struct.rs10
-rw-r--r--src/test/ui/deriving/deriving-clone-struct.rs28
-rw-r--r--src/test/ui/deriving/deriving-clone-tuple-struct.rs9
-rw-r--r--src/test/ui/deriving/deriving-cmp-generic-enum.rs44
-rw-r--r--src/test/ui/deriving/deriving-cmp-generic-struct-enum.rs48
-rw-r--r--src/test/ui/deriving/deriving-cmp-generic-struct.rs40
-rw-r--r--src/test/ui/deriving/deriving-cmp-generic-tuple-struct.rs38
-rw-r--r--src/test/ui/deriving/deriving-cmp-shortcircuit.rs37
-rw-r--r--src/test/ui/deriving/deriving-copyclone.rs38
-rw-r--r--src/test/ui/deriving/deriving-default-box.rs13
-rw-r--r--src/test/ui/deriving/deriving-default-enum.rs17
-rw-r--r--src/test/ui/deriving/deriving-enum-single-variant.rs12
-rw-r--r--src/test/ui/deriving/deriving-eq-ord-boxed-slice.rs15
-rw-r--r--src/test/ui/deriving/deriving-hash.rs76
-rw-r--r--src/test/ui/deriving/deriving-in-fn.rs13
-rw-r--r--src/test/ui/deriving/deriving-in-macro.rs16
-rw-r--r--src/test/ui/deriving/deriving-meta-multiple.rs26
-rw-r--r--src/test/ui/deriving/deriving-meta.rs23
-rw-r--r--src/test/ui/deriving/deriving-self-lifetime-totalord-totaleq.rs16
-rw-r--r--src/test/ui/deriving/deriving-show-2.rs54
-rw-r--r--src/test/ui/deriving/deriving-show.rs35
-rw-r--r--src/test/ui/deriving/deriving-via-extension-c-enum.rs17
-rw-r--r--src/test/ui/deriving/deriving-via-extension-enum.rs16
-rw-r--r--src/test/ui/deriving/deriving-via-extension-hash-enum.rs17
-rw-r--r--src/test/ui/deriving/deriving-via-extension-hash-struct.rs12
-rw-r--r--src/test/ui/deriving/deriving-via-extension-struct-empty.rs8
-rw-r--r--src/test/ui/deriving/deriving-via-extension-struct-like-enum-variant.rs13
-rw-r--r--src/test/ui/deriving/deriving-via-extension-struct-tuple.rs17
-rw-r--r--src/test/ui/deriving/deriving-via-extension-struct.rs16
-rw-r--r--src/test/ui/deriving/deriving-via-extension-type-params.rs16
-rw-r--r--src/test/ui/deriving/deriving-with-helper.rs36
-rw-r--r--src/test/ui/deriving/deriving-with-repr-packed.rs36
-rw-r--r--src/test/ui/deriving/issue-19358.rs23
-rw-r--r--src/test/ui/deriving/issue-3935.rs13
-rw-r--r--src/test/ui/deriving/issue-58319.rs622
-rw-r--r--src/test/ui/deriving/issue-6341.rs11
-rw-r--r--src/test/ui/deriving/issue-89188-gat-hrtb.rs39
48 files changed, 3046 insertions, 0 deletions
diff --git a/src/test/ui/deriving/auxiliary/derive-no-std.rs b/src/test/ui/deriving/auxiliary/derive-no-std.rs
new file mode 100644
index 000000000..3893dc1be
--- /dev/null
+++ b/src/test/ui/deriving/auxiliary/derive-no-std.rs
@@ -0,0 +1,29 @@
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
+#![no_std]
+
+// Issue #16803
+
+#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord,
+ Debug, Default, Copy)]
+pub struct Foo {
+ pub x: u32,
+}
+
+#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord,
+ Debug, Copy)]
+pub enum Bar {
+ Qux,
+ Quux(u32),
+}
+
+#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord,
+ Debug, Copy)]
+pub enum Void {}
+#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord,
+ Debug, Copy)]
+pub struct Empty;
+#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord,
+ Debug, Copy)]
+pub struct AlsoEmpty {}
diff --git a/src/test/ui/deriving/derive-no-std.rs b/src/test/ui/deriving/derive-no-std.rs
new file mode 100644
index 000000000..74c73b99c
--- /dev/null
+++ b/src/test/ui/deriving/derive-no-std.rs
@@ -0,0 +1,12 @@
+// run-pass
+// aux-build:derive-no-std.rs
+
+extern crate derive_no_std;
+use derive_no_std::*;
+
+fn main() {
+ let f = Foo { x: 0 };
+ assert_eq!(f.clone(), Foo::default());
+
+ assert!(Bar::Qux < Bar::Quux(42));
+}
diff --git a/src/test/ui/deriving/derive-partialord-correctness.rs b/src/test/ui/deriving/derive-partialord-correctness.rs
new file mode 100644
index 000000000..36763eda1
--- /dev/null
+++ b/src/test/ui/deriving/derive-partialord-correctness.rs
@@ -0,0 +1,9 @@
+// run-pass
+// Original issue: #49650
+
+#[derive(PartialOrd, PartialEq)]
+struct FloatWrapper(f64);
+
+fn main() {
+ assert!((0.0 / 0.0 >= 0.0) == (FloatWrapper(0.0 / 0.0) >= FloatWrapper(0.0)))
+}
diff --git a/src/test/ui/deriving/deriving-all-codegen.rs b/src/test/ui/deriving/deriving-all-codegen.rs
new file mode 100644
index 000000000..aef79ae8a
--- /dev/null
+++ b/src/test/ui/deriving/deriving-all-codegen.rs
@@ -0,0 +1,106 @@
+// check-pass
+// compile-flags: -Zunpretty=expanded
+// edition:2021
+//
+// This test checks the code generated for all[*] the builtin derivable traits
+// on a variety of structs and enums. It protects against accidental changes to
+// the generated code, and makes deliberate changes to the generated code
+// easier to review.
+//
+// [*] It excludes `Copy` in some cases, because that changes the code
+// generated for `Clone`.
+//
+// [*] It excludes `RustcEncodable` and `RustDecodable`, which are obsolete and
+// also require the `rustc_serialize` crate.
+
+#![crate_type = "lib"]
+#![allow(dead_code)]
+#![allow(deprecated)]
+
+// Empty struct.
+#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
+struct Empty;
+
+// A basic struct.
+#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
+struct Point {
+ x: u32,
+ y: u32,
+}
+
+// A large struct.
+#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
+struct Big {
+ b1: u32, b2: u32, b3: u32, b4: u32, b5: u32, b6: u32, b7: u32, b8: u32,
+}
+
+// A struct with an unsized field. Some derives are not usable in this case.
+#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
+struct Unsized([u32]);
+
+// A packed tuple struct that impls `Copy`.
+#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
+#[repr(packed)]
+struct PackedCopy(u32);
+
+// A packed tuple struct that does not impl `Copy`. Note that the alignment of
+// the field must be 1 for this code to be valid. Otherwise it triggers an
+// error "`#[derive]` can't be used on a `#[repr(packed)]` struct that does not
+// derive Copy (error E0133)" at MIR building time. This is a weird case and
+// it's possible that this struct is not supposed to work, but for now it does.
+#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
+#[repr(packed)]
+struct PackedNonCopy(u8);
+
+// An empty enum.
+#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
+enum Enum0 {}
+
+// A single-variant enum.
+#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
+enum Enum1 {
+ Single { x: u32 }
+}
+
+// A C-like, fieldless enum with a single variant.
+#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
+enum Fieldless1 {
+ #[default]
+ A,
+}
+
+// A C-like, fieldless enum.
+#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
+enum Fieldless {
+ #[default]
+ A,
+ B,
+ C,
+}
+
+// An enum with multiple fieldless and fielded variants.
+#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
+enum Mixed {
+ #[default]
+ P,
+ Q,
+ R(u32),
+ S { d1: u32, d2: u32 },
+}
+
+// An enum with no fieldless variants. Note that `Default` cannot be derived
+// for this enum.
+#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
+enum Fielded {
+ X(u32),
+ Y(bool),
+ Z(Option<i32>),
+}
+
+// A union. Most builtin traits are not derivable for unions.
+#[derive(Clone, Copy)]
+pub union Union {
+ pub b: bool,
+ pub u: u32,
+ pub i: i32,
+}
diff --git a/src/test/ui/deriving/deriving-all-codegen.stdout b/src/test/ui/deriving/deriving-all-codegen.stdout
new file mode 100644
index 000000000..21fe663f0
--- /dev/null
+++ b/src/test/ui/deriving/deriving-all-codegen.stdout
@@ -0,0 +1,1113 @@
+#![feature(prelude_import)]
+// check-pass
+// compile-flags: -Zunpretty=expanded
+// edition:2021
+//
+// This test checks the code generated for all[*] the builtin derivable traits
+// on a variety of structs and enums. It protects against accidental changes to
+// the generated code, and makes deliberate changes to the generated code
+// easier to review.
+//
+// [*] It excludes `Copy` in some cases, because that changes the code
+// generated for `Clone`.
+//
+// [*] It excludes `RustcEncodable` and `RustDecodable`, which are obsolete and
+// also require the `rustc_serialize` crate.
+
+#![crate_type = "lib"]
+#![allow(dead_code)]
+#![allow(deprecated)]
+#[prelude_import]
+use std::prelude::rust_2021::*;
+#[macro_use]
+extern crate std;
+
+// Empty struct.
+struct Empty;
+#[automatically_derived]
+impl ::core::clone::Clone for Empty {
+ #[inline]
+ fn clone(&self) -> Empty { *self }
+}
+#[automatically_derived]
+impl ::core::marker::Copy for Empty { }
+#[automatically_derived]
+impl ::core::fmt::Debug for Empty {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
+ ::core::fmt::Formatter::write_str(f, "Empty")
+ }
+}
+#[automatically_derived]
+impl ::core::default::Default for Empty {
+ #[inline]
+ fn default() -> Empty { Empty {} }
+}
+#[automatically_derived]
+impl ::core::hash::Hash for Empty {
+ fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {}
+}
+impl ::core::marker::StructuralPartialEq for Empty {}
+#[automatically_derived]
+impl ::core::cmp::PartialEq for Empty {
+ #[inline]
+ fn eq(&self, other: &Empty) -> bool { true }
+}
+impl ::core::marker::StructuralEq for Empty {}
+#[automatically_derived]
+impl ::core::cmp::Eq for Empty {
+ #[inline]
+ #[doc(hidden)]
+ #[no_coverage]
+ fn assert_receiver_is_total_eq(&self) -> () {}
+}
+#[automatically_derived]
+impl ::core::cmp::PartialOrd for Empty {
+ #[inline]
+ fn partial_cmp(&self, other: &Empty)
+ -> ::core::option::Option<::core::cmp::Ordering> {
+ ::core::option::Option::Some(::core::cmp::Ordering::Equal)
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::Ord for Empty {
+ #[inline]
+ fn cmp(&self, other: &Empty) -> ::core::cmp::Ordering {
+ ::core::cmp::Ordering::Equal
+ }
+}
+
+// A basic struct.
+struct Point {
+ x: u32,
+ y: u32,
+}
+#[automatically_derived]
+impl ::core::clone::Clone for Point {
+ #[inline]
+ fn clone(&self) -> Point {
+ let _: ::core::clone::AssertParamIsClone<u32>;
+ *self
+ }
+}
+#[automatically_derived]
+impl ::core::marker::Copy for Point { }
+#[automatically_derived]
+impl ::core::fmt::Debug for Point {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
+ ::core::fmt::Formatter::debug_struct_field2_finish(f, "Point", "x",
+ &&self.x, "y", &&self.y)
+ }
+}
+#[automatically_derived]
+impl ::core::default::Default for Point {
+ #[inline]
+ fn default() -> Point {
+ Point {
+ x: ::core::default::Default::default(),
+ y: ::core::default::Default::default(),
+ }
+ }
+}
+#[automatically_derived]
+impl ::core::hash::Hash for Point {
+ fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
+ ::core::hash::Hash::hash(&self.x, state);
+ ::core::hash::Hash::hash(&self.y, state)
+ }
+}
+impl ::core::marker::StructuralPartialEq for Point {}
+#[automatically_derived]
+impl ::core::cmp::PartialEq for Point {
+ #[inline]
+ fn eq(&self, other: &Point) -> bool {
+ self.x == other.x && self.y == other.y
+ }
+ #[inline]
+ fn ne(&self, other: &Point) -> bool {
+ self.x != other.x || self.y != other.y
+ }
+}
+impl ::core::marker::StructuralEq for Point {}
+#[automatically_derived]
+impl ::core::cmp::Eq for Point {
+ #[inline]
+ #[doc(hidden)]
+ #[no_coverage]
+ fn assert_receiver_is_total_eq(&self) -> () {
+ let _: ::core::cmp::AssertParamIsEq<u32>;
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::PartialOrd for Point {
+ #[inline]
+ fn partial_cmp(&self, other: &Point)
+ -> ::core::option::Option<::core::cmp::Ordering> {
+ match ::core::cmp::PartialOrd::partial_cmp(&self.x, &other.x) {
+ ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
+ ::core::cmp::PartialOrd::partial_cmp(&self.y, &other.y),
+ cmp => cmp,
+ }
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::Ord for Point {
+ #[inline]
+ fn cmp(&self, other: &Point) -> ::core::cmp::Ordering {
+ match ::core::cmp::Ord::cmp(&self.x, &other.x) {
+ ::core::cmp::Ordering::Equal =>
+ ::core::cmp::Ord::cmp(&self.y, &other.y),
+ cmp => cmp,
+ }
+ }
+}
+
+// A large struct.
+struct Big {
+ b1: u32,
+ b2: u32,
+ b3: u32,
+ b4: u32,
+ b5: u32,
+ b6: u32,
+ b7: u32,
+ b8: u32,
+}
+#[automatically_derived]
+impl ::core::clone::Clone for Big {
+ #[inline]
+ fn clone(&self) -> Big {
+ Big {
+ b1: ::core::clone::Clone::clone(&self.b1),
+ b2: ::core::clone::Clone::clone(&self.b2),
+ b3: ::core::clone::Clone::clone(&self.b3),
+ b4: ::core::clone::Clone::clone(&self.b4),
+ b5: ::core::clone::Clone::clone(&self.b5),
+ b6: ::core::clone::Clone::clone(&self.b6),
+ b7: ::core::clone::Clone::clone(&self.b7),
+ b8: ::core::clone::Clone::clone(&self.b8),
+ }
+ }
+}
+#[automatically_derived]
+impl ::core::fmt::Debug for Big {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
+ let names: &'static _ =
+ &["b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8"];
+ let values: &[&dyn ::core::fmt::Debug] =
+ &[&&self.b1, &&self.b2, &&self.b3, &&self.b4, &&self.b5,
+ &&self.b6, &&self.b7, &&self.b8];
+ ::core::fmt::Formatter::debug_struct_fields_finish(f, "Big", names,
+ values)
+ }
+}
+#[automatically_derived]
+impl ::core::default::Default for Big {
+ #[inline]
+ fn default() -> Big {
+ Big {
+ b1: ::core::default::Default::default(),
+ b2: ::core::default::Default::default(),
+ b3: ::core::default::Default::default(),
+ b4: ::core::default::Default::default(),
+ b5: ::core::default::Default::default(),
+ b6: ::core::default::Default::default(),
+ b7: ::core::default::Default::default(),
+ b8: ::core::default::Default::default(),
+ }
+ }
+}
+#[automatically_derived]
+impl ::core::hash::Hash for Big {
+ fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
+ ::core::hash::Hash::hash(&self.b1, state);
+ ::core::hash::Hash::hash(&self.b2, state);
+ ::core::hash::Hash::hash(&self.b3, state);
+ ::core::hash::Hash::hash(&self.b4, state);
+ ::core::hash::Hash::hash(&self.b5, state);
+ ::core::hash::Hash::hash(&self.b6, state);
+ ::core::hash::Hash::hash(&self.b7, state);
+ ::core::hash::Hash::hash(&self.b8, state)
+ }
+}
+impl ::core::marker::StructuralPartialEq for Big {}
+#[automatically_derived]
+impl ::core::cmp::PartialEq for Big {
+ #[inline]
+ fn eq(&self, other: &Big) -> bool {
+ self.b1 == other.b1 && self.b2 == other.b2 && self.b3 == other.b3 &&
+ self.b4 == other.b4 && self.b5 == other.b5 &&
+ self.b6 == other.b6 && self.b7 == other.b7 &&
+ self.b8 == other.b8
+ }
+ #[inline]
+ fn ne(&self, other: &Big) -> bool {
+ self.b1 != other.b1 || self.b2 != other.b2 || self.b3 != other.b3 ||
+ self.b4 != other.b4 || self.b5 != other.b5 ||
+ self.b6 != other.b6 || self.b7 != other.b7 ||
+ self.b8 != other.b8
+ }
+}
+impl ::core::marker::StructuralEq for Big {}
+#[automatically_derived]
+impl ::core::cmp::Eq for Big {
+ #[inline]
+ #[doc(hidden)]
+ #[no_coverage]
+ fn assert_receiver_is_total_eq(&self) -> () {
+ let _: ::core::cmp::AssertParamIsEq<u32>;
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::PartialOrd for Big {
+ #[inline]
+ fn partial_cmp(&self, other: &Big)
+ -> ::core::option::Option<::core::cmp::Ordering> {
+ match ::core::cmp::PartialOrd::partial_cmp(&self.b1, &other.b1) {
+ ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
+ match ::core::cmp::PartialOrd::partial_cmp(&self.b2,
+ &other.b2) {
+ ::core::option::Option::Some(::core::cmp::Ordering::Equal)
+ =>
+ match ::core::cmp::PartialOrd::partial_cmp(&self.b3,
+ &other.b3) {
+ ::core::option::Option::Some(::core::cmp::Ordering::Equal)
+ =>
+ match ::core::cmp::PartialOrd::partial_cmp(&self.b4,
+ &other.b4) {
+ ::core::option::Option::Some(::core::cmp::Ordering::Equal)
+ =>
+ match ::core::cmp::PartialOrd::partial_cmp(&self.b5,
+ &other.b5) {
+ ::core::option::Option::Some(::core::cmp::Ordering::Equal)
+ =>
+ match ::core::cmp::PartialOrd::partial_cmp(&self.b6,
+ &other.b6) {
+ ::core::option::Option::Some(::core::cmp::Ordering::Equal)
+ =>
+ match ::core::cmp::PartialOrd::partial_cmp(&self.b7,
+ &other.b7) {
+ ::core::option::Option::Some(::core::cmp::Ordering::Equal)
+ =>
+ ::core::cmp::PartialOrd::partial_cmp(&self.b8, &other.b8),
+ cmp => cmp,
+ },
+ cmp => cmp,
+ },
+ cmp => cmp,
+ },
+ cmp => cmp,
+ },
+ cmp => cmp,
+ },
+ cmp => cmp,
+ },
+ cmp => cmp,
+ }
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::Ord for Big {
+ #[inline]
+ fn cmp(&self, other: &Big) -> ::core::cmp::Ordering {
+ match ::core::cmp::Ord::cmp(&self.b1, &other.b1) {
+ ::core::cmp::Ordering::Equal =>
+ match ::core::cmp::Ord::cmp(&self.b2, &other.b2) {
+ ::core::cmp::Ordering::Equal =>
+ match ::core::cmp::Ord::cmp(&self.b3, &other.b3) {
+ ::core::cmp::Ordering::Equal =>
+ match ::core::cmp::Ord::cmp(&self.b4, &other.b4) {
+ ::core::cmp::Ordering::Equal =>
+ match ::core::cmp::Ord::cmp(&self.b5, &other.b5) {
+ ::core::cmp::Ordering::Equal =>
+ match ::core::cmp::Ord::cmp(&self.b6, &other.b6) {
+ ::core::cmp::Ordering::Equal =>
+ match ::core::cmp::Ord::cmp(&self.b7, &other.b7) {
+ ::core::cmp::Ordering::Equal =>
+ ::core::cmp::Ord::cmp(&self.b8, &other.b8),
+ cmp => cmp,
+ },
+ cmp => cmp,
+ },
+ cmp => cmp,
+ },
+ cmp => cmp,
+ },
+ cmp => cmp,
+ },
+ cmp => cmp,
+ },
+ cmp => cmp,
+ }
+ }
+}
+
+// A struct with an unsized field. Some derives are not usable in this case.
+struct Unsized([u32]);
+#[automatically_derived]
+impl ::core::fmt::Debug for Unsized {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
+ ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Unsized",
+ &&self.0)
+ }
+}
+#[automatically_derived]
+impl ::core::hash::Hash for Unsized {
+ fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
+ ::core::hash::Hash::hash(&self.0, state)
+ }
+}
+impl ::core::marker::StructuralPartialEq for Unsized {}
+#[automatically_derived]
+impl ::core::cmp::PartialEq for Unsized {
+ #[inline]
+ fn eq(&self, other: &Unsized) -> bool { self.0 == other.0 }
+ #[inline]
+ fn ne(&self, other: &Unsized) -> bool { self.0 != other.0 }
+}
+impl ::core::marker::StructuralEq for Unsized {}
+#[automatically_derived]
+impl ::core::cmp::Eq for Unsized {
+ #[inline]
+ #[doc(hidden)]
+ #[no_coverage]
+ fn assert_receiver_is_total_eq(&self) -> () {
+ let _: ::core::cmp::AssertParamIsEq<[u32]>;
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::PartialOrd for Unsized {
+ #[inline]
+ fn partial_cmp(&self, other: &Unsized)
+ -> ::core::option::Option<::core::cmp::Ordering> {
+ ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::Ord for Unsized {
+ #[inline]
+ fn cmp(&self, other: &Unsized) -> ::core::cmp::Ordering {
+ ::core::cmp::Ord::cmp(&self.0, &other.0)
+ }
+}
+
+// A packed tuple struct that impls `Copy`.
+#[repr(packed)]
+struct PackedCopy(u32);
+#[automatically_derived]
+impl ::core::clone::Clone for PackedCopy {
+ #[inline]
+ fn clone(&self) -> PackedCopy {
+ let _: ::core::clone::AssertParamIsClone<u32>;
+ *self
+ }
+}
+#[automatically_derived]
+impl ::core::marker::Copy for PackedCopy { }
+#[automatically_derived]
+impl ::core::fmt::Debug for PackedCopy {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
+ ::core::fmt::Formatter::debug_tuple_field1_finish(f, "PackedCopy",
+ &&{ self.0 })
+ }
+}
+#[automatically_derived]
+impl ::core::default::Default for PackedCopy {
+ #[inline]
+ fn default() -> PackedCopy {
+ PackedCopy(::core::default::Default::default())
+ }
+}
+#[automatically_derived]
+impl ::core::hash::Hash for PackedCopy {
+ fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
+ ::core::hash::Hash::hash(&{ self.0 }, state)
+ }
+}
+impl ::core::marker::StructuralPartialEq for PackedCopy {}
+#[automatically_derived]
+impl ::core::cmp::PartialEq for PackedCopy {
+ #[inline]
+ fn eq(&self, other: &PackedCopy) -> bool { { self.0 } == { other.0 } }
+ #[inline]
+ fn ne(&self, other: &PackedCopy) -> bool { { self.0 } != { other.0 } }
+}
+impl ::core::marker::StructuralEq for PackedCopy {}
+#[automatically_derived]
+impl ::core::cmp::Eq for PackedCopy {
+ #[inline]
+ #[doc(hidden)]
+ #[no_coverage]
+ fn assert_receiver_is_total_eq(&self) -> () {
+ let _: ::core::cmp::AssertParamIsEq<u32>;
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::PartialOrd for PackedCopy {
+ #[inline]
+ fn partial_cmp(&self, other: &PackedCopy)
+ -> ::core::option::Option<::core::cmp::Ordering> {
+ ::core::cmp::PartialOrd::partial_cmp(&{ self.0 }, &{ other.0 })
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::Ord for PackedCopy {
+ #[inline]
+ fn cmp(&self, other: &PackedCopy) -> ::core::cmp::Ordering {
+ ::core::cmp::Ord::cmp(&{ self.0 }, &{ other.0 })
+ }
+}
+
+// A packed tuple struct that does not impl `Copy`. Note that the alignment of
+// the field must be 1 for this code to be valid. Otherwise it triggers an
+// error "`#[derive]` can't be used on a `#[repr(packed)]` struct that does not
+// derive Copy (error E0133)" at MIR building time. This is a weird case and
+// it's possible that this struct is not supposed to work, but for now it does.
+#[repr(packed)]
+struct PackedNonCopy(u8);
+#[automatically_derived]
+impl ::core::clone::Clone for PackedNonCopy {
+ #[inline]
+ fn clone(&self) -> PackedNonCopy {
+ let Self(ref __self_0_0) = *self;
+ PackedNonCopy(::core::clone::Clone::clone(__self_0_0))
+ }
+}
+#[automatically_derived]
+impl ::core::fmt::Debug for PackedNonCopy {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
+ let Self(ref __self_0_0) = *self;
+ ::core::fmt::Formatter::debug_tuple_field1_finish(f, "PackedNonCopy",
+ &__self_0_0)
+ }
+}
+#[automatically_derived]
+impl ::core::default::Default for PackedNonCopy {
+ #[inline]
+ fn default() -> PackedNonCopy {
+ PackedNonCopy(::core::default::Default::default())
+ }
+}
+#[automatically_derived]
+impl ::core::hash::Hash for PackedNonCopy {
+ fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
+ let Self(ref __self_0_0) = *self;
+ ::core::hash::Hash::hash(__self_0_0, state)
+ }
+}
+impl ::core::marker::StructuralPartialEq for PackedNonCopy {}
+#[automatically_derived]
+impl ::core::cmp::PartialEq for PackedNonCopy {
+ #[inline]
+ fn eq(&self, other: &PackedNonCopy) -> bool {
+ let Self(ref __self_0_0) = *self;
+ let Self(ref __self_1_0) = *other;
+ *__self_0_0 == *__self_1_0
+ }
+ #[inline]
+ fn ne(&self, other: &PackedNonCopy) -> bool {
+ let Self(ref __self_0_0) = *self;
+ let Self(ref __self_1_0) = *other;
+ *__self_0_0 != *__self_1_0
+ }
+}
+impl ::core::marker::StructuralEq for PackedNonCopy {}
+#[automatically_derived]
+impl ::core::cmp::Eq for PackedNonCopy {
+ #[inline]
+ #[doc(hidden)]
+ #[no_coverage]
+ fn assert_receiver_is_total_eq(&self) -> () {
+ let _: ::core::cmp::AssertParamIsEq<u8>;
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::PartialOrd for PackedNonCopy {
+ #[inline]
+ fn partial_cmp(&self, other: &PackedNonCopy)
+ -> ::core::option::Option<::core::cmp::Ordering> {
+ let Self(ref __self_0_0) = *self;
+ let Self(ref __self_1_0) = *other;
+ ::core::cmp::PartialOrd::partial_cmp(__self_0_0, __self_1_0)
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::Ord for PackedNonCopy {
+ #[inline]
+ fn cmp(&self, other: &PackedNonCopy) -> ::core::cmp::Ordering {
+ let Self(ref __self_0_0) = *self;
+ let Self(ref __self_1_0) = *other;
+ ::core::cmp::Ord::cmp(__self_0_0, __self_1_0)
+ }
+}
+
+// An empty enum.
+enum Enum0 {}
+#[automatically_derived]
+impl ::core::clone::Clone for Enum0 {
+ #[inline]
+ fn clone(&self) -> Enum0 { *self }
+}
+#[automatically_derived]
+impl ::core::marker::Copy for Enum0 { }
+#[automatically_derived]
+impl ::core::fmt::Debug for Enum0 {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
+ unsafe { ::core::intrinsics::unreachable() }
+ }
+}
+#[automatically_derived]
+impl ::core::hash::Hash for Enum0 {
+ fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
+ unsafe { ::core::intrinsics::unreachable() }
+ }
+}
+impl ::core::marker::StructuralPartialEq for Enum0 {}
+#[automatically_derived]
+impl ::core::cmp::PartialEq for Enum0 {
+ #[inline]
+ fn eq(&self, other: &Enum0) -> bool {
+ unsafe { ::core::intrinsics::unreachable() }
+ }
+}
+impl ::core::marker::StructuralEq for Enum0 {}
+#[automatically_derived]
+impl ::core::cmp::Eq for Enum0 {
+ #[inline]
+ #[doc(hidden)]
+ #[no_coverage]
+ fn assert_receiver_is_total_eq(&self) -> () {}
+}
+#[automatically_derived]
+impl ::core::cmp::PartialOrd for Enum0 {
+ #[inline]
+ fn partial_cmp(&self, other: &Enum0)
+ -> ::core::option::Option<::core::cmp::Ordering> {
+ unsafe { ::core::intrinsics::unreachable() }
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::Ord for Enum0 {
+ #[inline]
+ fn cmp(&self, other: &Enum0) -> ::core::cmp::Ordering {
+ unsafe { ::core::intrinsics::unreachable() }
+ }
+}
+
+// A single-variant enum.
+enum Enum1 {
+ Single {
+ x: u32,
+ },
+}
+#[automatically_derived]
+impl ::core::clone::Clone for Enum1 {
+ #[inline]
+ fn clone(&self) -> Enum1 {
+ match self {
+ Enum1::Single { x: __self_0 } =>
+ Enum1::Single { x: ::core::clone::Clone::clone(__self_0) },
+ }
+ }
+}
+#[automatically_derived]
+impl ::core::fmt::Debug for Enum1 {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
+ match self {
+ Enum1::Single { x: __self_0 } =>
+ ::core::fmt::Formatter::debug_struct_field1_finish(f,
+ "Single", "x", &__self_0),
+ }
+ }
+}
+#[automatically_derived]
+impl ::core::hash::Hash for Enum1 {
+ fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
+ match self {
+ Enum1::Single { x: __self_0 } =>
+ ::core::hash::Hash::hash(__self_0, state),
+ }
+ }
+}
+impl ::core::marker::StructuralPartialEq for Enum1 {}
+#[automatically_derived]
+impl ::core::cmp::PartialEq for Enum1 {
+ #[inline]
+ fn eq(&self, other: &Enum1) -> bool {
+ match (self, other) {
+ (Enum1::Single { x: __self_0 }, Enum1::Single { x: __arg1_0 }) =>
+ *__self_0 == *__arg1_0,
+ }
+ }
+ #[inline]
+ fn ne(&self, other: &Enum1) -> bool {
+ match (self, other) {
+ (Enum1::Single { x: __self_0 }, Enum1::Single { x: __arg1_0 }) =>
+ *__self_0 != *__arg1_0,
+ }
+ }
+}
+impl ::core::marker::StructuralEq for Enum1 {}
+#[automatically_derived]
+impl ::core::cmp::Eq for Enum1 {
+ #[inline]
+ #[doc(hidden)]
+ #[no_coverage]
+ fn assert_receiver_is_total_eq(&self) -> () {
+ let _: ::core::cmp::AssertParamIsEq<u32>;
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::PartialOrd for Enum1 {
+ #[inline]
+ fn partial_cmp(&self, other: &Enum1)
+ -> ::core::option::Option<::core::cmp::Ordering> {
+ match (self, other) {
+ (Enum1::Single { x: __self_0 }, Enum1::Single { x: __arg1_0 }) =>
+ ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
+ }
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::Ord for Enum1 {
+ #[inline]
+ fn cmp(&self, other: &Enum1) -> ::core::cmp::Ordering {
+ match (self, other) {
+ (Enum1::Single { x: __self_0 }, Enum1::Single { x: __arg1_0 }) =>
+ ::core::cmp::Ord::cmp(__self_0, __arg1_0),
+ }
+ }
+}
+
+// A C-like, fieldless enum with a single variant.
+enum Fieldless1 {
+
+ #[default]
+ A,
+}
+#[automatically_derived]
+impl ::core::clone::Clone for Fieldless1 {
+ #[inline]
+ fn clone(&self) -> Fieldless1 { Fieldless1::A }
+}
+#[automatically_derived]
+impl ::core::fmt::Debug for Fieldless1 {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
+ ::core::fmt::Formatter::write_str(f, "A")
+ }
+}
+#[automatically_derived]
+impl ::core::default::Default for Fieldless1 {
+ #[inline]
+ fn default() -> Fieldless1 { Self::A }
+}
+#[automatically_derived]
+impl ::core::hash::Hash for Fieldless1 {
+ fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {}
+}
+impl ::core::marker::StructuralPartialEq for Fieldless1 {}
+#[automatically_derived]
+impl ::core::cmp::PartialEq for Fieldless1 {
+ #[inline]
+ fn eq(&self, other: &Fieldless1) -> bool { true }
+}
+impl ::core::marker::StructuralEq for Fieldless1 {}
+#[automatically_derived]
+impl ::core::cmp::Eq for Fieldless1 {
+ #[inline]
+ #[doc(hidden)]
+ #[no_coverage]
+ fn assert_receiver_is_total_eq(&self) -> () {}
+}
+#[automatically_derived]
+impl ::core::cmp::PartialOrd for Fieldless1 {
+ #[inline]
+ fn partial_cmp(&self, other: &Fieldless1)
+ -> ::core::option::Option<::core::cmp::Ordering> {
+ ::core::option::Option::Some(::core::cmp::Ordering::Equal)
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::Ord for Fieldless1 {
+ #[inline]
+ fn cmp(&self, other: &Fieldless1) -> ::core::cmp::Ordering {
+ ::core::cmp::Ordering::Equal
+ }
+}
+
+// A C-like, fieldless enum.
+enum Fieldless {
+
+ #[default]
+ A,
+ B,
+ C,
+}
+#[automatically_derived]
+impl ::core::clone::Clone for Fieldless {
+ #[inline]
+ fn clone(&self) -> Fieldless { *self }
+}
+#[automatically_derived]
+impl ::core::marker::Copy for Fieldless { }
+#[automatically_derived]
+impl ::core::fmt::Debug for Fieldless {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
+ match self {
+ Fieldless::A => ::core::fmt::Formatter::write_str(f, "A"),
+ Fieldless::B => ::core::fmt::Formatter::write_str(f, "B"),
+ Fieldless::C => ::core::fmt::Formatter::write_str(f, "C"),
+ }
+ }
+}
+#[automatically_derived]
+impl ::core::default::Default for Fieldless {
+ #[inline]
+ fn default() -> Fieldless { Self::A }
+}
+#[automatically_derived]
+impl ::core::hash::Hash for Fieldless {
+ fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
+ let __self_tag = ::core::intrinsics::discriminant_value(self);
+ ::core::hash::Hash::hash(&__self_tag, state)
+ }
+}
+impl ::core::marker::StructuralPartialEq for Fieldless {}
+#[automatically_derived]
+impl ::core::cmp::PartialEq for Fieldless {
+ #[inline]
+ fn eq(&self, other: &Fieldless) -> bool {
+ let __self_tag = ::core::intrinsics::discriminant_value(self);
+ let __arg1_tag = ::core::intrinsics::discriminant_value(other);
+ __self_tag == __arg1_tag
+ }
+}
+impl ::core::marker::StructuralEq for Fieldless {}
+#[automatically_derived]
+impl ::core::cmp::Eq for Fieldless {
+ #[inline]
+ #[doc(hidden)]
+ #[no_coverage]
+ fn assert_receiver_is_total_eq(&self) -> () {}
+}
+#[automatically_derived]
+impl ::core::cmp::PartialOrd for Fieldless {
+ #[inline]
+ fn partial_cmp(&self, other: &Fieldless)
+ -> ::core::option::Option<::core::cmp::Ordering> {
+ let __self_tag = ::core::intrinsics::discriminant_value(self);
+ let __arg1_tag = ::core::intrinsics::discriminant_value(other);
+ ::core::cmp::PartialOrd::partial_cmp(&__self_tag, &__arg1_tag)
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::Ord for Fieldless {
+ #[inline]
+ fn cmp(&self, other: &Fieldless) -> ::core::cmp::Ordering {
+ let __self_tag = ::core::intrinsics::discriminant_value(self);
+ let __arg1_tag = ::core::intrinsics::discriminant_value(other);
+ ::core::cmp::Ord::cmp(&__self_tag, &__arg1_tag)
+ }
+}
+
+// An enum with multiple fieldless and fielded variants.
+enum Mixed {
+
+ #[default]
+ P,
+ Q,
+ R(u32),
+ S {
+ d1: u32,
+ d2: u32,
+ },
+}
+#[automatically_derived]
+impl ::core::clone::Clone for Mixed {
+ #[inline]
+ fn clone(&self) -> Mixed {
+ let _: ::core::clone::AssertParamIsClone<u32>;
+ *self
+ }
+}
+#[automatically_derived]
+impl ::core::marker::Copy for Mixed { }
+#[automatically_derived]
+impl ::core::fmt::Debug for Mixed {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
+ match self {
+ Mixed::P => ::core::fmt::Formatter::write_str(f, "P"),
+ Mixed::Q => ::core::fmt::Formatter::write_str(f, "Q"),
+ Mixed::R(__self_0) =>
+ ::core::fmt::Formatter::debug_tuple_field1_finish(f, "R",
+ &__self_0),
+ Mixed::S { d1: __self_0, d2: __self_1 } =>
+ ::core::fmt::Formatter::debug_struct_field2_finish(f, "S",
+ "d1", &__self_0, "d2", &__self_1),
+ }
+ }
+}
+#[automatically_derived]
+impl ::core::default::Default for Mixed {
+ #[inline]
+ fn default() -> Mixed { Self::P }
+}
+#[automatically_derived]
+impl ::core::hash::Hash for Mixed {
+ fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
+ let __self_tag = ::core::intrinsics::discriminant_value(self);
+ ::core::hash::Hash::hash(&__self_tag, state);
+ match self {
+ Mixed::R(__self_0) => ::core::hash::Hash::hash(__self_0, state),
+ Mixed::S { d1: __self_0, d2: __self_1 } => {
+ ::core::hash::Hash::hash(__self_0, state);
+ ::core::hash::Hash::hash(__self_1, state)
+ }
+ _ => {}
+ }
+ }
+}
+impl ::core::marker::StructuralPartialEq for Mixed {}
+#[automatically_derived]
+impl ::core::cmp::PartialEq for Mixed {
+ #[inline]
+ fn eq(&self, other: &Mixed) -> bool {
+ let __self_tag = ::core::intrinsics::discriminant_value(self);
+ let __arg1_tag = ::core::intrinsics::discriminant_value(other);
+ __self_tag == __arg1_tag &&
+ match (self, other) {
+ (Mixed::R(__self_0), Mixed::R(__arg1_0)) =>
+ *__self_0 == *__arg1_0,
+ (Mixed::S { d1: __self_0, d2: __self_1 }, Mixed::S {
+ d1: __arg1_0, d2: __arg1_1 }) =>
+ *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1,
+ _ => true,
+ }
+ }
+ #[inline]
+ fn ne(&self, other: &Mixed) -> bool {
+ let __self_tag = ::core::intrinsics::discriminant_value(self);
+ let __arg1_tag = ::core::intrinsics::discriminant_value(other);
+ __self_tag != __arg1_tag ||
+ match (self, other) {
+ (Mixed::R(__self_0), Mixed::R(__arg1_0)) =>
+ *__self_0 != *__arg1_0,
+ (Mixed::S { d1: __self_0, d2: __self_1 }, Mixed::S {
+ d1: __arg1_0, d2: __arg1_1 }) =>
+ *__self_0 != *__arg1_0 || *__self_1 != *__arg1_1,
+ _ => false,
+ }
+ }
+}
+impl ::core::marker::StructuralEq for Mixed {}
+#[automatically_derived]
+impl ::core::cmp::Eq for Mixed {
+ #[inline]
+ #[doc(hidden)]
+ #[no_coverage]
+ fn assert_receiver_is_total_eq(&self) -> () {
+ let _: ::core::cmp::AssertParamIsEq<u32>;
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::PartialOrd for Mixed {
+ #[inline]
+ fn partial_cmp(&self, other: &Mixed)
+ -> ::core::option::Option<::core::cmp::Ordering> {
+ let __self_tag = ::core::intrinsics::discriminant_value(self);
+ let __arg1_tag = ::core::intrinsics::discriminant_value(other);
+ match ::core::cmp::PartialOrd::partial_cmp(&__self_tag, &__arg1_tag) {
+ ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
+ match (self, other) {
+ (Mixed::R(__self_0), Mixed::R(__arg1_0)) =>
+ ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
+ (Mixed::S { d1: __self_0, d2: __self_1 }, Mixed::S {
+ d1: __arg1_0, d2: __arg1_1 }) =>
+ match ::core::cmp::PartialOrd::partial_cmp(__self_0,
+ __arg1_0) {
+ ::core::option::Option::Some(::core::cmp::Ordering::Equal)
+ => ::core::cmp::PartialOrd::partial_cmp(__self_1, __arg1_1),
+ cmp => cmp,
+ },
+ _ =>
+ ::core::option::Option::Some(::core::cmp::Ordering::Equal),
+ },
+ cmp => cmp,
+ }
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::Ord for Mixed {
+ #[inline]
+ fn cmp(&self, other: &Mixed) -> ::core::cmp::Ordering {
+ let __self_tag = ::core::intrinsics::discriminant_value(self);
+ let __arg1_tag = ::core::intrinsics::discriminant_value(other);
+ match ::core::cmp::Ord::cmp(&__self_tag, &__arg1_tag) {
+ ::core::cmp::Ordering::Equal =>
+ match (self, other) {
+ (Mixed::R(__self_0), Mixed::R(__arg1_0)) =>
+ ::core::cmp::Ord::cmp(__self_0, __arg1_0),
+ (Mixed::S { d1: __self_0, d2: __self_1 }, Mixed::S {
+ d1: __arg1_0, d2: __arg1_1 }) =>
+ match ::core::cmp::Ord::cmp(__self_0, __arg1_0) {
+ ::core::cmp::Ordering::Equal =>
+ ::core::cmp::Ord::cmp(__self_1, __arg1_1),
+ cmp => cmp,
+ },
+ _ => ::core::cmp::Ordering::Equal,
+ },
+ cmp => cmp,
+ }
+ }
+}
+
+// An enum with no fieldless variants. Note that `Default` cannot be derived
+// for this enum.
+enum Fielded { X(u32), Y(bool), Z(Option<i32>), }
+#[automatically_derived]
+impl ::core::clone::Clone for Fielded {
+ #[inline]
+ fn clone(&self) -> Fielded {
+ match self {
+ Fielded::X(__self_0) =>
+ Fielded::X(::core::clone::Clone::clone(__self_0)),
+ Fielded::Y(__self_0) =>
+ Fielded::Y(::core::clone::Clone::clone(__self_0)),
+ Fielded::Z(__self_0) =>
+ Fielded::Z(::core::clone::Clone::clone(__self_0)),
+ }
+ }
+}
+#[automatically_derived]
+impl ::core::fmt::Debug for Fielded {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
+ match self {
+ Fielded::X(__self_0) =>
+ ::core::fmt::Formatter::debug_tuple_field1_finish(f, "X",
+ &__self_0),
+ Fielded::Y(__self_0) =>
+ ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Y",
+ &__self_0),
+ Fielded::Z(__self_0) =>
+ ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Z",
+ &__self_0),
+ }
+ }
+}
+#[automatically_derived]
+impl ::core::hash::Hash for Fielded {
+ fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
+ let __self_tag = ::core::intrinsics::discriminant_value(self);
+ ::core::hash::Hash::hash(&__self_tag, state);
+ match self {
+ Fielded::X(__self_0) => ::core::hash::Hash::hash(__self_0, state),
+ Fielded::Y(__self_0) => ::core::hash::Hash::hash(__self_0, state),
+ Fielded::Z(__self_0) => ::core::hash::Hash::hash(__self_0, state),
+ }
+ }
+}
+impl ::core::marker::StructuralPartialEq for Fielded {}
+#[automatically_derived]
+impl ::core::cmp::PartialEq for Fielded {
+ #[inline]
+ fn eq(&self, other: &Fielded) -> bool {
+ let __self_tag = ::core::intrinsics::discriminant_value(self);
+ let __arg1_tag = ::core::intrinsics::discriminant_value(other);
+ __self_tag == __arg1_tag &&
+ match (self, other) {
+ (Fielded::X(__self_0), Fielded::X(__arg1_0)) =>
+ *__self_0 == *__arg1_0,
+ (Fielded::Y(__self_0), Fielded::Y(__arg1_0)) =>
+ *__self_0 == *__arg1_0,
+ (Fielded::Z(__self_0), Fielded::Z(__arg1_0)) =>
+ *__self_0 == *__arg1_0,
+ _ => unsafe { ::core::intrinsics::unreachable() }
+ }
+ }
+ #[inline]
+ fn ne(&self, other: &Fielded) -> bool {
+ let __self_tag = ::core::intrinsics::discriminant_value(self);
+ let __arg1_tag = ::core::intrinsics::discriminant_value(other);
+ __self_tag != __arg1_tag ||
+ match (self, other) {
+ (Fielded::X(__self_0), Fielded::X(__arg1_0)) =>
+ *__self_0 != *__arg1_0,
+ (Fielded::Y(__self_0), Fielded::Y(__arg1_0)) =>
+ *__self_0 != *__arg1_0,
+ (Fielded::Z(__self_0), Fielded::Z(__arg1_0)) =>
+ *__self_0 != *__arg1_0,
+ _ => unsafe { ::core::intrinsics::unreachable() }
+ }
+ }
+}
+impl ::core::marker::StructuralEq for Fielded {}
+#[automatically_derived]
+impl ::core::cmp::Eq for Fielded {
+ #[inline]
+ #[doc(hidden)]
+ #[no_coverage]
+ fn assert_receiver_is_total_eq(&self) -> () {
+ let _: ::core::cmp::AssertParamIsEq<u32>;
+ let _: ::core::cmp::AssertParamIsEq<bool>;
+ let _: ::core::cmp::AssertParamIsEq<Option<i32>>;
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::PartialOrd for Fielded {
+ #[inline]
+ fn partial_cmp(&self, other: &Fielded)
+ -> ::core::option::Option<::core::cmp::Ordering> {
+ let __self_tag = ::core::intrinsics::discriminant_value(self);
+ let __arg1_tag = ::core::intrinsics::discriminant_value(other);
+ match ::core::cmp::PartialOrd::partial_cmp(&__self_tag, &__arg1_tag) {
+ ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
+ match (self, other) {
+ (Fielded::X(__self_0), Fielded::X(__arg1_0)) =>
+ ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
+ (Fielded::Y(__self_0), Fielded::Y(__arg1_0)) =>
+ ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
+ (Fielded::Z(__self_0), Fielded::Z(__arg1_0)) =>
+ ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
+ _ => unsafe { ::core::intrinsics::unreachable() }
+ },
+ cmp => cmp,
+ }
+ }
+}
+#[automatically_derived]
+impl ::core::cmp::Ord for Fielded {
+ #[inline]
+ fn cmp(&self, other: &Fielded) -> ::core::cmp::Ordering {
+ let __self_tag = ::core::intrinsics::discriminant_value(self);
+ let __arg1_tag = ::core::intrinsics::discriminant_value(other);
+ match ::core::cmp::Ord::cmp(&__self_tag, &__arg1_tag) {
+ ::core::cmp::Ordering::Equal =>
+ match (self, other) {
+ (Fielded::X(__self_0), Fielded::X(__arg1_0)) =>
+ ::core::cmp::Ord::cmp(__self_0, __arg1_0),
+ (Fielded::Y(__self_0), Fielded::Y(__arg1_0)) =>
+ ::core::cmp::Ord::cmp(__self_0, __arg1_0),
+ (Fielded::Z(__self_0), Fielded::Z(__arg1_0)) =>
+ ::core::cmp::Ord::cmp(__self_0, __arg1_0),
+ _ => unsafe { ::core::intrinsics::unreachable() }
+ },
+ cmp => cmp,
+ }
+ }
+}
+
+// A union. Most builtin traits are not derivable for unions.
+pub union Union {
+ pub b: bool,
+ pub u: u32,
+ pub i: i32,
+}
+#[automatically_derived]
+impl ::core::clone::Clone for Union {
+ #[inline]
+ fn clone(&self) -> Union {
+ let _: ::core::clone::AssertParamIsCopy<Self>;
+ *self
+ }
+}
+#[automatically_derived]
+impl ::core::marker::Copy for Union { }
diff --git a/src/test/ui/deriving/deriving-associated-types.rs b/src/test/ui/deriving/deriving-associated-types.rs
new file mode 100644
index 000000000..4b1cbe80c
--- /dev/null
+++ b/src/test/ui/deriving/deriving-associated-types.rs
@@ -0,0 +1,199 @@
+// run-pass
+pub trait DeclaredTrait {
+ type Type;
+}
+
+impl DeclaredTrait for i32 {
+ type Type = i32;
+}
+
+pub trait WhereTrait {
+ type Type;
+}
+
+impl WhereTrait for i32 {
+ type Type = i32;
+}
+
+// Make sure we don't add a bound that just shares a name with an associated
+// type.
+pub mod module {
+ pub type Type = i32;
+}
+
+#[derive(PartialEq, Debug)]
+struct PrivateStruct<T>(T);
+
+#[derive(PartialEq, Debug)]
+struct TupleStruct<A, B: DeclaredTrait, C>(
+ module::Type,
+ Option<module::Type>,
+ A,
+ PrivateStruct<A>,
+ B,
+ B::Type,
+ Option<B::Type>,
+ <B as DeclaredTrait>::Type,
+ Option<<B as DeclaredTrait>::Type>,
+ C,
+ C::Type,
+ Option<C::Type>,
+ <C as WhereTrait>::Type,
+ Option<<C as WhereTrait>::Type>,
+ <i32 as DeclaredTrait>::Type,
+) where C: WhereTrait;
+
+#[derive(PartialEq, Debug)]
+pub struct Struct<A, B: DeclaredTrait, C> where C: WhereTrait {
+ m1: module::Type,
+ m2: Option<module::Type>,
+ a1: A,
+ a2: PrivateStruct<A>,
+ b: B,
+ b1: B::Type,
+ b2: Option<B::Type>,
+ b3: <B as DeclaredTrait>::Type,
+ b4: Option<<B as DeclaredTrait>::Type>,
+ c: C,
+ c1: C::Type,
+ c2: Option<C::Type>,
+ c3: <C as WhereTrait>::Type,
+ c4: Option<<C as WhereTrait>::Type>,
+ d: <i32 as DeclaredTrait>::Type,
+}
+
+#[derive(PartialEq, Debug)]
+enum Enum<A, B: DeclaredTrait, C> where C: WhereTrait {
+ Unit,
+ Seq(
+ module::Type,
+ Option<module::Type>,
+ A,
+ PrivateStruct<A>,
+ B,
+ B::Type,
+ Option<B::Type>,
+ <B as DeclaredTrait>::Type,
+ Option<<B as DeclaredTrait>::Type>,
+ C,
+ C::Type,
+ Option<C::Type>,
+ <C as WhereTrait>::Type,
+ Option<<C as WhereTrait>::Type>,
+ <i32 as DeclaredTrait>::Type,
+ ),
+ Map {
+ m1: module::Type,
+ m2: Option<module::Type>,
+ a1: A,
+ a2: PrivateStruct<A>,
+ b: B,
+ b1: B::Type,
+ b2: Option<B::Type>,
+ b3: <B as DeclaredTrait>::Type,
+ b4: Option<<B as DeclaredTrait>::Type>,
+ c: C,
+ c1: C::Type,
+ c2: Option<C::Type>,
+ c3: <C as WhereTrait>::Type,
+ c4: Option<<C as WhereTrait>::Type>,
+ d: <i32 as DeclaredTrait>::Type,
+ },
+}
+
+fn main() {
+ let e: TupleStruct<
+ i32,
+ i32,
+ i32,
+ > = TupleStruct(
+ 0,
+ None,
+ 0,
+ PrivateStruct(0),
+ 0,
+ 0,
+ None,
+ 0,
+ None,
+ 0,
+ 0,
+ None,
+ 0,
+ None,
+ 0,
+ );
+ assert_eq!(e, e);
+
+ let e: Struct<
+ i32,
+ i32,
+ i32,
+ > = Struct {
+ m1: 0,
+ m2: None,
+ a1: 0,
+ a2: PrivateStruct(0),
+ b: 0,
+ b1: 0,
+ b2: None,
+ b3: 0,
+ b4: None,
+ c: 0,
+ c1: 0,
+ c2: None,
+ c3: 0,
+ c4: None,
+ d: 0,
+ };
+ assert_eq!(e, e);
+
+ let e = Enum::Unit::<i32, i32, i32>;
+ assert_eq!(e, e);
+
+ let e: Enum<
+ i32,
+ i32,
+ i32,
+ > = Enum::Seq(
+ 0,
+ None,
+ 0,
+ PrivateStruct(0),
+ 0,
+ 0,
+ None,
+ 0,
+ None,
+ 0,
+ 0,
+ None,
+ 0,
+ None,
+ 0,
+ );
+ assert_eq!(e, e);
+
+ let e: Enum<
+ i32,
+ i32,
+ i32,
+ > = Enum::Map {
+ m1: 0,
+ m2: None,
+ a1: 0,
+ a2: PrivateStruct(0),
+ b: 0,
+ b1: 0,
+ b2: None,
+ b3: 0,
+ b4: None,
+ c: 0,
+ c1: 0,
+ c2: None,
+ c3: 0,
+ c4: None,
+ d: 0,
+ };
+ assert_eq!(e, e);
+}
diff --git a/src/test/ui/deriving/deriving-bounds.rs b/src/test/ui/deriving/deriving-bounds.rs
new file mode 100644
index 000000000..f0b921d0e
--- /dev/null
+++ b/src/test/ui/deriving/deriving-bounds.rs
@@ -0,0 +1,5 @@
+// run-pass
+#[derive(Copy, Clone)]
+struct Test;
+
+pub fn main() {}
diff --git a/src/test/ui/deriving/deriving-clone-array.rs b/src/test/ui/deriving/deriving-clone-array.rs
new file mode 100644
index 000000000..4569749df
--- /dev/null
+++ b/src/test/ui/deriving/deriving-clone-array.rs
@@ -0,0 +1,10 @@
+// run-pass
+#![allow(dead_code)]
+// test for issue #30244
+
+#[derive(Copy, Clone)]
+struct Array {
+ arr: [[u8; 256]; 4]
+}
+
+pub fn main() {}
diff --git a/src/test/ui/deriving/deriving-clone-enum.rs b/src/test/ui/deriving/deriving-clone-enum.rs
new file mode 100644
index 000000000..09e749740
--- /dev/null
+++ b/src/test/ui/deriving/deriving-clone-enum.rs
@@ -0,0 +1,14 @@
+// run-pass
+#![allow(dead_code)]
+// pretty-expanded FIXME #23616
+
+#[derive(Clone)]
+enum E {
+ A,
+ B(()),
+ C
+}
+
+pub fn main() {
+ let _ = E::A.clone();
+}
diff --git a/src/test/ui/deriving/deriving-clone-generic-enum.rs b/src/test/ui/deriving/deriving-clone-generic-enum.rs
new file mode 100644
index 000000000..a344d7fc4
--- /dev/null
+++ b/src/test/ui/deriving/deriving-clone-generic-enum.rs
@@ -0,0 +1,14 @@
+// run-pass
+#![allow(dead_code)]
+// pretty-expanded FIXME #23616
+
+#[derive(Clone)]
+enum E<T,U> {
+ A(T),
+ B(T,U),
+ C
+}
+
+pub fn main() {
+ let _ = E::A::<isize, isize>(1).clone();
+}
diff --git a/src/test/ui/deriving/deriving-clone-generic-struct.rs b/src/test/ui/deriving/deriving-clone-generic-struct.rs
new file mode 100644
index 000000000..4374d1594
--- /dev/null
+++ b/src/test/ui/deriving/deriving-clone-generic-struct.rs
@@ -0,0 +1,15 @@
+// run-pass
+// pretty-expanded FIXME #23616
+
+#![allow(dead_code)]
+
+#[derive(Clone)]
+struct S<T> {
+ foo: (),
+ bar: (),
+ baz: T,
+}
+
+pub fn main() {
+ let _ = S { foo: (), bar: (), baz: 1 }.clone();
+}
diff --git a/src/test/ui/deriving/deriving-clone-generic-tuple-struct.rs b/src/test/ui/deriving/deriving-clone-generic-tuple-struct.rs
new file mode 100644
index 000000000..3480ccc10
--- /dev/null
+++ b/src/test/ui/deriving/deriving-clone-generic-tuple-struct.rs
@@ -0,0 +1,10 @@
+// run-pass
+// pretty-expanded FIXME #23616
+
+#[derive(Clone)]
+#[allow(unused_tuple_struct_fields)]
+struct S<T>(T, ());
+
+pub fn main() {
+ let _ = S(1, ()).clone();
+}
diff --git a/src/test/ui/deriving/deriving-clone-struct.rs b/src/test/ui/deriving/deriving-clone-struct.rs
new file mode 100644
index 000000000..b93cbe5f8
--- /dev/null
+++ b/src/test/ui/deriving/deriving-clone-struct.rs
@@ -0,0 +1,28 @@
+// run-pass
+// pretty-expanded FIXME #23616
+
+#![allow(dead_code)]
+
+#[derive(Clone)]
+struct S {
+ _int: isize,
+ _i8: i8,
+ _i16: i16,
+ _i32: i32,
+ _i64: i64,
+
+ _uint: usize,
+ _u8: u8,
+ _u16: u16,
+ _u32: u32,
+ _u64: u64,
+
+ _f32: f32,
+ _f64: f64,
+
+ _bool: bool,
+ _char: char,
+ _nil: ()
+}
+
+pub fn main() {}
diff --git a/src/test/ui/deriving/deriving-clone-tuple-struct.rs b/src/test/ui/deriving/deriving-clone-tuple-struct.rs
new file mode 100644
index 000000000..7ad3f0347
--- /dev/null
+++ b/src/test/ui/deriving/deriving-clone-tuple-struct.rs
@@ -0,0 +1,9 @@
+// run-pass
+// pretty-expanded FIXME #23616
+
+#![allow(dead_code)]
+
+#[derive(Clone)]
+struct S((), ());
+
+pub fn main() {}
diff --git a/src/test/ui/deriving/deriving-cmp-generic-enum.rs b/src/test/ui/deriving/deriving-cmp-generic-enum.rs
new file mode 100644
index 000000000..88da4bd06
--- /dev/null
+++ b/src/test/ui/deriving/deriving-cmp-generic-enum.rs
@@ -0,0 +1,44 @@
+// run-pass
+#[derive(PartialEq, Eq, PartialOrd, Ord)]
+enum E<T> {
+ E0,
+ E1(T),
+ E2(T,T)
+}
+
+pub fn main() {
+ let e0 = E::E0;
+ let e11 = E::E1(1);
+ let e12 = E::E1(2);
+ let e21 = E::E2(1, 1);
+ let e22 = E::E2(1, 2);
+
+ // in order for both PartialOrd and Ord
+ let es = [e0, e11, e12, e21, e22];
+
+ for (i, e1) in es.iter().enumerate() {
+ for (j, e2) in es.iter().enumerate() {
+ let ord = i.cmp(&j);
+
+ let eq = i == j;
+ let lt = i < j;
+ let le = i <= j;
+ let gt = i > j;
+ let ge = i >= j;
+
+ // PartialEq
+ assert_eq!(*e1 == *e2, eq);
+ assert_eq!(*e1 != *e2, !eq);
+
+ // PartialOrd
+ assert_eq!(*e1 < *e2, lt);
+ assert_eq!(*e1 > *e2, gt);
+
+ assert_eq!(*e1 <= *e2, le);
+ assert_eq!(*e1 >= *e2, ge);
+
+ // Ord
+ assert_eq!(e1.cmp(e2), ord);
+ }
+ }
+}
diff --git a/src/test/ui/deriving/deriving-cmp-generic-struct-enum.rs b/src/test/ui/deriving/deriving-cmp-generic-struct-enum.rs
new file mode 100644
index 000000000..eeaf2ff7e
--- /dev/null
+++ b/src/test/ui/deriving/deriving-cmp-generic-struct-enum.rs
@@ -0,0 +1,48 @@
+// run-pass
+#[derive(PartialEq, Eq, PartialOrd, Ord)]
+enum ES<T> {
+ ES1 { x: T },
+ ES2 { x: T, y: T }
+}
+
+
+pub fn main() {
+ let (es11, es12, es21, es22) = (ES::ES1 {
+ x: 1
+ }, ES::ES1 {
+ x: 2
+ }, ES::ES2 {
+ x: 1,
+ y: 1
+ }, ES::ES2 {
+ x: 1,
+ y: 2
+ });
+
+ // in order for both PartialOrd and Ord
+ let ess = [es11, es12, es21, es22];
+
+ for (i, es1) in ess.iter().enumerate() {
+ for (j, es2) in ess.iter().enumerate() {
+ let ord = i.cmp(&j);
+
+ let eq = i == j;
+ let (lt, le) = (i < j, i <= j);
+ let (gt, ge) = (i > j, i >= j);
+
+ // PartialEq
+ assert_eq!(*es1 == *es2, eq);
+ assert_eq!(*es1 != *es2, !eq);
+
+ // PartialOrd
+ assert_eq!(*es1 < *es2, lt);
+ assert_eq!(*es1 > *es2, gt);
+
+ assert_eq!(*es1 <= *es2, le);
+ assert_eq!(*es1 >= *es2, ge);
+
+ // Ord
+ assert_eq!(es1.cmp(es2), ord);
+ }
+ }
+}
diff --git a/src/test/ui/deriving/deriving-cmp-generic-struct.rs b/src/test/ui/deriving/deriving-cmp-generic-struct.rs
new file mode 100644
index 000000000..538caf439
--- /dev/null
+++ b/src/test/ui/deriving/deriving-cmp-generic-struct.rs
@@ -0,0 +1,40 @@
+// run-pass
+#[derive(PartialEq, Eq, PartialOrd, Ord)]
+struct S<T> {
+ x: T,
+ y: T
+}
+
+pub fn main() {
+ let s1 = S {x: 1, y: 1};
+ let s2 = S {x: 1, y: 2};
+
+ // in order for both PartialOrd and Ord
+ let ss = [s1, s2];
+
+ for (i, s1) in ss.iter().enumerate() {
+ for (j, s2) in ss.iter().enumerate() {
+ let ord = i.cmp(&j);
+
+ let eq = i == j;
+ let lt = i < j;
+ let le = i <= j;
+ let gt = i > j;
+ let ge = i >= j;
+
+ // PartialEq
+ assert_eq!(*s1 == *s2, eq);
+ assert_eq!(*s1 != *s2, !eq);
+
+ // PartialOrd
+ assert_eq!(*s1 < *s2, lt);
+ assert_eq!(*s1 > *s2, gt);
+
+ assert_eq!(*s1 <= *s2, le);
+ assert_eq!(*s1 >= *s2, ge);
+
+ // Ord
+ assert_eq!(s1.cmp(s2), ord);
+ }
+ }
+}
diff --git a/src/test/ui/deriving/deriving-cmp-generic-tuple-struct.rs b/src/test/ui/deriving/deriving-cmp-generic-tuple-struct.rs
new file mode 100644
index 000000000..79f58d456
--- /dev/null
+++ b/src/test/ui/deriving/deriving-cmp-generic-tuple-struct.rs
@@ -0,0 +1,38 @@
+// run-pass
+#[derive(PartialEq, Eq, PartialOrd, Ord)]
+struct TS<T>(T,T);
+
+
+pub fn main() {
+ let ts1 = TS(1, 1);
+ let ts2 = TS(1, 2);
+
+ // in order for both PartialOrd and Ord
+ let tss = [ts1, ts2];
+
+ for (i, ts1) in tss.iter().enumerate() {
+ for (j, ts2) in tss.iter().enumerate() {
+ let ord = i.cmp(&j);
+
+ let eq = i == j;
+ let lt = i < j;
+ let le = i <= j;
+ let gt = i > j;
+ let ge = i >= j;
+
+ // PartialEq
+ assert_eq!(*ts1 == *ts2, eq);
+ assert_eq!(*ts1 != *ts2, !eq);
+
+ // PartialOrd
+ assert_eq!(*ts1 < *ts2, lt);
+ assert_eq!(*ts1 > *ts2, gt);
+
+ assert_eq!(*ts1 <= *ts2, le);
+ assert_eq!(*ts1 >= *ts2, ge);
+
+ // Ord
+ assert_eq!(ts1.cmp(ts2), ord);
+ }
+ }
+}
diff --git a/src/test/ui/deriving/deriving-cmp-shortcircuit.rs b/src/test/ui/deriving/deriving-cmp-shortcircuit.rs
new file mode 100644
index 000000000..140373e95
--- /dev/null
+++ b/src/test/ui/deriving/deriving-cmp-shortcircuit.rs
@@ -0,0 +1,37 @@
+// run-pass
+// check that the derived impls for the comparison traits shortcircuit
+// where possible, by having a type that panics when compared as the
+// second element, so this passes iff the instances shortcircuit.
+
+
+use std::cmp::Ordering;
+
+pub struct FailCmp;
+impl PartialEq for FailCmp {
+ fn eq(&self, _: &FailCmp) -> bool { panic!("eq") }
+}
+
+impl PartialOrd for FailCmp {
+ fn partial_cmp(&self, _: &FailCmp) -> Option<Ordering> { panic!("partial_cmp") }
+}
+
+impl Eq for FailCmp {}
+
+impl Ord for FailCmp {
+ fn cmp(&self, _: &FailCmp) -> Ordering { panic!("cmp") }
+}
+
+#[derive(PartialEq,PartialOrd,Eq,Ord)]
+struct ShortCircuit {
+ x: isize,
+ y: FailCmp
+}
+
+pub fn main() {
+ let a = ShortCircuit { x: 1, y: FailCmp };
+ let b = ShortCircuit { x: 2, y: FailCmp };
+
+ assert!(a != b);
+ assert!(a < b);
+ assert_eq!(a.cmp(&b), ::std::cmp::Ordering::Less);
+}
diff --git a/src/test/ui/deriving/deriving-copyclone.rs b/src/test/ui/deriving/deriving-copyclone.rs
new file mode 100644
index 000000000..f8403b1fe
--- /dev/null
+++ b/src/test/ui/deriving/deriving-copyclone.rs
@@ -0,0 +1,38 @@
+// run-pass
+//! Test that #[derive(Copy, Clone)] produces a shallow copy
+//! even when a member violates RFC 1521
+
+use std::sync::atomic::{AtomicBool, Ordering};
+
+/// A struct that pretends to be Copy, but actually does something
+/// in its Clone impl
+#[derive(Copy)]
+struct Liar;
+
+/// Static cooperating with the rogue Clone impl
+static CLONED: AtomicBool = AtomicBool::new(false);
+
+impl Clone for Liar {
+ fn clone(&self) -> Self {
+ // this makes Clone vs Copy observable
+ CLONED.store(true, Ordering::SeqCst);
+
+ *self
+ }
+}
+
+/// This struct is actually Copy... at least, it thinks it is!
+#[derive(Copy, Clone)]
+struct Innocent(#[allow(unused_tuple_struct_fields)] Liar);
+
+impl Innocent {
+ fn new() -> Self {
+ Innocent(Liar)
+ }
+}
+
+fn main() {
+ let _ = Innocent::new().clone();
+ // if Innocent was byte-for-byte copied, CLONED will still be false
+ assert!(!CLONED.load(Ordering::SeqCst));
+}
diff --git a/src/test/ui/deriving/deriving-default-box.rs b/src/test/ui/deriving/deriving-default-box.rs
new file mode 100644
index 000000000..b71e11496
--- /dev/null
+++ b/src/test/ui/deriving/deriving-default-box.rs
@@ -0,0 +1,13 @@
+// run-pass
+use std::default::Default;
+
+#[derive(Default)]
+struct A {
+ foo: Box<[bool]>,
+}
+
+pub fn main() {
+ let a: A = Default::default();
+ let b: Box<[_]> = Box::<[bool; 0]>::new([]);
+ assert_eq!(a.foo, b);
+}
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 000000000..d1a81c72c
--- /dev/null
+++ b/src/test/ui/deriving/deriving-default-enum.rs
@@ -0,0 +1,17 @@
+// run-pass
+
+// 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-enum-single-variant.rs b/src/test/ui/deriving/deriving-enum-single-variant.rs
new file mode 100644
index 000000000..1c5979c07
--- /dev/null
+++ b/src/test/ui/deriving/deriving-enum-single-variant.rs
@@ -0,0 +1,12 @@
+// run-pass
+// pretty-expanded FIXME #23616
+#![allow(non_camel_case_types)]
+
+pub type task_id = isize;
+
+#[derive(PartialEq)]
+pub enum Task {
+ TaskHandle(task_id)
+}
+
+pub fn main() { }
diff --git a/src/test/ui/deriving/deriving-eq-ord-boxed-slice.rs b/src/test/ui/deriving/deriving-eq-ord-boxed-slice.rs
new file mode 100644
index 000000000..5b4b09836
--- /dev/null
+++ b/src/test/ui/deriving/deriving-eq-ord-boxed-slice.rs
@@ -0,0 +1,15 @@
+// run-pass
+#[derive(PartialEq, PartialOrd, Eq, Ord, Debug)]
+struct Foo(Box<[u8]>);
+
+pub fn main() {
+ let a = Foo(Box::new([0, 1, 2]));
+ let b = Foo(Box::new([0, 1, 2]));
+ assert_eq!(a, b);
+ println!("{}", a != b);
+ println!("{}", a < b);
+ println!("{}", a <= b);
+ println!("{}", a == b);
+ println!("{}", a > b);
+ println!("{}", a >= b);
+}
diff --git a/src/test/ui/deriving/deriving-hash.rs b/src/test/ui/deriving/deriving-hash.rs
new file mode 100644
index 000000000..8b51370bc
--- /dev/null
+++ b/src/test/ui/deriving/deriving-hash.rs
@@ -0,0 +1,76 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(unused_imports)]
+#![allow(deprecated)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![allow(overflowing_literals)]
+
+use std::hash::{Hash, SipHasher, Hasher};
+use std::mem::size_of;
+
+#[derive(Hash)]
+struct Person {
+ id: usize,
+ name: String,
+ phone: usize,
+}
+
+// test for hygiene name collisions
+#[derive(Hash)] struct __H__H;
+#[derive(Hash)] enum Collision<__H> { __H { __H__H: __H } }
+
+#[derive(Hash)]
+enum E { A=1, B }
+
+fn hash<T: Hash>(t: &T) -> u64 {
+ let mut s = SipHasher::new();
+ t.hash(&mut s);
+ s.finish()
+}
+
+struct FakeHasher<'a>(&'a mut Vec<u8>);
+impl<'a> Hasher for FakeHasher<'a> {
+ fn finish(&self) -> u64 {
+ unimplemented!()
+ }
+
+ fn write(&mut self, bytes: &[u8]) {
+ self.0.extend(bytes);
+ }
+}
+
+fn fake_hash<A: Hash>(v: &mut Vec<u8>, a: A) {
+ a.hash(&mut FakeHasher(v));
+}
+
+fn main() {
+ let person1 = Person {
+ id: 5,
+ name: "Janet".to_string(),
+ phone: 555_666_7777
+ };
+ let person2 = Person {
+ id: 5,
+ name: "Bob".to_string(),
+ phone: 555_666_7777
+ };
+ assert_eq!(hash(&person1), hash(&person1));
+ assert!(hash(&person1) != hash(&person2));
+
+ // test #21714
+ let mut va = vec![];
+ let mut vb = vec![];
+ fake_hash(&mut va, E::A);
+ fake_hash(&mut vb, E::B);
+ assert!(va != vb);
+
+ // issue #39137: single variant enum hash should not hash discriminant
+ #[derive(Hash)]
+ enum SingleVariantEnum {
+ A(u8),
+ }
+ let mut v = vec![];
+ fake_hash(&mut v, SingleVariantEnum::A(17));
+ assert_eq!(vec![17], v);
+}
diff --git a/src/test/ui/deriving/deriving-in-fn.rs b/src/test/ui/deriving/deriving-in-fn.rs
new file mode 100644
index 000000000..07f91d059
--- /dev/null
+++ b/src/test/ui/deriving/deriving-in-fn.rs
@@ -0,0 +1,13 @@
+// run-pass
+
+#![allow(dead_code)]
+
+pub fn main() {
+ #[derive(Debug)]
+ struct Foo {
+ foo: isize,
+ }
+
+ let f = Foo { foo: 10 };
+ format!("{:?}", f);
+}
diff --git a/src/test/ui/deriving/deriving-in-macro.rs b/src/test/ui/deriving/deriving-in-macro.rs
new file mode 100644
index 000000000..46e8e3783
--- /dev/null
+++ b/src/test/ui/deriving/deriving-in-macro.rs
@@ -0,0 +1,16 @@
+// run-pass
+// pretty-expanded FIXME #23616
+#![allow(non_camel_case_types)]
+
+macro_rules! define_vec {
+ () => (
+ mod foo {
+ #[derive(PartialEq)]
+ pub struct bar;
+ }
+ )
+}
+
+define_vec![];
+
+pub fn main() {}
diff --git a/src/test/ui/deriving/deriving-meta-multiple.rs b/src/test/ui/deriving/deriving-meta-multiple.rs
new file mode 100644
index 000000000..ad255be8d
--- /dev/null
+++ b/src/test/ui/deriving/deriving-meta-multiple.rs
@@ -0,0 +1,26 @@
+// run-pass
+#![allow(unused_must_use)]
+#![allow(unused_imports)]
+// pretty-expanded FIXME #23616
+#![allow(deprecated)]
+
+use std::hash::{Hash, SipHasher};
+
+// testing multiple separate deriving attributes
+#[derive(PartialEq)]
+#[derive(Clone)]
+#[derive(Hash)]
+struct Foo {
+ bar: usize,
+ baz: isize
+}
+
+fn hash<T: Hash>(_t: &T) {}
+
+pub fn main() {
+ let a = Foo {bar: 4, baz: -3};
+
+ a == a; // check for PartialEq impl w/o testing its correctness
+ a.clone(); // check for Clone impl w/o testing its correctness
+ hash(&a); // check for Hash impl w/o testing its correctness
+}
diff --git a/src/test/ui/deriving/deriving-meta.rs b/src/test/ui/deriving/deriving-meta.rs
new file mode 100644
index 000000000..f2ff4f535
--- /dev/null
+++ b/src/test/ui/deriving/deriving-meta.rs
@@ -0,0 +1,23 @@
+// run-pass
+#![allow(unused_must_use)]
+#![allow(unused_imports)]
+// pretty-expanded FIXME #23616
+#![allow(deprecated)]
+
+use std::hash::{Hash, SipHasher};
+
+#[derive(PartialEq, Clone, Hash)]
+struct Foo {
+ bar: usize,
+ baz: isize
+}
+
+fn hash<T: Hash>(_t: &T) {}
+
+pub fn main() {
+ let a = Foo {bar: 4, baz: -3};
+
+ a == a; // check for PartialEq impl w/o testing its correctness
+ a.clone(); // check for Clone impl w/o testing its correctness
+ hash(&a); // check for Hash impl w/o testing its correctness
+}
diff --git a/src/test/ui/deriving/deriving-self-lifetime-totalord-totaleq.rs b/src/test/ui/deriving/deriving-self-lifetime-totalord-totaleq.rs
new file mode 100644
index 000000000..e01b5a26f
--- /dev/null
+++ b/src/test/ui/deriving/deriving-self-lifetime-totalord-totaleq.rs
@@ -0,0 +1,16 @@
+// run-pass
+use std::cmp::Ordering::{Less,Equal,Greater};
+
+#[derive(PartialEq, Eq, PartialOrd, Ord)]
+struct A<'a> {
+ x: &'a isize
+}
+pub fn main() {
+ let (a, b) = (A { x: &1 }, A { x: &2 });
+
+ assert_eq!(a.cmp(&a), Equal);
+ assert_eq!(b.cmp(&b), Equal);
+
+ assert_eq!(a.cmp(&b), Less);
+ assert_eq!(b.cmp(&a), Greater);
+}
diff --git a/src/test/ui/deriving/deriving-show-2.rs b/src/test/ui/deriving/deriving-show-2.rs
new file mode 100644
index 000000000..13d124ed4
--- /dev/null
+++ b/src/test/ui/deriving/deriving-show-2.rs
@@ -0,0 +1,54 @@
+// run-pass
+#![allow(dead_code)]
+use std::fmt;
+
+#[derive(Debug)]
+enum A {}
+#[derive(Debug)]
+enum B { B1, B2, B3 }
+#[derive(Debug)]
+enum C { C1(isize), C2(B), C3(String) }
+#[derive(Debug)]
+enum D { D1{ a: isize } }
+#[derive(Debug)]
+struct E;
+#[derive(Debug)]
+struct F(isize);
+#[derive(Debug)]
+struct G(isize, isize);
+#[derive(Debug)]
+struct H { a: isize }
+#[derive(Debug)]
+struct I { a: isize, b: isize }
+#[derive(Debug)]
+struct J(Custom);
+
+struct Custom;
+impl fmt::Debug for Custom {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "yay")
+ }
+}
+
+trait ToDebug {
+ fn to_show(&self) -> String;
+}
+
+impl<T: fmt::Debug> ToDebug for T {
+ fn to_show(&self) -> String {
+ format!("{:?}", self)
+ }
+}
+
+pub fn main() {
+ assert_eq!(B::B1.to_show(), "B1".to_string());
+ assert_eq!(B::B2.to_show(), "B2".to_string());
+ assert_eq!(C::C1(3).to_show(), "C1(3)".to_string());
+ assert_eq!(C::C2(B::B2).to_show(), "C2(B2)".to_string());
+ assert_eq!(D::D1{ a: 2 }.to_show(), "D1 { a: 2 }".to_string());
+ assert_eq!(E.to_show(), "E".to_string());
+ assert_eq!(F(3).to_show(), "F(3)".to_string());
+ assert_eq!(G(3, 4).to_show(), "G(3, 4)".to_string());
+ assert_eq!(I{ a: 2, b: 4 }.to_show(), "I { a: 2, b: 4 }".to_string());
+ assert_eq!(J(Custom).to_show(), "J(yay)".to_string());
+}
diff --git a/src/test/ui/deriving/deriving-show.rs b/src/test/ui/deriving/deriving-show.rs
new file mode 100644
index 000000000..eb3a8948f
--- /dev/null
+++ b/src/test/ui/deriving/deriving-show.rs
@@ -0,0 +1,35 @@
+// run-pass
+#![allow(dead_code)]
+#[derive(Debug)]
+struct Unit;
+
+#[derive(Debug)]
+struct Tuple(isize, usize);
+
+#[derive(Debug)]
+struct Struct { x: isize, y: usize }
+
+#[derive(Debug)]
+enum Enum {
+ Nullary,
+ Variant(isize, usize),
+ StructVariant { x: isize, y : usize }
+}
+
+#[derive(Debug)]
+struct Pointers(*const dyn Send, *mut dyn Sync);
+
+macro_rules! t {
+ ($x:expr, $expected:expr) => {
+ assert_eq!(format!("{:?}", $x), $expected.to_string())
+ }
+}
+
+pub fn main() {
+ t!(Unit, "Unit");
+ t!(Tuple(1, 2), "Tuple(1, 2)");
+ t!(Struct { x: 1, y: 2 }, "Struct { x: 1, y: 2 }");
+ t!(Enum::Nullary, "Nullary");
+ t!(Enum::Variant(1, 2), "Variant(1, 2)");
+ t!(Enum::StructVariant { x: 1, y: 2 }, "StructVariant { x: 1, y: 2 }");
+}
diff --git a/src/test/ui/deriving/deriving-via-extension-c-enum.rs b/src/test/ui/deriving/deriving-via-extension-c-enum.rs
new file mode 100644
index 000000000..7fa1a69d7
--- /dev/null
+++ b/src/test/ui/deriving/deriving-via-extension-c-enum.rs
@@ -0,0 +1,17 @@
+// run-pass
+#![allow(dead_code)]
+#[derive(PartialEq, Debug)]
+enum Foo {
+ Bar,
+ Baz,
+ Boo
+}
+
+pub fn main() {
+ let a = Foo::Bar;
+ let b = Foo::Bar;
+ assert_eq!(a, b);
+ assert!(!(a != b));
+ assert!(a.eq(&b));
+ assert!(!a.ne(&b));
+}
diff --git a/src/test/ui/deriving/deriving-via-extension-enum.rs b/src/test/ui/deriving/deriving-via-extension-enum.rs
new file mode 100644
index 000000000..6b58fd966
--- /dev/null
+++ b/src/test/ui/deriving/deriving-via-extension-enum.rs
@@ -0,0 +1,16 @@
+// run-pass
+#![allow(dead_code)]
+#[derive(PartialEq, Debug)]
+enum Foo {
+ Bar(isize, isize),
+ Baz(f64, f64)
+}
+
+pub fn main() {
+ let a = Foo::Bar(1, 2);
+ let b = Foo::Bar(1, 2);
+ assert_eq!(a, b);
+ assert!(!(a != b));
+ assert!(a.eq(&b));
+ assert!(!a.ne(&b));
+}
diff --git a/src/test/ui/deriving/deriving-via-extension-hash-enum.rs b/src/test/ui/deriving/deriving-via-extension-hash-enum.rs
new file mode 100644
index 000000000..2d1ca05f4
--- /dev/null
+++ b/src/test/ui/deriving/deriving-via-extension-hash-enum.rs
@@ -0,0 +1,17 @@
+// run-pass
+#![allow(dead_code)]
+#[derive(Hash)]
+enum Foo {
+ Bar(isize, char),
+ Baz(char, isize)
+}
+
+#[derive(Hash)]
+enum A {
+ B,
+ C,
+ D,
+ E
+}
+
+pub fn main(){}
diff --git a/src/test/ui/deriving/deriving-via-extension-hash-struct.rs b/src/test/ui/deriving/deriving-via-extension-hash-struct.rs
new file mode 100644
index 000000000..c4037dc27
--- /dev/null
+++ b/src/test/ui/deriving/deriving-via-extension-hash-struct.rs
@@ -0,0 +1,12 @@
+// run-pass
+#![allow(dead_code)]
+// pretty-expanded FIXME #23616
+
+#[derive(Hash)]
+struct Foo {
+ x: isize,
+ y: isize,
+ z: isize
+}
+
+pub fn main() {}
diff --git a/src/test/ui/deriving/deriving-via-extension-struct-empty.rs b/src/test/ui/deriving/deriving-via-extension-struct-empty.rs
new file mode 100644
index 000000000..9fb250e84
--- /dev/null
+++ b/src/test/ui/deriving/deriving-via-extension-struct-empty.rs
@@ -0,0 +1,8 @@
+// run-pass
+#[derive(PartialEq, Debug)]
+struct Foo;
+
+pub fn main() {
+ assert_eq!(Foo, Foo);
+ assert!(!(Foo != Foo));
+}
diff --git a/src/test/ui/deriving/deriving-via-extension-struct-like-enum-variant.rs b/src/test/ui/deriving/deriving-via-extension-struct-like-enum-variant.rs
new file mode 100644
index 000000000..b6e6f136c
--- /dev/null
+++ b/src/test/ui/deriving/deriving-via-extension-struct-like-enum-variant.rs
@@ -0,0 +1,13 @@
+// run-pass
+#![allow(dead_code)]
+#[derive(PartialEq, Debug)]
+enum S {
+ X { x: isize, y: isize },
+ Y
+}
+
+pub fn main() {
+ let x = S::X { x: 1, y: 2 };
+ assert_eq!(x, x);
+ assert!(!(x != x));
+}
diff --git a/src/test/ui/deriving/deriving-via-extension-struct-tuple.rs b/src/test/ui/deriving/deriving-via-extension-struct-tuple.rs
new file mode 100644
index 000000000..e84906c96
--- /dev/null
+++ b/src/test/ui/deriving/deriving-via-extension-struct-tuple.rs
@@ -0,0 +1,17 @@
+// run-pass
+#[derive(PartialEq, Debug)]
+struct Foo(isize, isize, String);
+
+pub fn main() {
+ let a1 = Foo(5, 6, "abc".to_string());
+ let a2 = Foo(5, 6, "abc".to_string());
+ let b = Foo(5, 7, "def".to_string());
+
+ assert_eq!(a1, a1);
+ assert_eq!(a2, a1);
+ assert!(!(a1 == b));
+
+ assert!(a1 != b);
+ assert!(!(a1 != a1));
+ assert!(!(a2 != a1));
+}
diff --git a/src/test/ui/deriving/deriving-via-extension-struct.rs b/src/test/ui/deriving/deriving-via-extension-struct.rs
new file mode 100644
index 000000000..f4d8b16a0
--- /dev/null
+++ b/src/test/ui/deriving/deriving-via-extension-struct.rs
@@ -0,0 +1,16 @@
+// run-pass
+#[derive(PartialEq, Debug)]
+struct Foo {
+ x: isize,
+ y: isize,
+ z: isize,
+}
+
+pub fn main() {
+ let a = Foo { x: 1, y: 2, z: 3 };
+ let b = Foo { x: 1, y: 2, z: 3 };
+ assert_eq!(a, b);
+ assert!(!(a != b));
+ assert!(a.eq(&b));
+ assert!(!a.ne(&b));
+}
diff --git a/src/test/ui/deriving/deriving-via-extension-type-params.rs b/src/test/ui/deriving/deriving-via-extension-type-params.rs
new file mode 100644
index 000000000..a5dec8ee1
--- /dev/null
+++ b/src/test/ui/deriving/deriving-via-extension-type-params.rs
@@ -0,0 +1,16 @@
+// run-pass
+#[derive(PartialEq, Hash, Debug)]
+struct Foo<T> {
+ x: isize,
+ y: T,
+ z: isize
+}
+
+pub fn main() {
+ let a = Foo { x: 1, y: 2.0f64, z: 3 };
+ let b = Foo { x: 1, y: 2.0f64, z: 3 };
+ assert_eq!(a, b);
+ assert!(!(a != b));
+ assert!(a.eq(&b));
+ assert!(!a.ne(&b));
+}
diff --git a/src/test/ui/deriving/deriving-with-helper.rs b/src/test/ui/deriving/deriving-with-helper.rs
new file mode 100644
index 000000000..1c30b0b6f
--- /dev/null
+++ b/src/test/ui/deriving/deriving-with-helper.rs
@@ -0,0 +1,36 @@
+// check-pass
+// compile-flags: --crate-type=lib
+
+#![feature(decl_macro)]
+#![feature(lang_items)]
+#![feature(no_core)]
+#![feature(rustc_attrs)]
+
+#![no_core]
+
+#[rustc_builtin_macro]
+macro derive() {}
+
+#[rustc_builtin_macro(Default, attributes(default))]
+macro Default() {}
+
+mod default {
+ pub trait Default {
+ fn default() -> Self;
+ }
+
+ impl Default for u8 {
+ fn default() -> u8 {
+ 0
+ }
+ }
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+#[derive(Default)]
+enum S {
+ #[default] // OK
+ Foo,
+}
diff --git a/src/test/ui/deriving/deriving-with-repr-packed.rs b/src/test/ui/deriving/deriving-with-repr-packed.rs
new file mode 100644
index 000000000..8ce444be1
--- /dev/null
+++ b/src/test/ui/deriving/deriving-with-repr-packed.rs
@@ -0,0 +1,36 @@
+// run-pass
+// check that derive on a packed struct does not call field
+// methods with a misaligned field.
+
+use std::mem;
+
+#[derive(Copy, Clone)]
+struct Aligned(usize);
+
+#[inline(never)]
+fn check_align(ptr: *const Aligned) {
+ assert_eq!(ptr as usize % mem::align_of::<Aligned>(),
+ 0);
+}
+
+impl PartialEq for Aligned {
+ fn eq(&self, other: &Self) -> bool {
+ check_align(self);
+ check_align(other);
+ self.0 == other.0
+ }
+}
+
+#[repr(packed)]
+#[derive(Copy, Clone, PartialEq)]
+struct Packed(Aligned, Aligned);
+
+#[derive(PartialEq)]
+#[repr(C)]
+struct Dealigned<T>(u8, T);
+
+fn main() {
+ let d1 = Dealigned(0, Packed(Aligned(1), Aligned(2)));
+ let ck = d1 == d1;
+ assert!(ck);
+}
diff --git a/src/test/ui/deriving/issue-19358.rs b/src/test/ui/deriving/issue-19358.rs
new file mode 100644
index 000000000..3970a4155
--- /dev/null
+++ b/src/test/ui/deriving/issue-19358.rs
@@ -0,0 +1,23 @@
+// run-pass
+
+#![allow(dead_code)]
+
+trait Trait { fn dummy(&self) { } }
+
+#[derive(Debug)]
+struct Foo<T: Trait> {
+ foo: T,
+}
+
+#[derive(Debug)]
+struct Bar<T> where T: Trait {
+ bar: T,
+}
+
+impl Trait for isize {}
+
+fn main() {
+ let a = Foo { foo: 12 };
+ let b = Bar { bar: 12 };
+ println!("{:?} {:?}", a, b);
+}
diff --git a/src/test/ui/deriving/issue-3935.rs b/src/test/ui/deriving/issue-3935.rs
new file mode 100644
index 000000000..e98d68e0e
--- /dev/null
+++ b/src/test/ui/deriving/issue-3935.rs
@@ -0,0 +1,13 @@
+// run-pass
+
+#[derive(PartialEq)]
+struct Bike {
+ name: String,
+}
+
+pub fn main() {
+ let town_bike = Bike { name: "schwinn".to_string() };
+ let my_bike = Bike { name: "surly".to_string() };
+
+ assert!(town_bike != my_bike);
+}
diff --git a/src/test/ui/deriving/issue-58319.rs b/src/test/ui/deriving/issue-58319.rs
new file mode 100644
index 000000000..8041bd5bb
--- /dev/null
+++ b/src/test/ui/deriving/issue-58319.rs
@@ -0,0 +1,622 @@
+// run-pass
+fn main() {}
+#[derive(Clone)]
+pub struct Little;
+#[derive(Clone)]
+#[allow(unused_tuple_struct_fields)]
+pub struct Big(
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+ Little,
+);
diff --git a/src/test/ui/deriving/issue-6341.rs b/src/test/ui/deriving/issue-6341.rs
new file mode 100644
index 000000000..1be1394df
--- /dev/null
+++ b/src/test/ui/deriving/issue-6341.rs
@@ -0,0 +1,11 @@
+// check-pass
+// pretty-expanded FIXME #23616
+
+#[derive(PartialEq)]
+struct A { x: usize }
+
+impl Drop for A {
+ fn drop(&mut self) {}
+}
+
+pub fn main() {}
diff --git a/src/test/ui/deriving/issue-89188-gat-hrtb.rs b/src/test/ui/deriving/issue-89188-gat-hrtb.rs
new file mode 100644
index 000000000..abd85a616
--- /dev/null
+++ b/src/test/ui/deriving/issue-89188-gat-hrtb.rs
@@ -0,0 +1,39 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+trait CallWithShim: Sized {
+ type Shim<'s>
+ where
+ Self: 's;
+}
+
+#[derive(Clone)]
+struct ShimMethod<T: CallWithShim + 'static>(pub &'static dyn for<'s> Fn(&'s mut T::Shim<'s>));
+
+trait CallWithShim2: Sized {
+ type Shim<T>;
+}
+
+struct S<'s>(&'s ());
+
+#[derive(Clone)]
+struct ShimMethod2<T: CallWithShim2 + 'static>(pub &'static dyn for<'s> Fn(&'s mut T::Shim<S<'s>>));
+
+trait Trait<'s, 't, 'u> {}
+
+#[derive(Clone)]
+struct ShimMethod3<T: CallWithShim2 + 'static>(
+ pub &'static dyn for<'s> Fn(
+ &'s mut T::Shim<dyn for<'t> Fn(&'s mut T::Shim<dyn for<'u> Trait<'s, 't, 'u>>)>,
+ ),
+);
+
+trait Trait2 {
+ type As;
+}
+
+#[derive(Clone)]
+struct ShimMethod4<T: Trait2 + 'static>(pub &'static dyn for<'s> Fn(&'s mut T::As));
+
+pub fn main() {}