Rollup merge of #135064 - RalfJung:const-in-pat-partial-eq-not-const, r=compiler-errors
const-in-pattern: test that the PartialEq impl does not need to be const Fixes https://github.com/rust-lang/rust/issues/119398 by adding a test. `@compiler-errors` is there some place in the code where we could add a comment saying "as a backcompat hack, here we only require `PartialEq` and not `const PartialEq`"? r? `@compiler-errors`
This commit is contained in:
commit
966a5be559
2 changed files with 58 additions and 0 deletions
|
@ -491,6 +491,10 @@ fn type_has_partial_eq_impl<'tcx>(
|
|||
// `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem
|
||||
// we'll need to leave some sort of trace of this requirement in the MIR so that borrowck
|
||||
// can ensure that the type really implements `PartialEq`.
|
||||
// We also do *not* require `const PartialEq`, not even in `const fn`. This violates the model
|
||||
// that patterns can only do things that the code could also do without patterns, but it is
|
||||
// needed for backwards compatibility. The actual pattern matching compares primitive values,
|
||||
// `PartialEq::eq` never gets invoked, so there's no risk of us running non-const code.
|
||||
(
|
||||
infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation),
|
||||
automatically_derived,
|
||||
|
|
54
tests/ui/traits/const-traits/pattern-custom-partial-eq.rs
Normal file
54
tests/ui/traits/const-traits/pattern-custom-partial-eq.rs
Normal file
|
@ -0,0 +1,54 @@
|
|||
//! Ensure that a `const fn` can match on constants of a type that is `PartialEq`
|
||||
//! but not `const PartialEq`. This is accepted for backwards compatibility reasons.
|
||||
//@ check-pass
|
||||
#![feature(const_trait_impl)]
|
||||
|
||||
#[derive(Eq, PartialEq)]
|
||||
pub struct Y(u8);
|
||||
pub const GREEN: Y = Y(4);
|
||||
pub const fn is_green(x: Y) -> bool {
|
||||
match x { GREEN => true, _ => false }
|
||||
}
|
||||
|
||||
struct CustomEq;
|
||||
|
||||
impl Eq for CustomEq {}
|
||||
impl PartialEq for CustomEq {
|
||||
fn eq(&self, _: &Self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
#[allow(unused)]
|
||||
enum Foo {
|
||||
Bar,
|
||||
Baz,
|
||||
Qux(CustomEq),
|
||||
}
|
||||
|
||||
const BAR_BAZ: Foo = if 42 == 42 {
|
||||
Foo::Bar
|
||||
} else {
|
||||
Foo::Qux(CustomEq) // dead arm
|
||||
};
|
||||
|
||||
const EMPTY: &[CustomEq] = &[];
|
||||
|
||||
const fn test() {
|
||||
// BAR_BAZ itself is fine but the enum has other variants
|
||||
// that are non-structural. Still, this should be accepted.
|
||||
match Foo::Qux(CustomEq) {
|
||||
BAR_BAZ => panic!(),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Similarly, an empty slice of a type that is non-structural
|
||||
// is accepted.
|
||||
match &[CustomEq] as &[CustomEq] {
|
||||
EMPTY => panic!(),
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue