std: add type alias for raw OS errors
Implement rust-lang/libs-team#173.
This commit is contained in:
parent
dc3e59cb3f
commit
42cc28ac8b
5 changed files with 26 additions and 10 deletions
|
@ -88,12 +88,23 @@ impl From<alloc::ffi::NulError> for Error {
|
||||||
// doesn't accidentally get printed.
|
// doesn't accidentally get printed.
|
||||||
#[cfg_attr(test, derive(Debug))]
|
#[cfg_attr(test, derive(Debug))]
|
||||||
enum ErrorData<C> {
|
enum ErrorData<C> {
|
||||||
Os(i32),
|
Os(RawOsError),
|
||||||
Simple(ErrorKind),
|
Simple(ErrorKind),
|
||||||
SimpleMessage(&'static SimpleMessage),
|
SimpleMessage(&'static SimpleMessage),
|
||||||
Custom(C),
|
Custom(C),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The type of raw OS error codes returned by [`Error::raw_os_error`].
|
||||||
|
///
|
||||||
|
/// This is an [`i32`] on all currently supported platforms, but platforms
|
||||||
|
/// added in the future (such as UEFI) may use a different primitive type like
|
||||||
|
/// [`usize`]. Use `as`or [`into`] conversions where applicable to ensure maximum
|
||||||
|
/// portability.
|
||||||
|
///
|
||||||
|
/// [`into`]: Into::into
|
||||||
|
#[unstable(feature = "raw_os_error_ty", issue = "none")]
|
||||||
|
pub type RawOsError = i32;
|
||||||
|
|
||||||
// `#[repr(align(4))]` is probably redundant, it should have that value or
|
// `#[repr(align(4))]` is probably redundant, it should have that value or
|
||||||
// higher already. We include it just because repr_bitpacked.rs's encoding
|
// higher already. We include it just because repr_bitpacked.rs's encoding
|
||||||
// requires an alignment >= 4 (note that `#[repr(align)]` will not reduce the
|
// requires an alignment >= 4 (note that `#[repr(align)]` will not reduce the
|
||||||
|
@ -579,7 +590,7 @@ impl Error {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn last_os_error() -> Error {
|
pub fn last_os_error() -> Error {
|
||||||
Error::from_raw_os_error(sys::os::errno() as i32)
|
Error::from_raw_os_error(sys::os::errno())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new instance of an [`Error`] from a particular OS error code.
|
/// Creates a new instance of an [`Error`] from a particular OS error code.
|
||||||
|
@ -610,7 +621,7 @@ impl Error {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_raw_os_error(code: i32) -> Error {
|
pub fn from_raw_os_error(code: RawOsError) -> Error {
|
||||||
Error { repr: Repr::new_os(code) }
|
Error { repr: Repr::new_os(code) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,7 +657,7 @@ impl Error {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn raw_os_error(&self) -> Option<i32> {
|
pub fn raw_os_error(&self) -> Option<RawOsError> {
|
||||||
match self.repr.data() {
|
match self.repr.data() {
|
||||||
ErrorData::Os(i) => Some(i),
|
ErrorData::Os(i) => Some(i),
|
||||||
ErrorData::Custom(..) => None,
|
ErrorData::Custom(..) => None,
|
||||||
|
|
|
@ -102,7 +102,7 @@
|
||||||
//! to use a pointer type to store something that may hold an integer, some of
|
//! to use a pointer type to store something that may hold an integer, some of
|
||||||
//! the time.
|
//! the time.
|
||||||
|
|
||||||
use super::{Custom, ErrorData, ErrorKind, SimpleMessage};
|
use super::{Custom, ErrorData, ErrorKind, RawOsError, SimpleMessage};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::mem::{align_of, size_of};
|
use core::mem::{align_of, size_of};
|
||||||
|
@ -172,7 +172,7 @@ impl Repr {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super) fn new_os(code: i32) -> Self {
|
pub(super) fn new_os(code: RawOsError) -> Self {
|
||||||
let utagged = ((code as usize) << 32) | TAG_OS;
|
let utagged = ((code as usize) << 32) | TAG_OS;
|
||||||
// Safety: `TAG_OS` is not zero, so the result of the `|` is not 0.
|
// Safety: `TAG_OS` is not zero, so the result of the `|` is not 0.
|
||||||
let res = Self(unsafe { NonNull::new_unchecked(ptr::invalid_mut(utagged)) }, PhantomData);
|
let res = Self(unsafe { NonNull::new_unchecked(ptr::invalid_mut(utagged)) }, PhantomData);
|
||||||
|
@ -250,7 +250,7 @@ where
|
||||||
let bits = ptr.as_ptr().addr();
|
let bits = ptr.as_ptr().addr();
|
||||||
match bits & TAG_MASK {
|
match bits & TAG_MASK {
|
||||||
TAG_OS => {
|
TAG_OS => {
|
||||||
let code = ((bits as i64) >> 32) as i32;
|
let code = ((bits as i64) >> 32) as RawOsError;
|
||||||
ErrorData::Os(code)
|
ErrorData::Os(code)
|
||||||
}
|
}
|
||||||
TAG_SIMPLE => {
|
TAG_SIMPLE => {
|
||||||
|
@ -374,6 +374,9 @@ static_assert!((TAG_MASK + 1).is_power_of_two());
|
||||||
static_assert!(align_of::<SimpleMessage>() >= TAG_MASK + 1);
|
static_assert!(align_of::<SimpleMessage>() >= TAG_MASK + 1);
|
||||||
static_assert!(align_of::<Custom>() >= TAG_MASK + 1);
|
static_assert!(align_of::<Custom>() >= TAG_MASK + 1);
|
||||||
|
|
||||||
|
// `RawOsError` must be an alias for `i32`.
|
||||||
|
const _: fn(RawOsError) -> i32 = |os| os;
|
||||||
|
|
||||||
static_assert!(@usize_eq: TAG_MASK & TAG_SIMPLE_MESSAGE, TAG_SIMPLE_MESSAGE);
|
static_assert!(@usize_eq: TAG_MASK & TAG_SIMPLE_MESSAGE, TAG_SIMPLE_MESSAGE);
|
||||||
static_assert!(@usize_eq: TAG_MASK & TAG_CUSTOM, TAG_CUSTOM);
|
static_assert!(@usize_eq: TAG_MASK & TAG_CUSTOM, TAG_CUSTOM);
|
||||||
static_assert!(@usize_eq: TAG_MASK & TAG_OS, TAG_OS);
|
static_assert!(@usize_eq: TAG_MASK & TAG_OS, TAG_OS);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//! non-64bit targets, where the packed 64 bit representation wouldn't work, and
|
//! non-64bit targets, where the packed 64 bit representation wouldn't work, and
|
||||||
//! would have no benefit.
|
//! would have no benefit.
|
||||||
|
|
||||||
use super::{Custom, ErrorData, ErrorKind, SimpleMessage};
|
use super::{Custom, ErrorData, ErrorKind, RawOsError, SimpleMessage};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
|
|
||||||
type Inner = ErrorData<Box<Custom>>;
|
type Inner = ErrorData<Box<Custom>>;
|
||||||
|
@ -18,7 +18,7 @@ impl Repr {
|
||||||
Self(Inner::Custom(b))
|
Self(Inner::Custom(b))
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super) fn new_os(code: i32) -> Self {
|
pub(super) fn new_os(code: RawOsError) -> Self {
|
||||||
Self(Inner::Os(code))
|
Self(Inner::Os(code))
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -71,7 +71,7 @@ fn test_const() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_os_packing() {
|
fn test_os_packing() {
|
||||||
for code in -20i32..20i32 {
|
for code in -20..20 {
|
||||||
let e = Error::from_raw_os_error(code);
|
let e = Error::from_raw_os_error(code);
|
||||||
assert_eq!(e.raw_os_error(), Some(code));
|
assert_eq!(e.raw_os_error(), Some(code));
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
|
|
|
@ -262,6 +262,8 @@ use crate::sys_common::memchr;
|
||||||
|
|
||||||
#[stable(feature = "bufwriter_into_parts", since = "1.56.0")]
|
#[stable(feature = "bufwriter_into_parts", since = "1.56.0")]
|
||||||
pub use self::buffered::WriterPanicked;
|
pub use self::buffered::WriterPanicked;
|
||||||
|
#[unstable(feature = "raw_os_error_ty", issue = "none")]
|
||||||
|
pub use self::error::RawOsError;
|
||||||
pub(crate) use self::stdio::attempt_print_to_stderr;
|
pub(crate) use self::stdio::attempt_print_to_stderr;
|
||||||
#[unstable(feature = "internal_output_capture", issue = "none")]
|
#[unstable(feature = "internal_output_capture", issue = "none")]
|
||||||
#[doc(no_inline, hidden)]
|
#[doc(no_inline, hidden)]
|
||||||
|
|
Loading…
Add table
Reference in a new issue