23
23
//! All error types provide an `into_src` method that converts the error into
24
24
//! the source value underlying the failed conversion.
25
25
26
- use core:: { convert:: Infallible , fmt, marker :: PhantomData , ops:: Deref } ;
26
+ use core:: { convert:: Infallible , fmt, ops:: Deref } ;
27
27
28
- use crate :: TryFromBytes ;
28
+ use crate :: { util :: SendSyncPhantomData , KnownLayout , TryFromBytes } ;
29
29
#[ cfg( doc) ]
30
30
use crate :: { FromBytes , Ref } ;
31
31
@@ -82,18 +82,27 @@ impl<A: fmt::Display, S: fmt::Display, V: fmt::Display> fmt::Display for Convert
82
82
}
83
83
}
84
84
85
+ #[ cfg( feature = "std-error" ) ]
86
+ impl < A , S , V > std:: error:: Error for ConvertError < A , S , V >
87
+ where
88
+ A : fmt:: Display + fmt:: Debug ,
89
+ S : fmt:: Display + fmt:: Debug ,
90
+ V : fmt:: Display + fmt:: Debug ,
91
+ {
92
+ }
93
+
85
94
/// The error emitted if the conversion source is improperly aligned.
86
95
#[ derive( PartialEq , Eq ) ]
87
96
pub struct AlignmentError < Src , Dst : ?Sized > {
88
97
/// The source value involved in the conversion.
89
98
src : Src ,
90
99
/// The inner destination type inolved in the conversion.
91
- dst : PhantomData < Dst > ,
100
+ dst : SendSyncPhantomData < Dst > ,
92
101
}
93
102
94
103
impl < Src , Dst : ?Sized > AlignmentError < Src , Dst > {
95
104
pub ( crate ) fn new ( src : Src ) -> Self {
96
- Self { src, dst : PhantomData }
105
+ Self { src, dst : SendSyncPhantomData :: default ( ) }
97
106
}
98
107
99
108
/// Produces the source underlying the failed conversion.
@@ -103,11 +112,11 @@ impl<Src, Dst: ?Sized> AlignmentError<Src, Dst> {
103
112
}
104
113
105
114
pub ( crate ) fn with_src < NewSrc > ( self , new_src : NewSrc ) -> AlignmentError < NewSrc , Dst > {
106
- AlignmentError { src : new_src, dst : PhantomData }
115
+ AlignmentError { src : new_src, dst : SendSyncPhantomData :: default ( ) }
107
116
}
108
117
109
118
pub ( crate ) fn map_src < NewSrc > ( self , f : impl Fn ( Src ) -> NewSrc ) -> AlignmentError < NewSrc , Dst > {
110
- AlignmentError { src : f ( self . src ) , dst : PhantomData }
119
+ AlignmentError { src : f ( self . src ) , dst : SendSyncPhantomData :: default ( ) }
111
120
}
112
121
113
122
pub ( crate ) fn into < S , V > ( self ) -> ConvertError < Self , S , V > {
@@ -126,9 +135,10 @@ impl<Src, Dst: ?Sized> fmt::Debug for AlignmentError<Src, Dst> {
126
135
// The bounds on this impl are intentionally conservative, and can be relaxed
127
136
// either once a `?Sized` alignment accessor is stabilized, or by storing the
128
137
// alignment as a runtime value.
129
- impl < Src , Dst > fmt:: Display for AlignmentError < Src , Dst >
138
+ impl < Src , Dst : ? Sized > fmt:: Display for AlignmentError < Src , Dst >
130
139
where
131
140
Src : Deref ,
141
+ Dst : KnownLayout ,
132
142
{
133
143
#[ inline]
134
144
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
@@ -139,14 +149,22 @@ where
139
149
f. write_str ( "the conversion failed because the address of the source (a multiple of " ) ?;
140
150
addr_align. fmt ( f) ?;
141
151
f. write_str ( ") is not a multiple of the alignment (" ) ?;
142
- core :: mem :: align_of :: < Dst > ( ) . fmt ( f) ?;
152
+ <Dst as KnownLayout > :: LAYOUT . align . get ( ) . fmt ( f) ?;
143
153
f. write_str ( ") of the destination type: " ) ?;
144
154
f. write_str ( core:: any:: type_name :: < Dst > ( ) ) ?;
145
155
Ok ( ( ) )
146
156
}
147
157
}
148
158
149
- impl < Src , Dst , S , V > From < AlignmentError < Src , Dst > >
159
+ #[ cfg( feature = "std-error" ) ]
160
+ impl < Src , Dst : ?Sized > std:: error:: Error for AlignmentError < Src , Dst >
161
+ where
162
+ Src : Deref ,
163
+ Dst : KnownLayout ,
164
+ {
165
+ }
166
+
167
+ impl < Src , Dst : ?Sized , S , V > From < AlignmentError < Src , Dst > >
150
168
for ConvertError < AlignmentError < Src , Dst > , S , V >
151
169
{
152
170
#[ inline]
@@ -161,12 +179,12 @@ pub struct SizeError<Src, Dst: ?Sized> {
161
179
/// The source value involved in the conversion.
162
180
src : Src ,
163
181
/// The inner destination type inolved in the conversion.
164
- dst : PhantomData < Dst > ,
182
+ dst : SendSyncPhantomData < Dst > ,
165
183
}
166
184
167
185
impl < Src , Dst : ?Sized > SizeError < Src , Dst > {
168
186
pub ( crate ) fn new ( src : Src ) -> Self {
169
- Self { src, dst : PhantomData }
187
+ Self { src, dst : SendSyncPhantomData :: default ( ) }
170
188
}
171
189
172
190
/// Produces the source underlying the failed conversion.
@@ -177,17 +195,17 @@ impl<Src, Dst: ?Sized> SizeError<Src, Dst> {
177
195
178
196
/// Sets the source value associated with the conversion error.
179
197
pub ( crate ) fn with_src < NewSrc > ( self , new_src : NewSrc ) -> SizeError < NewSrc , Dst > {
180
- SizeError { src : new_src, dst : PhantomData }
198
+ SizeError { src : new_src, dst : SendSyncPhantomData :: default ( ) }
181
199
}
182
200
183
201
/// Maps the source value associated with the conversion error.
184
202
pub ( crate ) fn map_src < NewSrc > ( self , f : impl Fn ( Src ) -> NewSrc ) -> SizeError < NewSrc , Dst > {
185
- SizeError { src : f ( self . src ) , dst : PhantomData }
203
+ SizeError { src : f ( self . src ) , dst : SendSyncPhantomData :: default ( ) }
186
204
}
187
205
188
206
/// Sets the destination type associated with the conversion error.
189
207
pub ( crate ) fn with_dst < NewDst : ?Sized > ( self ) -> SizeError < Src , NewDst > {
190
- SizeError { src : self . src , dst : PhantomData }
208
+ SizeError { src : self . src , dst : SendSyncPhantomData :: default ( ) }
191
209
}
192
210
193
211
/// Converts the error into a general [`ConvertError`].
@@ -204,10 +222,7 @@ impl<Src, Dst: ?Sized> fmt::Debug for SizeError<Src, Dst> {
204
222
}
205
223
206
224
/// Produces a human-readable error message.
207
- impl < Src , Dst : ?Sized > fmt:: Display for SizeError < Src , Dst >
208
- where
209
- Src : Deref ,
210
- {
225
+ impl < Src , Dst : ?Sized > fmt:: Display for SizeError < Src , Dst > {
211
226
#[ inline]
212
227
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
213
228
f. write_str ( "the conversion failed because the source was incorrectly sized to complete the conversion into the destination type: " ) ?;
@@ -216,7 +231,10 @@ where
216
231
}
217
232
}
218
233
219
- impl < Src , Dst , A , V > From < SizeError < Src , Dst > > for ConvertError < A , SizeError < Src , Dst > , V > {
234
+ #[ cfg( feature = "std-error" ) ]
235
+ impl < Src , Dst : ?Sized > std:: error:: Error for SizeError < Src , Dst > { }
236
+
237
+ impl < Src , Dst : ?Sized , A , V > From < SizeError < Src , Dst > > for ConvertError < A , SizeError < Src , Dst > , V > {
220
238
#[ inline]
221
239
fn from ( err : SizeError < Src , Dst > ) -> Self {
222
240
Self :: Size ( err)
@@ -229,12 +247,12 @@ pub struct ValidityError<Src, Dst: ?Sized + TryFromBytes> {
229
247
/// The source value involved in the conversion.
230
248
pub ( crate ) src : Src ,
231
249
/// The inner destination type inolved in the conversion.
232
- dst : PhantomData < Dst > ,
250
+ dst : SendSyncPhantomData < Dst > ,
233
251
}
234
252
235
253
impl < Src , Dst : ?Sized + TryFromBytes > ValidityError < Src , Dst > {
236
254
pub ( crate ) fn new ( src : Src ) -> Self {
237
- Self { src, dst : PhantomData }
255
+ Self { src, dst : SendSyncPhantomData :: default ( ) }
238
256
}
239
257
240
258
/// Produces the source underlying the failed conversion.
@@ -245,7 +263,7 @@ impl<Src, Dst: ?Sized + TryFromBytes> ValidityError<Src, Dst> {
245
263
246
264
/// Maps the source value associated with the conversion error.
247
265
pub ( crate ) fn map_src < NewSrc > ( self , f : impl Fn ( Src ) -> NewSrc ) -> ValidityError < NewSrc , Dst > {
248
- ValidityError { src : f ( self . src ) , dst : PhantomData }
266
+ ValidityError { src : f ( self . src ) , dst : SendSyncPhantomData :: default ( ) }
249
267
}
250
268
251
269
/// Converts the error into a general [`ConvertError`].
@@ -262,10 +280,7 @@ impl<Src, Dst: ?Sized + TryFromBytes> fmt::Debug for ValidityError<Src, Dst> {
262
280
}
263
281
264
282
/// Produces a human-readable error message.
265
- impl < Src , Dst : ?Sized + TryFromBytes > fmt:: Display for ValidityError < Src , Dst >
266
- where
267
- Src : Deref ,
268
- {
283
+ impl < Src , Dst : ?Sized + TryFromBytes > fmt:: Display for ValidityError < Src , Dst > {
269
284
#[ inline]
270
285
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
271
286
f. write_str ( "the conversion failed because the source bytes are not a valid value of the destination type: " ) ?;
@@ -274,6 +289,9 @@ where
274
289
}
275
290
}
276
291
292
+ #[ cfg( feature = "std-error" ) ]
293
+ impl < Src , Dst : ?Sized + TryFromBytes > std:: error:: Error for ValidityError < Src , Dst > { }
294
+
277
295
impl < Src , Dst : ?Sized + TryFromBytes , A , S > From < ValidityError < Src , Dst > >
278
296
for ConvertError < A , S , ValidityError < Src , Dst > >
279
297
{
@@ -395,16 +413,44 @@ impl<Src, Dst: ?Sized + TryFromBytes> TryReadError<Src, Dst> {
395
413
}
396
414
397
415
#[ cfg( test) ]
398
- mod test {
416
+ mod tests {
399
417
use super :: * ;
400
418
419
+ #[ test]
420
+ fn test_send_sync ( ) {
421
+ // Test that all error types are `Send + Sync` even if `Dst: !Send +
422
+ // !Sync`.
423
+
424
+ #[ allow( dead_code) ]
425
+ fn is_send_sync < T : Send + Sync > ( _t : T ) { }
426
+
427
+ #[ allow( dead_code) ]
428
+ fn size_err_is_send_sync < Src : Send + Sync , Dst > ( err : SizeError < Src , Dst > ) {
429
+ is_send_sync ( err)
430
+ }
431
+
432
+ #[ allow( dead_code) ]
433
+ fn alignment_err_is_send_sync < Src : Send + Sync , Dst > ( err : AlignmentError < Src , Dst > ) {
434
+ is_send_sync ( err)
435
+ }
436
+
437
+ #[ allow( dead_code) ]
438
+ fn validity_err_is_send_sync < Src : Send + Sync , Dst : TryFromBytes > (
439
+ err : ValidityError < Src , Dst > ,
440
+ ) {
441
+ is_send_sync ( err)
442
+ }
443
+ }
444
+
401
445
#[ test]
402
446
fn alignment_display ( ) {
403
447
#[ repr( C , align( 128 ) ) ]
404
448
struct Aligned {
405
449
bytes : [ u8 ; 128 ] ,
406
450
}
407
451
452
+ impl_known_layout ! ( elain:: Align :: <8 >) ;
453
+
408
454
let aligned = Aligned { bytes : [ 0 ; 128 ] } ;
409
455
410
456
assert_eq ! (
0 commit comments