safe transmute: revise safety analysis

Migrate to a simplified safety analysis that does not use visibility.

Closes https://github.com/rust-lang/project-safe-transmute/issues/15
This commit is contained in:
Jack Wrenn
2024-02-26 16:49:25 +00:00
parent 9afdb8d1d5
commit 23ab1bda92
127 changed files with 1387 additions and 1948 deletions

View File

@@ -3,6 +3,65 @@ use crate::maybe_transmutable::MaybeTransmutableQuery;
use crate::{layout, Reason};
use itertools::Itertools;
mod safety {
use crate::Answer;
use super::*;
type Tree = layout::Tree<Def, !>;
const DST_HAS_SAFETY_INVARIANTS: Answer<!> =
Answer::No(crate::Reason::DstMayHaveSafetyInvariants);
fn is_transmutable(src: &Tree, dst: &Tree, assume_safety: bool) -> crate::Answer<!> {
let src = src.clone();
let dst = dst.clone();
// The only dimension of the transmutability analysis we want to test
// here is the safety analysis. To ensure this, we disable all other
// toggleable aspects of the transmutability analysis.
let assume = crate::Assume {
alignment: true,
lifetimes: true,
validity: true,
safety: assume_safety,
};
crate::maybe_transmutable::MaybeTransmutableQuery::new(src, dst, assume, UltraMinimal)
.answer()
}
#[test]
fn src_safe_dst_safe() {
let src = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8());
let dst = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8());
assert_eq!(is_transmutable(&src, &dst, false), Answer::Yes);
assert_eq!(is_transmutable(&src, &dst, true), Answer::Yes);
}
#[test]
fn src_safe_dst_unsafe() {
let src = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8());
let dst = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8());
assert_eq!(is_transmutable(&src, &dst, false), DST_HAS_SAFETY_INVARIANTS);
assert_eq!(is_transmutable(&src, &dst, true), Answer::Yes);
}
#[test]
fn src_unsafe_dst_safe() {
let src = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8());
let dst = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8());
assert_eq!(is_transmutable(&src, &dst, false), Answer::Yes);
assert_eq!(is_transmutable(&src, &dst, true), Answer::Yes);
}
#[test]
fn src_unsafe_dst_unsafe() {
let src = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8());
let dst = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8());
assert_eq!(is_transmutable(&src, &dst, false), DST_HAS_SAFETY_INVARIANTS);
assert_eq!(is_transmutable(&src, &dst, true), Answer::Yes);
}
}
mod bool {
use crate::Answer;
@@ -10,11 +69,9 @@ mod bool {
#[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, safety: false },
UltraMinimal,
)
@@ -27,7 +84,6 @@ mod bool {
let answer = crate::maybe_transmutable::MaybeTransmutableQuery::new(
layout::Dfa::<!>::bool(),
layout::Dfa::<!>::bool(),
(),
crate::Assume { alignment: false, lifetimes: false, validity: true, safety: false },
UltraMinimal,
)
@@ -71,7 +127,6 @@ mod bool {
MaybeTransmutableQuery::new(
src_layout.clone(),
dst_layout.clone(),
(),
crate::Assume { validity: false, ..crate::Assume::default() },
UltraMinimal,
)
@@ -86,7 +141,6 @@ mod bool {
MaybeTransmutableQuery::new(
src_layout.clone(),
dst_layout.clone(),
(),
crate::Assume { validity: true, ..crate::Assume::default() },
UltraMinimal,
)
@@ -101,7 +155,6 @@ mod bool {
MaybeTransmutableQuery::new(
src_layout.clone(),
dst_layout.clone(),
(),
crate::Assume { validity: false, ..crate::Assume::default() },
UltraMinimal,
)