Skip to content

Commit

Permalink
Reduce MSRV to 1.61.0
Browse files Browse the repository at this point in the history
It turned out that there were only a few lines of code that required
our MSRV to be as high as it was before this commit (1.65.0), and those
lines were easy to modify to be compatible with this new MSRV.

Note that this requires re-introducing a bug that was removed in #156
because the bug is based on an underlying bug in the standard library.
That bug was considered minor at the time it was discovered, and I still
consider it minor now. See #64 for more details.
  • Loading branch information
joshlf committed Aug 8, 2023
1 parent ab7ed8f commit 475472f
Show file tree
Hide file tree
Showing 12 changed files with 89 additions and 180 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ authors = ["Joshua Liebow-Feeser <joshlf@google.com>"]
description = "Utilities for zero-copy parsing and serialization"
license = "BSD-2-Clause"
repository = "https://github.com/google/zerocopy"
rust-version = "1.65.0"
rust-version = "1.61.0"

exclude = [".*"]

Expand Down
72 changes: 49 additions & 23 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1265,12 +1265,16 @@ impl<T> Unalign<T> {
/// If `self` does not satisfy `mem::align_of::<T>()`, then
/// `self.deref_unchecked()` may cause undefined behavior.
pub const unsafe fn deref_unchecked(&self) -> &T {
// SAFETY: `self.get_ptr()` returns a raw pointer to a valid `T` at the
// same memory location as `self`. It has no alignment guarantee, but
// the caller has promised that `self` is properly aligned, so we know
// that the pointer itself is aligned, and thus that it is sound to
// create a reference to a `T` at this memory location.
unsafe { &*self.get_ptr() }
// SAFETY: `Unalign<T>` is `repr(transparent)`, so there is a valid `T`
// at the same memory location as `self`. It has no alignment guarantee,
// but the caller has promised that `self` is properly aligned, so we
// know that it is sound to create a reference to `T` at this memory
// location.
//
// We use `mem::transmute` instead of `&*self.get_ptr()` because
// dereferencing pointers is not stable in `const` on our current MSRV
// (1.56 as of this writing).
unsafe { mem::transmute(self) }
}

/// Returns a mutable reference to the wrapped `T` without checking
Expand Down Expand Up @@ -1518,6 +1522,10 @@ macro_rules! transmute {
// were to use `core::mem::transmute`, this macro would not work in
// `std` contexts in which `core` was not manually imported. This is
// not a problem for 2018 edition crates.
//
// Some older versions of Clippy have a bug in which they don't
// recognize the preceding safety comment.
#[allow(clippy::undocumented_unsafe_blocks)]
unsafe { $crate::__real_transmute(e) }
}
}}
Expand Down Expand Up @@ -2777,8 +2785,6 @@ mod alloc_support {

#[cfg(test)]
mod tests {
use core::convert::TryFrom as _;

use super::*;

#[test]
Expand Down Expand Up @@ -2870,30 +2876,21 @@ mod alloc_support {
drop(v);

// Insert at start.
let mut v: Vec<()> = Vec::with_capacity(3);
v.push(());
v.push(());
v.push(());
let mut v = vec![(), (), ()];
insert_vec_zeroed(&mut v, 0, 2);
assert_eq!(v.len(), 5);
assert_eq!(&*v, &[(), (), (), (), ()]);
drop(v);

// Insert at middle.
let mut v: Vec<()> = Vec::with_capacity(3);
v.push(());
v.push(());
v.push(());
let mut v = vec![(), (), ()];
insert_vec_zeroed(&mut v, 1, 1);
assert_eq!(v.len(), 4);
assert_eq!(&*v, &[(), (), (), ()]);
drop(v);

// Insert at end.
let mut v: Vec<()> = Vec::with_capacity(3);
v.push(());
v.push(());
v.push(());
let mut v = vec![(), (), ()];
insert_vec_zeroed(&mut v, 3, 1);
assert_eq!(v.len(), 4);
assert_eq!(&*v, &[(), (), (), ()]);
Expand Down Expand Up @@ -2961,9 +2958,38 @@ mod alloc_support {
let _ = u16::new_box_slice_zeroed(usize::MAX);
}

// This test fails on stable <= 1.64.0, but succeeds on 1.65.0-beta.2
// (2022-09-13). In particular, on stable <= 1.64.0,
// `new_box_slice_zeroed` attempts to perform the allocation (which of
// course fails). `Layout::from_size_align` should be returning an error
// due to `isize` overflow, but it doesn't. I (joshlf) haven't
// investigated enough to confirm, but my guess is that this was a bug
// that was fixed recently.
//
// Triggering the bug requires calling
// `FromZeroes::new_box_slice_zeroed` with an allocation which overflows
// `isize`, and all that happens is that the program panics due to a
// failed allocation. Even on 32-bit platforms, this requires a 2GB
// allocation. On 64-bit platforms, this requires a 2^63-byte
// allocation. In both cases, even a slightly smaller allocation that
// didn't trigger this bug would likely (absolutely certainly in the
// case of 64-bit platforms) fail to allocate in exactly the same way
// regardless.
//
// Given how minor the impact is, and given that the bug seems fixed in
// 1.65.0, I've chosen to just release the code as-is and disable the
// test on buggy toolchains. Once our MSRV is at or above 1.65.0, we can
// remove this conditional compilation (and this comment) entirely.
#[rustversion::since(1.65.0)]
#[test]
#[should_panic(expected = "total allocation size overflows `isize`: LayoutError")]
fn test_new_box_slice_zeroed_panics_isize_overflow() {
// TODO: Move this to the top of the module once this test is
// compiled unconditionally. Right now, it causes an unused import
// warning (which in CI becomes an error) on versions prior to
// 1.65.0.
use core::convert::TryFrom as _;

let max = usize::try_from(isize::MAX).unwrap();
let _ = u16::new_box_slice_zeroed((max / mem::size_of::<u16>()) + 1);
}
Expand Down Expand Up @@ -3753,7 +3779,7 @@ mod tests {
/// has had its bits flipped (by applying `^= 0xFF`).
///
/// `N` is the size of `t` in bytes.
fn test<const N: usize, T: FromBytes + AsBytes + Debug + Eq + ?Sized>(
fn test<T: FromBytes + AsBytes + Debug + Eq + ?Sized, const N: usize>(
t: &mut T,
bytes: &[u8],
post_mutation: &T,
Expand Down Expand Up @@ -3825,12 +3851,12 @@ mod tests {
};
let post_mutation_expected_a =
if cfg!(target_endian = "little") { 0x00_00_00_FE } else { 0xFF_00_00_01 };
test::<12, _>(
test::<_, 12>(
&mut Foo { a: 1, b: Wrapping(2), c: None },
expected_bytes.as_bytes(),
&Foo { a: post_mutation_expected_a, b: Wrapping(2), c: None },
);
test::<3, _>(
test::<_, 3>(
Unsized::from_mut_slice(&mut [1, 2, 3]),
&[1, 2, 3],
Unsized::from_mut_slice(&mut [0xFE, 2, 3]),
Expand Down
6 changes: 3 additions & 3 deletions tests/trybuild.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
// - `tests/ui-msrv` - Contains symlinks to the `.rs` files in
// `tests/ui-nightly`, and contains `.err` and `.out` files for MSRV

#[rustversion::any(nightly)]
#[rustversion::nightly]
const SOURCE_FILES_GLOB: &str = "tests/ui-nightly/*.rs";
#[rustversion::all(stable, not(stable(1.65.0)))]
#[rustversion::stable(1.69.0)]
const SOURCE_FILES_GLOB: &str = "tests/ui-stable/*.rs";
#[rustversion::stable(1.65.0)]
#[rustversion::stable(1.61.0)]
const SOURCE_FILES_GLOB: &str = "tests/ui-msrv/*.rs";

#[test]
Expand Down
19 changes: 6 additions & 13 deletions tests/ui-msrv/transmute-illegal.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,13 @@ error[E0277]: the trait bound `*const usize: AsBytes` is not satisfied
--> tests/ui-msrv/transmute-illegal.rs:10:30
|
10 | const POINTER_VALUE: usize = zerocopy::transmute!(&0usize as *const usize);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| the trait `AsBytes` is not implemented for `*const usize`
| required by a bound introduced by this call
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `AsBytes` is not implemented for `*const usize`
|
= help: the following other types implement trait `AsBytes`:
f32
f64
i128
i16
i32
i64
i8
isize
= help: the following implementations were found:
<usize as AsBytes>
<f32 as AsBytes>
<f64 as AsBytes>
<i128 as AsBytes>
and $N others
note: required by a bound in `POINTER_VALUE::transmute`
--> tests/ui-msrv/transmute-illegal.rs:10:30
Expand Down
2 changes: 1 addition & 1 deletion zerocopy-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ authors = ["Joshua Liebow-Feeser <joshlf@google.com>"]
description = "Custom derive for traits from the zerocopy crate"
license = "BSD-2-Clause"
repository = "https://github.com/google/zerocopy"
rust-version = "1.65.0"
rust-version = "1.61.0"

exclude = [".*"]

Expand Down
4 changes: 2 additions & 2 deletions zerocopy-derive/src/repr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ impl Repr {
let ident = path
.get_ident()
.ok_or_else(|| Error::new_spanned(meta, "unrecognized representation hint"))?;
match format!("{ident}").as_str() {
match format!("{}", ident).as_str() {
"u8" => return Ok(Repr::U8),
"u16" => return Ok(Repr::U16),
"u32" => return Ok(Repr::U32),
Expand Down Expand Up @@ -221,7 +221,7 @@ impl Repr {
impl Display for Repr {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
if let Repr::Align(n) = self {
return write!(f, "repr(align({n}))");
return write!(f, "repr(align({}))", n);
}
write!(
f,
Expand Down
6 changes: 3 additions & 3 deletions zerocopy-derive/tests/trybuild.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
// - `tests/ui-msrv` - Contains symlinks to the `.rs` files in
// `tests/ui-nightly`, and contains `.err` and `.out` files for MSRV

#[rustversion::any(nightly)]
#[rustversion::nightly]
const SOURCE_FILES_GLOB: &str = "tests/ui-nightly/*.rs";
#[rustversion::all(stable, not(stable(1.65.0)))]
#[rustversion::stable(1.69.0)]
const SOURCE_FILES_GLOB: &str = "tests/ui-stable/*.rs";
#[rustversion::stable(1.65.0)]
#[rustversion::stable(1.61.0)]
const SOURCE_FILES_GLOB: &str = "tests/ui-msrv/*.rs";

#[test]
Expand Down
80 changes: 20 additions & 60 deletions zerocopy-derive/tests/ui-msrv/derive_transparent.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,10 @@
error[E0277]: the trait bound `NotZerocopy: FromZeroes` is not satisfied
--> tests/ui-msrv/derive_transparent.rs:33:18
--> tests/ui-msrv/derive_transparent.rs:33:1
|
33 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeroes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromZeroes` is not implemented for `NotZerocopy`
|
= help: the following other types implement trait `FromZeroes`:
()
AU16
F32<O>
F64<O>
I128<O>
I16<O>
I32<O>
I64<O>
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `FromZeroes`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromZeroes` is not implemented for `NotZerocopy`
|
note: required because of the requirements on the impl of `FromZeroes` for `TransparentStruct<NotZerocopy>`
--> tests/ui-msrv/derive_transparent.rs:23:19
|
23 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
Expand All @@ -24,25 +14,15 @@ note: required by a bound in `_::{closure#0}::assert_impl_all`
|
33 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeroes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `_::{closure#0}::assert_impl_all`
= note: this error originates in the derive macro `FromZeroes` which comes from the expansion of the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: this error originates in the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `NotZerocopy: FromBytes` is not satisfied
--> tests/ui-msrv/derive_transparent.rs:34:18
--> tests/ui-msrv/derive_transparent.rs:34:1
|
34 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromBytes` is not implemented for `NotZerocopy`
|
= help: the following other types implement trait `FromBytes`:
()
AU16
F32<O>
F64<O>
I128<O>
I16<O>
I32<O>
I64<O>
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `FromBytes`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromBytes` is not implemented for `NotZerocopy`
|
note: required because of the requirements on the impl of `FromBytes` for `TransparentStruct<NotZerocopy>`
--> tests/ui-msrv/derive_transparent.rs:23:31
|
23 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
Expand All @@ -52,25 +32,15 @@ note: required by a bound in `_::{closure#0}::assert_impl_all`
|
34 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `_::{closure#0}::assert_impl_all`
= note: this error originates in the derive macro `FromBytes` which comes from the expansion of the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: this error originates in the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `NotZerocopy: AsBytes` is not satisfied
--> tests/ui-msrv/derive_transparent.rs:35:18
--> tests/ui-msrv/derive_transparent.rs:35:1
|
35 | assert_impl_all!(TransparentStruct<NotZerocopy>: AsBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `AsBytes` is not implemented for `NotZerocopy`
|
= help: the following other types implement trait `AsBytes`:
()
AU16
F32<O>
F64<O>
I128<O>
I16<O>
I32<O>
I64<O>
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `AsBytes`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `AsBytes` is not implemented for `NotZerocopy`
|
note: required because of the requirements on the impl of `AsBytes` for `TransparentStruct<NotZerocopy>`
--> tests/ui-msrv/derive_transparent.rs:23:10
|
23 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
Expand All @@ -80,25 +50,15 @@ note: required by a bound in `_::{closure#0}::assert_impl_all`
|
35 | assert_impl_all!(TransparentStruct<NotZerocopy>: AsBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `_::{closure#0}::assert_impl_all`
= note: this error originates in the derive macro `AsBytes` which comes from the expansion of the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: this error originates in the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `NotZerocopy: Unaligned` is not satisfied
--> tests/ui-msrv/derive_transparent.rs:36:18
--> tests/ui-msrv/derive_transparent.rs:36:1
|
36 | assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unaligned` is not implemented for `NotZerocopy`
|
= help: the following other types implement trait `Unaligned`:
()
F32<O>
F64<O>
I128<O>
I16<O>
I32<O>
I64<O>
ManuallyDrop<T>
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `Unaligned`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unaligned` is not implemented for `NotZerocopy`
|
note: required because of the requirements on the impl of `Unaligned` for `TransparentStruct<NotZerocopy>`
--> tests/ui-msrv/derive_transparent.rs:23:42
|
23 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
Expand All @@ -108,4 +68,4 @@ note: required by a bound in `_::{closure#0}::assert_impl_all`
|
36 | assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `_::{closure#0}::assert_impl_all`
= note: this error originates in the derive macro `Unaligned` which comes from the expansion of the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: this error originates in the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
2 changes: 0 additions & 2 deletions zerocopy-derive/tests/ui-msrv/enum.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,6 @@ error[E0552]: unrecognized representation hint
|
21 | #[repr(foo)]
| ^^^
|
= help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`

error[E0566]: conflicting representation hints
--> tests/ui-msrv/enum.rs:33:8
Expand Down
Loading

0 comments on commit 475472f

Please sign in to comment.