Skip to content

Commit

Permalink
Regression tests and updates to existing tests.
Browse files Browse the repository at this point in the history
The regression tests explore:
  (direct | indirect | doubly-indirect | unsafe) x (embedded | param):

where:
  embedded: `struct Wrapper(... NoDerive ...);`
  param:    `struct Wrapper<X>(... X ...);`

  direct:          `const A:     Wrapper<...> = Wrapper(NoDerive);`
  indirect:        `const A: & & Wrapper<...> = Wrapper(NoDerive)`
  doubly-indirect: `const A: & & Wrapper<...> = & & Wrapper(& & NoDerive)`
  unsafe:          `const A: UnsafeWrap<...>  = UnsafeWrap(std::ptr::null())`
  • Loading branch information
pnkfelix committed Jul 8, 2019
1 parent b560801 commit 02714b8
Show file tree
Hide file tree
Showing 24 changed files with 448 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/test/ui/issues/issue-55511.rs
Expand Up @@ -14,6 +14,8 @@ fn main() {
//~^ ERROR `a` does not live long enough [E0597]
match b {
<() as Foo<'static>>::C => { }
//~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
//~| WARN will become a hard error in a future release
_ => { }
}
}
10 changes: 10 additions & 0 deletions src/test/ui/issues/issue-55511.stderr
@@ -1,3 +1,13 @@
warning: to use a constant of type `std::cell::Cell` in a pattern, `std::cell::Cell` must be annotated with `#[derive(PartialEq, Eq)]`
--> $DIR/issue-55511.rs:16:9
|
LL | <() as Foo<'static>>::C => { }
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(indirect_structural_match)] on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>

error[E0597]: `a` does not live long enough
--> $DIR/issue-55511.rs:13:28
|
Expand Down
@@ -0,0 +1,24 @@
// Test explores how `#[structral_match]` behaves in tandem with
// `*const` and `*mut` pointers.

// run-pass

struct NoDerive(i32);

// This impl makes NoDerive irreflexive
// (which doesn't matter here because `<*const T>::eq` won't recur on `T`).
impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }

impl Eq for NoDerive { }

#[derive(PartialEq, Eq)]
struct WrapEmbedded(*const NoDerive);

const WRAP_UNSAFE_EMBEDDED: WrapEmbedded = WrapEmbedded(std::ptr::null());

fn main() {
match WRAP_UNSAFE_EMBEDDED {
WRAP_UNSAFE_EMBEDDED => { println!("WRAP_UNSAFE_EMBEDDED correctly matched itself"); }
_ => { panic!("WRAP_UNSAFE_EMBEDDED did not match itself"); }
}
}
24 changes: 24 additions & 0 deletions src/test/ui/rfc1445/allow-hide-behind-direct-unsafe-ptr-param.rs
@@ -0,0 +1,24 @@
// Test explores how `#[structral_match]` behaves in tandem with
// `*const` and `*mut` pointers.

// run-pass

struct NoDerive(i32);

// This impl makes NoDerive irreflexive
// (which doesn't matter here because `<*const T>::eq` won't recur on `T`).
impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }

impl Eq for NoDerive { }

#[derive(PartialEq, Eq)]
struct WrapParam<X>(*const X);

const WRAP_UNSAFE_PARAM: WrapParam<NoDerive> = WrapParam(std::ptr::null());

fn main() {
match WRAP_UNSAFE_PARAM {
WRAP_UNSAFE_PARAM => { println!("WRAP_UNSAFE_PARAM correctly matched itself"); }
_ => { panic!("WRAP_UNSAFE_PARAM did not match itself"); }
}
}
@@ -0,0 +1,24 @@
// Test explores how `#[structral_match]` behaves in tandem with
// `*const` and `*mut` pointers.

// run-pass

struct NoDerive(i32);

// This impl makes NoDerive irreflexive
// (which doesn't matter here because `<*const T>::eq` won't recur on `T`).
impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }

impl Eq for NoDerive { }

#[derive(PartialEq, Eq)]
struct WrapEmbedded(*const NoDerive);

const WRAP_UNSAFE_EMBEDDED: & &WrapEmbedded = & &WrapEmbedded(std::ptr::null());

