Skip to content

Commit 12b6697

Browse files
committed
Lower MSRV to 1.60
Modify the way that certain memory safety properties are validated in our `transmute!`, `transmute_ref!`, and `transmute_mut!` macros to allow that code to compile on 1.60. Makes progress on #554
1 parent f47b4df commit 12b6697

File tree

74 files changed

+1544
-313
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+1544
-313
lines changed

Cargo.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@
1313
[workspace]
1414

1515
[package]
16-
edition = "2021"
16+
edition = "2018"
1717
name = "zerocopy"
18-
version = "0.7.18"
18+
version = "0.7.19"
1919
authors = ["Joshua Liebow-Feeser <[email protected]>"]
2020
description = "Utilities for zero-copy parsing and serialization"
2121
license = "BSD-2-Clause OR Apache-2.0 OR MIT"
2222
repository = "https://github.com/google/zerocopy"
23-
rust-version = "1.61.0"
23+
rust-version = "1.60.0"
2424

2525
exclude = [".*"]
2626

@@ -45,7 +45,7 @@ simd-nightly = ["simd"]
4545
__internal_use_only_features_that_work_on_stable = ["alloc", "derive", "simd"]
4646

4747
[dependencies]
48-
zerocopy-derive = { version = "=0.7.18", path = "zerocopy-derive", optional = true }
48+
zerocopy-derive = { version = "=0.7.19", path = "zerocopy-derive", optional = true }
4949

5050
[dependencies.byteorder]
5151
version = "1.3"
@@ -56,7 +56,7 @@ optional = true
5656
# zerocopy-derive remain equal, even if the 'derive' feature isn't used.
5757
# See: https://github.com/matklad/macro-dep-test
5858
[target.'cfg(any())'.dependencies]
59-
zerocopy-derive = { version = "=0.7.18", path = "zerocopy-derive" }
59+
zerocopy-derive = { version = "=0.7.19", path = "zerocopy-derive" }
6060

6161
[dev-dependencies]
6262
assert_matches = "1.5"
@@ -71,4 +71,4 @@ testutil = { path = "testutil" }
7171
# CI test failures.
7272
trybuild = { version = "=1.0.85", features = ["diff"] }
7373
# In tests, unlike in production, zerocopy-derive is not optional
74-
zerocopy-derive = { version = "=0.7.18", path = "zerocopy-derive" }
74+
zerocopy-derive = { version = "=0.7.19", path = "zerocopy-derive" }

