File tree 2 files changed +58
-0
lines changed
compiler/rustc_mir_build/src/thir/pattern
tests/ui/traits/const-traits
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>(
491
491
// `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem
492
492
// we'll need to leave some sort of trace of this requirement in the MIR so that borrowck
493
493
// 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.
494
498
(
495
499
infcx. predicate_must_hold_modulo_regions ( & partial_eq_obligation) ,
496
500
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