Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #99305

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
d11ff2a
Impl `io::error::repr_unpacked::Repr::new`
NobodyXu Jun 22, 2022
1713e25
Impl `io::error::repr_bitpacked::Repr::new`
NobodyXu Jun 22, 2022
e0ea0c2
Add new unstable API `Error::try_downgrade_inner`
NobodyXu Jun 22, 2022
d2211c9
Add new unit test `test_try_downcast_inner`
NobodyXu Jun 22, 2022
516da4c
Use `unwrap` instead of `unwrap_unchecked`
NobodyXu Jun 23, 2022
07a0fd2
Add std::fs::write documentation precision
LucasDumont Jun 29, 2022
111253c
Rename `std::io::Error::try_downcast_inner` to `downcast`
NobodyXu Jul 14, 2022
9da4fea
Implement set_output_kind for emscripten linker
hoodmane Jun 21, 2022
0d45977
Remove FIXME from MIR `always_storage_live_locals`
pierwill Jul 14, 2022
d8aba10
Improve example of `downcast`
NobodyXu Jul 15, 2022
67a6c0a
Fix typo in mod.rs
eltociear Jul 15, 2022
fa3156e
add `#[must_use]` to `Box::from_raw`
rhysd Jul 15, 2022
d6b7480
Stabilize `core::ffi::CStr`, `alloc::ffi::CString`, and friends
joshtriplett Jul 15, 2022
8e8a3be
Apply suggestions from code review
yaahc Jul 15, 2022
93d3b18
Rollup merge of #98358 - hoodmane:emscripten-dynlib, r=petrochenkov
JohnTitor Jul 16, 2022
bced96e
Rollup merge of #98387 - NobodyXu:feature/std_io_Error_try_downgrade_…
JohnTitor Jul 16, 2022
4d0df40
Rollup merge of #98662 - LucasDumont:document_fs_write, r=thomcc
JohnTitor Jul 16, 2022
982d8f9
Rollup merge of #99253 - pierwill:pierwill/rm-storage-fixme, r=oli-obk
JohnTitor Jul 16, 2022
64fcd24
Rollup merge of #99264 - eltociear:patch-14, r=compiler-errors
JohnTitor Jul 16, 2022
8ec29c7
Rollup merge of #99270 - rhysd:issue-99269, r=Mark-Simulacrum
JohnTitor Jul 16, 2022
512922a
Rollup merge of #99277 - joshtriplett:stabilize-core-cstr-alloc-cstri…
JohnTitor Jul 16, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion compiler/rustc_codegen_ssa/src/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,38 @@ impl<'a> Linker for EmLinker<'a> {
&mut self.cmd
}

fn set_output_kind(&mut self, _output_kind: LinkOutputKind, _out_filename: &Path) {}
fn set_output_kind(&mut self, output_kind: LinkOutputKind, _out_filename: &Path) {
match output_kind {
LinkOutputKind::DynamicNoPicExe | LinkOutputKind::DynamicPicExe => {
// "-sMAIN_MODULE=1" breaks
// https://github.com/rust-lang/rust/issues/92738
self.cmd.arg("-sMAIN_MODULE=2");
warn!(
"Building dynamic executable with -sMAIN_MODULE=2. \
Dead code elimination may break things. \
See https://emscripten.org/docs/compiling/Dynamic-Linking.html?highlight=main_module#code-size \
"
);
}
LinkOutputKind::DynamicDylib | LinkOutputKind::StaticDylib => {
// -sSIDE_MODULE=1 breaks
// https://github.com/rust-lang/rust/issues/92738
// In any case, -sSIDE_MODULE=2 is better because Rust is good at
// calculating exports.
self.cmd.arg("-sSIDE_MODULE=2");
// Without -sWASM_BIGINT there are issues with dynamic Rust libraries. There
// are no plans to fix this in Emscripten AFAIK. See
// https://github.com/emscripten-core/emscripten/pull/16693 This could also
// be fixed with panic=abort.
self.cmd.arg("-sWASM_BIGINT");
}
// -fno-pie is the default on Emscripten.
LinkOutputKind::StaticNoPicExe | LinkOutputKind::StaticPicExe => {}
LinkOutputKind::WasiReactorExe => {
unreachable!();
}
}
}

