Skip to content

Commit 66f2d44

Browse files
Add tests from rust-lang#67088 and the issues mentioned in its description
1 parent 796c0ca commit 66f2d44

12 files changed

+468
-16
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// run-pass
2+
3+
#![warn(indirect_structural_match)]
4+
5+
// This test is checking our logic for structural match checking by enumerating
6+
// the different kinds of const expressions. This test is collecting cases where
7+
// we have accepted the const expression as a pattern in the past and wish to
8+
// continue doing so.
9+
//
10+
// Even if a non-structural-match type is part of an expression in a const's
11+
// definition, that does not necessarily disqualify the const from being a match
12+
// pattern: in principle, we just need the types involved in the final value to
13+
// be structurally matchable.
14+
15+
// See also RFC 1445
16+
17+
#![feature(type_ascription)]
18+
19+
#[derive(Copy, Clone, Debug)]
20+
struct NoPartialEq(u32);
21+
22+
#[derive(Copy, Clone, Debug)]
23+
struct NoDerive(u32);
24+
25+
// This impl makes `NoDerive` irreflexive.
26+
impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
27+
impl Eq for NoDerive { }
28+
29+
type OND = Option<NoDerive>;
30+
31+
fn main() {
32+
const FIELD1: u32 = NoPartialEq(1).0;
33+
match 1 { FIELD1 => dbg!(FIELD1), _ => panic!("whoops"), };
34+
const FIELD2: u32 = NoDerive(1).0;
35+
match 1 { FIELD2 => dbg!(FIELD2), _ => panic!("whoops"), };
36+
37+
enum CLike { One = 1, #[allow(dead_code)] Two = 2, }
38+
const ONE_CAST: u32 = CLike::One as u32;
39+
match 1 { ONE_CAST => dbg!(ONE_CAST), _ => panic!("whoops"), };
40+
41+
const NO_DERIVE_NONE: OND = None;
42+
const INDIRECT: OND = NO_DERIVE_NONE;
43+
match None { INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), };
44+
45+
const TUPLE: (OND, OND) = (None, None);
46+
match (None, None) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), };
47+
48+
const TYPE: OND = None: OND;
49+
match None { TYPE => dbg!(TYPE), _ => panic!("whoops"), };
50+
51+
const ARRAY: [OND; 2] = [None, None];
52+
match [None; 2] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), };
53+
54+
const REPEAT: [OND; 2] = [None; 2];
55+
match [None, None] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), };
56+
57+
trait Trait: Sized { const ASSOC: Option<Self>; }
58+
impl Trait for NoDerive { const ASSOC: Option<NoDerive> = None; }
59+
match None { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), };
60+
61+
const BLOCK: OND = { NoDerive(10); None };
62+
match None { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), };
63+
64+
const ADDR_OF: &OND = &None;
65+
match &None { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), };
66+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// run-pass
2+
3+
struct Sum(u32, u32);
4+
5+
impl PartialEq for Sum {
6+
fn eq(&self, other: &Self) -> bool { self.0 + self.1 == other.0 + other.1 }
7+
}
8+
9+
impl Eq for Sum { }
10+
11+
#[derive(PartialEq, Eq)]
12+
enum Eek {
13+
TheConst,
14+
UnusedByTheConst(Sum)
15+
}
16+
17+
const THE_CONST: Eek = Eek::TheConst;
18+
19+
pub fn main() {
20+
match Eek::UnusedByTheConst(Sum(1,2)) {
21+
THE_CONST => { panic!(); }
22+
_ => {}
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#![deny(indirect_structural_match)]
2+
3+
#[derive(PartialEq, Eq)]
4+
enum O<T> {
5+
Some(*const T), // Can also use PhantomData<T>
6+
None,
7+
}
8+
9+
struct B;
10+
11+
const C: &[O<B>] = &[O::None];
12+
13+
fn main() {
14+
let x = O::None;
15+
match &[x][..] {
16+
C => (),
17+
_ => (),
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0601]: `main` function not found in crate `issue_65466`
2+
--> $DIR/issue-65466.rs:1:1
3+
|
4+
LL | / #![deny(indirect_structural_match)]
5+
LL | |
6+
LL | | #[derive(PartialEq, Eq)]
7+
LL | | enum O<T> {
8+
... |
9+
LL | | }
10+
LL | | }
11+
| |_^ consider adding a `main` function to `$DIR/issue-65466.rs`
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0601`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// This test is illustrating the difference between how failing to derive
2+
// `PartialEq` is handled compared to failing to implement it at all.
3+
4+
// See also RFC 1445
5+
6+
#[derive(PartialEq, Eq)]
7+
struct Structural(u32);
8+
9+
struct NoPartialEq(u32);
10+
11+
struct NoDerive(u32);
12+
13+
// This impl makes NoDerive irreflexive.
14+
impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
15+
16+
impl Eq for NoDerive { }
17+
18+
const NO_DERIVE_NONE: Option<NoDerive> = None;
19+
const NO_PARTIAL_EQ_NONE: Option<NoPartialEq> = None;
20+
21+
fn main() {
22+
match None {
23+
NO_DERIVE_NONE => println!("NO_DERIVE_NONE"),
24+
_ => panic!("whoops"),
25+
}
26+
27+
match None {
28+
NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"),
29+
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
30+
_ => panic!("whoops"),
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: to use a constant of type `NoPartialEq` in a pattern, `NoPartialEq` must be annotated with `#[derive(PartialEq, Eq)]`
2+
--> $DIR/reject_non_partial_eq.rs:28:9
3+
|
4+
LL | NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"),
5+
| ^^^^^^^^^^^^^^^^^^
6+
7+
error: aborting due to previous error
8+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// This test of structural match checking enumerates the different kinds of
2+
// const definitions, collecting cases where the const pattern is rejected.
3+
//
4+
// Note: Even if a non-structural-match type is part of an expression in a
5+
// const's definition, that does not necessarily disqualify the const from being
6+
// a match pattern: in principle, we just need the types involved in the final
7+
// value to be structurally matchable.
8+
9+
// See also RFC 1445
10+
11+
#![feature(type_ascription)]
12+
#![warn(indirect_structural_match)]
13+
//~^ NOTE lint level is defined here
14+
15+
#[derive(Copy, Clone, Debug)]
16+
struct NoPartialEq;
17+
18+
#[derive(Copy, Clone, Debug)]
19+
struct NoDerive;
20+
21+
// This impl makes `NoDerive` irreflexive.
22+
impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
23+
24+
impl Eq for NoDerive { }
25+
26+
type OND = Option<NoDerive>;
27+
28+
struct TrivialEq(OND);
29+
30+
// This impl makes `TrivialEq` trivial.
31+
impl PartialEq for TrivialEq { fn eq(&self, _: &Self) -> bool { true } }
32+
33+
impl Eq for TrivialEq { }
34+
35+
fn main() {
36+
#[derive(PartialEq, Eq, Debug)]
37+
enum Derive<X> { Some(X), None, }
38+
39+
const ENUM: Derive<NoDerive> = Derive::Some(NoDerive);
40+
match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), };
41+
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
42+
//~| ERROR must be annotated with `#[derive(PartialEq, Eq)]`
43+
44+
const FIELD: OND = TrivialEq(Some(NoDerive)).0;
45+
match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), };
46+
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
47+
//~| ERROR must be annotated with `#[derive(PartialEq, Eq)]`
48+
49+
const NO_DERIVE_SOME: OND = Some(NoDerive);
50+
const INDIRECT: OND = NO_DERIVE_SOME;
51+
match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), };
52+
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
53+
//~| ERROR must be annotated with `#[derive(PartialEq, Eq)]`
54+
55+
const TUPLE: (OND, OND) = (None, Some(NoDerive));
56+
match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), };
57+
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
58+
//~| ERROR must be annotated with `#[derive(PartialEq, Eq)]`
59+
60+
const TYPE: OND = Some(NoDerive): OND;
61+
match Some(NoDerive) { TYPE => dbg!(TYPE), _ => panic!("whoops"), };
62+
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
63+
//~| ERROR must be annotated with `#[derive(PartialEq, Eq)]`
64+
65+
const ARRAY: [OND; 2] = [None, Some(NoDerive)];
66+
match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), };
67+
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
68+
//~| ERROR must be annotated with `#[derive(PartialEq, Eq)]`
69+
70+
const REPEAT: [OND; 2] = [Some(NoDerive); 2];
71+
match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), };
72+
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
73+
//~| ERROR must be annotated with `#[derive(PartialEq, Eq)]`
74+
//~| ERROR must be annotated with `#[derive(PartialEq, Eq)]`
75+
//~| ERROR must be annotated with `#[derive(PartialEq, Eq)]`
76+
77+
trait Trait: Sized { const ASSOC: Option<Self>; }
78+
impl Trait for NoDerive { const ASSOC: Option<NoDerive> = Some(NoDerive); }
79+
match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), };
80+
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
81+
//~| ERROR must be annotated with `#[derive(PartialEq, Eq)]`
82+
83+
const BLOCK: OND = { NoDerive; Some(NoDerive) };
84+
match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), };
85+
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
86+
//~| ERROR must be annotated with `#[derive(PartialEq, Eq)]`
87+
88+
const ADDR_OF: &OND = &Some(NoDerive);
89+
match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), };
90+
//~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
91+
//~| WARN previously accepted by the compiler but is being phased out
92+
//~| NOTE for more information, see issue #62411
93+
}

0 commit comments

Comments
 (0)