safe transmute: require that src referent is smaller than dst

The source referent absolutely must be smaller than the destination
referent of a ref-to-ref transmute; the excess bytes referenced
cannot arise from thin air, even if those bytes are uninitialized.
This commit is contained in:
Jack Wrenn
2024-03-13 00:11:36 +00:00
parent a165f1f650
commit 216df4a8e6
8 changed files with 122 additions and 5 deletions

View File

@@ -35,6 +35,8 @@ pub(crate) trait Def: Debug + Hash + Eq + PartialEq + Copy + Clone {
pub trait Ref: Debug + Hash + Eq + PartialEq + Copy + Clone {
fn min_align(&self) -> usize;
fn size(&self) -> usize;
fn is_mutable(&self) -> bool;
}
@@ -48,6 +50,9 @@ impl Ref for ! {
fn min_align(&self) -> usize {
unreachable!()
}
fn size(&self) -> usize {
unreachable!()
}
fn is_mutable(&self) -> bool {
unreachable!()
}
@@ -57,6 +62,7 @@ impl Ref for ! {
pub mod rustc {
use rustc_middle::mir::Mutability;
use rustc_middle::ty::{self, Ty};
use std::fmt::{self, Write};
/// A reference in the layout.
#[derive(Debug, Hash, Eq, PartialEq, PartialOrd, Ord, Clone, Copy)]
@@ -65,6 +71,7 @@ pub mod rustc {
pub ty: Ty<'tcx>,
pub mutability: Mutability,
pub align: usize,
pub size: usize,
}
impl<'tcx> super::Ref for Ref<'tcx> {
@@ -72,6 +79,10 @@ pub mod rustc {
self.align
}
fn size(&self) -> usize {
self.size
}
fn is_mutable(&self) -> bool {
match self.mutability {
Mutability::Mut => true,
@@ -81,6 +92,16 @@ pub mod rustc {
}
impl<'tcx> Ref<'tcx> {}
impl<'tcx> fmt::Display for Ref<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_char('&')?;
if self.mutability == Mutability::Mut {
f.write_str("mut ")?;
}
self.ty.fmt(f)
}
}
/// A visibility node in the layout.
#[derive(Debug, Hash, Eq, PartialEq, Clone, Copy)]
pub enum Def<'tcx> {