fn include_path(&mut self, path: &Path) {
self.cmd.arg("-L").arg(path);
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_mir_dataflow/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ use rustc_middle::mir::{self, Local};
/// The set of locals in a MIR body that do not have `StorageLive`/`StorageDead` annotations.
///
/// These locals have fixed storage for the duration of the body.
//
// FIXME: Currently, we need to traverse the entire MIR to compute this. We should instead store it
// as a field in the `LocalDecl` for each `Local`.
pub fn always_storage_live_locals(body: &mir::Body<'_>) -> BitSet<Local> {
let mut always_live_locals = BitSet::new_filled(body.local_decls.len());

Expand Down
1 change: 1 addition & 0 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,7 @@ impl<T: ?Sized> Box<T> {
/// [`Layout`]: crate::Layout
#[stable(feature = "box_raw", since = "1.4.0")]
#[inline]
#[must_use = "call `drop(from_raw(ptr))` if you intend to drop the `Box`"]
pub unsafe fn from_raw(raw: *mut T) -> Self {
unsafe { Self::from_raw_in(raw, Global) }
}
Expand Down
8 changes: 4 additions & 4 deletions library/alloc/src/ffi/c_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ use crate::sync::Arc;
/// and other memory errors.
#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
#[cfg_attr(not(test), rustc_diagnostic_item = "cstring_type")]
#[unstable(feature = "alloc_c_string", issue = "94079")]
#[stable(feature = "alloc_c_string", since = "1.64.0")]
pub struct CString {
// Invariant 1: the slice ends with a zero byte and has a length of at least one.
// Invariant 2: the slice contains only one zero byte.
Expand All @@ -132,7 +132,7 @@ pub struct CString {
/// let _: NulError = CString::new(b"f\0oo".to_vec()).unwrap_err();
/// ```
#[derive(Clone, PartialEq, Eq, Debug)]
#[unstable(feature = "alloc_c_string", issue = "94079")]
#[stable(feature = "alloc_c_string", since = "1.64.0")]
pub struct NulError(usize, Vec<u8>);

#[derive(Clone, PartialEq, Eq, Debug)]
Expand All @@ -157,7 +157,7 @@ enum FromBytesWithNulErrorKind {
/// let _: FromVecWithNulError = CString::from_vec_with_nul(b"f\0oo".to_vec()).unwrap_err();
/// ```
#[derive(Clone, PartialEq, Eq, Debug)]
#[unstable(feature = "alloc_c_string", issue = "94079")]
#[stable(feature = "alloc_c_string", since = "1.64.0")]
pub struct FromVecWithNulError {
error_kind: FromBytesWithNulErrorKind,
bytes: Vec<u8>,
Expand Down Expand Up @@ -223,7 +223,7 @@ impl FromVecWithNulError {
/// This `struct` is created by [`CString::into_string()`]. See
/// its documentation for more.
#[derive(Clone, PartialEq, Eq, Debug)]
#[unstable(feature = "alloc_c_string", issue = "94079")]
#[stable(feature = "alloc_c_string", since = "1.64.0")]
pub struct IntoStringError {
inner: CString,
error: Utf8Error,
Expand Down
6 changes: 3 additions & 3 deletions library/alloc/src/ffi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,11 @@
//! [`String`]: crate::string::String
//! [`CStr`]: core::ffi::CStr

#![unstable(feature = "alloc_ffi", issue = "94079")]
#![stable(feature = "alloc_ffi", since = "1.64.0")]

#[unstable(feature = "alloc_c_string", issue = "94079")]
#[stable(feature = "alloc_c_string", since = "1.64.0")]
pub use self::c_str::FromVecWithNulError;
#[unstable(feature = "alloc_c_string", issue = "94079")]
#[stable(feature = "alloc_c_string", since = "1.64.0")]
pub use self::c_str::{CString, IntoStringError, NulError};

mod c_str;
2 changes: 0 additions & 2 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@
#![allow(explicit_outlives_requirements)]
//
// Library features:
#![cfg_attr(not(no_global_oom_handling), feature(alloc_c_string))]
#![feature(alloc_layout_extra)]
#![feature(allocator_api)]
#![feature(array_chunks)]
Expand All @@ -106,7 +105,6 @@
#![feature(const_maybe_uninit_write)]
#![feature(const_maybe_uninit_as_mut_ptr)]
#![feature(const_refs_to_cell)]
#![feature(core_c_str)]
#![feature(core_intrinsics)]
#![feature(const_eval_select)]
#![feature(const_pin)]
Expand Down
1 change: 0 additions & 1 deletion library/alloc/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#![feature(const_nonnull_slice_from_raw_parts)]
#![feature(const_ptr_write)]
#![feature(const_try)]
#![feature(core_c_str)]
#![feature(core_intrinsics)]
#![feature(drain_filter)]
#![feature(exact_size_is_empty)]
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/ffi/c_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ use crate::str;
/// [str]: prim@str "str"
#[derive(Hash)]
#[cfg_attr(not(test), rustc_diagnostic_item = "CStr")]
#[unstable(feature = "core_c_str", issue = "94079")]
#[stable(feature = "core_c_str", since = "1.64.0")]
#[rustc_has_incoherent_inherent_impls]
// FIXME:
// `fn from` in `impl From<&CStr> for Box<CStr>` current implementation relies
Expand Down Expand Up @@ -108,7 +108,7 @@ pub struct CStr {
/// let _: FromBytesWithNulError = CStr::from_bytes_with_nul(b"f\0oo").unwrap_err();
/// ```
#[derive(Clone, PartialEq, Eq, Debug)]
#[unstable(feature = "core_c_str", issue = "94079")]
#[stable(feature = "core_c_str", since = "1.64.0")]
pub struct FromBytesWithNulError {
kind: FromBytesWithNulErrorKind,
}
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/ffi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::marker::PhantomData;
use crate::num::*;
use crate::ops::{Deref, DerefMut};

#[unstable(feature = "core_c_str", issue = "94079")]
#[stable(feature = "core_c_str", since = "1.64.0")]
pub use self::c_str::{CStr, FromBytesUntilNulError, FromBytesWithNulError};

mod c_str;
Expand Down
22 changes: 4 additions & 18 deletions library/std/src/ffi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,24 +146,10 @@

#![stable(feature = "rust1", since = "1.0.0")]

/// See [alloc::ffi::FromVecWithNulError].
#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
pub type FromVecWithNulError = alloc::ffi::FromVecWithNulError;
/// See [alloc::ffi::CString].
#[stable(feature = "rust1", since = "1.0.0")]
pub type CString = alloc::ffi::CString;
/// See [alloc::ffi::IntoStringError].
#[stable(feature = "rust1", since = "1.0.0")]
pub type IntoStringError = alloc::ffi::IntoStringError;
/// See [alloc::ffi::NulError].
#[stable(feature = "rust1", since = "1.0.0")]
pub type NulError = alloc::ffi::NulError;
/// See [core::ffi::CStr].
#[stable(feature = "rust1", since = "1.0.0")]
pub type CStr = core::ffi::CStr;
/// See [core::ffi::FromBytesWithNulError].
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
pub type FromBytesWithNulError = core::ffi::FromBytesWithNulError;
#[stable(feature = "alloc_c_string", since = "1.64.0")]
pub use alloc::ffi::{CString, FromVecWithNulError, IntoStringError, NulError};
#[stable(feature = "core_c_str", since = "1.64.0")]
pub use core::ffi::{CStr, FromBytesWithNulError};

#[stable(feature = "rust1", since = "1.0.0")]
pub use self::os_str::{OsStr, OsString};
Expand Down
6 changes: 6 additions & 0 deletions library/std/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,9 @@ pub fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
/// This function will create a file if it does not exist,
/// and will entirely replace its contents if it does.
///
/// Depending on the platform, this function may fail if the
/// full directory path does not exist.
///
/// This is a convenience function for using [`File::create`] and [`write_all`]
/// with fewer imports.
///
Expand Down Expand Up @@ -349,6 +352,9 @@ impl File {
/// This function will create a file if it does not exist,
/// and will truncate it if it does.
///
/// Depending on the platform, this function may fail if the
/// full directory path does not exist.
///
/// See the [`OpenOptions::open`] function for more details.
///
/// # Examples
Expand Down
62 changes: 62 additions & 0 deletions library/std/src/io/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,68 @@ impl Error {
}
}

/// Attempt to downgrade the inner error to `E` if any.
///
/// If this [`Error`] was constructed via [`new`] then this function will
/// attempt to perform downgrade on it, otherwise it will return [`Err`].
///
/// If downgrade succeeds, it will return [`Ok`], otherwise it will also
/// return [`Err`].
///
/// [`new`]: Error::new
///
/// # Examples
///
/// ```
/// #![feature(io_error_downcast)]
///
/// use std::fmt;
/// use std::io;
/// use std::error::Error;
///
/// #[derive(Debug)]
/// enum E {
/// Io(io::Error),
/// SomeOtherVariant,
/// }
///
/// impl fmt::Display for E {
/// // ...
/// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// # todo!()
/// # }
/// }
/// impl Error for E {}
///
/// impl From<io::Error> for E {
/// fn from(err: io::Error) -> E {
/// err.downcast::<E>()
/// .map(|b| *b)
/// .unwrap_or_else(E::Io)
/// }
/// }
/// ```
#[unstable(feature = "io_error_downcast", issue = "99262")]
pub fn downcast<E>(self) -> result::Result<Box<E>, Self>
where
E: error::Error + Send + Sync + 'static,
{
match self.repr.into_data() {
ErrorData::Custom(b) if b.error.is::<E>() => {
let res = (*b).error.downcast::<E>();

// downcast is a really trivial and is marked as inline, so
// it's likely be inlined here.
//
// And the compiler should be able to eliminate the branch
// that produces `Err` here since b.error.is::<E>()
// returns true.
Ok(res.unwrap())
}
repr_data => Err(Self { repr: Repr::new(repr_data) }),
}
}

/// Returns the corresponding [`ErrorKind`] for this error.
///
/// # Examples
Expand Down
9 changes: 9 additions & 0 deletions library/std/src/io/error/repr_bitpacked.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,15 @@ unsafe impl Send for Repr {}
unsafe impl Sync for Repr {}

impl Repr {
pub(super) fn new(dat: ErrorData<Box<Custom>>) -> Self {
match dat {
ErrorData::Os(code) => Self::new_os(code),
ErrorData::Simple(kind) => Self::new_simple(kind),
ErrorData::SimpleMessage(simple_message) => Self::new_simple_message(simple_message),
ErrorData::Custom(b) => Self::new_custom(b),
}
}

pub(super) fn new_custom(b: Box<Custom>) -> Self {
let p = Box::into_raw(b).cast::<u8>();
// Should only be possible if an allocator handed out a pointer with
Expand Down
4 changes: 4 additions & 0 deletions library/std/src/io/error/repr_unpacked.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ type Inner = ErrorData<Box<Custom>>;
pub(super) struct Repr(Inner);

impl Repr {
#[inline]
pub(super) fn new(dat: ErrorData<Box<Custom>>) -> Self {
Self(dat)
}
pub(super) fn new_custom(b: Box<Custom>) -> Self {
Self(Inner::Custom(b))
}
Expand Down
53 changes: 52 additions & 1 deletion library/std/src/io/error/tests.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{const_io_error, Custom, Error, ErrorData, ErrorKind, Repr};
use super::{const_io_error, Custom, Error, ErrorData, ErrorKind, Repr, SimpleMessage};
use crate::assert_matches::assert_matches;
use crate::error;
use crate::fmt;
Expand Down Expand Up @@ -141,3 +141,54 @@ fn test_custom_error_packing() {
}) if error.downcast_ref::<Bojji>().as_deref() == Some(&Bojji(true)),
);
}

#[derive(Debug)]
struct E;

impl fmt::Display for E {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
Ok(())
}
}

impl error::Error for E {}

#[test]
fn test_std_io_error_downcast() {
// Case 1: custom error, downcast succeeds
let io_error = Error::new(ErrorKind::Other, Bojji(true));
let e: Box<Bojji> = io_error.downcast().unwrap();
assert!(e.0);

// Case 2: custom error, downcast fails
let io_error = Error::new(ErrorKind::Other, Bojji(true));
let io_error = io_error.downcast::<E>().unwrap_err();

// ensures that the custom error is intact
assert_eq!(ErrorKind::Other, io_error.kind());
let e: Box<Bojji> = io_error.downcast().unwrap();
assert!(e.0);

// Case 3: os error
let errno = 20;
let io_error = Error::from_raw_os_error(errno);
let io_error = io_error.downcast::<E>().unwrap_err();

assert_eq!(errno, io_error.raw_os_error().unwrap());

// Case 4: simple
let kind = ErrorKind::OutOfMemory;
let io_error: Error = kind.into();
let io_error = io_error.downcast::<E>().unwrap_err();

assert_eq!(kind, io_error.kind());

// Case 5: simple message
const SIMPLE_MESSAGE: SimpleMessage =
SimpleMessage { kind: ErrorKind::Other, message: "simple message error test" };
let io_error = Error::from_static_message(&SIMPLE_MESSAGE);
let io_error = io_error.downcast::<E>().unwrap_err();

assert_eq!(SIMPLE_MESSAGE.kind, io_error.kind());
assert_eq!(SIMPLE_MESSAGE.message, &*format!("{io_error}"));
}
3 changes: 0 additions & 3 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,6 @@
#![feature(atomic_mut_ptr)]
#![feature(char_error_internals)]
#![feature(char_internals)]
#![feature(core_c_str)]
#![feature(core_intrinsics)]
#![feature(cstr_from_bytes_until_nul)]
#![feature(cstr_internals)]
Expand Down Expand Up @@ -297,8 +296,6 @@
//
// Library features (alloc):
#![feature(alloc_layout_extra)]
#![feature(alloc_c_string)]
#![feature(alloc_ffi)]
#![feature(allocator_api)]
#![feature(get_mut_unchecked)]
#![feature(map_try_insert)]
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/thread/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,7 @@ impl Thread {
// Used only internally to construct a thread object without spawning
// Panics if the name contains nuls.
pub(crate) fn new(name: Option<CString>) -> Thread {
// We have to use `unsafe` here to constuct the `Parker` in-place,
// We have to use `unsafe` here to construct the `Parker` in-place,
// which is required for the UNIX implementation.
//
// SAFETY: We pin the Arc immediately after creation, so its address never
Expand Down
Loading