]>
Commit | Line | Data |
---|---|---|
064997fb FG |
1 | use super::query_context::test::{Def, UltraMinimal}; |
2 | use crate::maybe_transmutable::MaybeTransmutableQuery; | |
3 | use crate::{layout, Answer, Reason, Set}; | |
4 | use itertools::Itertools; | |
5 | ||
6 | mod bool { | |
7 | use super::*; | |
8 | ||
9 | #[test] | |
10 | fn should_permit_identity_transmutation_tree() { | |
11 | println!("{:?}", layout::Tree::<!, !>::bool()); | |
12 | let answer = crate::maybe_transmutable::MaybeTransmutableQuery::new( | |
13 | layout::Tree::<Def, !>::bool(), | |
14 | layout::Tree::<Def, !>::bool(), | |
15 | (), | |
16 | crate::Assume { alignment: false, lifetimes: false, validity: true, visibility: false }, | |
17 | UltraMinimal, | |
18 | ) | |
19 | .answer(); | |
20 | assert_eq!(answer, Answer::Yes); | |
21 | } | |
22 | ||
23 | #[test] | |
24 | fn should_permit_identity_transmutation_dfa() { | |
25 | let answer = crate::maybe_transmutable::MaybeTransmutableQuery::new( | |
26 | layout::Dfa::<!>::bool(), | |
27 | layout::Dfa::<!>::bool(), | |
28 | (), | |
29 | crate::Assume { alignment: false, lifetimes: false, validity: true, visibility: false }, | |
30 | UltraMinimal, | |
31 | ) | |
32 | .answer(); | |
33 | assert_eq!(answer, Answer::Yes); | |
34 | } | |
35 | ||
36 | #[test] | |
37 | fn should_permit_validity_expansion_and_reject_contraction() { | |
38 | let un = layout::Tree::<Def, !>::uninhabited(); | |
39 | let b0 = layout::Tree::<Def, !>::from_bits(0); | |
40 | let b1 = layout::Tree::<Def, !>::from_bits(1); | |
41 | let b2 = layout::Tree::<Def, !>::from_bits(2); | |
42 | ||
43 | let alts = [b0, b1, b2]; | |
44 | ||
45 | let into_layout = |alts: Vec<_>| { | |
46 | alts.into_iter().fold(layout::Tree::<Def, !>::uninhabited(), layout::Tree::<Def, !>::or) | |
47 | }; | |
48 | ||
49 | let into_set = |alts: Vec<_>| { | |
50 | #[cfg(feature = "rustc")] | |
51 | let mut set = Set::default(); | |
52 | #[cfg(not(feature = "rustc"))] | |
53 | let mut set = Set::new(); | |
54 | set.extend(alts); | |
55 | set | |
56 | }; | |
57 | ||
58 | for src_alts in alts.clone().into_iter().powerset() { | |
59 | let src_layout = into_layout(src_alts.clone()); | |
60 | let src_set = into_set(src_alts.clone()); | |
61 | ||
62 | for dst_alts in alts.clone().into_iter().powerset().filter(|alts| !alts.is_empty()) { | |
63 | let dst_layout = into_layout(dst_alts.clone()); | |
64 | let dst_set = into_set(dst_alts.clone()); | |
65 | ||
66 | if src_set.is_subset(&dst_set) { | |
67 | assert_eq!( | |
68 | Answer::Yes, | |
69 | MaybeTransmutableQuery::new( | |
70 | src_layout.clone(), | |
71 | dst_layout.clone(), | |
72 | (), | |
73 | crate::Assume { validity: false, ..crate::Assume::default() }, | |
74 | UltraMinimal, | |
75 | ) | |
76 | .answer(), | |
77 | "{:?} SHOULD be transmutable into {:?}", | |
78 | src_layout, | |
79 | dst_layout | |
80 | ); | |
81 | } else if !src_set.is_disjoint(&dst_set) { | |
82 | assert_eq!( | |
83 | Answer::Yes, | |
84 | MaybeTransmutableQuery::new( | |
85 | src_layout.clone(), | |
86 | dst_layout.clone(), | |
87 | (), | |
88 | crate::Assume { validity: true, ..crate::Assume::default() }, | |
89 | UltraMinimal, | |
90 | ) | |
91 | .answer(), | |
92 | "{:?} SHOULD be transmutable (assuming validity) into {:?}", | |
93 | src_layout, | |
94 | dst_layout | |
95 | ); | |
96 | } else { | |
97 | assert_eq!( | |
98 | Answer::No(Reason::DstIsBitIncompatible), | |
99 | MaybeTransmutableQuery::new( | |
100 | src_layout.clone(), | |
101 | dst_layout.clone(), | |
102 | (), | |
103 | crate::Assume { validity: false, ..crate::Assume::default() }, | |
104 | UltraMinimal, | |
105 | ) | |
106 | .answer(), | |
107 | "{:?} should NOT be transmutable into {:?}", | |
108 | src_layout, | |
109 | dst_layout | |
110 | ); | |
111 | } | |
112 | } | |
113 | } | |
114 | } | |
115 | } |