src/lib.rs

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2007,10 +2007,14 @@ macro_rules! transmute {
20072007
// This branch, though never taken, ensures that the type of `e` is
20082008
// `AsBytes` and that the type of this macro invocation expression
20092009
// is `FromBytes`.
2010-
const fn transmute<T: $crate::AsBytes, U: $crate::FromBytes>(_t: T) -> U {
2011-
loop {}
2012-
}
2013-
transmute(e)
2010+
2011+
struct AssertIsAsBytes<T: $crate::AsBytes>(T);
2012+
let _ = AssertIsAsBytes(e);
2013+
2014+
struct AssertIsFromBytes<U: $crate::FromBytes>(U);
2015+
#[allow(unused, unreachable_code)]
2016+
let u = AssertIsFromBytes(loop {});
2017+
u.0
20142018
} else {
20152019
// SAFETY: `core::mem::transmute` ensures that the type of `e` and
20162020
// the type of this macro invocation expression have the same size.
@@ -2092,7 +2096,18 @@ macro_rules! transmute_ref {
20922096
// `&T` where `T: 't + Sized + AsBytes`, that the type of this macro
20932097
// expression is `&U` where `U: 'u + Sized + FromBytes`, and that
20942098
// `'t` outlives `'u`.
2095-
const fn transmute<'u, 't: 'u, T: 't + Sized + $crate::AsBytes, U: 'u + Sized + $crate::FromBytes>(_t: &'t T) -> &'u U {
2099+
2100+
struct AssertIsAsBytes<'a, T: ::core::marker::Sized + $crate::AsBytes>(&'a T);
2101+
let _ = AssertIsAsBytes(e);
2102+
2103+
struct AssertIsFromBytes<'a, U: ::core::marker::Sized + $crate::FromBytes>(&'a U);
2104+
#[allow(unused, unreachable_code)]
2105+
let u = AssertIsFromBytes(loop {});
2106+
u.0
2107+
} else if false {
2108+
// This branch, though never taken, ensures that the source lifetime
2109+
// is not shorter than the destination lifetime.
2110+
const fn transmute<'u, 't: 'u, T: 't, U: 'u>(t: &'t T) -> &'u U {
20962111
loop {}
20972112
}
20982113
transmute(e)
@@ -2191,19 +2206,44 @@ macro_rules! transmute_mut {
21912206
// because there's no way, in a generic context, to enforce that two
21922207
// types have the same size or alignment.
21932208

2194-
let e = $e;
2209+
// Ensure that the source type is a mutable reference.
2210+
let e = &mut *$e;
21952211

21962212
#[allow(unused, clippy::diverging_sub_expression)]
21972213
if false {
21982214
// This branch, though never taken, ensures that the type of `e` is
2199-
// `&mut T` where `T: 't + Sized + AsBytes + FromBytes`, that the
2215+
// `&mut T` where `T: 't + Sized + FromBytes + AsBytes`, that the
22002216
// type of this macro expression is `&mut U` where `U: 'u + Sized +
2201-
// AsBytes + FromBytes`.
2202-
fn transmute<'t, T, U>(_t: &'t mut T) -> &'t mut U
2203-
where
2204-
T: 't + Sized + $crate::AsBytes + $crate::FromBytes,
2205-
U: 't + Sized + $crate::AsBytes + $crate::FromBytes,
2206-
{
2217+
// FromBytes + AsBytes`.
2218+
2219+
// We use immutable references here rather than mutable so that, if
2220+
// this macro is used in a const context (in which, as of this
2221+
// writing, mutable references are banned), the error message
2222+
// appears to originate in the user's code rather than in the
2223+
// internals of this macro.
2224+
struct AssertIsFromBytes<'a, T: ::core::marker::Sized + $crate::FromBytes>(&'a T);
2225+
struct AssertIsAsBytes<'a, T: ::core::marker::Sized + $crate::AsBytes>(&'a T);
2226+
2227+
if true {
2228+
let _ = AssertIsFromBytes(&*e);
2229+
} else {
2230+
let _ = AssertIsAsBytes(&*e);
2231+
}
2232+
2233+
if true {
2234+
#[allow(unused, unreachable_code)]
2235+
let u = AssertIsFromBytes(loop {});
2236+
&mut *u.0
2237+
} else {
2238+
#[allow(unused, unreachable_code)]
2239+
let u = AssertIsAsBytes(loop {});
2240+
&mut *u.0
2241+
}
2242+
} else if false {
2243+
// This branch, though never taken, ensures that the source lifetime
2244+
// is not shorter than the destination lifetime, and that the source
2245+
// type is a mutable (rather than immutable) reference.
2246+
fn transmute<'u, 't: 'u, T: 't, U: 'u>(t: &'t mut T) -> &'u mut U {
22072247
loop {}
22082248
}
22092249
transmute(e)
@@ -3654,7 +3694,7 @@ pub use alloc_support::*;
36543694
mod tests {
36553695
#![allow(clippy::unreadable_literal)]
36563696

3657-
use core::ops::Deref;
3697+
use core::{convert::TryInto as _, ops::Deref};
36583698

36593699
use static_assertions::assert_impl_all;
36603700

tests/ui-msrv/include_value_not_from_bytes.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ error[E0277]: the trait bound `UnsafeCell<u32>: FromBytes` is not satisfied
44
12 | include_value!("../../testdata/include_value/data");
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromBytes` is not implemented for `UnsafeCell<u32>`
66
|
7-
note: required by a bound in `NOT_FROM_BYTES::transmute`
7+
note: required by a bound in `AssertIsFromBytes`
88
--> tests/ui-msrv/include_value_not_from_bytes.rs:12:5
99
|
1010
12 | include_value!("../../testdata/include_value/data");
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `NOT_FROM_BYTES::transmute`
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `AssertIsFromBytes`
1212
= note: this error originates in the macro `$crate::transmute` (in Nightly builds, run with -Z macro-backtrace for more info)

tests/ui-msrv/transmute-dst-not-frombytes.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ error[E0277]: the trait bound `NotZerocopy: FromBytes` is not satisfied
44
18 | const DST_NOT_FROM_BYTES: NotZerocopy = transmute!(AU16(0));
55
| ^^^^^^^^^^^^^^^^^^^ the trait `FromBytes` is not implemented for `NotZerocopy`
66
|
7-
note: required by a bound in `DST_NOT_FROM_BYTES::transmute`
7+
note: required by a bound in `AssertIsFromBytes`
88
--> tests/ui-msrv/transmute-dst-not-frombytes.rs:18:41
99
|
1010
18 | const DST_NOT_FROM_BYTES: NotZerocopy = transmute!(AU16(0));
11-
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `DST_NOT_FROM_BYTES::transmute`
11+
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `AssertIsFromBytes`
1212
= note: this error originates in the macro `transmute` (in Nightly builds, run with -Z macro-backtrace for more info)

tests/ui-msrv/transmute-mut-dst-not-a-reference.stderr

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,23 @@ error[E0308]: mismatched types
1717
= note: expected type `usize`
1818
found mutable reference `&mut _`
1919
= note: this error originates in the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)
20+
21+
error[E0308]: mismatched types
22+
--> tests/ui-msrv/transmute-mut-dst-not-a-reference.rs:17:36
23+
|
24+
17 | const DST_NOT_A_REFERENCE: usize = transmute_mut!(&mut 0u8);
25+
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `&mut _`
26+
|
27+
= note: expected type `usize`
28+
found mutable reference `&mut _`
29+
= note: this error originates in the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)
30+
31+
error[E0308]: mismatched types
32+
--> tests/ui-msrv/transmute-mut-dst-not-a-reference.rs:17:36
33+
|
34+
17 | const DST_NOT_A_REFERENCE: usize = transmute_mut!(&mut 0u8);
35+
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `&mut _`
36+
|
37+
= note: expected type `usize`
38+
found mutable reference `&mut _`
39+
= note: this error originates in the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)

tests/ui-msrv/transmute-mut-dst-not-asbytes.stderr

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,9 @@ error[E0277]: the trait bound `Dst: AsBytes` is not satisfied
44
24 | const DST_NOT_AS_BYTES: &mut Dst = transmute_mut!(&mut Src);
55
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `AsBytes` is not implemented for `Dst`
66
|
7-
note: required by a bound in `DST_NOT_AS_BYTES::transmute`
7+
note: required by a bound in `AssertIsAsBytes`
88
--> tests/ui-msrv/transmute-mut-dst-not-asbytes.rs:24:36
99
|
1010
24 | const DST_NOT_AS_BYTES: &mut Dst = transmute_mut!(&mut Src);
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^
12-
| |
13-
| required by a bound in this
14-
| required by this bound in `DST_NOT_AS_BYTES::transmute`
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `AssertIsAsBytes`
1512
= note: this error originates in the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)

tests/ui-msrv/transmute-mut-dst-not-frombytes.stderr

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,9 @@ error[E0277]: the trait bound `Dst: FromBytes` is not satisfied
44
24 | const DST_NOT_FROM_BYTES: &mut Dst = transmute_mut!(&mut Src);
55
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromBytes` is not implemented for `Dst`
66
|
7-
note: required by a bound in `DST_NOT_FROM_BYTES::transmute`
7+
note: required by a bound in `AssertIsFromBytes`
88
--> tests/ui-msrv/transmute-mut-dst-not-frombytes.rs:24:38
99
|
1010
24 | const DST_NOT_FROM_BYTES: &mut Dst = transmute_mut!(&mut Src);
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^
12-
| |
13-
| required by a bound in this
14-
| required by this bound in `DST_NOT_FROM_BYTES::transmute`
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `AssertIsFromBytes`
1512
= note: this error originates in the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)

