summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_transmute/src/maybe_transmutable/tests.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_transmute/src/maybe_transmutable/tests.rs')
-rw-r--r--compiler/rustc_transmute/src/maybe_transmutable/tests.rs115
1 files changed, 115 insertions, 0 deletions
diff --git a/compiler/rustc_transmute/src/maybe_transmutable/tests.rs b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs
new file mode 100644
index 000000000..d9d125687
--- /dev/null
+++ b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs
@@ -0,0 +1,115 @@
+use super::query_context::test::{Def, UltraMinimal};
+use crate::maybe_transmutable::MaybeTransmutableQuery;
+use crate::{layout, Answer, Reason, Set};
+use itertools::Itertools;
+
+mod bool {
+ use super::*;
+
+ #[test]
+ fn should_permit_identity_transmutation_tree() {
+ println!("{:?}", layout::Tree::<!, !>::bool());
+ let answer = crate::maybe_transmutable::MaybeTransmutableQuery::new(
+ layout::Tree::<Def, !>::bool(),
+ layout::Tree::<Def, !>::bool(),
+ (),
+ crate::Assume { alignment: false, lifetimes: false, validity: true, visibility: false },
+ UltraMinimal,
+ )
+ .answer();
+ assert_eq!(answer, Answer::Yes);
+ }
+
+ #[test]
+ fn should_permit_identity_transmutation_dfa() {
+ let answer = crate::maybe_transmutable::MaybeTransmutableQuery::new(
+ layout::Dfa::<!>::bool(),
+ layout::Dfa::<!>::bool(),
+ (),
+ crate::Assume { alignment: false, lifetimes: false, validity: true, visibility: false },
+ UltraMinimal,
+ )
+ .answer();
+ assert_eq!(answer, Answer::Yes);
+ }
+
+ #[test]
+ fn should_permit_validity_expansion_and_reject_contraction() {
+ let un = layout::Tree::<Def, !>::uninhabited();
+ let b0 = layout::Tree::<Def, !>::from_bits(0);
+ let b1 = layout::Tree::<Def, !>::from_bits(1);
+ let b2 = layout::Tree::<Def, !>::from_bits(2);
+
+ let alts = [b0, b1, b2];
+
+ let into_layout = |alts: Vec<_>| {
+ alts.into_iter().fold(layout::Tree::<Def, !>::uninhabited(), layout::Tree::<Def, !>::or)
+ };
+
+ let into_set = |alts: Vec<_>| {
+ #[cfg(feature = "rustc")]
+ let mut set = Set::default();
+ #[cfg(not(feature = "rustc"))]
+ let mut set = Set::new();
+ set.extend(alts);
+ set
+ };
+
+ for src_alts in alts.clone().into_iter().powerset() {
+ let src_layout = into_layout(src_alts.clone());
+ let src_set = into_set(src_alts.clone());
+
+ for dst_alts in alts.clone().into_iter().powerset().filter(|alts| !alts.is_empty()) {
+ let dst_layout = into_layout(dst_alts.clone());
+ let dst_set = into_set(dst_alts.clone());
+
+ if src_set.is_subset(&dst_set) {
+ assert_eq!(
+ Answer::Yes,
+ MaybeTransmutableQuery::new(
+ src_layout.clone(),
+ dst_layout.clone(),
+ (),
+ crate::Assume { validity: false, ..crate::Assume::default() },
+ UltraMinimal,
+ )
+ .answer(),
+ "{:?} SHOULD be transmutable into {:?}",
+ src_layout,
+ dst_layout
+ );
+ } else if !src_set.is_disjoint(&dst_set) {
+ assert_eq!(
+ Answer::Yes,
+ MaybeTransmutableQuery::new(
+ src_layout.clone(),
+ dst_layout.clone(),
+ (),
+ crate::Assume { validity: true, ..crate::Assume::default() },
+ UltraMinimal,
+ )
+ .answer(),
+ "{:?} SHOULD be transmutable (assuming validity) into {:?}",
+ src_layout,
+ dst_layout
+ );
+ } else {
+ assert_eq!(
+ Answer::No(Reason::DstIsBitIncompatible),
+ MaybeTransmutableQuery::new(
+ src_layout.clone(),
+ dst_layout.clone(),
+ (),
+ crate::Assume { validity: false, ..crate::Assume::default() },
+ UltraMinimal,
+ )
+ .answer(),
+ "{:?} should NOT be transmutable into {:?}",
+ src_layout,
+ dst_layout
+ );
+ }
+ }
+ }
+ }
+}