This repository was archived by the owner on May 28, 2025. It is now read-only.
File tree Expand file tree Collapse file tree 2 files changed +58
-0
lines changed
compiler/rustc_mir_build/src/thir/pattern
tests/ui/traits/const-traits Expand file tree Collapse file tree 2 files changed +58
-0
lines changed Original file line number Diff line number Diff line change @@ -491,6 +491,10 @@ fn type_has_partial_eq_impl<'tcx>(
491491 // `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem
492492 // we'll need to leave some sort of trace of this requirement in the MIR so that borrowck
493493 // can ensure that the type really implements `PartialEq`.
494+ // We also do *not* require `const PartialEq`, not even in `const fn`. This violates the model
495+ // that patterns can only do things that the code could also do without patterns, but it is
496+ // needed for backwards compatibility. The actual pattern matching compares primitive values,
497+ // `PartialEq::eq` never gets invoked, so there's no risk of us running non-const code.
494498 (
495499 infcx. predicate_must_hold_modulo_regions ( & partial_eq_obligation) ,
496500 automatically_derived,
Original file line number Diff line number Diff line change 1+ //! Ensure that a `const fn` can match on constants of a type that is `PartialEq`
2+ //! but not `const PartialEq`. This is accepted for backwards compatibility reasons.
3+ //@ check-pass
4+ #![ feature( const_trait_impl) ]
5+
6+ #[ derive( Eq , PartialEq ) ]
7+ pub struct Y ( u8 ) ;
8+ pub const GREEN : Y = Y ( 4 ) ;
9+ pub const fn is_green ( x : Y ) -> bool {
10+ match x { GREEN => true , _ => false }
11+ }
12+
13+ struct CustomEq ;
14+
15+ impl Eq for CustomEq { }
16+ impl PartialEq for CustomEq {
17+ fn eq ( & self , _: & Self ) -> bool {
18+ false
19+ }
20+ }
21+
22+ #[ derive( PartialEq , Eq ) ]
23+ #[ allow( unused) ]
24+ enum Foo {
25+ Bar ,
26+ Baz ,
27+ Qux ( CustomEq ) ,
28+ }
29+
30+ const BAR_BAZ : Foo = if 42 == 42 {
31+ Foo :: Bar
32+ } else {
33+ Foo :: Qux ( CustomEq ) // dead arm
34+ } ;
35+
36+ const EMPTY : & [ CustomEq ] = & [ ] ;
37+
38+ const fn test ( ) {
39+ // BAR_BAZ itself is fine but the enum has other variants
40+ // that are non-structural. Still, this should be accepted.
41+ match Foo :: Qux ( CustomEq ) {
42+ BAR_BAZ => panic ! ( ) ,
43+ _ => { }
44+ }
45+
46+ // Similarly, an empty slice of a type that is non-structural
47+ // is accepted.
48+ match & [ CustomEq ] as & [ CustomEq ] {
49+ EMPTY => panic ! ( ) ,
50+ _ => { } ,
51+ }
52+ }
53+
54+ fn main ( ) { }
You can’t perform that action at this time.
0 commit comments