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

@ -30,33 +30,46 @@ impl fmt::Debug for Byte {
}
pub(crate) trait Def: Debug + Hash + Eq + PartialEq + Copy + Clone {}
pub trait Ref: Debug + Hash + Eq + PartialEq + Copy + Clone {}
pub trait Ref: Debug + Hash + Eq + PartialEq + Copy + Clone {
fn min_align(&self) -> usize {
1
}
fn is_mutable(&self) -> bool {
false
}
}
impl Def for ! {}
impl Ref for ! {}
#[cfg(feature = "rustc")]
pub(crate) mod rustc {
pub mod rustc {
use rustc_middle::mir::Mutability;
use rustc_middle::ty;
use rustc_middle::ty::Region;
use rustc_middle::ty::Ty;
use rustc_middle::ty::{self, Ty};
/// A reference in the layout.
#[derive(Debug, Hash, Eq, PartialEq, PartialOrd, Ord, Clone, Copy)]
pub struct Ref<'tcx> {
lifetime: Region<'tcx>,
ty: Ty<'tcx>,
mutability: Mutability,
pub lifetime: ty::Region<'tcx>,
pub ty: Ty<'tcx>,
pub mutability: Mutability,
pub align: usize,
}
impl<'tcx> super::Ref for Ref<'tcx> {}
impl<'tcx> super::Ref for Ref<'tcx> {
fn min_align(&self) -> usize {
self.align
}
impl<'tcx> Ref<'tcx> {
pub fn min_align(&self) -> usize {
todo!()
fn is_mutable(&self) -> bool {
match self.mutability {
Mutability::Mut => true,
Mutability::Not => false,
}
}
}
impl<'tcx> Ref<'tcx> {}
/// A visibility node in the layout.
#[derive(Debug, Hash, Eq, PartialEq, Clone, Copy)]

View file

@ -365,6 +365,17 @@ pub(crate) mod rustc {
}
}))
}
ty::Ref(lifetime, ty, mutability) => {
let align = layout_of(tcx, *ty)?.align();
Ok(Tree::Ref(Ref {
lifetime: *lifetime,
ty: *ty,
mutability: *mutability,
align,
}))
}
_ => Err(Err::Unspecified),
}
}