Skip to content

Commit c763f06

Browse files
thomccpietroalbini
authored andcommitted
Ensure io::Error's bitpacked repr doesn't accidentally impl UnwindSafe
1 parent edbed40 commit c763f06

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

library/std/src/io/error/repr_bitpacked.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
105105
use super::{Custom, ErrorData, ErrorKind, SimpleMessage};
106106
use alloc::boxed::Box;
107+
use core::marker::PhantomData;
107108
use core::mem::{align_of, size_of};
108109
use core::ptr::NonNull;
109110

@@ -115,7 +116,7 @@ const TAG_OS: usize = 0b10;
115116
const TAG_SIMPLE: usize = 0b11;
116117

117118
#[repr(transparent)]
118-
pub(super) struct Repr(NonNull<()>);
119+
pub(super) struct Repr(NonNull<()>, PhantomData<ErrorData<Box<Custom>>>);
119120

120121
// All the types `Repr` stores internally are Send + Sync, and so is it.
121122
unsafe impl Send for Repr {}
@@ -145,7 +146,7 @@ impl Repr {
145146
// box, and `TAG_CUSTOM` just... isn't zero -- it's `0b01`). Therefore,
146147
// `TAG_CUSTOM + p` isn't zero and so `tagged` can't be, and the
147148
// `new_unchecked` is safe.
148-
let res = Self(unsafe { NonNull::new_unchecked(tagged) });
149+
let res = Self(unsafe { NonNull::new_unchecked(tagged) }, PhantomData);
149150
// quickly smoke-check we encoded the right thing (This generally will
150151
// only run in libstd's tests, unless the user uses -Zbuild-std)
151152
debug_assert!(matches!(res.data(), ErrorData::Custom(_)), "repr(custom) encoding failed");
@@ -156,7 +157,7 @@ impl Repr {
156157
pub(super) fn new_os(code: i32) -> Self {
157158
let utagged = ((code as usize) << 32) | TAG_OS;
158159
// 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 ()) });
160+
let res = Self(unsafe { NonNull::new_unchecked(utagged as *mut ()) }, PhantomData);
160161
// quickly smoke-check we encoded the right thing (This generally will
161162
// only run in libstd's tests, unless the user uses -Zbuild-std)
162163
debug_assert!(
@@ -171,7 +172,7 @@ impl Repr {
171172
pub(super) fn new_simple(kind: ErrorKind) -> Self {
172173
let utagged = ((kind as usize) << 32) | TAG_SIMPLE;
173174
// Safety: `TAG_SIMPLE` is not zero, so the result of the `|` is not 0.
174-
let res = Self(unsafe { NonNull::new_unchecked(utagged as *mut ()) });
175+
let res = Self(unsafe { NonNull::new_unchecked(utagged as *mut ()) }, PhantomData);
175176
// quickly smoke-check we encoded the right thing (This generally will
176177
// only run in libstd's tests, unless the user uses -Zbuild-std)
177178
debug_assert!(
@@ -185,7 +186,7 @@ impl Repr {
185186
#[inline]
186187
pub(super) const fn new_simple_message(m: &'static SimpleMessage) -> Self {
187188
// Safety: References are never null.
188-
Self(unsafe { NonNull::new_unchecked(m as *const _ as *mut ()) })
189+
Self(unsafe { NonNull::new_unchecked(m as *const _ as *mut ()) }, PhantomData)
189190
}
190191

191192
#[inline]

0 commit comments

Comments
 (0)