1
- //@ run-pass
1
+ //! Nullable pointer optimization with iota-reduction for enums.
2
+ //!
3
+ //! Iota-reduction is a rule from the Calculus of (Co-)Inductive Constructions:
4
+ //! "a destructor applied to an object built from a constructor behaves as expected".
5
+ //! See <https://coq.inria.fr/doc/language/core/conversion.html#iota-reduction>.
6
+ //!
7
+ //! This test verifies that nullable pointer optimization works correctly for both
8
+ //! Option<T> and custom enums, accounting for pointers and regions.
2
9
3
- // Iota-reduction is a rule in the Calculus of (Co-)Inductive Constructions,
4
- // which "says that a destructor applied to an object built from a constructor
5
- // behaves as expected". -- https://coq.inria.fr/doc/language/core/conversion.html#iota-reduction
6
- //
7
- // It's a little more complicated here, because of pointers and regions and
8
- // trying to get assert failure messages that at least identify which case
9
- // failed.
10
+ //@ run-pass
10
11
11
12
#![ allow( unpredictable_function_pointer_comparisons) ]
12
13
13
- enum E < T > { Thing ( isize , T ) , #[ allow( dead_code) ] Nothing ( ( ) , ( ( ) , ( ) ) , [ i8 ; 0 ] ) }
14
+ enum E < T > {
15
+ Thing ( isize , T ) ,
16
+ #[ allow( dead_code) ]
17
+ Nothing ( ( ) , ( ( ) , ( ) ) , [ i8 ; 0 ] ) ,
18
+ }
19
+
14
20
impl < T > E < T > {
15
21
fn is_none ( & self ) -> bool {
16
22
match * self {
17
23
E :: Thing ( ..) => false ,
18
- E :: Nothing ( ..) => true
24
+ E :: Nothing ( ..) => true ,
19
25
}
20
26
}
27
+
21
28
fn get_ref ( & self ) -> ( isize , & T ) {
22
29
match * self {
23
- E :: Nothing ( ..) => panic ! ( "E::get_ref(Nothing::<{}>)" , stringify!( T ) ) ,
24
- E :: Thing ( x, ref y) => ( x, y)
30
+ E :: Nothing ( ..) => panic ! ( "E::get_ref(Nothing::<{}>)" , stringify!( T ) ) ,
31
+ E :: Thing ( x, ref y) => ( x, y) ,
25
32
}
26
33
}
27
34
}
@@ -36,7 +43,7 @@ macro_rules! check_option {
36
43
let s_ = Some :: <$T>( e) ;
37
44
let $v = s_. as_ref( ) . unwrap( ) ;
38
45
$chk
39
- } }
46
+ } } ;
40
47
}
41
48
42
49
macro_rules! check_fancy {
@@ -48,11 +55,10 @@ macro_rules! check_fancy {
48
55
let e = $e;
49
56
let t_ = E :: Thing :: <$T>( 23 , e) ;
50
57
match t_. get_ref( ) {
51
- ( 23 , $v) => { $chk }
52
- _ => panic!( "Thing::<{}>(23, {}).get_ref() != (23, _)" ,
53
- stringify!( $T) , stringify!( $e) )
58
+ ( 23 , $v) => $chk,
59
+ _ => panic!( "Thing::<{}>(23, {}).get_ref() != (23, _)" , stringify!( $T) , stringify!( $e) ) ,
54
60
}
55
- } }
61
+ } } ;
56
62
}
57
63
58
64
macro_rules! check_type {
@@ -67,7 +73,5 @@ pub fn main() {
67
73
check_type ! ( Box :: new( 18 ) , Box <isize >) ;
68
74
check_type ! ( "foo" . to_string( ) , String ) ;
69
75
check_type ! ( vec![ 20 , 22 ] , Vec <isize >) ;
70
- check_type ! ( main, fn ( ) , |pthing| {
71
- assert_eq!( main as fn ( ) , * pthing as fn ( ) )
72
- } ) ;
76
+ check_type ! ( main, fn ( ) , |pthing| assert_eq!( main as fn ( ) , * pthing as fn ( ) ) ) ;
73
77
}
0 commit comments