104104
105105use super :: { Custom , ErrorData , ErrorKind , SimpleMessage } ;
106106use alloc:: boxed:: Box ;
107+ use core:: marker:: PhantomData ;
107108use core:: mem:: { align_of, size_of} ;
108109use core:: ptr:: NonNull ;
109110
@@ -114,8 +115,17 @@ const TAG_CUSTOM: usize = 0b01;
114115const TAG_OS : usize = 0b10 ;
115116const TAG_SIMPLE : usize = 0b11 ;
116117
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+ /// ```
117127#[ repr( transparent) ]
118- pub ( super ) struct Repr ( NonNull < ( ) > ) ;
128+ pub ( super ) struct Repr ( NonNull < ( ) > , PhantomData < ErrorData < Box < Custom > > > ) ;
119129
120130// All the types `Repr` stores internally are Send + Sync, and so is it.
121131unsafe impl Send for Repr { }
@@ -145,7 +155,7 @@ impl Repr {
145155 // box, and `TAG_CUSTOM` just... isn't zero -- it's `0b01`). Therefore,
146156 // `TAG_CUSTOM + p` isn't zero and so `tagged` can't be, and the
147157 // `new_unchecked` is safe.
148- let res = Self ( unsafe { NonNull :: new_unchecked ( tagged) } ) ;
158+ let res = Self ( unsafe { NonNull :: new_unchecked ( tagged) } , PhantomData ) ;
149159 // quickly smoke-check we encoded the right thing (This generally will
150160 // only run in libstd's tests, unless the user uses -Zbuild-std)
151161 debug_assert ! ( matches!( res. data( ) , ErrorData :: Custom ( _) ) , "repr(custom) encoding failed" ) ;
@@ -156,7 +166,7 @@ impl Repr {
156166 pub ( super ) fn new_os ( code : i32 ) -> Self {
157167 let utagged = ( ( code as usize ) << 32 ) | TAG_OS ;
158168 // 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 ) ;
160170 // quickly smoke-check we encoded the right thing (This generally will
161171 // only run in libstd's tests, unless the user uses -Zbuild-std)
162172 debug_assert ! (
@@ -170,7 +180,7 @@ impl Repr {
170180 pub ( super ) fn new_simple ( kind : ErrorKind ) -> Self {
171181 let utagged = ( ( kind as usize ) << 32 ) | TAG_SIMPLE ;
172182 // 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 ) ;
174184 // quickly smoke-check we encoded the right thing (This generally will
175185 // only run in libstd's tests, unless the user uses -Zbuild-std)
176186 debug_assert ! (
@@ -184,7 +194,7 @@ impl Repr {
184194 #[ inline]
185195 pub ( super ) const fn new_simple_message ( m : & ' static SimpleMessage ) -> Self {
186196 // 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 )
188198 }
189199
190200 #[ inline]
0 commit comments