fn main() {
match WRAP_UNSAFE_EMBEDDED {
WRAP_UNSAFE_EMBEDDED => { println!("WRAP_UNSAFE_EMBEDDED correctly matched itself"); }
_ => { panic!("WRAP_UNSAFE_EMBEDDED did not match itself"); }
}
}
24 changes: 24 additions & 0 deletions src/test/ui/rfc1445/allow-hide-behind-indirect-unsafe-ptr-param.rs
@@ -0,0 +1,24 @@
// Test explores how `#[structral_match]` behaves in tandem with
// `*const` and `*mut` pointers.

// run-pass

struct NoDerive(i32);

// This impl makes NoDerive irreflexive
// (which doesn't matter here because `<*const T>::eq` won't recur on `T`).
impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }

impl Eq for NoDerive { }

#[derive(PartialEq, Eq)]
struct WrapParam<X>(*const X);

const WRAP_UNSAFE_PARAM: & &WrapParam<NoDerive> = & &WrapParam(std::ptr::null());

fn main() {
match WRAP_UNSAFE_PARAM {
WRAP_UNSAFE_PARAM => { println!("WRAP_UNSAFE_PARAM correctly matched itself"); }
_ => { panic!("WRAP_UNSAFE_PARAM did not match itself"); }
}
}
26 changes: 26 additions & 0 deletions src/test/ui/rfc1445/cant-hide-behind-direct-struct-embedded.rs
@@ -0,0 +1,26 @@
// This is part of a set of tests exploring the different ways a
// `#[structural_match]` ADT might try to hold a
// non-`#[structural_match]` in hidden manner that lets matches
// through that we had intended to reject.
//
// See discussion on rust-lang/rust#62307 and rust-lang/rust#62339

struct NoDerive(i32);

// This impl makes NoDerive irreflexive.
impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }

impl Eq for NoDerive { }

#[derive(PartialEq, Eq)]
struct WrapInline(NoDerive);

const WRAP_DIRECT_INLINE: WrapInline = WrapInline(NoDerive(0));

fn main() {
match WRAP_DIRECT_INLINE {
WRAP_DIRECT_INLINE => { panic!("WRAP_DIRECT_INLINE matched itself"); }
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
_ => { println!("WRAP_DIRECT_INLINE did not match itself"); }
}
}
@@ -0,0 +1,8 @@
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]`
--> $DIR/cant-hide-behind-direct-struct-embedded.rs:22:9
|
LL | WRAP_DIRECT_INLINE => { panic!("WRAP_DIRECT_INLINE matched itself"); }
| ^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

26 changes: 26 additions & 0 deletions src/test/ui/rfc1445/cant-hide-behind-direct-struct-param.rs
@@ -0,0 +1,26 @@
// This is part of a set of tests exploring the different ways a
// `#[structural_match]` ADT might try to hold a
// non-`#[structural_match]` in hidden manner that lets matches
// through that we had intended to reject.
//
// See discussion on rust-lang/rust#62307 and rust-lang/rust#62339

struct NoDerive(i32);

// This impl makes NoDerive irreflexive.
impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }

impl Eq for NoDerive { }

#[derive(PartialEq, Eq)]
struct WrapParam<T>(T);

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 must be annotated with `#[derive(PartialEq, Eq)]`
_ => { println!("WRAP_DIRECT_PARAM did not match itself"); }
}
}
@@ -0,0 +1,8 @@
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]`
--> $DIR/cant-hide-behind-direct-struct-param.rs:22:9
|
LL | WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); }
| ^^^^^^^^^^^^^^^^^

error: aborting due to previous error

29 changes: 29 additions & 0 deletions src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.rs
@@ -0,0 +1,29 @@
// This is part of a set of tests exploring the different ways a
// `#[structural_match]` ADT might try to hold a
// non-`#[structural_match]` in hidden manner that lets matches
// through that we had intended to reject.
//
// See discussion on rust-lang/rust#62307 and rust-lang/rust#62339

// run-pass

struct NoDerive(i32);

// This impl makes NoDerive irreflexive.
impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }

impl Eq for NoDerive { }

#[derive(PartialEq, Eq)]
struct WrapInline<'a>(&'a &'a NoDerive);

const WRAP_DOUBLY_INDIRECT_INLINE: & &WrapInline = & &WrapInline(& & NoDerive(0));

fn main() {
match WRAP_DOUBLY_INDIRECT_INLINE {
WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); }
//~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
//~| WARN will become a hard error in a future release
_ => { println!("WRAP_DOUBLY_INDIRECT_INLINE correctly did not match itself"); }
}
}
@@ -0,0 +1,10 @@
warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]`
--> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:24:9
|
LL | WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(indirect_structural_match)] on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>

29 changes: 29 additions & 0 deletions src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.rs
@@ -0,0 +1,29 @@
// This is part of a set of tests exploring the different ways a
// `#[structural_match]` ADT might try to hold a
// non-`#[structural_match]` in hidden manner that lets matches
// through that we had intended to reject.
//
// See discussion on rust-lang/rust#62307 and rust-lang/rust#62339

