@@ -8,9 +8,30 @@ use core::mem::{align_of, size_of};
8
8
9
9
struct Cast < A , B > ( ( A , B ) ) ;
10
10
impl < A , B > Cast < A , B > {
11
- const ASSERT_ALIGN_GREATER_THAN_EQUAL : ( ) = assert ! ( align_of:: <A >( ) >= align_of:: <B >( ) ) ;
12
- const ASSERT_SIZE_EQUAL : ( ) = assert ! ( size_of:: <A >( ) == size_of:: <B >( ) ) ;
13
- const ASSERT_SIZE_MULTIPLE_OF : ( ) = assert ! ( ( size_of:: <A >( ) == 0 ) == ( size_of:: <B >( ) == 0 ) && ( size_of:: <A >( ) % size_of:: <B >( ) == 0 ) ) ;
11
+ const ASSERT_ALIGN_GREATER_THAN_EQUAL : ( ) =
12
+ assert ! ( align_of:: <A >( ) >= align_of:: <B >( ) ) ;
13
+ const ASSERT_SIZE_EQUAL : ( ) = assert ! ( size_of:: <A >( ) == size_of:: <B >( ) ) ;
14
+ const ASSERT_SIZE_MULTIPLE_OF : ( ) = assert ! (
15
+ ( size_of:: <A >( ) == 0 ) == ( size_of:: <B >( ) == 0 )
16
+ && ( size_of:: <A >( ) % size_of:: <B >( ) == 0 )
17
+ ) ;
18
+ }
19
+
20
+ // Workaround for https://github.com/rust-lang/miri/issues/2423.
21
+ // Miri currently doesn't see post-monomorphization errors until runtime,
22
+ // so `compile_fail` tests relying on post-monomorphization errors don't
23
+ // actually fail. Instead use `should_panic` under miri as a workaround.
24
+ #[ cfg( miri) ]
25
+ macro_rules! post_mono_compile_fail_doctest {
26
+ ( ) => {
27
+ "```should_panic"
28
+ } ;
29
+ }
30
+ #[ cfg( not( miri) ) ]
31
+ macro_rules! post_mono_compile_fail_doctest {
32
+ ( ) => {
33
+ "```compile_fail,E0080"
34
+ } ;
14
35
}
15
36
16
37
/// Cast `A` into `B` if infalliable, or fail to compile.
@@ -27,9 +48,9 @@ impl<A, B> Cast<A, B> {
27
48
/// ## Examples
28
49
/// ```
29
50
/// // compiles:
30
- /// let bytes : [u8; 2] = bytemuck::must_cast(12_u16);
51
+ /// let bytes: [u8; 2] = bytemuck::must_cast(12_u16);
31
52
/// ```
32
- /// ```compile_fail,E0080
53
+ # [ doc = post_mono_compile_fail_doctest ! ( ) ]
33
54
/// // fails to compile (size mismatch):
34
55
/// let bytes : [u8; 3] = bytemuck::must_cast(12_u16);
35
56
/// ```
@@ -49,13 +70,13 @@ pub fn must_cast<A: NoUninit, B: AnyBitPattern>(a: A) -> B {
49
70
/// ## Examples
50
71
/// ```
51
72
/// // compiles:
52
- /// let bytes : &[u8; 2] = bytemuck::must_cast_ref(&12_u16);
73
+ /// let bytes: &[u8; 2] = bytemuck::must_cast_ref(&12_u16);
53
74
/// ```
54
- /// ```compile_fail,E0080
75
+ # [ doc = post_mono_compile_fail_doctest ! ( ) ]
55
76
/// // fails to compile (size mismatch):
56
77
/// let bytes : &[u8; 3] = bytemuck::must_cast_ref(&12_u16);
57
78
/// ```
58
- /// ```compile_fail,E0080
79
+ # [ doc = post_mono_compile_fail_doctest ! ( ) ]
59
80
/// // fails to compile (alignment requirements increased):
60
81
/// let bytes : &u16 = bytemuck::must_cast_ref(&[1u8, 2u8]);
61
82
/// ```
@@ -74,15 +95,14 @@ pub fn must_cast_ref<A: NoUninit, B: AnyBitPattern>(a: &A) -> &B {
74
95
/// ```
75
96
/// let mut i = 12_u16;
76
97
/// // compiles:
77
- /// let bytes : &mut [u8; 2] = bytemuck::must_cast_mut(&mut i);
98
+ /// let bytes: &mut [u8; 2] = bytemuck::must_cast_mut(&mut i);
78
99
/// ```
79
- /// ```compile_fail,E0080
80
- /// # let mut bytes : [u8; 2] = [1, 2];
81
- /// # let bytes = &mut bytes[..];
100
+ #[ doc = post_mono_compile_fail_doctest ! ( ) ]
101
+ /// # let mut bytes: &mut [u8; 2] = &mut [1, 2];
82
102
/// // fails to compile (alignment requirements increased):
83
103
/// let i : &mut u16 = bytemuck::must_cast_mut(bytes);
84
104
/// ```
85
- /// ```compile_fail,E0080
105
+ # [ doc = post_mono_compile_fail_doctest ! ( ) ]
86
106
/// # let mut i = 12_u16;
87
107
/// // fails to compile (size mismatch):
88
108
/// let bytes : &mut [u8; 3] = bytemuck::must_cast_mut(&mut i);
@@ -99,31 +119,32 @@ pub fn must_cast_mut<
99
119
unsafe { & mut * ( a as * mut A as * mut B ) }
100
120
}
101
121
102
- /// Convert `&[A]` into `&[B]` (possibly with a change in length) if infalliable, or fail to compile.
122
+ /// Convert `&[A]` into `&[B]` (possibly with a change in length) if
123
+ /// infalliable, or fail to compile.
103
124
///
104
125
/// * `input.as_ptr() as usize == output.as_ptr() as usize`
105
126
/// * `input.len() * size_of::<A>() == output.len() * size_of::<B>()`
106
127
///
107
128
/// ## Failure
108
129
///
109
130
/// * If the target type has a greater alignment requirement.
110
- /// * If the target element type doesn't evenly fit into the the current element type
111
- /// (eg: 3 `u16` values is 1.5 `u32` values, so that's a failure).
131
+ /// * If the target element type doesn't evenly fit into the the current element
132
+ /// type (eg: 3 `u16` values is 1.5 `u32` values, so that's a failure).
112
133
/// * Similarly, you can't convert between a [ZST](https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts)
113
134
/// and a non-ZST.
114
135
///
115
136
/// ## Examples
116
137
/// ```
117
- /// let indicies : &[u16] = &[1, 2, 3];
138
+ /// let indicies: &[u16] = &[1, 2, 3];
118
139
/// // compiles:
119
- /// let bytes : &[u8] = bytemuck::must_cast_slice(indicies);
140
+ /// let bytes: &[u8] = bytemuck::must_cast_slice(indicies);
120
141
/// ```
121
- /// ```compile_fail,E0080
122
- /// # let bytes : &[u8] = [1, 0, 2, 0, 3, 0];
142
+ # [ doc = post_mono_compile_fail_doctest ! ( ) ]
143
+ /// # let bytes : &[u8] = & [1, 0, 2, 0, 3, 0];
123
144
/// // fails to compile (bytes.len() might not be a multiple of 2):
124
145
/// let byte_pairs : &[[u8; 2]] = bytemuck::must_cast_slice(bytes);
125
146
/// ```
126
- /// ```compile_fail,E0080
147
+ # [ doc = post_mono_compile_fail_doctest ! ( ) ]
127
148
/// # let byte_pairs : &[[u8; 2]] = &[[1, 0], [2, 0], [3, 0]];
128
149
/// // fails to compile (alignment requirements increased):
129
150
/// let indicies : &[u16] = bytemuck::must_cast_slice(byte_pairs);
@@ -140,24 +161,25 @@ pub fn must_cast_slice<A: NoUninit, B: AnyBitPattern>(a: &[A]) -> &[B] {
140
161
unsafe { core:: slice:: from_raw_parts ( a. as_ptr ( ) as * const B , new_len) }
141
162
}
142
163
143
- /// Convert `&mut [A]` into `&mut [B]` (possibly with a change in length) if infalliable, or fail to compile.
164
+ /// Convert `&mut [A]` into `&mut [B]` (possibly with a change in length) if
165
+ /// infalliable, or fail to compile.
144
166
///
145
167
/// As [`must_cast_slice`], but `&mut`.
146
168
///
147
169
/// ## Examples
148
170
/// ```
149
171
/// let mut indicies = [1, 2, 3];
150
- /// let indicies : &mut [u16] = &mut indicies;
172
+ /// let indicies: &mut [u16] = &mut indicies;
151
173
/// // compiles:
152
- /// let bytes : &mut [u8] = bytemuck::must_cast_slice_mut(indicies);
174
+ /// let bytes: &mut [u8] = bytemuck::must_cast_slice_mut(indicies);
153
175
/// ```
154
- /// ```compile_fail,E0080
176
+ # [ doc = post_mono_compile_fail_doctest ! ( ) ]
155
177
/// # let mut bytes = [1, 0, 2, 0, 3, 0];
156
178
/// # let bytes : &mut [u8] = &mut bytes[..];
157
179
/// // fails to compile (bytes.len() might not be a multiple of 2):
158
180
/// let byte_pairs : &mut [[u8; 2]] = bytemuck::must_cast_slice_mut(bytes);
159
181
/// ```
160
- /// ```compile_fail,E0080
182
+ # [ doc = post_mono_compile_fail_doctest ! ( ) ]
161
183
/// # let mut byte_pairs = [[1, 0], [2, 0], [3, 0]];
162
184
/// # let byte_pairs : &mut [[u8; 2]] = &mut byte_pairs[..];
163
185
/// // fails to compile (alignment requirements increased):
0 commit comments