mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 16:54:01 +00:00
Auto merge of #115469 - matthiaskrgr:rollup-25ybx39, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #114349 (rustc_llvm: Link to `zlib` on dragonfly and solaris) - #114845 (Add alignment to the NPO guarantee) - #115427 (kmc-solid: Fix `is_interrupted`) - #115443 (feat(std): Stabilize 'os_str_bytes' feature) - #115444 (Create a SMIR visitor) - #115449 (Const-stabilize `is_ascii`) - #115456 (Add spastorino on vacation) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
ad8f601ca2
@ -252,7 +252,10 @@ fn main() {
|
|||||||
} else if target.contains("windows-gnu") {
|
} else if target.contains("windows-gnu") {
|
||||||
println!("cargo:rustc-link-lib=shell32");
|
println!("cargo:rustc-link-lib=shell32");
|
||||||
println!("cargo:rustc-link-lib=uuid");
|
println!("cargo:rustc-link-lib=uuid");
|
||||||
} else if target.contains("haiku") || target.contains("darwin") {
|
} else if target.contains("haiku")
|
||||||
|
|| target.contains("darwin")
|
||||||
|
|| (is_crossed && (target.contains("dragonfly") || target.contains("solaris")))
|
||||||
|
{
|
||||||
println!("cargo:rustc-link-lib=z");
|
println!("cargo:rustc-link-lib=z");
|
||||||
} else if target.contains("netbsd") {
|
} else if target.contains("netbsd") {
|
||||||
println!("cargo:rustc-link-lib=z");
|
println!("cargo:rustc-link-lib=z");
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::ops::Index;
|
use std::ops::Index;
|
||||||
use std::string::ToString;
|
|
||||||
|
|
||||||
use crate::rustc_internal;
|
use crate::rustc_internal;
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -156,10 +155,23 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A type that provides internal information but that can still be used for debug purpose.
|
/// A type that provides internal information but that can still be used for debug purpose.
|
||||||
pub type Opaque = impl Debug + ToString + Clone;
|
#[derive(Clone)]
|
||||||
|
pub struct Opaque(String);
|
||||||
|
|
||||||
|
impl std::fmt::Display for Opaque {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Opaque {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{:?}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn opaque<T: Debug>(value: &T) -> Opaque {
|
pub(crate) fn opaque<T: Debug>(value: &T) -> Opaque {
|
||||||
format!("{value:?}")
|
Opaque(format!("{value:?}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StableMir {
|
pub struct StableMir {
|
||||||
|
@ -20,6 +20,7 @@ use crate::rustc_smir::Tables;
|
|||||||
|
|
||||||
pub mod mir;
|
pub mod mir;
|
||||||
pub mod ty;
|
pub mod ty;
|
||||||
|
pub mod visitor;
|
||||||
|
|
||||||
/// Use String for now but we should replace it.
|
/// Use String for now but we should replace it.
|
||||||
pub type Symbol = String;
|
pub type Symbol = String;
|
||||||
|
186
compiler/rustc_smir/src/stable_mir/visitor.rs
Normal file
186
compiler/rustc_smir/src/stable_mir/visitor.rs
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
|
use crate::rustc_internal::Opaque;
|
||||||
|
|
||||||
|
use super::ty::{
|
||||||
|
Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs,
|
||||||
|
Promoted, RigidTy, TermKind, Ty, UnevaluatedConst,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub trait Visitor: Sized {
|
||||||
|
type Break;
|
||||||
|
fn visit_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break> {
|
||||||
|
ty.super_visit(self)
|
||||||
|
}
|
||||||
|
fn visit_const(&mut self, c: &Const) -> ControlFlow<Self::Break> {
|
||||||
|
c.super_visit(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Visitable {
|
||||||
|
fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
self.super_visit(visitor)
|
||||||
|
}
|
||||||
|
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for Ty {
|
||||||
|
fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
visitor.visit_ty(self)
|
||||||
|
}
|
||||||
|
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
match self.kind() {
|
||||||
|
super::ty::TyKind::RigidTy(ty) => ty.visit(visitor),
|
||||||
|
super::ty::TyKind::Alias(_, alias) => alias.args.visit(visitor),
|
||||||
|
super::ty::TyKind::Param(_) => todo!(),
|
||||||
|
super::ty::TyKind::Bound(_, _) => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for Const {
|
||||||
|
fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
visitor.visit_const(self)
|
||||||
|
}
|
||||||
|
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
match &self.literal {
|
||||||
|
super::ty::ConstantKind::Allocated(alloc) => alloc.visit(visitor),
|
||||||
|
super::ty::ConstantKind::Unevaluated(uv) => uv.visit(visitor),
|
||||||
|
super::ty::ConstantKind::ParamCt(param) => param.visit(visitor),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for Opaque {
|
||||||
|
fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for Allocation {
|
||||||
|
fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for UnevaluatedConst {
|
||||||
|
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
let UnevaluatedConst { ty, def, args, promoted } = self;
|
||||||
|
ty.visit(visitor)?;
|
||||||
|
def.visit(visitor)?;
|
||||||
|
args.visit(visitor)?;
|
||||||
|
promoted.visit(visitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for ConstDef {
|
||||||
|
fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Visitable> Visitable for Option<T> {
|
||||||
|
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
match self {
|
||||||
|
Some(val) => val.visit(visitor),
|
||||||
|
None => ControlFlow::Continue(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for Promoted {
|
||||||
|
fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for GenericArgs {
|
||||||
|
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
self.0.visit(visitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for GenericArgKind {
|
||||||
|
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
match self {
|
||||||
|
GenericArgKind::Lifetime(lt) => lt.visit(visitor),
|
||||||
|
GenericArgKind::Type(t) => t.visit(visitor),
|
||||||
|
GenericArgKind::Const(c) => c.visit(visitor),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for RigidTy {
|
||||||
|
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
match self {
|
||||||
|
RigidTy::Bool
|
||||||
|
| RigidTy::Char
|
||||||
|
| RigidTy::Int(_)
|
||||||
|
| RigidTy::Uint(_)
|
||||||
|
| RigidTy::Float(_)
|
||||||
|
| RigidTy::Never
|
||||||
|
| RigidTy::Foreign(_)
|
||||||
|
| RigidTy::Str => ControlFlow::Continue(()),
|
||||||
|
RigidTy::Array(t, c) => {
|
||||||
|
t.visit(visitor)?;
|
||||||
|
c.visit(visitor)
|
||||||
|
}
|
||||||
|
RigidTy::Slice(inner) => inner.visit(visitor),
|
||||||
|
RigidTy::RawPtr(ty, _) => ty.visit(visitor),
|
||||||
|
RigidTy::Ref(_, ty, _) => ty.visit(visitor),
|
||||||
|
RigidTy::FnDef(_, args) => args.visit(visitor),
|
||||||
|
RigidTy::FnPtr(sig) => sig.visit(visitor),
|
||||||
|
RigidTy::Closure(_, args) => args.visit(visitor),
|
||||||
|
RigidTy::Generator(_, args, _) => args.visit(visitor),
|
||||||
|
RigidTy::Dynamic(pred, r, _) => {
|
||||||
|
pred.visit(visitor)?;
|
||||||
|
r.visit(visitor)
|
||||||
|
}
|
||||||
|
RigidTy::Tuple(fields) => fields.visit(visitor),
|
||||||
|
RigidTy::Adt(_, args) => args.visit(visitor),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Visitable> Visitable for Vec<T> {
|
||||||
|
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
for arg in self {
|
||||||
|
arg.visit(visitor)?;
|
||||||
|
}
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Visitable> Visitable for Binder<T> {
|
||||||
|
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
self.value.visit(visitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for ExistentialPredicate {
|
||||||
|
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
match self {
|
||||||
|
ExistentialPredicate::Trait(tr) => tr.generic_args.visit(visitor),
|
||||||
|
ExistentialPredicate::Projection(p) => {
|
||||||
|
p.term.visit(visitor)?;
|
||||||
|
p.generic_args.visit(visitor)
|
||||||
|
}
|
||||||
|
ExistentialPredicate::AutoTrait(_) => ControlFlow::Continue(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for TermKind {
|
||||||
|
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
match self {
|
||||||
|
TermKind::Type(t) => t.visit(visitor),
|
||||||
|
TermKind::Const(c) => c.visit(visitor),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for FnSig {
|
||||||
|
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
self.inputs_and_output.visit(visitor)
|
||||||
|
}
|
||||||
|
}
|
@ -152,7 +152,6 @@
|
|||||||
#![feature(const_slice_from_raw_parts_mut)]
|
#![feature(const_slice_from_raw_parts_mut)]
|
||||||
#![feature(const_slice_from_ref)]
|
#![feature(const_slice_from_ref)]
|
||||||
#![feature(const_slice_index)]
|
#![feature(const_slice_index)]
|
||||||
#![feature(const_slice_is_ascii)]
|
|
||||||
#![feature(const_slice_ptr_len)]
|
#![feature(const_slice_ptr_len)]
|
||||||
#![feature(const_slice_split_at_mut)]
|
#![feature(const_slice_split_at_mut)]
|
||||||
#![feature(const_str_from_utf8_unchecked_mut)]
|
#![feature(const_str_from_utf8_unchecked_mut)]
|
||||||
|
@ -41,6 +41,20 @@ macro_rules! nonzero_integers {
|
|||||||
/// with the exception that `0` is not a valid instance.
|
/// with the exception that `0` is not a valid instance.
|
||||||
#[doc = concat!("`Option<", stringify!($Ty), ">` is guaranteed to be compatible with `", stringify!($Int), "`,")]
|
#[doc = concat!("`Option<", stringify!($Ty), ">` is guaranteed to be compatible with `", stringify!($Int), "`,")]
|
||||||
/// including in FFI.
|
/// including in FFI.
|
||||||
|
///
|
||||||
|
/// Thanks to the [null pointer optimization],
|
||||||
|
#[doc = concat!("`", stringify!($Ty), "` and `Option<", stringify!($Ty), ">`")]
|
||||||
|
/// are guaranteed to have the same size and alignment:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use std::mem::{size_of, align_of};
|
||||||
|
#[doc = concat!("use std::num::", stringify!($Ty), ";")]
|
||||||
|
///
|
||||||
|
#[doc = concat!("assert_eq!(size_of::<", stringify!($Ty), ">(), size_of::<Option<", stringify!($Ty), ">>());")]
|
||||||
|
#[doc = concat!("assert_eq!(align_of::<", stringify!($Ty), ">(), align_of::<Option<", stringify!($Ty), ">>());")]
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [null pointer optimization]: crate::option#representation
|
||||||
#[$stability]
|
#[$stability]
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
@ -119,7 +119,7 @@
|
|||||||
//! # Representation
|
//! # Representation
|
||||||
//!
|
//!
|
||||||
//! Rust guarantees to optimize the following types `T` such that
|
//! Rust guarantees to optimize the following types `T` such that
|
||||||
//! [`Option<T>`] has the same size as `T`:
|
//! [`Option<T>`] has the same size and alignment as `T`:
|
||||||
//!
|
//!
|
||||||
//! * [`Box<U>`]
|
//! * [`Box<U>`]
|
||||||
//! * `&U`
|
//! * `&U`
|
||||||
|
@ -43,9 +43,27 @@ use crate::slice::{self, SliceIndex};
|
|||||||
/// it is your responsibility to ensure that `as_mut` is never called, and `as_ptr`
|
/// it is your responsibility to ensure that `as_mut` is never called, and `as_ptr`
|
||||||
/// is never used for mutation.
|
/// is never used for mutation.
|
||||||
///
|
///
|
||||||
|
/// # Representation
|
||||||
|
///
|
||||||
|
/// Thanks to the [null pointer optimization],
|
||||||
|
/// `NonNull<T>` and `Option<NonNull<T>>`
|
||||||
|
/// are guaranteed to have the same size and alignment:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use std::mem::{size_of, align_of};
|
||||||
|
/// use std::ptr::NonNull;
|
||||||
|
///
|
||||||
|
/// assert_eq!(size_of::<NonNull<i16>>(), size_of::<Option<NonNull<i16>>>());
|
||||||
|
/// assert_eq!(align_of::<NonNull<i16>>(), align_of::<Option<NonNull<i16>>>());
|
||||||
|
///
|
||||||
|
/// assert_eq!(size_of::<NonNull<str>>(), size_of::<Option<NonNull<str>>>());
|
||||||
|
/// assert_eq!(align_of::<NonNull<str>>(), align_of::<Option<NonNull<str>>>());
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// [covariant]: https://doc.rust-lang.org/reference/subtyping.html
|
/// [covariant]: https://doc.rust-lang.org/reference/subtyping.html
|
||||||
/// [`PhantomData`]: crate::marker::PhantomData
|
/// [`PhantomData`]: crate::marker::PhantomData
|
||||||
/// [`UnsafeCell<T>`]: crate::cell::UnsafeCell
|
/// [`UnsafeCell<T>`]: crate::cell::UnsafeCell
|
||||||
|
/// [null pointer optimization]: crate::option#representation
|
||||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[rustc_layout_scalar_valid_range_start(1)]
|
#[rustc_layout_scalar_valid_range_start(1)]
|
||||||
|
@ -10,7 +10,7 @@ use crate::ops;
|
|||||||
impl [u8] {
|
impl [u8] {
|
||||||
/// Checks if all bytes in this slice are within the ASCII range.
|
/// Checks if all bytes in this slice are within the ASCII range.
|
||||||
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
||||||
#[rustc_const_unstable(feature = "const_slice_is_ascii", issue = "111090")]
|
#[rustc_const_stable(feature = "const_slice_is_ascii", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn is_ascii(&self) -> bool {
|
pub const fn is_ascii(&self) -> bool {
|
||||||
|
@ -2322,7 +2322,7 @@ impl str {
|
|||||||
/// assert!(!non_ascii.is_ascii());
|
/// assert!(!non_ascii.is_ascii());
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
||||||
#[rustc_const_unstable(feature = "const_slice_is_ascii", issue = "111090")]
|
#[rustc_const_stable(feature = "const_slice_is_ascii", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn is_ascii(&self) -> bool {
|
pub const fn is_ascii(&self) -> bool {
|
||||||
|
@ -132,8 +132,8 @@
|
|||||||
//! On all platforms, [`OsStr`] consists of a sequence of bytes that is encoded as a superset of
|
//! On all platforms, [`OsStr`] consists of a sequence of bytes that is encoded as a superset of
|
||||||
//! UTF-8; see [`OsString`] for more details on its encoding on different platforms.
|
//! UTF-8; see [`OsString`] for more details on its encoding on different platforms.
|
||||||
//!
|
//!
|
||||||
//! For limited, inexpensive conversions from and to bytes, see [`OsStr::as_os_str_bytes`] and
|
//! For limited, inexpensive conversions from and to bytes, see [`OsStr::as_encoded_bytes`] and
|
||||||
//! [`OsStr::from_os_str_bytes_unchecked`].
|
//! [`OsStr::from_encoded_bytes_unchecked`].
|
||||||
//!
|
//!
|
||||||
//! [Unicode scalar value]: https://www.unicode.org/glossary/#unicode_scalar_value
|
//! [Unicode scalar value]: https://www.unicode.org/glossary/#unicode_scalar_value
|
||||||
//! [Unicode code point]: https://www.unicode.org/glossary/#code_point
|
//! [Unicode code point]: https://www.unicode.org/glossary/#code_point
|
||||||
|
@ -154,36 +154,34 @@ impl OsString {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// As the encoding is unspecified, callers must pass in bytes that originated as a mixture of
|
/// As the encoding is unspecified, callers must pass in bytes that originated as a mixture of
|
||||||
/// validated UTF-8 and bytes from [`OsStr::as_os_str_bytes`] from within the same rust version
|
/// validated UTF-8 and bytes from [`OsStr::as_encoded_bytes`] from within the same rust version
|
||||||
/// built for the same target platform. For example, reconstructing an `OsString` from bytes sent
|
/// built for the same target platform. For example, reconstructing an `OsString` from bytes sent
|
||||||
/// over the network or stored in a file will likely violate these safety rules.
|
/// over the network or stored in a file will likely violate these safety rules.
|
||||||
///
|
///
|
||||||
/// Due to the encoding being self-synchronizing, the bytes from [`OsStr::as_os_str_bytes`] can be
|
/// Due to the encoding being self-synchronizing, the bytes from [`OsStr::as_encoded_bytes`] can be
|
||||||
/// split either immediately before or immediately after any valid non-empty UTF-8 substring.
|
/// split either immediately before or immediately after any valid non-empty UTF-8 substring.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(os_str_bytes)]
|
|
||||||
///
|
|
||||||
/// use std::ffi::OsStr;
|
/// use std::ffi::OsStr;
|
||||||
///
|
///
|
||||||
/// let os_str = OsStr::new("Mary had a little lamb");
|
/// let os_str = OsStr::new("Mary had a little lamb");
|
||||||
/// let bytes = os_str.as_os_str_bytes();
|
/// let bytes = os_str.as_encoded_bytes();
|
||||||
/// let words = bytes.split(|b| *b == b' ');
|
/// let words = bytes.split(|b| *b == b' ');
|
||||||
/// let words: Vec<&OsStr> = words.map(|word| {
|
/// let words: Vec<&OsStr> = words.map(|word| {
|
||||||
/// // SAFETY:
|
/// // SAFETY:
|
||||||
/// // - Each `word` only contains content that originated from `OsStr::as_os_str_bytes`
|
/// // - Each `word` only contains content that originated from `OsStr::as_encoded_bytes`
|
||||||
/// // - Only split with ASCII whitespace which is a non-empty UTF-8 substring
|
/// // - Only split with ASCII whitespace which is a non-empty UTF-8 substring
|
||||||
/// unsafe { OsStr::from_os_str_bytes_unchecked(word) }
|
/// unsafe { OsStr::from_encoded_bytes_unchecked(word) }
|
||||||
/// }).collect();
|
/// }).collect();
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [conversions]: super#conversions
|
/// [conversions]: super#conversions
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable(feature = "os_str_bytes", issue = "111544")]
|
#[stable(feature = "os_str_bytes", since = "CURRENT_RUSTC_VERSION")]
|
||||||
pub unsafe fn from_os_str_bytes_unchecked(bytes: Vec<u8>) -> Self {
|
pub unsafe fn from_encoded_bytes_unchecked(bytes: Vec<u8>) -> Self {
|
||||||
OsString { inner: Buf::from_os_str_bytes_unchecked(bytes) }
|
OsString { inner: Buf::from_encoded_bytes_unchecked(bytes) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts to an [`OsStr`] slice.
|
/// Converts to an [`OsStr`] slice.
|
||||||
@ -205,7 +203,7 @@ impl OsString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Converts the `OsString` into a byte slice. To convert the byte slice back into an
|
/// Converts the `OsString` into a byte slice. To convert the byte slice back into an
|
||||||
/// `OsString`, use the [`OsStr::from_os_str_bytes_unchecked`] function.
|
/// `OsString`, use the [`OsStr::from_encoded_bytes_unchecked`] function.
|
||||||
///
|
///
|
||||||
/// The byte encoding is an unspecified, platform-specific, self-synchronizing superset of UTF-8.
|
/// The byte encoding is an unspecified, platform-specific, self-synchronizing superset of UTF-8.
|
||||||
/// By being a self-synchronizing superset of UTF-8, this encoding is also a superset of 7-bit
|
/// By being a self-synchronizing superset of UTF-8, this encoding is also a superset of 7-bit
|
||||||
@ -219,9 +217,9 @@ impl OsString {
|
|||||||
///
|
///
|
||||||
/// [`std::ffi`]: crate::ffi
|
/// [`std::ffi`]: crate::ffi
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable(feature = "os_str_bytes", issue = "111544")]
|
#[stable(feature = "os_str_bytes", since = "CURRENT_RUSTC_VERSION")]
|
||||||
pub fn into_os_str_bytes(self) -> Vec<u8> {
|
pub fn into_encoded_bytes(self) -> Vec<u8> {
|
||||||
self.inner.into_os_str_bytes()
|
self.inner.into_encoded_bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts the `OsString` into a [`String`] if it contains valid Unicode data.
|
/// Converts the `OsString` into a [`String`] if it contains valid Unicode data.
|
||||||
@ -745,36 +743,34 @@ impl OsStr {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// As the encoding is unspecified, callers must pass in bytes that originated as a mixture of
|
/// As the encoding is unspecified, callers must pass in bytes that originated as a mixture of
|
||||||
/// validated UTF-8 and bytes from [`OsStr::as_os_str_bytes`] from within the same rust version
|
/// validated UTF-8 and bytes from [`OsStr::as_encoded_bytes`] from within the same rust version
|
||||||
/// built for the same target platform. For example, reconstructing an `OsStr` from bytes sent
|
/// built for the same target platform. For example, reconstructing an `OsStr` from bytes sent
|
||||||
/// over the network or stored in a file will likely violate these safety rules.
|
/// over the network or stored in a file will likely violate these safety rules.
|
||||||
///
|
///
|
||||||
/// Due to the encoding being self-synchronizing, the bytes from [`OsStr::as_os_str_bytes`] can be
|
/// Due to the encoding being self-synchronizing, the bytes from [`OsStr::as_encoded_bytes`] can be
|
||||||
/// split either immediately before or immediately after any valid non-empty UTF-8 substring.
|
/// split either immediately before or immediately after any valid non-empty UTF-8 substring.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(os_str_bytes)]
|
|
||||||
///
|
|
||||||
/// use std::ffi::OsStr;
|
/// use std::ffi::OsStr;
|
||||||
///
|
///
|
||||||
/// let os_str = OsStr::new("Mary had a little lamb");
|
/// let os_str = OsStr::new("Mary had a little lamb");
|
||||||
/// let bytes = os_str.as_os_str_bytes();
|
/// let bytes = os_str.as_encoded_bytes();
|
||||||
/// let words = bytes.split(|b| *b == b' ');
|
/// let words = bytes.split(|b| *b == b' ');
|
||||||
/// let words: Vec<&OsStr> = words.map(|word| {
|
/// let words: Vec<&OsStr> = words.map(|word| {
|
||||||
/// // SAFETY:
|
/// // SAFETY:
|
||||||
/// // - Each `word` only contains content that originated from `OsStr::as_os_str_bytes`
|
/// // - Each `word` only contains content that originated from `OsStr::as_encoded_bytes`
|
||||||
/// // - Only split with ASCII whitespace which is a non-empty UTF-8 substring
|
/// // - Only split with ASCII whitespace which is a non-empty UTF-8 substring
|
||||||
/// unsafe { OsStr::from_os_str_bytes_unchecked(word) }
|
/// unsafe { OsStr::from_encoded_bytes_unchecked(word) }
|
||||||
/// }).collect();
|
/// }).collect();
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [conversions]: super#conversions
|
/// [conversions]: super#conversions
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable(feature = "os_str_bytes", issue = "111544")]
|
#[stable(feature = "os_str_bytes", since = "CURRENT_RUSTC_VERSION")]
|
||||||
pub unsafe fn from_os_str_bytes_unchecked(bytes: &[u8]) -> &Self {
|
pub unsafe fn from_encoded_bytes_unchecked(bytes: &[u8]) -> &Self {
|
||||||
Self::from_inner(Slice::from_os_str_bytes_unchecked(bytes))
|
Self::from_inner(Slice::from_encoded_bytes_unchecked(bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -948,7 +944,7 @@ impl OsStr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Converts an OS string slice to a byte slice. To convert the byte slice back into an OS
|
/// Converts an OS string slice to a byte slice. To convert the byte slice back into an OS
|
||||||
/// string slice, use the [`OsStr::from_os_str_bytes_unchecked`] function.
|
/// string slice, use the [`OsStr::from_encoded_bytes_unchecked`] function.
|
||||||
///
|
///
|
||||||
/// The byte encoding is an unspecified, platform-specific, self-synchronizing superset of UTF-8.
|
/// The byte encoding is an unspecified, platform-specific, self-synchronizing superset of UTF-8.
|
||||||
/// By being a self-synchronizing superset of UTF-8, this encoding is also a superset of 7-bit
|
/// By being a self-synchronizing superset of UTF-8, this encoding is also a superset of 7-bit
|
||||||
@ -962,9 +958,9 @@ impl OsStr {
|
|||||||
///
|
///
|
||||||
/// [`std::ffi`]: crate::ffi
|
/// [`std::ffi`]: crate::ffi
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable(feature = "os_str_bytes", issue = "111544")]
|
#[stable(feature = "os_str_bytes", since = "CURRENT_RUSTC_VERSION")]
|
||||||
pub fn as_os_str_bytes(&self) -> &[u8] {
|
pub fn as_encoded_bytes(&self) -> &[u8] {
|
||||||
self.inner.as_os_str_bytes()
|
self.inner.as_encoded_bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts this string to its ASCII lower case equivalent in-place.
|
/// Converts this string to its ASCII lower case equivalent in-place.
|
||||||
@ -1270,7 +1266,7 @@ impl Default for &OsStr {
|
|||||||
impl PartialEq for OsStr {
|
impl PartialEq for OsStr {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eq(&self, other: &OsStr) -> bool {
|
fn eq(&self, other: &OsStr) -> bool {
|
||||||
self.as_os_str_bytes().eq(other.as_os_str_bytes())
|
self.as_encoded_bytes().eq(other.as_encoded_bytes())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1297,23 +1293,23 @@ impl Eq for OsStr {}
|
|||||||
impl PartialOrd for OsStr {
|
impl PartialOrd for OsStr {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
|
fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
|
||||||
self.as_os_str_bytes().partial_cmp(other.as_os_str_bytes())
|
self.as_encoded_bytes().partial_cmp(other.as_encoded_bytes())
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn lt(&self, other: &OsStr) -> bool {
|
fn lt(&self, other: &OsStr) -> bool {
|
||||||
self.as_os_str_bytes().lt(other.as_os_str_bytes())
|
self.as_encoded_bytes().lt(other.as_encoded_bytes())
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn le(&self, other: &OsStr) -> bool {
|
fn le(&self, other: &OsStr) -> bool {
|
||||||
self.as_os_str_bytes().le(other.as_os_str_bytes())
|
self.as_encoded_bytes().le(other.as_encoded_bytes())
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn gt(&self, other: &OsStr) -> bool {
|
fn gt(&self, other: &OsStr) -> bool {
|
||||||
self.as_os_str_bytes().gt(other.as_os_str_bytes())
|
self.as_encoded_bytes().gt(other.as_encoded_bytes())
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ge(&self, other: &OsStr) -> bool {
|
fn ge(&self, other: &OsStr) -> bool {
|
||||||
self.as_os_str_bytes().ge(other.as_os_str_bytes())
|
self.as_encoded_bytes().ge(other.as_encoded_bytes())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1332,7 +1328,7 @@ impl PartialOrd<str> for OsStr {
|
|||||||
impl Ord for OsStr {
|
impl Ord for OsStr {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn cmp(&self, other: &OsStr) -> cmp::Ordering {
|
fn cmp(&self, other: &OsStr) -> cmp::Ordering {
|
||||||
self.as_os_str_bytes().cmp(other.as_os_str_bytes())
|
self.as_encoded_bytes().cmp(other.as_encoded_bytes())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1382,7 +1378,7 @@ impl_cmp!(Cow<'a, OsStr>, OsString);
|
|||||||
impl Hash for OsStr {
|
impl Hash for OsStr {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.as_os_str_bytes().hash(state)
|
self.as_encoded_bytes().hash(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ impl<'a> Prefix<'a> {
|
|||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
use self::Prefix::*;
|
use self::Prefix::*;
|
||||||
fn os_str_len(s: &OsStr) -> usize {
|
fn os_str_len(s: &OsStr) -> usize {
|
||||||
s.as_os_str_bytes().len()
|
s.as_encoded_bytes().len()
|
||||||
}
|
}
|
||||||
match *self {
|
match *self {
|
||||||
Verbatim(x) => 4 + os_str_len(x),
|
Verbatim(x) => 4 + os_str_len(x),
|
||||||
@ -316,7 +316,7 @@ fn has_physical_root(s: &[u8], prefix: Option<Prefix<'_>>) -> bool {
|
|||||||
|
|
||||||
// basic workhorse for splitting stem and extension
|
// basic workhorse for splitting stem and extension
|
||||||
fn rsplit_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) {
|
fn rsplit_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) {
|
||||||
if file.as_os_str_bytes() == b".." {
|
if file.as_encoded_bytes() == b".." {
|
||||||
return (Some(file), None);
|
return (Some(file), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,7 +324,7 @@ fn rsplit_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) {
|
|||||||
// and back. This is safe to do because (1) we only look at ASCII
|
// and back. This is safe to do because (1) we only look at ASCII
|
||||||
// contents of the encoding and (2) new &OsStr values are produced
|
// contents of the encoding and (2) new &OsStr values are produced
|
||||||
// only from ASCII-bounded slices of existing &OsStr values.
|
// only from ASCII-bounded slices of existing &OsStr values.
|
||||||
let mut iter = file.as_os_str_bytes().rsplitn(2, |b| *b == b'.');
|
let mut iter = file.as_encoded_bytes().rsplitn(2, |b| *b == b'.');
|
||||||
let after = iter.next();
|
let after = iter.next();
|
||||||
let before = iter.next();
|
let before = iter.next();
|
||||||
if before == Some(b"") {
|
if before == Some(b"") {
|
||||||
@ -332,15 +332,15 @@ fn rsplit_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) {
|
|||||||
} else {
|
} else {
|
||||||
unsafe {
|
unsafe {
|
||||||
(
|
(
|
||||||
before.map(|s| OsStr::from_os_str_bytes_unchecked(s)),
|
before.map(|s| OsStr::from_encoded_bytes_unchecked(s)),
|
||||||
after.map(|s| OsStr::from_os_str_bytes_unchecked(s)),
|
after.map(|s| OsStr::from_encoded_bytes_unchecked(s)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_file_at_dot(file: &OsStr) -> (&OsStr, Option<&OsStr>) {
|
fn split_file_at_dot(file: &OsStr) -> (&OsStr, Option<&OsStr>) {
|
||||||
let slice = file.as_os_str_bytes();
|
let slice = file.as_encoded_bytes();
|
||||||
if slice == b".." {
|
if slice == b".." {
|
||||||
return (file, None);
|
return (file, None);
|
||||||
}
|
}
|
||||||
@ -357,8 +357,8 @@ fn split_file_at_dot(file: &OsStr) -> (&OsStr, Option<&OsStr>) {
|
|||||||
let after = &slice[i + 1..];
|
let after = &slice[i + 1..];
|
||||||
unsafe {
|
unsafe {
|
||||||
(
|
(
|
||||||
OsStr::from_os_str_bytes_unchecked(before),
|
OsStr::from_encoded_bytes_unchecked(before),
|
||||||
Some(OsStr::from_os_str_bytes_unchecked(after)),
|
Some(OsStr::from_encoded_bytes_unchecked(after)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -739,7 +739,7 @@ impl<'a> Components<'a> {
|
|||||||
// separately via `include_cur_dir`
|
// separately via `include_cur_dir`
|
||||||
b".." => Some(Component::ParentDir),
|
b".." => Some(Component::ParentDir),
|
||||||
b"" => None,
|
b"" => None,
|
||||||
_ => Some(Component::Normal(unsafe { OsStr::from_os_str_bytes_unchecked(comp) })),
|
_ => Some(Component::Normal(unsafe { OsStr::from_encoded_bytes_unchecked(comp) })),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -896,7 +896,7 @@ impl<'a> Iterator for Components<'a> {
|
|||||||
let raw = &self.path[..self.prefix_len()];
|
let raw = &self.path[..self.prefix_len()];
|
||||||
self.path = &self.path[self.prefix_len()..];
|
self.path = &self.path[self.prefix_len()..];
|
||||||
return Some(Component::Prefix(PrefixComponent {
|
return Some(Component::Prefix(PrefixComponent {
|
||||||
raw: unsafe { OsStr::from_os_str_bytes_unchecked(raw) },
|
raw: unsafe { OsStr::from_encoded_bytes_unchecked(raw) },
|
||||||
parsed: self.prefix.unwrap(),
|
parsed: self.prefix.unwrap(),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@ -968,7 +968,7 @@ impl<'a> DoubleEndedIterator for Components<'a> {
|
|||||||
State::Prefix if self.prefix_len() > 0 => {
|
State::Prefix if self.prefix_len() > 0 => {
|
||||||
self.back = State::Done;
|
self.back = State::Done;
|
||||||
return Some(Component::Prefix(PrefixComponent {
|
return Some(Component::Prefix(PrefixComponent {
|
||||||
raw: unsafe { OsStr::from_os_str_bytes_unchecked(self.path) },
|
raw: unsafe { OsStr::from_encoded_bytes_unchecked(self.path) },
|
||||||
parsed: self.prefix.unwrap(),
|
parsed: self.prefix.unwrap(),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@ -1477,17 +1477,17 @@ impl PathBuf {
|
|||||||
fn _set_extension(&mut self, extension: &OsStr) -> bool {
|
fn _set_extension(&mut self, extension: &OsStr) -> bool {
|
||||||
let file_stem = match self.file_stem() {
|
let file_stem = match self.file_stem() {
|
||||||
None => return false,
|
None => return false,
|
||||||
Some(f) => f.as_os_str_bytes(),
|
Some(f) => f.as_encoded_bytes(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// truncate until right after the file stem
|
// truncate until right after the file stem
|
||||||
let end_file_stem = file_stem[file_stem.len()..].as_ptr().addr();
|
let end_file_stem = file_stem[file_stem.len()..].as_ptr().addr();
|
||||||
let start = self.inner.as_os_str_bytes().as_ptr().addr();
|
let start = self.inner.as_encoded_bytes().as_ptr().addr();
|
||||||
let v = self.as_mut_vec();
|
let v = self.as_mut_vec();
|
||||||
v.truncate(end_file_stem.wrapping_sub(start));
|
v.truncate(end_file_stem.wrapping_sub(start));
|
||||||
|
|
||||||
// add the new extension, if any
|
// add the new extension, if any
|
||||||
let new = extension.as_os_str_bytes();
|
let new = extension.as_encoded_bytes();
|
||||||
if !new.is_empty() {
|
if !new.is_empty() {
|
||||||
v.reserve_exact(new.len() + 1);
|
v.reserve_exact(new.len() + 1);
|
||||||
v.push(b'.');
|
v.push(b'.');
|
||||||
@ -2007,11 +2007,11 @@ impl Path {
|
|||||||
// The following (private!) function allows construction of a path from a u8
|
// The following (private!) function allows construction of a path from a u8
|
||||||
// slice, which is only safe when it is known to follow the OsStr encoding.
|
// slice, which is only safe when it is known to follow the OsStr encoding.
|
||||||
unsafe fn from_u8_slice(s: &[u8]) -> &Path {
|
unsafe fn from_u8_slice(s: &[u8]) -> &Path {
|
||||||
unsafe { Path::new(OsStr::from_os_str_bytes_unchecked(s)) }
|
unsafe { Path::new(OsStr::from_encoded_bytes_unchecked(s)) }
|
||||||
}
|
}
|
||||||
// The following (private!) function reveals the byte encoding used for OsStr.
|
// The following (private!) function reveals the byte encoding used for OsStr.
|
||||||
fn as_u8_slice(&self) -> &[u8] {
|
fn as_u8_slice(&self) -> &[u8] {
|
||||||
self.inner.as_os_str_bytes()
|
self.inner.as_encoded_bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Directly wraps a string slice as a `Path` slice.
|
/// Directly wraps a string slice as a `Path` slice.
|
||||||
@ -2609,7 +2609,7 @@ impl Path {
|
|||||||
|
|
||||||
fn _with_extension(&self, extension: &OsStr) -> PathBuf {
|
fn _with_extension(&self, extension: &OsStr) -> PathBuf {
|
||||||
let self_len = self.as_os_str().len();
|
let self_len = self.as_os_str().len();
|
||||||
let self_bytes = self.as_os_str().as_os_str_bytes();
|
let self_bytes = self.as_os_str().as_encoded_bytes();
|
||||||
|
|
||||||
let (new_capacity, slice_to_copy) = match self.extension() {
|
let (new_capacity, slice_to_copy) = match self.extension() {
|
||||||
None => {
|
None => {
|
||||||
|
@ -19,7 +19,7 @@ pub fn run_path_with_cstr<T, F>(path: &Path, f: F) -> io::Result<T>
|
|||||||
where
|
where
|
||||||
F: FnOnce(&CStr) -> io::Result<T>,
|
F: FnOnce(&CStr) -> io::Result<T>,
|
||||||
{
|
{
|
||||||
run_with_cstr(path.as_os_str().as_os_str_bytes(), f)
|
run_with_cstr(path.as_os_str().as_encoded_bytes(), f)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -8,7 +8,7 @@ use core::iter::repeat;
|
|||||||
fn stack_allocation_works() {
|
fn stack_allocation_works() {
|
||||||
let path = Path::new("abc");
|
let path = Path::new("abc");
|
||||||
let result = run_path_with_cstr(path, |p| {
|
let result = run_path_with_cstr(path, |p| {
|
||||||
assert_eq!(p, &*CString::new(path.as_os_str().as_os_str_bytes()).unwrap());
|
assert_eq!(p, &*CString::new(path.as_os_str().as_encoded_bytes()).unwrap());
|
||||||
Ok(42)
|
Ok(42)
|
||||||
});
|
});
|
||||||
assert_eq!(result.unwrap(), 42);
|
assert_eq!(result.unwrap(), 42);
|
||||||
@ -25,7 +25,7 @@ fn heap_allocation_works() {
|
|||||||
let path = repeat("a").take(384).collect::<String>();
|
let path = repeat("a").take(384).collect::<String>();
|
||||||
let path = Path::new(&path);
|
let path = Path::new(&path);
|
||||||
let result = run_path_with_cstr(path, |p| {
|
let result = run_path_with_cstr(path, |p| {
|
||||||
assert_eq!(p, &*CString::new(path.as_os_str().as_os_str_bytes()).unwrap());
|
assert_eq!(p, &*CString::new(path.as_os_str().as_encoded_bytes()).unwrap());
|
||||||
Ok(42)
|
Ok(42)
|
||||||
});
|
});
|
||||||
assert_eq!(result.unwrap(), 42);
|
assert_eq!(result.unwrap(), 42);
|
||||||
|
@ -31,11 +31,6 @@ pub fn error_name(er: abi::ER) -> Option<&'static str> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn is_interrupted(er: abi::ER) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn decode_error_kind(er: abi::ER) -> ErrorKind {
|
pub fn decode_error_kind(er: abi::ER) -> ErrorKind {
|
||||||
match er {
|
match er {
|
||||||
// Success
|
// Success
|
||||||
|
@ -74,7 +74,7 @@ pub fn unsupported_err() -> crate::io::Error {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_interrupted(code: i32) -> bool {
|
pub fn is_interrupted(code: i32) -> bool {
|
||||||
error::is_interrupted(code)
|
net::is_interrupted(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decode_error_kind(code: i32) -> crate::io::ErrorKind {
|
pub fn decode_error_kind(code: i32) -> crate::io::ErrorKind {
|
||||||
|
@ -183,8 +183,7 @@ pub(super) fn error_name(er: abi::ER) -> Option<&'static str> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_interrupted(er: abi::ER) -> bool {
|
pub fn is_interrupted(er: abi::ER) -> bool {
|
||||||
let errno = netc::SOLID_NET_ERR_BASE - er;
|
er == netc::SOLID_NET_ERR_BASE - libc::EINTR
|
||||||
errno as libc::c_int == libc::EINTR
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn decode_error_kind(er: abi::ER) -> ErrorKind {
|
pub(super) fn decode_error_kind(er: abi::ER) -> ErrorKind {
|
||||||
|
@ -97,12 +97,12 @@ impl AsInner<[u8]> for Buf {
|
|||||||
|
|
||||||
impl Buf {
|
impl Buf {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_os_str_bytes(self) -> Vec<u8> {
|
pub fn into_encoded_bytes(self) -> Vec<u8> {
|
||||||
self.inner
|
self.inner
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_os_str_bytes_unchecked(s: Vec<u8>) -> Self {
|
pub unsafe fn from_encoded_bytes_unchecked(s: Vec<u8>) -> Self {
|
||||||
Self { inner: s }
|
Self { inner: s }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,18 +203,18 @@ impl Buf {
|
|||||||
|
|
||||||
impl Slice {
|
impl Slice {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_os_str_bytes(&self) -> &[u8] {
|
pub fn as_encoded_bytes(&self) -> &[u8] {
|
||||||
&self.inner
|
&self.inner
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_os_str_bytes_unchecked(s: &[u8]) -> &Slice {
|
pub unsafe fn from_encoded_bytes_unchecked(s: &[u8]) -> &Slice {
|
||||||
unsafe { mem::transmute(s) }
|
unsafe { mem::transmute(s) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_str(s: &str) -> &Slice {
|
pub fn from_str(s: &str) -> &Slice {
|
||||||
unsafe { Slice::from_os_str_bytes_unchecked(s.as_bytes()) }
|
unsafe { Slice::from_encoded_bytes_unchecked(s.as_bytes()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
|
pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
|
||||||
|
@ -2,7 +2,7 @@ use super::*;
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn slice_debug_output() {
|
fn slice_debug_output() {
|
||||||
let input = unsafe { Slice::from_os_str_bytes_unchecked(b"\xF0hello,\tworld") };
|
let input = unsafe { Slice::from_encoded_bytes_unchecked(b"\xF0hello,\tworld") };
|
||||||
let expected = r#""\xF0hello,\tworld""#;
|
let expected = r#""\xF0hello,\tworld""#;
|
||||||
let output = format!("{input:?}");
|
let output = format!("{input:?}");
|
||||||
|
|
||||||
@ -12,6 +12,6 @@ fn slice_debug_output() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn display() {
|
fn display() {
|
||||||
assert_eq!("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye", unsafe {
|
assert_eq!("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye", unsafe {
|
||||||
Slice::from_os_str_bytes_unchecked(b"Hello\xC0\x80 There\xE6\x83 Goodbye").to_string()
|
Slice::from_encoded_bytes_unchecked(b"Hello\xC0\x80 There\xE6\x83 Goodbye").to_string()
|
||||||
},);
|
},);
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
|
|||||||
|
|
||||||
// Get the components, skipping the redundant leading "." component if it exists.
|
// Get the components, skipping the redundant leading "." component if it exists.
|
||||||
let mut components = path.strip_prefix(".").unwrap_or(path).components();
|
let mut components = path.strip_prefix(".").unwrap_or(path).components();
|
||||||
let path_os = path.as_os_str().as_os_str_bytes();
|
let path_os = path.as_os_str().as_encoded_bytes();
|
||||||
|
|
||||||
let mut normalized = if path.is_absolute() {
|
let mut normalized = if path.is_absolute() {
|
||||||
// "If a pathname begins with two successive <slash> characters, the
|
// "If a pathname begins with two successive <slash> characters, the
|
||||||
|
@ -164,9 +164,9 @@ pub enum ProgramKind {
|
|||||||
|
|
||||||
impl ProgramKind {
|
impl ProgramKind {
|
||||||
fn new(program: &OsStr) -> Self {
|
fn new(program: &OsStr) -> Self {
|
||||||
if program.as_os_str_bytes().starts_with(b"/") {
|
if program.as_encoded_bytes().starts_with(b"/") {
|
||||||
Self::Absolute
|
Self::Absolute
|
||||||
} else if program.as_os_str_bytes().contains(&b'/') {
|
} else if program.as_encoded_bytes().contains(&b'/') {
|
||||||
// If the program has more than one component in it, it is a relative path.
|
// If the program has more than one component in it, it is a relative path.
|
||||||
Self::Relative
|
Self::Relative
|
||||||
} else {
|
} else {
|
||||||
|
@ -226,7 +226,7 @@ pub(crate) fn append_arg(cmd: &mut Vec<u16>, arg: &Arg, force_quotes: bool) -> i
|
|||||||
// that it actually gets passed through on the command line or otherwise
|
// that it actually gets passed through on the command line or otherwise
|
||||||
// it will be dropped entirely when parsed on the other end.
|
// it will be dropped entirely when parsed on the other end.
|
||||||
ensure_no_nuls(arg)?;
|
ensure_no_nuls(arg)?;
|
||||||
let arg_bytes = arg.as_os_str_bytes();
|
let arg_bytes = arg.as_encoded_bytes();
|
||||||
let (quote, escape) = match quote {
|
let (quote, escape) = match quote {
|
||||||
Quote::Always => (true, true),
|
Quote::Always => (true, true),
|
||||||
Quote::Auto => {
|
Quote::Auto => {
|
||||||
@ -298,7 +298,7 @@ pub(crate) fn make_bat_command_line(
|
|||||||
const SPECIAL: &[u8] = b"\t &()[]{}^=;!'+,`~%|<>";
|
const SPECIAL: &[u8] = b"\t &()[]{}^=;!'+,`~%|<>";
|
||||||
let force_quotes = match arg {
|
let force_quotes = match arg {
|
||||||
Arg::Regular(arg) if !force_quotes => {
|
Arg::Regular(arg) if !force_quotes => {
|
||||||
arg.as_os_str_bytes().iter().any(|c| SPECIAL.contains(c))
|
arg.as_encoded_bytes().iter().any(|c| SPECIAL.contains(c))
|
||||||
}
|
}
|
||||||
_ => force_quotes,
|
_ => force_quotes,
|
||||||
};
|
};
|
||||||
|
@ -64,12 +64,12 @@ impl fmt::Display for Slice {
|
|||||||
|
|
||||||
impl Buf {
|
impl Buf {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_os_str_bytes(self) -> Vec<u8> {
|
pub fn into_encoded_bytes(self) -> Vec<u8> {
|
||||||
self.inner.into_bytes()
|
self.inner.into_bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_os_str_bytes_unchecked(s: Vec<u8>) -> Self {
|
pub unsafe fn from_encoded_bytes_unchecked(s: Vec<u8>) -> Self {
|
||||||
Self { inner: Wtf8Buf::from_bytes_unchecked(s) }
|
Self { inner: Wtf8Buf::from_bytes_unchecked(s) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,12 +162,12 @@ impl Buf {
|
|||||||
|
|
||||||
impl Slice {
|
impl Slice {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_os_str_bytes(&self) -> &[u8] {
|
pub fn as_encoded_bytes(&self) -> &[u8] {
|
||||||
self.inner.as_bytes()
|
self.inner.as_bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_os_str_bytes_unchecked(s: &[u8]) -> &Slice {
|
pub unsafe fn from_encoded_bytes_unchecked(s: &[u8]) -> &Slice {
|
||||||
mem::transmute(Wtf8::from_bytes_unchecked(s))
|
mem::transmute(Wtf8::from_bytes_unchecked(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,12 +22,12 @@ pub fn is_verbatim_sep(b: u8) -> bool {
|
|||||||
|
|
||||||
/// Returns true if `path` looks like a lone filename.
|
/// Returns true if `path` looks like a lone filename.
|
||||||
pub(crate) fn is_file_name(path: &OsStr) -> bool {
|
pub(crate) fn is_file_name(path: &OsStr) -> bool {
|
||||||
!path.as_os_str_bytes().iter().copied().any(is_sep_byte)
|
!path.as_encoded_bytes().iter().copied().any(is_sep_byte)
|
||||||
}
|
}
|
||||||
pub(crate) fn has_trailing_slash(path: &OsStr) -> bool {
|
pub(crate) fn has_trailing_slash(path: &OsStr) -> bool {
|
||||||
let is_verbatim = path.as_os_str_bytes().starts_with(br"\\?\");
|
let is_verbatim = path.as_encoded_bytes().starts_with(br"\\?\");
|
||||||
let is_separator = if is_verbatim { is_verbatim_sep } else { is_sep_byte };
|
let is_separator = if is_verbatim { is_verbatim_sep } else { is_sep_byte };
|
||||||
if let Some(&c) = path.as_os_str_bytes().last() { is_separator(c) } else { false }
|
if let Some(&c) = path.as_encoded_bytes().last() { is_separator(c) } else { false }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Appends a suffix to a path.
|
/// Appends a suffix to a path.
|
||||||
@ -49,7 +49,7 @@ impl<'a, const LEN: usize> PrefixParser<'a, LEN> {
|
|||||||
fn get_prefix(path: &OsStr) -> [u8; LEN] {
|
fn get_prefix(path: &OsStr) -> [u8; LEN] {
|
||||||
let mut prefix = [0; LEN];
|
let mut prefix = [0; LEN];
|
||||||
// SAFETY: Only ASCII characters are modified.
|
// SAFETY: Only ASCII characters are modified.
|
||||||
for (i, &ch) in path.as_os_str_bytes().iter().take(LEN).enumerate() {
|
for (i, &ch) in path.as_encoded_bytes().iter().take(LEN).enumerate() {
|
||||||
prefix[i] = if ch == b'/' { b'\\' } else { ch };
|
prefix[i] = if ch == b'/' { b'\\' } else { ch };
|
||||||
}
|
}
|
||||||
prefix
|
prefix
|
||||||
@ -82,7 +82,7 @@ impl<'a> PrefixParserSlice<'a, '_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn prefix_bytes(&self) -> &'a [u8] {
|
fn prefix_bytes(&self) -> &'a [u8] {
|
||||||
&self.path.as_os_str_bytes()[..self.index]
|
&self.path.as_encoded_bytes()[..self.index]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish(self) -> &'a OsStr {
|
fn finish(self) -> &'a OsStr {
|
||||||
@ -90,7 +90,7 @@ impl<'a> PrefixParserSlice<'a, '_> {
|
|||||||
// &[u8] and back. This is safe to do because (1) we only look at ASCII
|
// &[u8] and back. This is safe to do because (1) we only look at ASCII
|
||||||
// contents of the encoding and (2) new &OsStr values are produced only
|
// contents of the encoding and (2) new &OsStr values are produced only
|
||||||
// from ASCII-bounded slices of existing &OsStr values.
|
// from ASCII-bounded slices of existing &OsStr values.
|
||||||
unsafe { OsStr::from_os_str_bytes_unchecked(&self.path.as_os_str_bytes()[self.index..]) }
|
unsafe { OsStr::from_encoded_bytes_unchecked(&self.path.as_encoded_bytes()[self.index..]) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ fn parse_drive(path: &OsStr) -> Option<u8> {
|
|||||||
drive.is_ascii_alphabetic()
|
drive.is_ascii_alphabetic()
|
||||||
}
|
}
|
||||||
|
|
||||||
match path.as_os_str_bytes() {
|
match path.as_encoded_bytes() {
|
||||||
[drive, b':', ..] if is_valid_drive_letter(drive) => Some(drive.to_ascii_uppercase()),
|
[drive, b':', ..] if is_valid_drive_letter(drive) => Some(drive.to_ascii_uppercase()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
@ -171,7 +171,7 @@ fn parse_drive(path: &OsStr) -> Option<u8> {
|
|||||||
// Parses a drive prefix exactly, e.g. "C:"
|
// Parses a drive prefix exactly, e.g. "C:"
|
||||||
fn parse_drive_exact(path: &OsStr) -> Option<u8> {
|
fn parse_drive_exact(path: &OsStr) -> Option<u8> {
|
||||||
// only parse two bytes: the drive letter and the drive separator
|
// only parse two bytes: the drive letter and the drive separator
|
||||||
if path.as_os_str_bytes().get(2).map(|&x| is_sep_byte(x)).unwrap_or(true) {
|
if path.as_encoded_bytes().get(2).map(|&x| is_sep_byte(x)).unwrap_or(true) {
|
||||||
parse_drive(path)
|
parse_drive(path)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -185,15 +185,15 @@ fn parse_drive_exact(path: &OsStr) -> Option<u8> {
|
|||||||
fn parse_next_component(path: &OsStr, verbatim: bool) -> (&OsStr, &OsStr) {
|
fn parse_next_component(path: &OsStr, verbatim: bool) -> (&OsStr, &OsStr) {
|
||||||
let separator = if verbatim { is_verbatim_sep } else { is_sep_byte };
|
let separator = if verbatim { is_verbatim_sep } else { is_sep_byte };
|
||||||
|
|
||||||
match path.as_os_str_bytes().iter().position(|&x| separator(x)) {
|
match path.as_encoded_bytes().iter().position(|&x| separator(x)) {
|
||||||
Some(separator_start) => {
|
Some(separator_start) => {
|
||||||
let separator_end = separator_start + 1;
|
let separator_end = separator_start + 1;
|
||||||
|
|
||||||
let component = &path.as_os_str_bytes()[..separator_start];
|
let component = &path.as_encoded_bytes()[..separator_start];
|
||||||
|
|
||||||
// Panic safe
|
// Panic safe
|
||||||
// The max `separator_end` is `bytes.len()` and `bytes[bytes.len()..]` is a valid index.
|
// The max `separator_end` is `bytes.len()` and `bytes[bytes.len()..]` is a valid index.
|
||||||
let path = &path.as_os_str_bytes()[separator_end..];
|
let path = &path.as_encoded_bytes()[separator_end..];
|
||||||
|
|
||||||
// SAFETY: `path` is a valid wtf8 encoded slice and each of the separators ('/', '\')
|
// SAFETY: `path` is a valid wtf8 encoded slice and each of the separators ('/', '\')
|
||||||
// is encoded in a single byte, therefore `bytes[separator_start]` and
|
// is encoded in a single byte, therefore `bytes[separator_start]` and
|
||||||
@ -201,8 +201,8 @@ fn parse_next_component(path: &OsStr, verbatim: bool) -> (&OsStr, &OsStr) {
|
|||||||
// `bytes[..separator_start]` and `bytes[separator_end..]` are valid wtf8 slices.
|
// `bytes[..separator_start]` and `bytes[separator_end..]` are valid wtf8 slices.
|
||||||
unsafe {
|
unsafe {
|
||||||
(
|
(
|
||||||
OsStr::from_os_str_bytes_unchecked(component),
|
OsStr::from_encoded_bytes_unchecked(component),
|
||||||
OsStr::from_os_str_bytes_unchecked(path),
|
OsStr::from_encoded_bytes_unchecked(path),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -323,7 +323,7 @@ pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
|
|||||||
// Verbatim paths should not be modified.
|
// Verbatim paths should not be modified.
|
||||||
if prefix.map(|x| x.is_verbatim()).unwrap_or(false) {
|
if prefix.map(|x| x.is_verbatim()).unwrap_or(false) {
|
||||||
// NULs in verbatim paths are rejected for consistency.
|
// NULs in verbatim paths are rejected for consistency.
|
||||||
if path.as_os_str_bytes().contains(&0) {
|
if path.as_encoded_bytes().contains(&0) {
|
||||||
return Err(io::const_io_error!(
|
return Err(io::const_io_error!(
|
||||||
io::ErrorKind::InvalidInput,
|
io::ErrorKind::InvalidInput,
|
||||||
"strings passed to WinAPI cannot contain NULs",
|
"strings passed to WinAPI cannot contain NULs",
|
||||||
|
@ -429,7 +429,7 @@ fn resolve_exe<'a>(
|
|||||||
// Test if the file name has the `exe` extension.
|
// Test if the file name has the `exe` extension.
|
||||||
// This does a case-insensitive `ends_with`.
|
// This does a case-insensitive `ends_with`.
|
||||||
let has_exe_suffix = if exe_path.len() >= EXE_SUFFIX.len() {
|
let has_exe_suffix = if exe_path.len() >= EXE_SUFFIX.len() {
|
||||||
exe_path.as_os_str_bytes()[exe_path.len() - EXE_SUFFIX.len()..]
|
exe_path.as_encoded_bytes()[exe_path.len() - EXE_SUFFIX.len()..]
|
||||||
.eq_ignore_ascii_case(EXE_SUFFIX.as_bytes())
|
.eq_ignore_ascii_case(EXE_SUFFIX.as_bytes())
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@ -459,7 +459,7 @@ fn resolve_exe<'a>(
|
|||||||
// From the `CreateProcessW` docs:
|
// From the `CreateProcessW` docs:
|
||||||
// > If the file name does not contain an extension, .exe is appended.
|
// > If the file name does not contain an extension, .exe is appended.
|
||||||
// Note that this rule only applies when searching paths.
|
// Note that this rule only applies when searching paths.
|
||||||
let has_extension = exe_path.as_os_str_bytes().contains(&b'.');
|
let has_extension = exe_path.as_encoded_bytes().contains(&b'.');
|
||||||
|
|
||||||
// Search the directories given by `search_paths`.
|
// Search the directories given by `search_paths`.
|
||||||
let result = search_paths(parent_paths, child_paths, |mut path| {
|
let result = search_paths(parent_paths, child_paths, |mut path| {
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#![feature(yeet_expr)]
|
#![feature(yeet_expr)]
|
||||||
#![feature(nonzero_ops)]
|
#![feature(nonzero_ops)]
|
||||||
#![feature(round_ties_even)]
|
#![feature(round_ties_even)]
|
||||||
#![feature(os_str_bytes)]
|
|
||||||
#![feature(lint_reasons)]
|
#![feature(lint_reasons)]
|
||||||
#![feature(trait_upcasting)]
|
#![feature(trait_upcasting)]
|
||||||
// Configure clippy and other lints
|
// Configure clippy and other lints
|
||||||
|
@ -24,7 +24,7 @@ pub fn bytes_to_os_str<'tcx>(bytes: &[u8]) -> InterpResult<'tcx, &OsStr> {
|
|||||||
}
|
}
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
pub fn bytes_to_os_str<'tcx>(bytes: &[u8]) -> InterpResult<'tcx, &OsStr> {
|
pub fn bytes_to_os_str<'tcx>(bytes: &[u8]) -> InterpResult<'tcx, &OsStr> {
|
||||||
// We cannot use `from_os_str_bytes_unchecked` here since we can't trust `bytes`.
|
// We cannot use `from_encoded_bytes_unchecked` here since we can't trust `bytes`.
|
||||||
let s = std::str::from_utf8(bytes)
|
let s = std::str::from_utf8(bytes)
|
||||||
.map_err(|_| err_unsup_format!("{:?} is not a valid utf-8 string", bytes))?;
|
.map_err(|_| err_unsup_format!("{:?} is not a valid utf-8 string", bytes))?;
|
||||||
Ok(OsStr::new(s))
|
Ok(OsStr::new(s))
|
||||||
@ -83,7 +83,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
ptr: Pointer<Option<Provenance>>,
|
ptr: Pointer<Option<Provenance>>,
|
||||||
size: u64,
|
size: u64,
|
||||||
) -> InterpResult<'tcx, (bool, u64)> {
|
) -> InterpResult<'tcx, (bool, u64)> {
|
||||||
let bytes = os_str.as_os_str_bytes();
|
let bytes = os_str.as_encoded_bytes();
|
||||||
self.eval_context_mut().write_c_str(bytes, ptr, size)
|
self.eval_context_mut().write_c_str(bytes, ptr, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1344,7 +1344,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
|
|
||||||
let mut name = dir_entry.file_name(); // not a Path as there are no separators!
|
let mut name = dir_entry.file_name(); // not a Path as there are no separators!
|
||||||
name.push("\0"); // Add a NUL terminator
|
name.push("\0"); // Add a NUL terminator
|
||||||
let name_bytes = name.as_os_str_bytes();
|
let name_bytes = name.as_encoded_bytes();
|
||||||
let name_len = u64::try_from(name_bytes.len()).unwrap();
|
let name_len = u64::try_from(name_bytes.len()).unwrap();
|
||||||
|
|
||||||
let dirent64_layout = this.libc_ty_layout("dirent64");
|
let dirent64_layout = this.libc_ty_layout("dirent64");
|
||||||
@ -1698,7 +1698,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
Cow::Borrowed(resolved.as_ref()),
|
Cow::Borrowed(resolved.as_ref()),
|
||||||
crate::shims::os_str::PathConversion::HostToTarget,
|
crate::shims::os_str::PathConversion::HostToTarget,
|
||||||
);
|
);
|
||||||
let mut path_bytes = resolved.as_os_str_bytes();
|
let mut path_bytes = resolved.as_encoded_bytes();
|
||||||
let bufsize: usize = bufsize.try_into().unwrap();
|
let bufsize: usize = bufsize.try_into().unwrap();
|
||||||
if path_bytes.len() > bufsize {
|
if path_bytes.len() > bufsize {
|
||||||
path_bytes = &path_bytes[..bufsize]
|
path_bytes = &path_bytes[..bufsize]
|
||||||
|
@ -6,7 +6,7 @@ use super::miri_extern;
|
|||||||
pub fn host_to_target_path(path: OsString) -> PathBuf {
|
pub fn host_to_target_path(path: OsString) -> PathBuf {
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
|
|
||||||
// Once into_os_str_bytes is stable we can use it here.
|
// Once into_encoded_bytes is stable we can use it here.
|
||||||
// (Unstable features would need feature flags in each test...)
|
// (Unstable features would need feature flags in each test...)
|
||||||
let path = CString::new(path.into_string().unwrap()).unwrap();
|
let path = CString::new(path.into_string().unwrap()).unwrap();
|
||||||
let mut out = Vec::with_capacity(1024);
|
let mut out = Vec::with_capacity(1024);
|
||||||
|
@ -585,7 +585,7 @@ cc = ["@nnethercote"]
|
|||||||
[assign]
|
[assign]
|
||||||
warn_non_default_branch = true
|
warn_non_default_branch = true
|
||||||
contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
|
contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
|
||||||
users_on_vacation = ["jyn514", "clubby789"]
|
users_on_vacation = ["jyn514", "clubby789", "spastorino"]
|
||||||
|
|
||||||
[assign.adhoc_groups]
|
[assign.adhoc_groups]
|
||||||
compiler-team = [
|
compiler-team = [
|
||||||
|
Loading…
Reference in New Issue
Block a user