// run-pass

struct NoDerive(i32);

// This impl makes NoDerive irreflexive.
impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }

impl Eq for NoDerive { }

#[derive(PartialEq, Eq)]
struct WrapParam<'a, T>(&'a &'a T);

const WRAP_DOUBLY_INDIRECT_PARAM: & &WrapParam<NoDerive> = & &WrapParam(& & NoDerive(0));

fn main() {
match WRAP_DOUBLY_INDIRECT_PARAM {
WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); }
//~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
//~| WARN will become a hard error in a future release
_ => { println!("WRAP_DOUBLY_INDIRECT_PARAM correctly did not match itself"); }
}
}
10 changes: 10 additions & 0 deletions src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.stderr
@@ -0,0 +1,10 @@
warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]`
--> $DIR/cant-hide-behind-doubly-indirect-param.rs:24:9
|
LL | WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(indirect_structural_match)] on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>

29 changes: 29 additions & 0 deletions src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.rs
@@ -0,0 +1,29 @@
// This is part of a set of tests exploring the different ways a
// `#[structural_match]` ADT might try to hold a
// non-`#[structural_match]` in hidden manner that lets matches
// through that we had intended to reject.
//
// See discussion on rust-lang/rust#62307 and rust-lang/rust#62339

// run-pass

struct NoDerive(i32);

// This impl makes NoDerive irreflexive.
impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }

impl Eq for NoDerive { }

#[derive(PartialEq, Eq)]
struct WrapInline(NoDerive);

const WRAP_INDIRECT_INLINE: & &WrapInline = & &WrapInline(NoDerive(0));

fn main() {
match WRAP_INDIRECT_INLINE {
WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); }
//~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
//~| WARN will become a hard error in a future release
_ => { println!("WRAP_INDIRECT_INLINE did not match itself"); }
}
}
@@ -0,0 +1,10 @@
warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]`
--> $DIR/cant-hide-behind-indirect-struct-embedded.rs:24:9
|
LL | WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); }
| ^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(indirect_structural_match)] on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>

29 changes: 29 additions & 0 deletions src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.rs
@@ -0,0 +1,29 @@
// This is part of a set of tests exploring the different ways a
// `#[structural_match]` ADT might try to hold a
// non-`#[structural_match]` in hidden manner that lets matches
// through that we had intended to reject.
//
// See discussion on rust-lang/rust#62307 and rust-lang/rust#62339

// run-pass

struct NoDerive(i32);

// This impl makes NoDerive irreflexive.
impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }

impl Eq for NoDerive { }

#[derive(PartialEq, Eq)]
struct WrapParam<T>(T);

const WRAP_INDIRECT_PARAM: & &WrapParam<NoDerive> = & &WrapParam(NoDerive(0));

fn main() {
match WRAP_INDIRECT_PARAM {
WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); }
//~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
//~| WARN will become a hard error in a future release
_ => { println!("WRAP_INDIRECT_PARAM correctly did not match itself"); }
}
}
10 changes: 10 additions & 0 deletions src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.stderr
@@ -0,0 +1,10 @@
warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]`
--> $DIR/cant-hide-behind-indirect-struct-param.rs:24:9
|
LL | WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); }
| ^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(indirect_structural_match)] on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>

@@ -0,0 +1,19 @@
// Issue 61118 pointed out a case where we hit an ICE during code gen:
// the compiler assumed that `PartialEq` was always implemented on any
// use of a `const` item in a pattern context, but the pre-existing
// checking for the presence of `#[structural_match]` was too shallow
// (see rust-lang/rust#62307), and so we hit cases where we were
// trying to dispatch to `PartialEq` on types that did not implement
// that trait.

struct B(i32);

const A: &[B] = &[];

pub fn main() {
match &[][..] {
A => (),
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
_ => (),
}
}
@@ -0,0 +1,8 @@
error: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq, Eq)]`
--> $DIR/issue-61118-match-slice-forbidden-without-eq.rs:15:9
|
LL | A => (),
| ^

error: aborting due to previous error

0 comments on commit 02714b8

Please sign in to comment.