|
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