Skip to content

Commit

Permalink
Rollup merge of rust-lang#137155 - thaliaarchi:wtf8-organize, r=Chris…
Browse files Browse the repository at this point in the history
…Denton

Organize `OsString`/`OsStr` shims

Synchronize the `bytes.rs` and `wtf8.rs` shims for `OsString`/`OsStr` so they're easier to diff between each other. This is mostly ordering items the same between the two. I tried to minimize moves and went for the average locations between the files.

With them in the same order, it is clear that `FromInner<_>` is not implemented for `bytes::Buf` and `Clone::clone_from` is not implemented for `wtf8::Buf`, but they are for the other. Fix that.

I added #[inline] to all inherent methods of the `OsString`/`OsStr` shims, because it seemed that was already the rough pattern. `bytes.rs` has more inlining than `wtf8.rs`, so I added the corresponding ones to `wtf8.rs`. Then, the common missing ones have no discernible pattern to me. They're not divided by non-allocating/allocating. Perhaps the pattern is that UTF-8 validation isn't inlined? Since these types are merely the inner values in `OsStr`/`OsString`, I put inline on all methods and let those public types dictate inlining. I have not inspected codegen or run benchmarks.

Also, touch up some (private) documentation comments.

r? ````@ChrisDenton````
  • Loading branch information
matthiaskrgr authored Feb 18, 2025
2 parents 5b12391 + 05e4175 commit 7ecbfe1
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 109 deletions.
86 changes: 50 additions & 36 deletions library/std/src/sys/os_str/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::collections::TryReserveError;
use crate::fmt::Write;
use crate::rc::Rc;
use crate::sync::Arc;
use crate::sys_common::{AsInner, IntoInner};
use crate::sys_common::{AsInner, FromInner, IntoInner};
use crate::{fmt, mem, str};

#[cfg(test)]
Expand All @@ -25,6 +25,37 @@ pub struct Slice {
pub inner: [u8],
}

impl IntoInner<Vec<u8>> for Buf {
fn into_inner(self) -> Vec<u8> {
self.inner
}
}

impl FromInner<Vec<u8>> for Buf {
fn from_inner(inner: Vec<u8>) -> Self {
Buf { inner }
}
}

impl AsInner<[u8]> for Buf {
#[inline]
fn as_inner(&self) -> &[u8] {
&self.inner
}
}

impl fmt::Debug for Buf {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.as_slice(), f)
}
}

impl fmt::Display for Buf {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self.as_slice(), f)
}
}

impl fmt::Debug for Slice {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.inner.utf8_chunks().debug(), f)
Expand Down Expand Up @@ -55,18 +86,6 @@ impl fmt::Display for Slice {
}
}

impl fmt::Debug for Buf {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.as_slice(), formatter)
}
}

impl fmt::Display for Buf {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self.as_slice(), formatter)
}
}

impl Clone for Buf {
#[inline]
fn clone(&self) -> Self {
Expand All @@ -79,19 +98,6 @@ impl Clone for Buf {
}
}

impl IntoInner<Vec<u8>> for Buf {
fn into_inner(self) -> Vec<u8> {
self.inner
}
}

impl AsInner<[u8]> for Buf {
#[inline]
fn as_inner(&self) -> &[u8] {
&self.inner
}
}

impl Buf {
#[inline]
pub fn into_encoded_bytes(self) -> Vec<u8> {
Expand All @@ -103,6 +109,12 @@ impl Buf {
Self { inner: s }
}

#[inline]
pub fn into_string(self) -> Result<String, Buf> {
String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() })
}

#[inline]
pub fn from_string(s: String) -> Buf {
Buf { inner: s.into_bytes() }
}
Expand All @@ -122,6 +134,11 @@ impl Buf {
self.inner.capacity()
}

#[inline]
pub fn push_slice(&mut self, s: &Slice) {
self.inner.extend_from_slice(&s.inner)
}

#[inline]
pub fn reserve(&mut self, additional: usize) {
self.inner.reserve(additional)
Expand Down Expand Up @@ -157,23 +174,15 @@ impl Buf {
// SAFETY: Slice just wraps [u8],
// and &*self.inner is &[u8], therefore
// transmuting &[u8] to &Slice is safe.
unsafe { mem::transmute(&*self.inner) }
unsafe { mem::transmute(self.inner.as_slice()) }
}

#[inline]
pub fn as_mut_slice(&mut self) -> &mut Slice {
// SAFETY: Slice just wraps [u8],
// and &mut *self.inner is &mut [u8], therefore
// transmuting &mut [u8] to &mut Slice is safe.
unsafe { mem::transmute(&mut *self.inner) }
}

pub fn into_string(self) -> Result<String, Buf> {
String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() })
}

