mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Rollup merge of #154118 - malezjaa:dont-suggest-some-traits-for-unions, r=JonathanBrouwer
don't suggest non-deriveable traits for unions Fixes rust-lang/rust#137587 Before, the compiler suggested adding `#[derive(Debug)]` (other traits too) for unions, which is misleading because some traits can't be automatically derived. Only traits that are still suggested are Copy and Clone. I noticed the error label changed after removing the suggestion. I hope this isn't a big deal, but let me know if that's an issue. original example: ```rs union Union { member: usize, } impl PartialEq<u8> for Union { fn eq(&self, rhs: &u8) -> bool { unsafe { self.member == (*rhs).into() } } } fn main() { assert_eq!(Union { member: 0 }, 0); } ``` before: ``` error[E0277]: `Union` doesn't implement `Debug` --> src\main.rs:13:5 | 13 | assert_eq!(Union { member: 0 }, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `Union` | = note: add `#[derive(Debug)]` to `Union` or manually `impl Debug for Union` = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Union` with `#[derive(Debug)]` | 2 + #[derive(Debug)] 3 | union Union { | ``` after (the message doesn't suggest adding #[derive(Debug)] to unions) ``` error[E0277]: `Union` doesn't implement `Debug` --> src\main.rs:13:5 | 13 | assert_eq!(Union { member: 0 }, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound | help: the trait `Debug` is not implemented for `Union` --> src\main.rs:2:1 | 2 | union Union { | ^^^^^^^^^^^ = note: manually `impl Debug for Union` ```
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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}`"
|
||||
|
||||
+5
-2
@@ -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}
|
||||
}
|
||||
|
||||
+44
-20
@@ -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<T> {}
|
||||
| ^^^^^^^^^^^^
|
||||
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<i32>) {}
|
||||
| ^^^^^^^^ 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`.
|
||||
|
||||
@@ -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<T: Trait>() {}
|
||||
|
||||
fn main() {
|
||||
needs_trait::<Union>();
|
||||
//~^ ERROR union self type
|
||||
needs_trait::<Enum>();
|
||||
//~^ ERROR enum self type
|
||||
needs_trait::<Struct>();
|
||||
//~^ ERROR struct self type
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
error[E0277]: union self type
|
||||
--> $DIR/self-types.rs:24:19
|
||||
|
|
||||
LL | needs_trait::<Union>();
|
||||
| ^^^^^ 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<T: Trait>() {}
|
||||
| ^^^^^ required by this bound in `needs_trait`
|
||||
|
||||
error[E0277]: enum self type
|
||||
--> $DIR/self-types.rs:26:19
|
||||
|
|
||||
LL | needs_trait::<Enum>();
|
||||
| ^^^^ 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<T: Trait>() {}
|
||||
| ^^^^^ required by this bound in `needs_trait`
|
||||
|
||||
error[E0277]: struct self type
|
||||
--> $DIR/self-types.rs:28:19
|
||||
|
|
||||
LL | needs_trait::<Struct>();
|
||||
| ^^^^^^ 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<T: 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`.
|
||||
@@ -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<T: Clone>() {}
|
||||
fn y<T: Copy>() {}
|
||||
|
||||
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::<U>(); //~ ERROR the trait bound `U: Clone` is not satisfied
|
||||
// Copy
|
||||
y::<U>(); //~ ERROR the trait bound `U: Copy` is not satisfied
|
||||
}
|
||||
@@ -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::<U>();
|
||||
| ^ 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<T: Clone>() {}
|
||||
| ^^^^^ 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::<U>();
|
||||
| ^ 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<T: Copy>() {}
|
||||
| ^^^^ 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`.
|
||||
Reference in New Issue
Block a user