Skip to content

Commit 7e3c9df

Browse files
committed
[WIP] transmute_from!(@allow_shrink)
gherrit-pr-id: I10874e2bc703fb6b7fcdea050b8971de869a850a
1 parent eec3ec9 commit 7e3c9df

File tree

1 file changed

+45
-18
lines changed

1 file changed

+45
-18
lines changed

src/layout.rs

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -694,8 +694,8 @@ mod cast_from_raw {
694694
/// `Src`'s alignment must not be smaller than `Dst`'s alignment.
695695
#[derive(Copy, Clone)]
696696
struct CastParams {
697-
offset_delta_elems: usize,
698-
elem_multiple: usize,
697+
offset_delta_elems: Fraction,
698+
elem_multiple: Fraction,
699699
}
700700

701701
impl CastParams {
@@ -718,32 +718,41 @@ mod cast_from_raw {
718718
return None;
719719
};
720720

721+
// TODO: When doing size-lossy casts, we can permit ZST trailing
722+
// slice elements in the destination type, although we'd need to
723+
// think carefully about what we promise about the metadata.
721724
let dst_elem_size = if let Some(e) = NonZeroUsize::new(dst.elem_size) {
722725
e
723726
} else {
724727
return None;
725728
};
726729

727-
// PANICS: `dst_elem_size: NonZeroUsize`, so this won't div by zero.
728-
#[allow(clippy::arithmetic_side_effects)]
729-
let delta_mod_other_elem = offset_delta % dst_elem_size.get();
730+
let offset_delta_elems =
731+
Fraction { num: offset_delta, denom: dst_elem_size }.simplify();
730732

731-
// PANICS: `dst_elem_size: NonZeroUsize`, so this won't div by zero.
732-
#[allow(clippy::arithmetic_side_effects)]
733-
let elem_remainder = src.elem_size % dst_elem_size.get();
733+
let elem_multiple =
734+
Fraction { num: src.elem_size, denom: dst_elem_size }.simplify();
734735

735-
if delta_mod_other_elem != 0 || src.elem_size < dst.elem_size || elem_remainder != 0
736-
{
737-
return None;
738-
}
736+
// // PANICS: `dst_elem_size: NonZeroUsize`, so this won't div by zero.
737+
// #[allow(clippy::arithmetic_side_effects)]
738+
// let delta_mod_other_elem = offset_delta % dst_elem_size.get();
739739

740-
// PANICS: `dst_elem_size: NonZeroUsize`, so this won't div by zero.
741-
#[allow(clippy::arithmetic_side_effects)]
742-
let offset_delta_elems = offset_delta / dst_elem_size.get();
740+
// // PANICS: `dst_elem_size: NonZeroUsize`, so this won't div by zero.
741+
// #[allow(clippy::arithmetic_side_effects)]
742+
// let elem_remainder = src.elem_size % dst_elem_size.get();
743743

744-
// PANICS: `dst_elem_size: NonZeroUsize`, so this won't div by zero.
745-
#[allow(clippy::arithmetic_side_effects)]
746-
let elem_multiple = src.elem_size / dst_elem_size.get();
744+
// if delta_mod_other_elem != 0 || src.elem_size < dst.elem_size || elem_remainder != 0
745+
// {
746+
// return None;
747+
// }
748+
749+
// // PANICS: `dst_elem_size: NonZeroUsize`, so this won't div by zero.
750+
// #[allow(clippy::arithmetic_side_effects)]
751+
// let offset_delta_elems = offset_delta / dst_elem_size.get();
752+
753+
// // PANICS: `dst_elem_size: NonZeroUsize`, so this won't div by zero.
754+
// #[allow(clippy::arithmetic_side_effects)]
755+
// let elem_multiple = src.elem_size / dst_elem_size.get();
747756

748757
// SAFETY: We checked above that `src.align >= dst.align`.
749758
Some(CastParams {
@@ -816,6 +825,24 @@ mod cast_from_raw {
816825
// subset of those bytes, and has provenance for those bytes.
817826
unsafe { PtrInner::new(dst) }
818827
}
828+
829+
#[derive(Copy, Clone)]
830+
struct Fraction {
831+
num: usize,
832+
denom: NonZeroUsize,
833+
}
834+
835+
impl Fraction {
836+
const fn simplify(self) -> Fraction {
837+
todo!() // https://stackoverflow.com/a/7777146/836390
838+
}
839+
840+
const fn mul(self, other: usize) -> Fraction {
841+
// TODO: How can we prove that it's sound to use `unchecked_mul`
842+
// when the denom is 1?
843+
todo!()
844+
}
845+
}
819846
}
820847

821848
// TODO(#67): For some reason, on our MSRV toolchain, this `allow` isn't

0 commit comments

Comments
 (0)