pub fn push_slice(&mut self, s: &Slice) {
self.inner.extend_from_slice(&s.inner)
unsafe { mem::transmute(self.inner.as_mut_slice()) }
}

#[inline]
Expand Down Expand Up @@ -278,18 +287,22 @@ impl Slice {
unsafe { Slice::from_encoded_bytes_unchecked(s.as_bytes()) }
}

#[inline]
pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
str::from_utf8(&self.inner)
}

#[inline]
pub fn to_string_lossy(&self) -> Cow<'_, str> {
String::from_utf8_lossy(&self.inner)
}

#[inline]
pub fn to_owned(&self) -> Buf {
Buf { inner: self.inner.to_vec() }
}

#[inline]
pub fn clone_into(&self, buf: &mut Buf) {
self.inner.clone_into(&mut buf.inner)
}
Expand All @@ -300,6 +313,7 @@ impl Slice {
unsafe { mem::transmute(boxed) }
}

#[inline]
pub fn empty_box() -> Box<Slice> {
let boxed: Box<[u8]> = Default::default();
unsafe { mem::transmute(boxed) }
Expand Down
107 changes: 69 additions & 38 deletions library/std/src/sys/os_str/wtf8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@ use crate::sys_common::wtf8::{Wtf8, Wtf8Buf, check_utf8_boundary};
use crate::sys_common::{AsInner, FromInner, IntoInner};
use crate::{fmt, mem};

#[derive(Clone, Hash)]
#[derive(Hash)]
pub struct Buf {
pub inner: Wtf8Buf,
}

#[repr(transparent)]
pub struct Slice {
pub inner: Wtf8,
}

impl IntoInner<Wtf8Buf> for Buf {
fn into_inner(self) -> Wtf8Buf {
self.inner
Expand All @@ -35,31 +40,38 @@ impl AsInner<Wtf8> for Buf {
}

impl fmt::Debug for Buf {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.as_slice(), formatter)
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.as_slice(), f)
}
}

impl fmt::Display for Buf {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self.as_slice(), formatter)
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self.as_slice(), f)
}
}

#[repr(transparent)]
pub struct Slice {
pub inner: Wtf8,
}

impl fmt::Debug for Slice {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.inner, formatter)
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.inner, f)
}
}

impl fmt::Display for Slice {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.inner, formatter)
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.inner, f)
}
}

impl Clone for Buf {
#[inline]
fn clone(&self) -> Self {
Buf { inner: self.inner.clone() }
}

#[inline]
fn clone_from(&mut self, source: &Self) {
self.inner.clone_from(&source.inner)
}
}

Expand All @@ -74,62 +86,57 @@ impl Buf {
unsafe { Self { inner: Wtf8Buf::from_bytes_unchecked(s) } }
}

pub fn with_capacity(capacity: usize) -> Buf {
Buf { inner: Wtf8Buf::with_capacity(capacity) }
}

pub fn clear(&mut self) {
self.inner.clear()
}

