Skip to content

Commit

Permalink
Remove Immutable where it's no longer needed (#1225)
Browse files Browse the repository at this point in the history
* Add `AliasingSafe` framework

This commit adds the `pointer::aliasing_safety::AliasingSafe` trait,
which is implemented for pointer conversions which do not violate
aliasing. This can happen either because the aliasing is exclusive or
because neither type contains `UnsafeCell`s.

This paves the way for us to remove `Immutable` bounds from some of our
API, including from some derives.

Makes progress on #251

Co-authored-by: Jack Wrenn <jswrenn@amazon.com>

* Remove `Immutable` where it's no longer needed

There are some APIs which still spuriously require `Immutable`, but
which require more work to update. These will be fixed in a separate
commit.

Makes progress on #251

Co-authored-by: Jack Wrenn <jswrenn@amazon.com>

---------

Co-authored-by: Jack Wrenn <jswrenn@amazon.com>
  • Loading branch information
joshlf and jswrenn authored May 9, 2024
1 parent 1c3c3da commit 730e2ba
Show file tree
Hide file tree
Showing 18 changed files with 16 additions and 294 deletions.
33 changes: 10 additions & 23 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1427,7 +1427,7 @@ pub unsafe trait TryFromBytes {
#[inline]
fn try_mut_from(bytes: &mut [u8]) -> Result<&mut Self, TryCastError<&mut [u8], Self>>
where
Self: KnownLayout + Immutable, // TODO(#251): Remove the `Immutable` bound.
Self: KnownLayout,
{
util::assert_dst_is_not_zst::<Self>();
match Ptr::from_mut(bytes).try_cast_into_no_leftover::<Self, BecauseExclusive>() {
Expand Down Expand Up @@ -1532,7 +1532,7 @@ pub unsafe trait TryFromBytes {
candidate: &mut [u8],
) -> Result<(&mut Self, &mut [u8]), TryCastError<&mut [u8], Self>>
where
Self: KnownLayout + Immutable,
Self: KnownLayout,
{
util::assert_dst_is_not_zst::<Self>();
try_mut_from_prefix_suffix(candidate, CastType::Prefix)
Expand Down Expand Up @@ -1619,7 +1619,7 @@ pub unsafe trait TryFromBytes {
candidate: &mut [u8],
) -> Result<(&mut [u8], &mut Self), TryCastError<&mut [u8], Self>>
where
Self: KnownLayout + Immutable,
Self: KnownLayout,
{
util::assert_dst_is_not_zst::<Self>();
try_mut_from_prefix_suffix(candidate, CastType::Suffix).map(swap)
Expand Down Expand Up @@ -2535,7 +2535,7 @@ pub unsafe trait FromBytes: FromZeros {
#[inline]
fn mut_from(bytes: &mut [u8]) -> Result<&mut Self, CastError<&mut [u8], Self>>
where
Self: IntoBytes + KnownLayout + Immutable,
Self: IntoBytes + KnownLayout,
{
util::assert_dst_is_not_zst::<Self>();
match Ptr::from_mut(bytes).try_cast_into_no_leftover::<_, BecauseExclusive>() {
Expand Down Expand Up @@ -2610,7 +2610,7 @@ pub unsafe trait FromBytes: FromZeros {
bytes: &mut [u8],
) -> Result<(&mut Self, &mut [u8]), CastError<&mut [u8], Self>>
where
Self: IntoBytes + KnownLayout + Immutable,
Self: IntoBytes + KnownLayout,
{
util::assert_dst_is_not_zst::<Self>();
let (slf, suffix) = Ptr::from_mut(bytes)
Expand Down Expand Up @@ -2679,7 +2679,7 @@ pub unsafe trait FromBytes: FromZeros {
bytes: &mut [u8],
) -> Result<(&mut [u8], &mut Self), CastError<&mut [u8], Self>>
where
Self: IntoBytes + KnownLayout + Immutable,
Self: IntoBytes + KnownLayout,
{
util::assert_dst_is_not_zst::<Self>();
let (slf, prefix) = Ptr::from_mut(bytes)
Expand Down Expand Up @@ -3483,7 +3483,7 @@ pub unsafe trait IntoBytes {
#[inline(always)]
fn as_mut_bytes(&mut self) -> &mut [u8]
where
Self: FromBytes + Immutable,
Self: FromBytes,
{
// Note that this method does not have a `Self: Sized` bound;
// `size_of_val` works for unsized values too.
Expand Down Expand Up @@ -3718,7 +3718,7 @@ pub unsafe trait IntoBytes {
#[inline]
fn as_bytes_mut(&mut self) -> &mut [u8]
where
Self: FromBytes + Immutable,
Self: FromBytes,
{
self.as_mut_bytes()
}
Expand Down Expand Up @@ -5076,20 +5076,16 @@ macro_rules! transmute_mut {
struct AssertSrcIsSized<'a, T: ::core::marker::Sized>(&'a T);
struct AssertSrcIsFromBytes<'a, T: ?::core::marker::Sized + $crate::FromBytes>(&'a T);
struct AssertSrcIsIntoBytes<'a, T: ?::core::marker::Sized + $crate::IntoBytes>(&'a T);
struct AssertSrcIsImmutable<'a, T: ?::core::marker::Sized + $crate::Immutable>(&'a T);
struct AssertDstIsSized<'a, T: ::core::marker::Sized>(&'a T);
struct AssertDstIsFromBytes<'a, T: ?::core::marker::Sized + $crate::FromBytes>(&'a T);
struct AssertDstIsIntoBytes<'a, T: ?::core::marker::Sized + $crate::IntoBytes>(&'a T);
struct AssertDstIsImmutable<'a, T: ?::core::marker::Sized + $crate::Immutable>(&'a T);

if true {
let _ = AssertSrcIsSized(&*e);
} else if true {
let _ = AssertSrcIsFromBytes(&*e);
} else if true {
let _ = AssertSrcIsIntoBytes(&*e);
} else {
let _ = AssertSrcIsImmutable(&*e);
let _ = AssertSrcIsIntoBytes(&*e);
}

if true {
Expand All @@ -5100,13 +5096,9 @@ macro_rules! transmute_mut {
#[allow(unused, unreachable_code)]
let u = AssertDstIsFromBytes(loop {});
&mut *u.0
} else if true {
#[allow(unused, unreachable_code)]
let u = AssertDstIsIntoBytes(loop {});
&mut *u.0
} else {
#[allow(unused, unreachable_code)]
let u = AssertDstIsImmutable(loop {});
let u = AssertDstIsIntoBytes(loop {});
&mut *u.0
}
} else if false {
Expand All @@ -5129,11 +5121,6 @@ macro_rules! transmute_mut {
&mut u
} else {
// SAFETY: For source type `Src` and destination type `Dst`:
// - We know that `Src: FromBytes + IntoBytes + Immutable` and `Dst:
// FromBytes + IntoBytes + Immutable` thanks to the uses of
// `AssertSrcIsFromBytes`, `AssertSrcIsIntoBytes`,
// `AssertSrcIsImmutable`, `AssertDstIsFromBytes`,
// `AssertDstIsIntoBytes`, and `AssertDstIsImmutable` above.
// - We know that `size_of::<Src>() == size_of::<Dst>()` thanks to
// the use of `assert_size_eq!` above.
// - We know that `align_of::<Src>() >= align_of::<Dst>()` thanks to
Expand Down
7 changes: 2 additions & 5 deletions src/macro_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,8 +386,8 @@ pub const unsafe fn transmute_ref<'dst, 'src: 'dst, Src: 'src, Dst: 'dst>(
/// # Safety
///
/// The caller must guarantee that:
/// - `Src: FromBytes + IntoBytes + Immutable`
/// - `Dst: FromBytes + IntoBytes + Immutable`
/// - `Src: FromBytes + IntoBytes`
/// - `Dst: FromBytes + IntoBytes`
/// - `size_of::<Src>() == size_of::<Dst>()`
/// - `align_of::<Src>() >= align_of::<Dst>()`
// TODO(#686): Consider removing the `Immutable` requirement.
Expand All @@ -403,9 +403,6 @@ pub unsafe fn transmute_mut<'dst, 'src: 'dst, Src: 'src, Dst: 'dst>(
// vice-versa because the caller has guaranteed that `Src: FromBytes +
// IntoBytes`, `Dst: FromBytes + IntoBytes`, and `size_of::<Src>() ==
// size_of::<Dst>()`.
// - We know that there are no `UnsafeCell`s, and thus we don't have to
// worry about `UnsafeCell` overlap, because `Src: Immutable`
// and `Dst: Immutable`.
// - The caller has guaranteed that alignment is not increased.
// - We know that the returned lifetime will not outlive the input lifetime
// thanks to the lifetime bounds on this function.
Expand Down
5 changes: 4 additions & 1 deletion src/ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,7 @@ where
impl<'a, B, T> Ref<B, T>
where
B: 'a + IntoByteSliceMut<'a>,
T: FromBytes + IntoBytes + KnownLayout + Immutable + ?Sized,
T: FromBytes + IntoBytes + KnownLayout + ?Sized,
{
/// Converts this `Ref` into a mutable reference.
///
Expand Down Expand Up @@ -802,6 +802,9 @@ where
impl<B, T> DerefMut for Ref<B, T>
where
B: ByteSliceMut,
// TODO(#251): We can't remove `Immutable` here because it's required by
// the impl of `Deref`, which is a super-trait of `DerefMut`. Maybe we can
// add a separate inherent method for this?
T: FromBytes + IntoBytes + KnownLayout + Immutable + ?Sized,
{
#[inline]
Expand Down
10 changes: 0 additions & 10 deletions tests/ui-msrv/transmute-mut-dst-not-a-reference.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,3 @@ error[E0308]: mismatched types
= note: expected type `usize`
found mutable reference `&mut _`
= note: this error originates in the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
--> tests/ui-msrv/transmute-mut-dst-not-a-reference.rs:17:36
|
17 | const DST_NOT_A_REFERENCE: usize = transmute_mut!(&mut 0u8);
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `&mut _`
|
= note: expected type `usize`
found mutable reference `&mut _`
= note: this error originates in the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)
1 change: 0 additions & 1 deletion tests/ui-msrv/transmute-mut-dst-not-nocell.rs

This file was deleted.

12 changes: 0 additions & 12 deletions tests/ui-msrv/transmute-mut-dst-not-nocell.stderr

This file was deleted.

1 change: 0 additions & 1 deletion tests/ui-msrv/transmute-mut-src-not-nocell.rs

This file was deleted.

25 changes: 0 additions & 25 deletions tests/ui-msrv/transmute-mut-src-not-nocell.stderr

This file was deleted.

10 changes: 0 additions & 10 deletions tests/ui-nightly/transmute-mut-dst-not-a-reference.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,6 @@ error[E0308]: mismatched types
found mutable reference `&mut _`
= note: this error originates in the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
--> tests/ui-nightly/transmute-mut-dst-not-a-reference.rs:17:36
|
17 | const DST_NOT_A_REFERENCE: usize = transmute_mut!(&mut 0u8);
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `&mut _`
|
= note: expected type `usize`
found mutable reference `&mut _`
= note: this error originates in the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
--> tests/ui-nightly/transmute-mut-dst-not-a-reference.rs:17:36
|
Expand Down
24 changes: 0 additions & 24 deletions tests/ui-nightly/transmute-mut-dst-not-nocell.rs

This file was deleted.

25 changes: 0 additions & 25 deletions tests/ui-nightly/transmute-mut-dst-not-nocell.stderr

This file was deleted.

24 changes: 0 additions & 24 deletions tests/ui-nightly/transmute-mut-src-not-nocell.rs

This file was deleted.

48 changes: 0 additions & 48 deletions tests/ui-nightly/transmute-mut-src-not-nocell.stderr

This file was deleted.

10 changes: 0 additions & 10 deletions tests/ui-stable/transmute-mut-dst-not-a-reference.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,6 @@ error[E0308]: mismatched types
found mutable reference `&mut _`
= note: this error originates in the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
--> tests/ui-stable/transmute-mut-dst-not-a-reference.rs:17:36
|
17 | const DST_NOT_A_REFERENCE: usize = transmute_mut!(&mut 0u8);
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `&mut _`
|
= note: expected type `usize`
found mutable reference `&mut _`
= note: this error originates in the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
--> tests/ui-stable/transmute-mut-dst-not-a-reference.rs:17:36
|
Expand Down
1 change: 0 additions & 1 deletion tests/ui-stable/transmute-mut-dst-not-nocell.rs

This file was deleted.

Loading

0 comments on commit 730e2ba

Please sign in to comment.