Skip to content

Commit 3b22cad

Browse files
committed
[pointer][WIP] Transmute
gherrit-pr-id: Iad14813bc6d933312bc8d7a1ddcf1aafc7126938
1 parent daf3a21 commit 3b22cad

File tree

11 files changed

+433
-97
lines changed

11 files changed

+433
-97
lines changed

src/impls.rs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -417,10 +417,11 @@ mod atomics {
417417
use super::*;
418418

419419
macro_rules! impl_traits_for_atomics {
420-
($($atomics:ident),* $(,)?) => {
420+
($($atomics:ident [$primitives:ident]),* $(,)?) => {
421421
$(
422422
impl_known_layout!($atomics);
423-
impl_for_transparent_wrapper!(=> TryFromBytes for $atomics);
423+
impl_for_transmute_from!(=> TryFromBytes for $atomics [UnsafeCell<$primitives>]);
424+
// impl_for_transparent_wrapper!(=> TryFromBytes for $atomics);
424425
impl_for_transparent_wrapper!(=> FromZeros for $atomics);
425426
impl_for_transparent_wrapper!(=> FromBytes for $atomics);
426427
impl_for_transparent_wrapper!(=> IntoBytes for $atomics);
@@ -435,11 +436,12 @@ mod atomics {
435436

436437
use super::*;
437438

438-
impl_traits_for_atomics!(AtomicU8, AtomicI8);
439+
impl_traits_for_atomics!(AtomicU8[u8], AtomicI8[i8]);
439440

440441
impl_known_layout!(AtomicBool);
441442

442-
impl_for_transparent_wrapper!(=> TryFromBytes for AtomicBool);
443+
// impl_for_transparent_wrapper!(=> TryFromBytes for AtomicBool);
444+
impl_for_transmute_from!(=> TryFromBytes for AtomicBool [UnsafeCell<bool>]);
443445
impl_for_transparent_wrapper!(=> FromZeros for AtomicBool);
444446
impl_for_transparent_wrapper!(=> IntoBytes for AtomicBool);
445447

@@ -472,6 +474,7 @@ mod atomics {
472474
/// All of these pass an atomic type and that type's native equivalent, as
473475
/// required by the macro safety preconditions.
474476
unsafe_impl_transparent_wrapper_for_atomic!(AtomicU8 [u8], AtomicI8 [i8], AtomicBool [bool]);
477+
unsafe_impl_transmute_from_for_atomic!(AtomicU8 [u8], AtomicI8 [i8], AtomicBool [bool]);
475478
}
476479
}
477480

@@ -482,13 +485,14 @@ mod atomics {
482485

483486
use super::*;
484487

485-
impl_traits_for_atomics!(AtomicU16, AtomicI16);
488+
impl_traits_for_atomics!(AtomicU16[u16], AtomicI16[i16]);
486489

487490
safety_comment! {
488491
/// SAFETY:
489492
/// All of these pass an atomic type and that type's native equivalent, as
490493
/// required by the macro safety preconditions.
491494
unsafe_impl_transparent_wrapper_for_atomic!(AtomicU16 [u16], AtomicI16 [i16]);
495+
unsafe_impl_transmute_from_for_atomic!(AtomicU16 [u16], AtomicI16 [i16]);
492496
}
493497
}
494498

@@ -499,13 +503,14 @@ mod atomics {
499503

500504
use super::*;
501505

502-
impl_traits_for_atomics!(AtomicU32, AtomicI32);
506+
impl_traits_for_atomics!(AtomicU32[u32], AtomicI32[i32]);
503507

504508
safety_comment! {
505509
/// SAFETY:
506510
/// All of these pass an atomic type and that type's native equivalent, as
507511
/// required by the macro safety preconditions.
508512
unsafe_impl_transparent_wrapper_for_atomic!(AtomicU32 [u32], AtomicI32 [i32]);
513+
unsafe_impl_transmute_from_for_atomic!(AtomicU32 [u32], AtomicI32 [i32]);
509514
}
510515
}
511516

@@ -516,13 +521,14 @@ mod atomics {
516521

517522
use super::*;
518523

519-
impl_traits_for_atomics!(AtomicU64, AtomicI64);
524+
impl_traits_for_atomics!(AtomicU64[u64], AtomicI64[i64]);
520525

521526
safety_comment! {
522527
/// SAFETY:
523528
/// All of these pass an atomic type and that type's native equivalent, as
524529
/// required by the macro safety preconditions.
525530
unsafe_impl_transparent_wrapper_for_atomic!(AtomicU64 [u64], AtomicI64 [i64]);
531+
unsafe_impl_transmute_from_for_atomic!(AtomicU64 [u64], AtomicI64 [i64]);
526532
}
527533
}
528534

@@ -533,13 +539,14 @@ mod atomics {
533539

534540
use super::*;
535541

536-
impl_traits_for_atomics!(AtomicUsize, AtomicIsize);
542+
impl_traits_for_atomics!(AtomicUsize[usize], AtomicIsize[isize]);
537543

538544
impl_known_layout!(T => AtomicPtr<T>);
539545

540546
// TODO(#170): Implement `FromBytes` and `IntoBytes` once we implement
541547
// those traits for `*mut T`.
542-
impl_for_transparent_wrapper!(T => TryFromBytes for AtomicPtr<T>);
548+
// impl_for_transparent_wrapper!(T => TryFromBytes for AtomicPtr<T>);
549+
impl_for_transmute_from!(T => TryFromBytes for AtomicPtr<T> [UnsafeCell<*mut T>]);
543550
impl_for_transparent_wrapper!(T => FromZeros for AtomicPtr<T>);
544551

545552
safety_comment! {
@@ -548,6 +555,9 @@ mod atomics {
548555
/// required by the macro safety preconditions.
549556
unsafe_impl_transparent_wrapper_for_atomic!(AtomicUsize [usize], AtomicIsize [isize]);
550557
unsafe_impl_transparent_wrapper_for_atomic!(T => AtomicPtr<T> [*mut T]);
558+
559+
unsafe_impl_transmute_from_for_atomic!(AtomicUsize [usize], AtomicIsize [isize]);
560+
unsafe_impl_transmute_from_for_atomic!(T => AtomicPtr<T> [*mut T]);
551561
}
552562
}
553563
}
@@ -578,7 +588,7 @@ safety_comment! {
578588
}
579589

580590
impl_for_transparent_wrapper!(T: Immutable => Immutable for Wrapping<T>);
581-
impl_for_transparent_wrapper!(T: TryFromBytes => TryFromBytes for Wrapping<T>);
591+
impl_for_transmute_from!(T: TryFromBytes => TryFromBytes for Wrapping<T>[T]);
582592
impl_for_transparent_wrapper!(T: FromZeros => FromZeros for Wrapping<T>);
583593
impl_for_transparent_wrapper!(T: FromBytes => FromBytes for Wrapping<T>);
584594
impl_for_transparent_wrapper!(T: IntoBytes => IntoBytes for Wrapping<T>);
@@ -599,7 +609,7 @@ impl_for_transparent_wrapper!(T: Unaligned => Unaligned for CoreMaybeUninit<T>);
599609
assert_unaligned!(CoreMaybeUninit<()>, CoreMaybeUninit<u8>);
600610

601611
impl_for_transparent_wrapper!(T: ?Sized + Immutable => Immutable for ManuallyDrop<T>);
602-
impl_for_transparent_wrapper!(T: ?Sized + TryFromBytes => TryFromBytes for ManuallyDrop<T>);
612+
impl_for_transmute_from!(T: ?Sized + TryFromBytes => TryFromBytes for ManuallyDrop<T> [T]);
603613
impl_for_transparent_wrapper!(T: ?Sized + FromZeros => FromZeros for ManuallyDrop<T>);
604614
impl_for_transparent_wrapper!(T: ?Sized + FromBytes => FromBytes for ManuallyDrop<T>);
605615
impl_for_transparent_wrapper!(T: ?Sized + IntoBytes => IntoBytes for ManuallyDrop<T>);

src/lib.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,10 @@ use core::{
375375
#[cfg(feature = "std")]
376376
use std::io;
377377

378-
use crate::pointer::invariant::{self, BecauseExclusive};
378+
use crate::pointer::{
379+
invariant::{self, BecauseExclusive},
380+
BecauseFoo,
381+
};
379382

380383
#[cfg(any(feature = "alloc", test))]
381384
extern crate alloc;
@@ -805,6 +808,14 @@ pub unsafe trait KnownLayout {
805808
// resulting size would not fit in a `usize`.
806809
meta.size_for_metadata(Self::LAYOUT)
807810
}
811+
812+
fn cast_from_raw<P: KnownLayout<PointerMetadata = Self::PointerMetadata> + ?Sized>(
813+
ptr: NonNull<P>,
814+
) -> NonNull<Self> {
815+
let data = ptr.cast::<u8>();
816+
let meta = P::pointer_to_metadata(ptr.as_ptr());
817+
Self::raw_from_ptr_len(data, meta)
818+
}
808819
}
809820

810821
/// The metadata associated with a [`KnownLayout`] type.
@@ -2843,15 +2854,15 @@ unsafe fn try_read_from<S, T: TryFromBytes>(
28432854
// We use `from_mut` despite not mutating via `c_ptr` so that we don't need
28442855
// to add a `T: Immutable` bound.
28452856
let c_ptr = Ptr::from_mut(&mut candidate);
2846-
let c_ptr = c_ptr.transparent_wrapper_into_inner();
28472857
// SAFETY: `c_ptr` has no uninitialized sub-ranges because it derived from
28482858
// `candidate`, which the caller promises is entirely initialized. Since
28492859
// `candidate` is a `MaybeUninit`, it has no validity requirements, and so
2850-
// no values written to `c_ptr` can violate its validity. Since `c_ptr` has
2851-
// `Exclusive` aliasing, no mutations may happen except via `c_ptr` so long
2852-
// as it is live, so we don't need to worry about the fact that `c_ptr` may
2853-
// have more restricted validity than `candidate`.
2860+
// no values written to an `Initialized` `c_ptr` can violate its validity.
2861+
// Since `c_ptr` has `Exclusive` aliasing, no mutations may happen except
2862+
// via `c_ptr` so long as it is live, so we don't need to worry about the
2863+
// fact that `c_ptr` may have more restricted validity than `candidate`.
28542864
let c_ptr = unsafe { c_ptr.assume_validity::<invariant::Initialized>() };
2865+
let c_ptr = c_ptr.transmute();
28552866

28562867
// This call may panic. If that happens, it doesn't cause any soundness
28572868
// issues, as we have not generated any invalid state which we need to
@@ -2861,7 +2872,7 @@ unsafe fn try_read_from<S, T: TryFromBytes>(
28612872
// calling `try_into_valid` (and thus `is_bit_valid`) with a shared
28622873
// pointer when `Self: !Immutable`. Since `Self: Immutable`, this panic
28632874
// condition will not happen.
2864-
if !T::is_bit_valid(c_ptr.forget_aligned()) {
2875+
if !util::SizedKnownLayout::<T>::is_bit_valid(c_ptr.forget_aligned()) {
28652876
return Err(ValidityError::new(source).into());
28662877
}
28672878

@@ -4258,7 +4269,7 @@ pub unsafe trait FromBytes: FromZeros {
42584269
let source = Ptr::from_mut(source);
42594270
let maybe_slf = source.try_cast_into_no_leftover::<_, BecauseImmutable>(Some(count));
42604271
match maybe_slf {
4261-
Ok(slf) => Ok(slf.bikeshed_recall_valid().as_mut()),
4272+
Ok(slf) => Ok(slf.bikeshed_recall_valid::<(_, (_, BecauseExclusive))>().as_mut()),
42624273
Err(err) => Err(err.map_src(|s| s.as_mut())),
42634274
}
42644275
}
@@ -4728,7 +4739,7 @@ fn ref_from_prefix_suffix<T: FromBytes + KnownLayout + Immutable + ?Sized>(
47284739
/// If there are insufficient bytes, or if that affix of `source` is not
47294740
/// appropriately aligned, this returns `Err`.
47304741
#[inline(always)]
4731-
fn mut_from_prefix_suffix<T: FromBytes + KnownLayout + ?Sized>(
4742+
fn mut_from_prefix_suffix<T: FromBytes + IntoBytes + KnownLayout + ?Sized>(
47324743
source: &mut [u8],
47334744
meta: Option<T::PointerMetadata>,
47344745
cast_type: CastType,

src/pointer/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,15 @@ mod inner;
1212
#[doc(hidden)]
1313
pub mod invariant;
1414
mod ptr;
15+
mod transmute;
1516

1617
#[doc(hidden)]
17-
pub use invariant::{BecauseExclusive, BecauseImmutable, Read};
18+
pub(crate) use transmute::*;
1819
#[doc(hidden)]
19-
pub use ptr::Ptr;
20+
pub use {
21+
invariant::{BecauseExclusive, BecauseImmutable, Read},
22+
ptr::Ptr,
23+
};
2024

2125
use crate::Unaligned;
2226

0 commit comments

Comments
 (0)