1
Fork 0

Safe Transmute: Enable handling references, including recursive types

This patch enables support for references in Safe Transmute, by generating
nested obligations during trait selection. Specifically, when we call
`confirm_transmutability_candidate(...)`, we now recursively traverse the
`rustc_transmute::Answer` tree and create obligations for all the `Answer`
variants, some of which include multiple nested `Answer`s.

Also, to handle recursive types, enable support for coinduction for the Safe
Transmute trait (`BikeshedIntrinsicFrom`) by adding the `#[rustc_coinduction]`
annotation.

Also fix some small logic issues when reducing the `or` and `and` combinations
in `rustc_transmute`, so that we don't end up with additional redundant
`Answer`s in the tree.

Co-authored-by: Jack Wrenn <jack@wrenn.fyi>
This commit is contained in:
Bryan Garza 2023-04-21 16:49:36 -07:00
parent 97d328012b
commit 8f1cec8d84
26 changed files with 460 additions and 103 deletions

View file

@ -8,7 +8,7 @@ extern crate tracing;
pub(crate) use rustc_data_structures::fx::{FxIndexMap as Map, FxIndexSet as Set};
pub(crate) mod layout;
pub mod layout;
pub(crate) mod maybe_transmutable;
#[derive(Default)]
@ -21,10 +21,7 @@ pub struct Assume {
/// The type encodes answers to the question: "Are these types transmutable?"
#[derive(Debug, Hash, Eq, PartialEq, PartialOrd, Ord, Clone)]
pub enum Answer<R>
where
R: layout::Ref,
{
pub enum Answer<R> {
/// `Src` is transmutable into `Dst`.
Yes,
@ -54,6 +51,10 @@ pub enum Reason {
DstIsPrivate,
/// `Dst` is larger than `Src`, and the excess bytes were not exclusively uninitialized.
DstIsTooBig,
/// Src should have a stricter alignment than Dst, but it does not.
DstHasStricterAlignment,
/// Can't go from shared pointer to unique pointer
DstIsMoreUnique,
}
#[cfg(feature = "rustc")]