diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs index 63780676bead..8abcaeb5fbf5 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs @@ -470,11 +470,12 @@ fn parse_filter(input: Symbol) -> FilterFormatString { // if the integer type has been resolved, to allow targeting all integers. // `"{integer}"` and `"{float}"` come from numerics that haven't been inferred yet, // from the `Display` impl of `InferTy` to be precise. + // `"{union|enum|struct}"` is used as a special selector for ADTs. // // Don't try to format these later! - Position::ArgumentNamed(arg @ ("integer" | "integral" | "float")) => { - LitOrArg::Lit(Symbol::intern(&format!("{{{arg}}}"))) - } + Position::ArgumentNamed( + arg @ ("integer" | "integral" | "float" | "union" | "enum" | "struct"), + ) => LitOrArg::Lit(Symbol::intern(&format!("{{{arg}}}"))), Position::ArgumentNamed(arg) => LitOrArg::Arg(Symbol::intern(arg)), Position::ArgumentImplicitlyIs(_) => LitOrArg::Lit(sym::empty_braces), diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 9d496c66f968..893cd025a089 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -3460,13 +3460,13 @@ fn consider_suggesting_derives_for_ty( let diagnostic_name = self.tcx.get_diagnostic_name(trait_pred.def_id())?; let can_derive = match diagnostic_name { + sym::Copy | sym::Clone => true, + _ if adt.is_union() => false, sym::Default | sym::Eq | sym::PartialEq | sym::Ord | sym::PartialOrd - | sym::Clone - | sym::Copy | sym::Hash | sym::Debug => true, _ => false, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index d08e0fa3521b..4ae6584fc2d1 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -124,8 +124,11 @@ pub(crate) fn on_unimplemented_components( } } - if let Some(true) = self_ty.ty_adt_def().map(|def| def.did().is_local()) { - crate_local = true; + if let Some(adt) = self_ty.ty_adt_def() { + if adt.did().is_local() { + crate_local = true; + } + self_types.push(format!("{{{}}}", adt.descr())) } // Allow targeting all integers using `{integral}`, even if the exact type was resolved diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index ee2f8d9783cf..4a6d5eb48f8f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -4037,12 +4037,13 @@ pub fn can_suggest_derive( _ => return false, }; let is_derivable_trait = match diagnostic_name { - sym::Default => !adt.is_enum(), + sym::Copy | sym::Clone => true, + _ if adt.is_union() => false, sym::PartialEq | sym::PartialOrd => { let rhs_ty = trait_pred.skip_binder().trait_ref.args.type_at(1); trait_pred.skip_binder().self_ty() == rhs_ty } - sym::Eq | sym::Ord | sym::Clone | sym::Copy | sym::Hash | sym::Debug => true, + sym::Eq | sym::Ord | sym::Hash | sym::Debug | sym::Default => true, _ => false, }; is_derivable_trait && diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 05d8e0d84f05..ecd1e34078e2 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -1037,9 +1037,10 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented( on( - crate_local, + all(crate_local, not(Self = "{union}")), note = "add `#[derive(Debug)]` to `{Self}` or manually `impl {This} for {Self}`" ), + on(all(crate_local, Self = "{union}"), note = "manually `impl {This} for {Self}`"), on( from_desugaring = "FormatLiteral", label = "`{Self}` cannot be formatted using `{{:?}}` because it doesn't implement `{This}`" diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.rs b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.rs index e64e60f30c0c..09c2a05cd009 100644 --- a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.rs +++ b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.rs @@ -26,12 +26,15 @@ impl Bar for i32 {} // cannot use special rustc_on_unimplement symbols // in the format string #[diagnostic::on_unimplemented( - message = "{from_desugaring}{direct}{cause}{integral}{integer}", + message = "{from_desugaring}{direct}{cause}{integral}{integer}{struct}{enum}{union}", //~^WARN there is no parameter `from_desugaring` on trait `Baz` //~|WARN there is no parameter `direct` on trait `Baz` //~|WARN there is no parameter `cause` on trait `Baz` //~|WARN there is no parameter `integral` on trait `Baz` //~|WARN there is no parameter `integer` on trait `Baz` + //~|WARN there is no parameter `r#struct` on trait `Baz` + //~|WARN there is no parameter `r#enum` on trait `Baz` + //~|WARN there is no parameter `union` on trait `Baz` label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}" //~^WARN there is no parameter `float` on trait `Baz` //~|WARN there is no parameter `_Self` on trait `Baz` @@ -52,5 +55,5 @@ fn main() { takes_bar(()); //~^ERROR the trait bound `(): Bar` is not satisfied takes_baz(()); - //~^ERROR {from_desugaring}{direct}{cause}{integral}{integer} + //~^ERROR {from_desugaring}{direct}{cause}{integral}{integer}{struct}{enum}{union} } diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr index 862f805e15ba..58d2bdbfc4d6 100644 --- a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr +++ b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr @@ -9,7 +9,7 @@ LL | #[diagnostic::on_unimplemented(message = "Not allowed to apply it on a impl warning: there is no parameter `from_desugaring` on trait `Baz` --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:17 | -LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}", +LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}{struct}{enum}{union}", | ^^^^^^^^^^^^^^^ | = help: expect either a generic argument name or `{Self}` as format argument @@ -18,7 +18,7 @@ LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}", warning: there is no parameter `direct` on trait `Baz` --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:34 | -LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}", +LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}{struct}{enum}{union}", | ^^^^^^ | = help: expect either a generic argument name or `{Self}` as format argument @@ -26,7 +26,7 @@ LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}", warning: there is no parameter `cause` on trait `Baz` --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:42 | -LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}", +LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}{struct}{enum}{union}", | ^^^^^ | = help: expect either a generic argument name or `{Self}` as format argument @@ -34,7 +34,7 @@ LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}", warning: there is no parameter `integral` on trait `Baz` --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:49 | -LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}", +LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}{struct}{enum}{union}", | ^^^^^^^^ | = help: expect either a generic argument name or `{Self}` as format argument @@ -42,13 +42,37 @@ LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}", warning: there is no parameter `integer` on trait `Baz` --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:59 | -LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}", +LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}{struct}{enum}{union}", | ^^^^^^^ | = help: expect either a generic argument name or `{Self}` as format argument +warning: there is no parameter `r#struct` on trait `Baz` + --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:68 + | +LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}{struct}{enum}{union}", + | ^^^^^^ + | + = help: expect either a generic argument name or `{Self}` as format argument + +warning: there is no parameter `r#enum` on trait `Baz` + --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:76 + | +LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}{struct}{enum}{union}", + | ^^^^ + | + = help: expect either a generic argument name or `{Self}` as format argument + +warning: there is no parameter `union` on trait `Baz` + --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:82 + | +LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}{struct}{enum}{union}", + | ^^^^^ + | + = help: expect either a generic argument name or `{Self}` as format argument + warning: there is no parameter `float` on trait `Baz` - --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:35:15 + --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:38:15 | LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}" | ^^^^^ @@ -56,7 +80,7 @@ LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}" = help: expect either a generic argument name or `{Self}` as format argument warning: there is no parameter `_Self` on trait `Baz` - --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:35:22 + --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:38:22 | LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}" | ^^^^^ @@ -64,7 +88,7 @@ LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}" = help: expect either a generic argument name or `{Self}` as format argument warning: there is no parameter `crate_local` on trait `Baz` - --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:35:29 + --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:38:29 | LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}" | ^^^^^^^^^^^ @@ -72,7 +96,7 @@ LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}" = help: expect either a generic argument name or `{Self}` as format argument warning: there is no parameter `Trait` on trait `Baz` - --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:35:42 + --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:38:42 | LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}" | ^^^^^ @@ -80,7 +104,7 @@ LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}" = help: expect either a generic argument name or `{Self}` as format argument warning: there is no parameter `ItemContext` on trait `Baz` - --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:35:49 + --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:38:49 | LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}" | ^^^^^^^^^^^ @@ -88,7 +112,7 @@ LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}" = help: expect either a generic argument name or `{Self}` as format argument warning: there is no parameter `This` on trait `Baz` - --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:35:62 + --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:38:62 | LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}" | ^^^^ @@ -129,7 +153,7 @@ LL | #[diagnostic::on_unimplemented = "Message"] = help: only `message`, `note` and `label` are allowed as options error[E0277]: trait has `()` and `i32` as params - --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:50:15 + --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:53:15 | LL | takes_foo(()); | --------- ^^ trait has `()` and `i32` as params @@ -144,13 +168,13 @@ help: this trait has no implementations, consider adding one LL | trait Foo {} | ^^^^^^^^^^^^ note: required by a bound in `takes_foo` - --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:45:22 + --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:48:22 | LL | fn takes_foo(_: impl Foo) {} | ^^^^^^^^ required by this bound in `takes_foo` error[E0277]: the trait bound `(): Bar` is not satisfied - --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:52:15 + --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:55:15 | LL | takes_bar(()); | --------- ^^ the trait `Bar` is not implemented for `()` @@ -163,13 +187,13 @@ help: the trait `Bar` is implemented for `i32` LL | impl Bar for i32 {} | ^^^^^^^^^^^^^^^^ note: required by a bound in `takes_bar` - --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:46:22 + --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:49:22 | LL | fn takes_bar(_: impl Bar) {} | ^^^ required by this bound in `takes_bar` -error[E0277]: {from_desugaring}{direct}{cause}{integral}{integer} - --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:54:15 +error[E0277]: {from_desugaring}{direct}{cause}{integral}{integer}{struct}{enum}{union} + --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:57:15 | LL | takes_baz(()); | --------- ^^ {float}{_Self}{crate_local}{Trait}{ItemContext}{This} @@ -178,16 +202,16 @@ LL | takes_baz(()); | = help: the trait `Baz` is not implemented for `()` help: this trait has no implementations, consider adding one - --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:43:1 + --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:46:1 | LL | trait Baz {} | ^^^^^^^^^ note: required by a bound in `takes_baz` - --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:47:22 + --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:50:22 | LL | fn takes_baz(_: impl Baz) {} | ^^^ required by this bound in `takes_baz` -error: aborting due to 3 previous errors; 16 warnings emitted +error: aborting due to 3 previous errors; 19 warnings emitted For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/on-unimplemented/self-types.rs b/tests/ui/on-unimplemented/self-types.rs new file mode 100644 index 000000000000..736d3baf60c7 --- /dev/null +++ b/tests/ui/on-unimplemented/self-types.rs @@ -0,0 +1,30 @@ +#![feature(rustc_attrs)] + +#[rustc_on_unimplemented( + on(Self = "{union}", message = "union self type"), + on(Self = "{enum}", message = "enum self type"), + on(Self = "{struct}", message = "struct self type"), + message = "fallback self type `{Self}`" +)] +trait Trait {} + +union Union { + value: u8, +} + +enum Enum { + Variant, +} + +struct Struct; + +fn needs_trait() {} + +fn main() { + needs_trait::(); + //~^ ERROR union self type + needs_trait::(); + //~^ ERROR enum self type + needs_trait::(); + //~^ ERROR struct self type +} diff --git a/tests/ui/on-unimplemented/self-types.stderr b/tests/ui/on-unimplemented/self-types.stderr new file mode 100644 index 000000000000..ea40ac566bb9 --- /dev/null +++ b/tests/ui/on-unimplemented/self-types.stderr @@ -0,0 +1,69 @@ +error[E0277]: union self type + --> $DIR/self-types.rs:24:19 + | +LL | needs_trait::(); + | ^^^^^ unsatisfied trait bound + | +help: the trait `Trait` is not implemented for `Union` + --> $DIR/self-types.rs:11:1 + | +LL | union Union { + | ^^^^^^^^^^^ +help: this trait has no implementations, consider adding one + --> $DIR/self-types.rs:9:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ +note: required by a bound in `needs_trait` + --> $DIR/self-types.rs:21:19 + | +LL | fn needs_trait() {} + | ^^^^^ required by this bound in `needs_trait` + +error[E0277]: enum self type + --> $DIR/self-types.rs:26:19 + | +LL | needs_trait::(); + | ^^^^ unsatisfied trait bound + | +help: the trait `Trait` is not implemented for `Enum` + --> $DIR/self-types.rs:15:1 + | +LL | enum Enum { + | ^^^^^^^^^ +help: this trait has no implementations, consider adding one + --> $DIR/self-types.rs:9:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ +note: required by a bound in `needs_trait` + --> $DIR/self-types.rs:21:19 + | +LL | fn needs_trait() {} + | ^^^^^ required by this bound in `needs_trait` + +error[E0277]: struct self type + --> $DIR/self-types.rs:28:19 + | +LL | needs_trait::(); + | ^^^^^^ unsatisfied trait bound + | +help: the trait `Trait` is not implemented for `Struct` + --> $DIR/self-types.rs:19:1 + | +LL | struct Struct; + | ^^^^^^^^^^^^^ +help: this trait has no implementations, consider adding one + --> $DIR/self-types.rs:9:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ +note: required by a bound in `needs_trait` + --> $DIR/self-types.rs:21:19 + | +LL | fn needs_trait() {} + | ^^^^^ required by this bound in `needs_trait` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/union/union-no-derive-suggestion.rs b/tests/ui/union/union-no-derive-suggestion.rs new file mode 100644 index 000000000000..0ccbac3167f2 --- /dev/null +++ b/tests/ui/union/union-no-derive-suggestion.rs @@ -0,0 +1,37 @@ +//! Check that we do not suggest using `#[derive(...)]` for unions, +//! as some traits cannot be autoderived for them. +//@ dont-require-annotations: NOTE + +union U { //~ HELP consider annotating `U` with `#[derive(Clone)]` + //~| HELP consider annotating `U` with `#[derive(Copy)]` + //~| HELP the trait `Debug` is not implemented for `U` + //~| HELP the trait `Default` is not implemented for `U` + //~| HELP the trait `Hash` is not implemented for `U` + a: u8, +} + +fn x() {} +fn y() {} + +fn main() { + let u = U { a: 0 }; + // Debug + println!("{u:?}"); //~ ERROR `U` doesn't implement `Debug` + //~| NOTE manually `impl Debug for U` + // PartialEq + let _ = u == U { a: 0 }; //~ ERROR binary operation `==` cannot be applied to type `U` + //~| NOTE the trait `PartialEq` must be implemented + // PartialOrd + let _ = u < U { a: 1 }; //~ ERROR binary operation `<` cannot be applied to type `U` + //~| NOTE the trait `PartialOrd` must be implemented + // Default + let _: U = Default::default(); //~ ERROR the trait bound `U: Default` is not satisfied + // Hash + let mut h = std::collections::hash_map::DefaultHasher::new(); + std::hash::Hash::hash(&u, &mut h); //~ ERROR the trait bound `U: Hash` is not satisfied + + // Clone + x::(); //~ ERROR the trait bound `U: Clone` is not satisfied + // Copy + y::(); //~ ERROR the trait bound `U: Copy` is not satisfied +} diff --git a/tests/ui/union/union-no-derive-suggestion.stderr b/tests/ui/union/union-no-derive-suggestion.stderr new file mode 100644 index 000000000000..7a42b871b80d --- /dev/null +++ b/tests/ui/union/union-no-derive-suggestion.stderr @@ -0,0 +1,109 @@ +error[E0277]: `U` doesn't implement `Debug` + --> $DIR/union-no-derive-suggestion.rs:19:15 + | +LL | println!("{u:?}"); + | ^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | +help: the trait `Debug` is not implemented for `U` + --> $DIR/union-no-derive-suggestion.rs:5:1 + | +LL | union U { + | ^^^^^^^ + = note: manually `impl Debug for U` + +error[E0369]: binary operation `==` cannot be applied to type `U` + --> $DIR/union-no-derive-suggestion.rs:22:15 + | +LL | let _ = u == U { a: 0 }; + | - ^^ ---------- U + | | + | U + | +note: an implementation of `PartialEq` might be missing for `U` + --> $DIR/union-no-derive-suggestion.rs:5:1 + | +LL | union U { + | ^^^^^^^ must implement `PartialEq` +note: the trait `PartialEq` must be implemented + --> $SRC_DIR/core/src/cmp.rs:LL:COL + +error[E0369]: binary operation `<` cannot be applied to type `U` + --> $DIR/union-no-derive-suggestion.rs:25:15 + | +LL | let _ = u < U { a: 1 }; + | - ^ ---------- U + | | + | U + | +note: an implementation of `PartialOrd` might be missing for `U` + --> $DIR/union-no-derive-suggestion.rs:5:1 + | +LL | union U { + | ^^^^^^^ must implement `PartialOrd` +note: the trait `PartialOrd` must be implemented + --> $SRC_DIR/core/src/cmp.rs:LL:COL + +error[E0277]: the trait bound `U: Default` is not satisfied + --> $DIR/union-no-derive-suggestion.rs:28:16 + | +LL | let _: U = Default::default(); + | ^^^^^^^^^^^^^^^^^^ unsatisfied trait bound + | +help: the trait `Default` is not implemented for `U` + --> $DIR/union-no-derive-suggestion.rs:5:1 + | +LL | union U { + | ^^^^^^^ + +error[E0277]: the trait bound `U: Hash` is not satisfied + --> $DIR/union-no-derive-suggestion.rs:31:27 + | +LL | std::hash::Hash::hash(&u, &mut h); + | --------------------- ^^ unsatisfied trait bound + | | + | required by a bound introduced by this call + | +help: the trait `Hash` is not implemented for `U` + --> $DIR/union-no-derive-suggestion.rs:5:1 + | +LL | union U { + | ^^^^^^^ + +error[E0277]: the trait bound `U: Clone` is not satisfied + --> $DIR/union-no-derive-suggestion.rs:34:9 + | +LL | x::(); + | ^ the trait `Clone` is not implemented for `U` + | +note: required by a bound in `x` + --> $DIR/union-no-derive-suggestion.rs:13:9 + | +LL | fn x() {} + | ^^^^^ required by this bound in `x` +help: consider annotating `U` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | union U { + | + +error[E0277]: the trait bound `U: Copy` is not satisfied + --> $DIR/union-no-derive-suggestion.rs:36:9 + | +LL | y::(); + | ^ the trait `Copy` is not implemented for `U` + | +note: required by a bound in `y` + --> $DIR/union-no-derive-suggestion.rs:14:9 + | +LL | fn y() {} + | ^^^^ required by this bound in `y` +help: consider annotating `U` with `#[derive(Copy)]` + | +LL + #[derive(Copy)] +LL | union U { + | + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0277, E0369. +For more information about an error, try `rustc --explain E0277`.