diff options
| author | Jack Wrenn <jack@wrenn.fyi> | 2025-06-04 15:58:01 +0000 |
|---|---|---|
| committer | Jack Wrenn <jack@wrenn.fyi> | 2025-06-09 14:08:12 +0000 |
| commit | e9eae28eee0a99c64e81f4fdf87d3c76241e56bd (patch) | |
| tree | 51caaa23c92cceeff5c65e86248adf94f63a4762 /compiler/rustc_transmute/src/lib.rs | |
| parent | 7c10378e1fee5ddc6573b916aeb884ab10e0de17 (diff) | |
| download | rust-e9eae28eee0a99c64e81f4fdf87d3c76241e56bd.tar.gz rust-e9eae28eee0a99c64e81f4fdf87d3c76241e56bd.zip | |
transmutability: shift abstraction boundary
Previously, `rustc_transmute`'s layout representations were genericized over `R`, a reference. Now, it's instead genericized over representations of type and region. This allows us to move reference transmutability logic from `rustc_trait_selection` to `rustc_transmutability` (and thus unit test it independently of the compiler), and — in a follow-up PR — will make it possible to support analyzing function pointer transmutability with minimal surgery.
Diffstat (limited to 'compiler/rustc_transmute/src/lib.rs')
| -rw-r--r-- | compiler/rustc_transmute/src/lib.rs | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index ce18dad5517..36281ff16bc 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -19,23 +19,29 @@ pub struct Assume { /// Either transmutation is allowed, we have an error, or we have an optional /// Condition that must hold. #[derive(Debug, Hash, Eq, PartialEq, Clone)] -pub enum Answer<R> { +pub enum Answer<R, T> { Yes, - No(Reason<R>), - If(Condition<R>), + No(Reason<T>), + If(Condition<R, T>), } /// A condition which must hold for safe transmutation to be possible. #[derive(Debug, Hash, Eq, PartialEq, Clone)] -pub enum Condition<R> { +pub enum Condition<R, T> { /// `Src` is transmutable into `Dst`, if `src` is transmutable into `dst`. - IfTransmutable { src: R, dst: R }, + Transmutable { src: T, dst: T }, + + /// The region `long` must outlive `short`. + Outlives { long: R, short: R }, + + /// The `ty` is immutable. + Immutable { ty: T }, /// `Src` is transmutable into `Dst`, if all of the enclosed requirements are met. - IfAll(Vec<Condition<R>>), + IfAll(Vec<Condition<R, T>>), /// `Src` is transmutable into `Dst` if any of the enclosed requirements are met. - IfAny(Vec<Condition<R>>), + IfAny(Vec<Condition<R, T>>), } /// Answers "why wasn't the source type transmutable into the destination type?" @@ -53,12 +59,16 @@ pub enum Reason<T> { DstMayHaveSafetyInvariants, /// `Dst` is larger than `Src`, and the excess bytes were not exclusively uninitialized. DstIsTooBig, - /// A referent of `Dst` is larger than a referent in `Src`. + /// `Dst` is larger `Src`. DstRefIsTooBig { /// The referent of the source type. src: T, + /// The size of the source type's referent. + src_size: usize, /// The too-large referent of the destination type. dst: T, + /// The size of the destination type's referent. + dst_size: usize, }, /// Src should have a stricter alignment than Dst, but it does not. DstHasStricterAlignment { src_min_align: usize, dst_min_align: usize }, @@ -79,7 +89,7 @@ pub enum Reason<T> { #[cfg(feature = "rustc")] mod rustc { use rustc_hir::lang_items::LangItem; - use rustc_middle::ty::{Const, Ty, TyCtxt}; + use rustc_middle::ty::{Const, Region, Ty, TyCtxt}; use super::*; @@ -105,7 +115,7 @@ mod rustc { &mut self, types: Types<'tcx>, assume: crate::Assume, - ) -> crate::Answer<crate::layout::rustc::Ref<'tcx>> { + ) -> crate::Answer<Region<'tcx>, Ty<'tcx>> { crate::maybe_transmutable::MaybeTransmutableQuery::new( types.src, types.dst, assume, self.tcx, ) |
