Skip to content

Commit 61273b7

Browse files
committed
Define a dedicated error type for HandleOrNull and HandleOrInvalid.
Define a `NotHandle` type, that implements `std::error::Error`, and use it as the error type in `HandleOrNull` and `HandleOrInvalid`.
1 parent ab0c2e1 commit 61273b7

File tree

2 files changed

+24
-6
lines changed

2 files changed

+24
-6
lines changed

library/std/src/error.rs

+4
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,10 @@ impl Error for alloc::collections::TryReserveError {}
604604
#[unstable(feature = "duration_checked_float", issue = "83400")]
605605
impl Error for time::FromFloatSecsError {}
606606

607+
#[cfg(windows)]
608+
#[unstable(feature = "io_safety", issue = "87074")]
609+
impl Error for crate::os::windows::io::NotHandle {}
610+
607611
// Copied from `any.rs`.
608612
impl dyn Error + 'static {
609613
/// Returns `true` if the inner type is the same as `T`.

library/std/src/os/windows/io/handle.rs

+20-6
Original file line numberDiff line numberDiff line change
@@ -142,17 +142,17 @@ impl BorrowedHandle<'_> {
142142
}
143143

144144
impl TryFrom<HandleOrNull> for OwnedHandle {
145-
type Error = ();
145+
type Error = NotHandle;
146146

147147
#[inline]
148-
fn try_from(handle_or_null: HandleOrNull) -> Result<Self, ()> {
148+
fn try_from(handle_or_null: HandleOrNull) -> Result<Self, NotHandle> {
149149
let owned_handle = handle_or_null.0;
150150
if owned_handle.handle.is_null() {
151151
// Don't call `CloseHandle`; it'd be harmless, except that it could
152152
// overwrite the `GetLastError` error.
153153
forget(owned_handle);
154154

155-
Err(())
155+
Err(NotHandle(()))
156156
} else {
157157
Ok(owned_handle)
158158
}
@@ -200,23 +200,37 @@ impl OwnedHandle {
200200
}
201201

202202
impl TryFrom<HandleOrInvalid> for OwnedHandle {
203-
type Error = ();
203+
type Error = NotHandle;
204204

205205
#[inline]
206-
fn try_from(handle_or_invalid: HandleOrInvalid) -> Result<Self, ()> {
206+
fn try_from(handle_or_invalid: HandleOrInvalid) -> Result<Self, NotHandle> {
207207
let owned_handle = handle_or_invalid.0;
208208
if owned_handle.handle == c::INVALID_HANDLE_VALUE {
209209
// Don't call `CloseHandle`; it'd be harmless, except that it could
210210
// overwrite the `GetLastError` error.
211211
forget(owned_handle);
212212

213-
Err(())
213+
Err(NotHandle(()))
214214
} else {
215215
Ok(owned_handle)
216216
}
217217
}
218218
}
219219

220+
/// This is the error type used by [`HandleOrInvalid`] and
221+
/// [`HandleOrNull`] when attempting to convert into a handle,
222+
/// to indicate that the value is not a handle.
223+
#[unstable(feature = "io_safety", issue = "87074")]
224+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
225+
pub struct NotHandle(());
226+
227+
#[unstable(feature = "io_safety", issue = "87074")]
228+
impl fmt::Display for NotHandle {
229+
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
230+
"the return value of a Windows API call indicated an error".fmt(fmt)
231+
}
232+
}
233+
220234
impl AsRawHandle for BorrowedHandle<'_> {
221235
#[inline]
222236
fn as_raw_handle(&self) -> RawHandle {

0 commit comments

Comments
 (0)