Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub(crate) fn expand_deriving_partial_eq(
path: path_std!(marker::StructuralPartialEq),
skip_path_as_bound: true, // crucial!
needs_copy_as_bound_if_packed: false,
additional_bounds: Vec::new(),
additional_bounds: vec![Ty::Path(path_std!(marker::StructuralPartialEq))],
// We really don't support unions, but that's already checked by the impl generated below;
// a second check here would lead to redundant error messages.
supports_unions: true,
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/consts/const_in_pattern/issue-65466.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const C: &[O<B>] = &[O::None];
fn main() {
let x = O::None;
match &[x][..] {
C => (), //~ ERROR constant of non-structural type `&[O<B>]` in a pattern
C => (), //~ ERROR constant of non-structural type `O<B>` in a pattern
_ => (),
}
}
14 changes: 9 additions & 5 deletions tests/ui/consts/const_in_pattern/issue-65466.stderr
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
error: constant of non-structural type `&[O<B>]` in a pattern
error: constant of non-structural type `O<B>` in a pattern
--> $DIR/issue-65466.rs:14:9
|
LL | struct B;
| -------- must be annotated with `#[derive(PartialEq)]` to be usable in patterns
LL |
LL | enum O<T> {
| --------- `O<B>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const C: &[O<B>] = &[O::None];
| ---------------- constant defined here
...
LL | C => (),
| ^ constant of non-structural type
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
help: if `O<B>` manually implemented `PartialEq`, you could add a condition to the match arm checking for equality
|
LL - C => (),
LL + binding if binding == C => (),
|

error: aborting due to 1 previous error

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Regression test for https://github.com/rust-lang/rust/issues/147714.

#[allow(dead_code)]
#[derive(PartialEq)]
enum Thing<T> {
A(T),
B,
}

struct Incomparable;

impl PartialEq for Thing<Incomparable> {
fn eq(&self, _: &Self) -> bool {
panic!()
}
}

const X: Thing<Incomparable> = Thing::B;

fn main() {
if let X = X { //~ ERROR constant of non-structural type `Thing<Incomparable>` in a pattern
println!("equal");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error: constant of non-structural type `Thing<Incomparable>` in a pattern
--> $DIR/put-structural-partial-eq-bound-on-generics-issue-147714.rs:21:12
|
LL | enum Thing<T> {
| ------------- `Thing<Incomparable>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const X: Thing<Incomparable> = Thing::B;
| ---------------------------- constant defined here
...
LL | if let X = X {
| ^ constant of non-structural type
|
help: if `Thing<Incomparable>` manually implemented `PartialEq`, you could check for equality instead of pattern matching
|
LL - if let X = X {
LL + if X == X {
|

error: aborting due to 1 previous error

23 changes: 11 additions & 12 deletions tests/ui/consts/const_in_pattern/reject_non_structural.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,15 @@ struct NoPartialEq;

#[derive(Copy, Clone, Debug)]
struct NoDerive;
//~^ NOTE must be annotated with `#[derive(PartialEq)]`
//~| NOTE must be annotated with `#[derive(PartialEq)]`
//~| NOTE must be annotated with `#[derive(PartialEq)]`
//~| NOTE must be annotated with `#[derive(PartialEq)]`
//~| NOTE must be annotated with `#[derive(PartialEq)]`
//~| NOTE must be annotated with `#[derive(PartialEq)]`
//~| NOTE must be annotated with `#[derive(PartialEq)]`
//~| NOTE must be annotated with `#[derive(PartialEq)]`
//~| NOTE must be annotated with `#[derive(PartialEq)]`
//~| NOTE must be annotated with `#[derive(PartialEq)]`
//~^ NOTE `NoDerive` must be annotated with `#[derive(PartialEq)]`
//~| NOTE `NoDerive` must be annotated with `#[derive(PartialEq)]`
//~| NOTE `NoDerive` must be annotated with `#[derive(PartialEq)]`
//~| NOTE `NoDerive` must be annotated with `#[derive(PartialEq)]`
//~| NOTE `NoDerive` must be annotated with `#[derive(PartialEq)]`
//~| NOTE `NoDerive` must be annotated with `#[derive(PartialEq)]`
//~| NOTE `NoDerive` must be annotated with `#[derive(PartialEq)]`
//~| NOTE `NoDerive` must be annotated with `#[derive(PartialEq)]`
//~| NOTE `NoDerive` must be annotated with `#[derive(PartialEq)]`

// This impl makes `NoDerive` irreflexive.
impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
Expand All @@ -39,7 +38,6 @@ impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
//~| NOTE StructuralPartialEq.html for details
//~| NOTE StructuralPartialEq.html for details
//~| NOTE StructuralPartialEq.html for details
//~| NOTE StructuralPartialEq.html for details

impl Eq for NoDerive { }

Expand All @@ -55,10 +53,11 @@ impl Eq for TrivialEq { }
fn main() {
#[derive(PartialEq, Eq, Debug)]
enum Derive<X> { Some(X), None, }
//~^ NOTE `Derive<NoDerive>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns

const ENUM: Derive<NoDerive> = Derive::Some(NoDerive); //~ NOTE constant defined here
match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), };
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
//~^ ERROR constant of non-structural type `Derive<NoDerive>` in a pattern
//~| NOTE constant of non-structural type

const FIELD: OND = TrivialEq(Some(NoDerive)).0; //~ NOTE constant defined here
Expand Down
51 changes: 23 additions & 28 deletions tests/ui/consts/const_in_pattern/reject_non_structural.stderr
Original file line number Diff line number Diff line change
@@ -1,27 +1,22 @@
error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:60:36
error: constant of non-structural type `Derive<NoDerive>` in a pattern
--> $DIR/reject_non_structural.rs:59:36
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
LL | enum Derive<X> { Some(X), None, }
| -------------- `Derive<NoDerive>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const ENUM: Derive<NoDerive> = Derive::Some(NoDerive);
| ---------------------------- constant defined here
LL | match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), };
| ^^^^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: add a condition to the match arm checking for equality
help: if `Derive<NoDerive>` manually implemented `PartialEq`, you could add a condition to the match arm checking for equality
|
LL - match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), };
LL + match Derive::Some(NoDerive) { binding if binding == ENUM => dbg!(ENUM), _ => panic!("whoops"), };
|

error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:65:28
--> $DIR/reject_non_structural.rs:64:28
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
Expand All @@ -32,7 +27,7 @@ LL | match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), };
| ^^^^^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
--> $DIR/reject_non_structural.rs:31:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -43,7 +38,7 @@ LL + match Some(NoDerive) { binding if binding == FIELD => dbg!(FIELD), _ =>
|

error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:71:27
--> $DIR/reject_non_structural.rs:70:27
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
Expand All @@ -54,7 +49,7 @@ LL | match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops")
| ^^^^^^^^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
--> $DIR/reject_non_structural.rs:31:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -65,7 +60,7 @@ LL + match Some(NoDerive) {binding if binding == INDIRECT => dbg!(INDIRECT),
|

error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:76:36
--> $DIR/reject_non_structural.rs:75:36
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
Expand All @@ -76,7 +71,7 @@ LL | match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoop
| ^^^^^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
--> $DIR/reject_non_structural.rs:31:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -87,7 +82,7 @@ LL + match (None, Some(NoDerive)) { binding if binding == TUPLE => dbg!(TUPL
|

error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:81:28
--> $DIR/reject_non_structural.rs:80:28
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
Expand All @@ -98,7 +93,7 @@ LL | match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => p
| ^^^^^^^^^^^^^^^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
--> $DIR/reject_non_structural.rs:31:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -109,7 +104,7 @@ LL + match Some(NoDerive) { binding if binding == TYPE_ASCRIPTION => dbg!(TY
|

error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:86:36
--> $DIR/reject_non_structural.rs:85:36
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
Expand All @@ -120,7 +115,7 @@ LL | match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoop
| ^^^^^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
--> $DIR/reject_non_structural.rs:31:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -131,7 +126,7 @@ LL + match [None, Some(NoDerive)] { binding if binding == ARRAY => dbg!(ARRA
|

error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:91:33
--> $DIR/reject_non_structural.rs:90:33
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
Expand All @@ -142,7 +137,7 @@ LL | match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops
| ^^^^^^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
--> $DIR/reject_non_structural.rs:31:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -153,7 +148,7 @@ LL + match [Some(NoDerive); 2] { binding if binding == REPEAT => dbg!(REPEAT
|

error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:97:28
--> $DIR/reject_non_structural.rs:96:28
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
Expand All @@ -165,7 +160,7 @@ LL | match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => p
| ^^^^^^^^^^^^^^^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
--> $DIR/reject_non_structural.rs:31:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -176,7 +171,7 @@ LL + match Some(NoDerive) { binding if binding == NoDerive::ASSOC => dbg!(No
|

error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:102:28
--> $DIR/reject_non_structural.rs:101:28
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
Expand All @@ -187,7 +182,7 @@ LL | match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), };
| ^^^^^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
--> $DIR/reject_non_structural.rs:31:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -198,7 +193,7 @@ LL + match Some(NoDerive) { binding if binding == BLOCK => dbg!(BLOCK), _ =>
|

error: constant of non-structural type `NoDerive` in a pattern
--> $DIR/reject_non_structural.rs:107:29
--> $DIR/reject_non_structural.rs:106:29
|
LL | struct NoDerive;
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
Expand All @@ -209,7 +204,7 @@ LL | match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops")
| ^^^^^^^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/reject_non_structural.rs:32:1
--> $DIR/reject_non_structural.rs:31:1
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
17 changes: 13 additions & 4 deletions tests/ui/derives/deriving-all-codegen.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,11 @@ impl<T: ::core::hash::Hash + Trait, U: ::core::hash::Hash> ::core::hash::Hash
}
}
#[automatically_derived]
impl<T: Trait, U> ::core::marker::StructuralPartialEq for Generic<T, U> { }
impl<T: ::core::marker::StructuralPartialEq + Trait,
U: ::core::marker::StructuralPartialEq>
::core::marker::StructuralPartialEq for Generic<T, U> where
T::A: ::core::marker::StructuralPartialEq {
}
#[automatically_derived]
impl<T: ::core::cmp::PartialEq + Trait, U: ::core::cmp::PartialEq>
::core::cmp::PartialEq for Generic<T, U> where
Expand Down Expand Up @@ -953,8 +957,10 @@ impl<T: ::core::hash::Hash + ::core::marker::Copy + Trait,
}
}
#[automatically_derived]
impl<T: Trait, U> ::core::marker::StructuralPartialEq for PackedGeneric<T, U>
{
impl<T: ::core::marker::StructuralPartialEq + Trait,
U: ::core::marker::StructuralPartialEq>
::core::marker::StructuralPartialEq for PackedGeneric<T, U> where
T::A: ::core::marker::StructuralPartialEq {
}
#[automatically_derived]
impl<T: ::core::cmp::PartialEq + ::core::marker::Copy + Trait,
Expand Down Expand Up @@ -1678,7 +1684,10 @@ impl<T: ::core::hash::Hash, U: ::core::hash::Hash> ::core::hash::Hash for
}
}
#[automatically_derived]
impl<T, U> ::core::marker::StructuralPartialEq for EnumGeneric<T, U> { }
impl<T: ::core::marker::StructuralPartialEq,
U: ::core::marker::StructuralPartialEq>
::core::marker::StructuralPartialEq for EnumGeneric<T, U> {
}
#[automatically_derived]
impl<T: ::core::cmp::PartialEq, U: ::core::cmp::PartialEq>
::core::cmp::PartialEq for EnumGeneric<T, U> {
Expand Down
10 changes: 7 additions & 3 deletions tests/ui/match/issue-72896-non-partial-eq-const.stderr
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
error: constant of non-structural type `EnumSet<Enum8>` in a pattern
--> $DIR/issue-72896-non-partial-eq-const.rs:19:9
|
LL | enum Enum8 { }
| ---------- must be annotated with `#[derive(PartialEq)]` to be usable in patterns
LL | struct EnumSet<T: EnumSetType> {
| ------------------------------ `EnumSet<Enum8>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 };
| ------------------------------- constant defined here
...
LL | CONST_SET => { /* ok */ }
| ^^^^^^^^^ constant of non-structural type
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
help: if `EnumSet<Enum8>` manually implemented `PartialEq`, you could add a condition to the match arm checking for equality
|
LL - CONST_SET => { /* ok */ }
LL + binding if binding == CONST_SET => { /* ok */ }
|

error: aborting due to 1 previous error

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const WRAP_DIRECT_PARAM: WrapParam<NoDerive> = WrapParam(NoDerive(0));
fn main() {
match WRAP_DIRECT_PARAM {
WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); }
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
//~^ ERROR constant of non-structural type `WrapParam<NoDerive>` in a pattern
_ => { println!("WRAP_DIRECT_PARAM did not match itself"); }
}
}
Loading
Loading