104
104
105
105
use super :: { Custom , ErrorData , ErrorKind , SimpleMessage } ;
106
106
use alloc:: boxed:: Box ;
107
+ use core:: marker:: PhantomData ;
107
108
use core:: mem:: { align_of, size_of} ;
108
109
use core:: ptr:: NonNull ;
109
110
@@ -114,8 +115,17 @@ const TAG_CUSTOM: usize = 0b01;
114
115
const TAG_OS : usize = 0b10 ;
115
116
const TAG_SIMPLE : usize = 0b11 ;
116
117
118
+ /// The internal representation.
119
+ ///
120
+ /// See the module docs for more, this is just a way to hack in a check that we
121
+ /// indeed are not unwind-safe.
122
+ ///
123
+ /// ```compile_fail,E0277
124
+ /// fn is_unwind_safe<T: core::panic::UnwindSafe>() {}
125
+ /// is_unwind_safe::<std::io::Error>();
126
+ /// ```
117
127
#[ repr( transparent) ]
118
- pub ( super ) struct Repr ( NonNull < ( ) > ) ;
128
+ pub ( super ) struct Repr ( NonNull < ( ) > , PhantomData < ErrorData < Box < Custom > > > ) ;
119
129
120
130
// All the types `Repr` stores internally are Send + Sync, and so is it.
121
131
unsafe impl Send for Repr { }
@@ -145,7 +155,7 @@ impl Repr {
145
155
// box, and `TAG_CUSTOM` just... isn't zero -- it's `0b01`). Therefore,
146
156
// `TAG_CUSTOM + p` isn't zero and so `tagged` can't be, and the
147
157
// `new_unchecked` is safe.
148
- let res = Self ( unsafe { NonNull :: new_unchecked ( tagged) } ) ;
158
+ let res = Self ( unsafe { NonNull :: new_unchecked ( tagged) } , PhantomData ) ;
149
159
// quickly smoke-check we encoded the right thing (This generally will
150
160
// only run in libstd's tests, unless the user uses -Zbuild-std)
151
161
debug_assert ! ( matches!( res. data( ) , ErrorData :: Custom ( _) ) , "repr(custom) encoding failed" ) ;
@@ -156,7 +166,7 @@ impl Repr {
156
166
pub ( super ) fn new_os ( code : i32 ) -> Self {
157
167
let utagged = ( ( code as usize ) << 32 ) | TAG_OS ;
158
168
// Safety: `TAG_OS` is not zero, so the result of the `|` is not 0.
159
- let res = Self ( unsafe { NonNull :: new_unchecked ( utagged as * mut ( ) ) } ) ;
169
+ let res = Self ( unsafe { NonNull :: new_unchecked ( utagged as * mut ( ) ) } , PhantomData ) ;
160
170
// quickly smoke-check we encoded the right thing (This generally will
161
171
// only run in libstd's tests, unless the user uses -Zbuild-std)
162
172
debug_assert ! (
@@ -170,7 +180,7 @@ impl Repr {
170
180
pub ( super ) fn new_simple ( kind : ErrorKind ) -> Self {
171
181
let utagged = ( ( kind as usize ) << 32 ) | TAG_SIMPLE ;
172
182
// Safety: `TAG_SIMPLE` is not zero, so the result of the `|` is not 0.
173
- let res = Self ( unsafe { NonNull :: new_unchecked ( utagged as * mut ( ) ) } ) ;
183
+ let res = Self ( unsafe { NonNull :: new_unchecked ( utagged as * mut ( ) ) } , PhantomData ) ;
174
184
// quickly smoke-check we encoded the right thing (This generally will
175
185
// only run in libstd's tests, unless the user uses -Zbuild-std)
176
186
debug_assert ! (
@@ -184,7 +194,7 @@ impl Repr {
184
194
#[ inline]
185
195
pub ( super ) const fn new_simple_message ( m : & ' static SimpleMessage ) -> Self {
186
196
// Safety: References are never null.
187
- Self ( unsafe { NonNull :: new_unchecked ( m as * const _ as * mut ( ) ) } )
197
+ Self ( unsafe { NonNull :: new_unchecked ( m as * const _ as * mut ( ) ) } , PhantomData )
188
198
}
189
199
190
200
#[ inline]
0 commit comments