tests/ui-msrv/transmute-mut-dst-unsized.stderr

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
1+
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
2+
--> tests/ui-msrv/transmute-mut-dst-unsized.rs:17:32
3+
|
4+
17 | const DST_UNSIZED: &mut [u8] = transmute_mut!(&mut [0u8; 1]);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
6+
|
7+
= help: the trait `Sized` is not implemented for `[u8]`
8+
note: required by a bound in `AssertIsFromBytes`
9+
--> tests/ui-msrv/transmute-mut-dst-unsized.rs:17:32
10+
|
11+
17 | const DST_UNSIZED: &mut [u8] = transmute_mut!(&mut [0u8; 1]);
12+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `AssertIsFromBytes`
13+
= note: this error originates in the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)
14+
15+
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
16+
--> tests/ui-msrv/transmute-mut-dst-unsized.rs:17:32
17+
|
18+
17 | const DST_UNSIZED: &mut [u8] = transmute_mut!(&mut [0u8; 1]);
19+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
20+
|
21+
= help: the trait `Sized` is not implemented for `[u8]`
22+
note: required by a bound in `AssertIsAsBytes`
23+
--> tests/ui-msrv/transmute-mut-dst-unsized.rs:17:32
24+
|
25+
17 | const DST_UNSIZED: &mut [u8] = transmute_mut!(&mut [0u8; 1]);
26+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `AssertIsAsBytes`
27+
= note: this error originates in the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)
28+
129
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
230
--> tests/ui-msrv/transmute-mut-dst-unsized.rs:17:32
331
|
@@ -11,6 +39,10 @@ note: required by a bound in `DST_UNSIZED::transmute`
1139
17 | const DST_UNSIZED: &mut [u8] = transmute_mut!(&mut [0u8; 1]);
1240
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `DST_UNSIZED::transmute`
1341
= note: this error originates in the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)
42+
help: consider relaxing the implicit `Sized` restriction
43+
|
44+
226| fn transmute<'u, 't: 'u, T: 't, U: 'u + ?Sized>(t: &'t mut T) -> &'u mut U {
45+
| ++++++++
1446

