|
1 | 1 | use itertools::Itertools; |
2 | 2 |
|
3 | 3 | use super::query_context::test::{Def, UltraMinimal}; |
4 | | -use crate::maybe_transmutable::MaybeTransmutableQuery; |
5 | | -use crate::{Reason, layout}; |
| 4 | +use crate::{Answer, Assume, Reason, layout}; |
6 | 5 |
|
7 | | -mod safety { |
8 | | - use super::*; |
9 | | - use crate::Answer; |
| 6 | +type Tree = layout::Tree<Def, !>; |
| 7 | +type Dfa = layout::Dfa<!>; |
10 | 8 |
|
11 | | - type Tree = layout::Tree<Def, !>; |
| 9 | +trait Representation { |
| 10 | + fn is_transmutable(src: Self, dst: Self, assume: Assume) -> Answer<!>; |
| 11 | +} |
12 | 12 |
|
13 | | - const DST_HAS_SAFETY_INVARIANTS: Answer<!> = |
14 | | - Answer::No(crate::Reason::DstMayHaveSafetyInvariants); |
| 13 | +impl Representation for Tree { |
| 14 | + fn is_transmutable(src: Self, dst: Self, assume: Assume) -> Answer<!> { |
| 15 | + crate::maybe_transmutable::MaybeTransmutableQuery::new(src, dst, assume, UltraMinimal) |
| 16 | + .answer() |
| 17 | + } |
| 18 | +} |
15 | 19 |
|
16 | | - fn is_transmutable(src: &Tree, dst: &Tree, assume_safety: bool) -> crate::Answer<!> { |
17 | | - let src = src.clone(); |
18 | | - let dst = dst.clone(); |
19 | | - // The only dimension of the transmutability analysis we want to test |
20 | | - // here is the safety analysis. To ensure this, we disable all other |
21 | | - // toggleable aspects of the transmutability analysis. |
22 | | - let assume = crate::Assume { |
23 | | - alignment: true, |
24 | | - lifetimes: true, |
25 | | - validity: true, |
26 | | - safety: assume_safety, |
27 | | - }; |
| 20 | +impl Representation for Dfa { |
| 21 | + fn is_transmutable(src: Self, dst: Self, assume: Assume) -> Answer<!> { |
28 | 22 | crate::maybe_transmutable::MaybeTransmutableQuery::new(src, dst, assume, UltraMinimal) |
29 | 23 | .answer() |
30 | 24 | } |
| 25 | +} |
| 26 | + |
| 27 | +fn is_transmutable<R: Representation + Clone>( |
| 28 | + src: &R, |
| 29 | + dst: &R, |
| 30 | + assume: Assume, |
| 31 | +) -> crate::Answer<!> { |
| 32 | + let src = src.clone(); |
| 33 | + let dst = dst.clone(); |
| 34 | + // The only dimension of the transmutability analysis we want to test |
| 35 | + // here is the safety analysis. To ensure this, we disable all other |
| 36 | + // toggleable aspects of the transmutability analysis. |
| 37 | + R::is_transmutable(src, dst, assume) |
| 38 | +} |
| 39 | + |
| 40 | +mod safety { |
| 41 | + use super::*; |
| 42 | + use crate::Answer; |
| 43 | + |
| 44 | + const DST_HAS_SAFETY_INVARIANTS: Answer<!> = |
| 45 | + Answer::No(crate::Reason::DstMayHaveSafetyInvariants); |
31 | 46 |
|
32 | 47 | #[test] |
33 | 48 | fn src_safe_dst_safe() { |
34 | 49 | let src = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8()); |
35 | 50 | let dst = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8()); |
36 | | - assert_eq!(is_transmutable(&src, &dst, false), Answer::Yes); |
37 | | - assert_eq!(is_transmutable(&src, &dst, true), Answer::Yes); |
| 51 | + assert_eq!(is_transmutable(&src, &dst, Assume::default()), Answer::Yes); |
| 52 | + assert_eq!( |
| 53 | + is_transmutable(&src, &dst, Assume { safety: true, ..Assume::default() }), |
| 54 | + Answer::Yes |
| 55 | + ); |
38 | 56 | } |
39 | 57 |
|
40 | 58 | #[test] |
41 | 59 | fn src_safe_dst_unsafe() { |
42 | 60 | let src = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8()); |
43 | 61 | let dst = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8()); |
44 | | - assert_eq!(is_transmutable(&src, &dst, false), DST_HAS_SAFETY_INVARIANTS); |
45 | | - assert_eq!(is_transmutable(&src, &dst, true), Answer::Yes); |
| 62 | + assert_eq!(is_transmutable(&src, &dst, Assume::default()), DST_HAS_SAFETY_INVARIANTS); |
| 63 | + assert_eq!( |
| 64 | + is_transmutable(&src, &dst, Assume { safety: true, ..Assume::default() }), |
| 65 | + Answer::Yes |
| 66 | + ); |
46 | 67 | } |
47 | 68 |
|
48 | 69 | #[test] |
49 | 70 | fn src_unsafe_dst_safe() { |
50 | 71 | let src = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8()); |
51 | 72 | let dst = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8()); |
52 | | - assert_eq!(is_transmutable(&src, &dst, false), Answer::Yes); |
53 | | - assert_eq!(is_transmutable(&src, &dst, true), Answer::Yes); |
| 73 | + assert_eq!(is_transmutable(&src, &dst, Assume::default()), Answer::Yes); |
| 74 | + assert_eq!( |
| 75 | + is_transmutable(&src, &dst, Assume { safety: true, ..Assume::default() }), |
| 76 | + Answer::Yes |
| 77 | + ); |
54 | 78 | } |
55 | 79 |
|
56 | 80 | #[test] |
57 | 81 | fn src_unsafe_dst_unsafe() { |
58 | 82 | let src = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8()); |
59 | 83 | let dst = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8()); |
60 | | - assert_eq!(is_transmutable(&src, &dst, false), DST_HAS_SAFETY_INVARIANTS); |
61 | | - assert_eq!(is_transmutable(&src, &dst, true), Answer::Yes); |
| 84 | + assert_eq!(is_transmutable(&src, &dst, Assume::default()), DST_HAS_SAFETY_INVARIANTS); |
| 85 | + assert_eq!( |
| 86 | + is_transmutable(&src, &dst, Assume { safety: true, ..Assume::default() }), |
| 87 | + Answer::Yes |
| 88 | + ); |
62 | 89 | } |
63 | 90 | } |
64 | 91 |
|
65 | 92 | mod bool { |
66 | 93 | use super::*; |
67 | | - use crate::Answer; |
68 | 94 |
|
69 | 95 | #[test] |
70 | 96 | fn should_permit_identity_transmutation_tree() { |
71 | | - let answer = crate::maybe_transmutable::MaybeTransmutableQuery::new( |
72 | | - layout::Tree::<Def, !>::bool(), |
73 | | - layout::Tree::<Def, !>::bool(), |
74 | | - crate::Assume { alignment: false, lifetimes: false, validity: true, safety: false }, |
75 | | - UltraMinimal, |
76 | | - ) |
77 | | - .answer(); |
78 | | - assert_eq!(answer, Answer::Yes); |
| 97 | + let src = Tree::bool(); |
| 98 | + assert_eq!(is_transmutable(&src, &src, Assume::default()), Answer::Yes); |
| 99 | + assert_eq!( |
| 100 | + is_transmutable(&src, &src, Assume { validity: true, ..Assume::default() }), |
| 101 | + Answer::Yes |
| 102 | + ); |
79 | 103 | } |
80 | 104 |
|
81 | 105 | #[test] |
82 | 106 | fn should_permit_identity_transmutation_dfa() { |
83 | | - let answer = crate::maybe_transmutable::MaybeTransmutableQuery::new( |
84 | | - layout::Dfa::<!>::bool(), |
85 | | - layout::Dfa::<!>::bool(), |
86 | | - crate::Assume { alignment: false, lifetimes: false, validity: true, safety: false }, |
87 | | - UltraMinimal, |
88 | | - ) |
89 | | - .answer(); |
90 | | - assert_eq!(answer, Answer::Yes); |
| 107 | + let src = Dfa::bool(); |
| 108 | + assert_eq!(is_transmutable(&src, &src, Assume::default()), Answer::Yes); |
| 109 | + assert_eq!( |
| 110 | + is_transmutable(&src, &src, Assume { validity: true, ..Assume::default() }), |
| 111 | + Answer::Yes |
| 112 | + ); |
91 | 113 | } |
92 | 114 |
|
93 | 115 | #[test] |
@@ -122,41 +144,27 @@ mod bool { |
122 | 144 | if src_set.is_subset(&dst_set) { |
123 | 145 | assert_eq!( |
124 | 146 | Answer::Yes, |
125 | | - MaybeTransmutableQuery::new( |
126 | | - src_layout.clone(), |
127 | | - dst_layout.clone(), |
128 | | - crate::Assume { validity: false, ..crate::Assume::default() }, |
129 | | - UltraMinimal, |
130 | | - ) |
131 | | - .answer(), |
| 147 | + is_transmutable(&src_layout, &dst_layout, Assume::default()), |
132 | 148 | "{:?} SHOULD be transmutable into {:?}", |
133 | 149 | src_layout, |
134 | 150 | dst_layout |
135 | 151 | ); |
136 | 152 | } else if !src_set.is_disjoint(&dst_set) { |
137 | 153 | assert_eq!( |
138 | 154 | Answer::Yes, |
139 | | - MaybeTransmutableQuery::new( |
140 | | - src_layout.clone(), |
141 | | - dst_layout.clone(), |
142 | | - crate::Assume { validity: true, ..crate::Assume::default() }, |
143 | | - UltraMinimal, |
144 | | - ) |
145 | | - .answer(), |
| 155 | + is_transmutable( |
| 156 | + &src_layout, |
| 157 | + &dst_layout, |
| 158 | + Assume { validity: true, ..Assume::default() } |
| 159 | + ), |
146 | 160 | "{:?} SHOULD be transmutable (assuming validity) into {:?}", |
147 | 161 | src_layout, |
148 | 162 | dst_layout |
149 | 163 | ); |
150 | 164 | } else { |
151 | 165 | assert_eq!( |
152 | 166 | Answer::No(Reason::DstIsBitIncompatible), |
153 | | - MaybeTransmutableQuery::new( |
154 | | - src_layout.clone(), |
155 | | - dst_layout.clone(), |
156 | | - crate::Assume { validity: false, ..crate::Assume::default() }, |
157 | | - UltraMinimal, |
158 | | - ) |
159 | | - .answer(), |
| 167 | + is_transmutable(&src_layout, &dst_layout, Assume::default()), |
160 | 168 | "{:?} should NOT be transmutable into {:?}", |
161 | 169 | src_layout, |
162 | 170 | dst_layout |
|
0 commit comments