pub fn capacity(&self) -> usize {
self.inner.capacity()
#[inline]
pub fn into_string(self) -> Result<String, Buf> {
self.inner.into_string().map_err(|buf| Buf { inner: buf })
}

#[inline]
pub fn from_string(s: String) -> Buf {
Buf { inner: Wtf8Buf::from_string(s) }
}

pub fn as_slice(&self) -> &Slice {
// SAFETY: Slice is just a wrapper for Wtf8,
// and self.inner.as_slice() returns &Wtf8.
// Therefore, transmuting &Wtf8 to &Slice is safe.
unsafe { mem::transmute(self.inner.as_slice()) }
#[inline]
pub fn with_capacity(capacity: usize) -> Buf {
Buf { inner: Wtf8Buf::with_capacity(capacity) }
}

pub fn as_mut_slice(&mut self) -> &mut Slice {
// SAFETY: Slice is just a wrapper for Wtf8,
// and self.inner.as_mut_slice() returns &mut Wtf8.
// Therefore, transmuting &mut Wtf8 to &mut Slice is safe.
// Additionally, care should be taken to ensure the slice
// is always valid Wtf8.
unsafe { mem::transmute(self.inner.as_mut_slice()) }
#[inline]
pub fn clear(&mut self) {
self.inner.clear()
}

pub fn into_string(self) -> Result<String, Buf> {
self.inner.into_string().map_err(|buf| Buf { inner: buf })
#[inline]
pub fn capacity(&self) -> usize {
self.inner.capacity()
}

#[inline]
pub fn push_slice(&mut self, s: &Slice) {
self.inner.push_wtf8(&s.inner)
}

#[inline]
pub fn reserve(&mut self, additional: usize) {
self.inner.reserve(additional)
}

#[inline]
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.inner.try_reserve(additional)
}

#[inline]
pub fn reserve_exact(&mut self, additional: usize) {
self.inner.reserve_exact(additional)
}

#[inline]
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.inner.try_reserve_exact(additional)
}

#[inline]
pub fn shrink_to_fit(&mut self) {
self.inner.shrink_to_fit()
}
Expand All @@ -139,6 +146,24 @@ impl Buf {
self.inner.shrink_to(min_capacity)
}

#[inline]
pub fn as_slice(&self) -> &Slice {
// SAFETY: Slice is just a wrapper for Wtf8,
// and self.inner.as_slice() returns &Wtf8.
// Therefore, transmuting &Wtf8 to &Slice is safe.
unsafe { mem::transmute(self.inner.as_slice()) }
}

#[inline]
pub fn as_mut_slice(&mut self) -> &mut Slice {
// SAFETY: Slice is just a wrapper for Wtf8,
// and self.inner.as_mut_slice() returns &mut Wtf8.
// Therefore, transmuting &mut Wtf8 to &mut Slice is safe.
// Additionally, care should be taken to ensure the slice
// is always valid Wtf8.
unsafe { mem::transmute(self.inner.as_mut_slice()) }
}

#[inline]
pub fn leak<'a>(self) -> &'a mut Slice {
unsafe { mem::transmute(self.inner.leak()) }
Expand Down Expand Up @@ -194,6 +219,7 @@ impl Slice {
}

#[track_caller]
#[inline]
pub fn check_public_boundary(&self, index: usize) {
check_utf8_boundary(&self.inner, index);
}
Expand All @@ -203,18 +229,22 @@ impl Slice {
unsafe { mem::transmute(Wtf8::from_str(s)) }
}

#[inline]
pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
self.inner.as_str()
}

#[inline]
pub fn to_string_lossy(&self) -> Cow<'_, str> {
self.inner.to_string_lossy()
}

#[inline]
pub fn to_owned(&self) -> Buf {
Buf { inner: self.inner.to_owned() }
}

#[inline]
pub fn clone_into(&self, buf: &mut Buf) {
self.inner.clone_into(&mut buf.inner)
}
Expand All @@ -224,6 +254,7 @@ impl Slice {
unsafe { mem::transmute(self.inner.into_box()) }
}

#[inline]
pub fn empty_box() -> Box<Slice> {
unsafe { mem::transmute(Wtf8::empty_box()) }
}
Expand Down
Loading

0 comments on commit 7ecbfe1

Please sign in to comment.