1547
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
1648
--> tests/ui-msrv/transmute-mut-dst-unsized.rs:17:32
@@ -45,10 +77,6 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation
4577
|
4678
= help: the trait `Sized` is not implemented for `[u8]`
4779
note: required by a bound in `std::intrinsics::transmute`
48-
--> $RUST/core/src/intrinsics.rs
49-
|
50-
| pub fn transmute<T, U>(e: T) -> U;
51-
| ^ required by this bound in `std::intrinsics::transmute`
5280
= note: this error originates in the macro `$crate::assert_size_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
5381

5482
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,7 @@
1-
error[E0308]: mismatched types
1+
error[E0614]: type `usize` cannot be dereferenced
22
--> tests/ui-msrv/transmute-mut-src-dst-not-references.rs:17:44
33
|
44
17 | const SRC_DST_NOT_REFERENCES: &mut usize = transmute_mut!(0usize);
5-
| ^^^^^^^^^^^^^^^^^^^^^^ expected `&mut _`, found `usize`
5+
| ^^^^^^^^^^^^^^^^^^^^^^
66
|
7-
= note: expected mutable reference `&mut _`
8-
found type `usize`
9-
= note: this error originates in the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)
10-
11-
error[E0308]: mismatched types
12-
--> tests/ui-msrv/transmute-mut-src-dst-not-references.rs:17:44
13-
|
14-
17 | const SRC_DST_NOT_REFERENCES: &mut usize = transmute_mut!(0usize);
15-
| ^^^^^^^^^^^^^^^------^
16-
| | |
17-
| | expected due to this value
18-
| expected `usize`, found `&mut _`
19-
|
20-
= note: expected type `usize`
21-
found mutable reference `&mut _`
227
= note: this error originates in the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)

0 commit comments

Comments
 (0)