Skip to content

Implement ByteStr and ByteString types #135073

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

Merged
merged 8 commits into from
Jan 24, 2025
702 changes: 702 additions & 0 deletions library/alloc/src/bstr.rs

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -102,6 +102,8 @@
#![feature(async_fn_traits)]
#![feature(async_iterator)]
#![feature(box_uninit_write)]
#![feature(bstr)]
#![feature(bstr_internals)]
#![feature(clone_to_uninit)]
#![feature(coerce_unsized)]
#![feature(const_eval_select)]
@@ -226,6 +228,8 @@ mod boxed {
pub use std::boxed::Box;
}
pub mod borrow;
#[unstable(feature = "bstr", issue = "134915")]
pub mod bstr;
pub mod collections;
#[cfg(all(not(no_rc), not(no_sync), not(no_global_oom_handling)))]
pub mod ffi;
581 changes: 581 additions & 0 deletions library/core/src/bstr.rs

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions library/core/src/clone.rs
Original file line number Diff line number Diff line change
@@ -311,6 +311,16 @@ unsafe impl CloneToUninit for crate::ffi::CStr {
}
}

#[unstable(feature = "bstr", issue = "134915")]
unsafe impl CloneToUninit for crate::bstr::ByteStr {
#[inline]
#[cfg_attr(debug_assertions, track_caller)]
unsafe fn clone_to_uninit(&self, dst: *mut u8) {
// SAFETY: ByteStr is a `#[repr(transparent)]` wrapper around `[u8]`
unsafe { self.as_bytes().clone_to_uninit(dst) }
}
}

/// Implementations of `Clone` for primitive types.
///
/// Implementations that cannot be described in Rust
4 changes: 4 additions & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -110,6 +110,8 @@
#![feature(array_ptr_get)]
#![feature(asm_experimental_arch)]
#![feature(bigint_helper_methods)]
#![feature(bstr)]
#![feature(bstr_internals)]
#![feature(const_carrying_mul_add)]
#![feature(const_eval_select)]
#![feature(core_intrinsics)]
@@ -335,6 +337,8 @@ pub mod ascii;
pub mod asserting;
#[unstable(feature = "async_iterator", issue = "79024")]
pub mod async_iter;
#[unstable(feature = "bstr", issue = "134915")]
pub mod bstr;
pub mod cell;
pub mod char;
pub mod ffi;
54 changes: 54 additions & 0 deletions library/core/tests/bstr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#![feature(bstr)]

use core::ByteStr;

#[test]
fn test_debug() {
assert_eq!(
r#""\0\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x11\x12\r\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f \x7f\x80\x81\xfe\xff""#,
format!("{:?}", ByteStr::new(b"\0\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x11\x12\r\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f \x7f\x80\x81\xfe\xff")),
);
}

#[test]
fn test_display() {
let b1 = ByteStr::new("abc");
let b2 = ByteStr::new(b"\xf0\x28\x8c\xbc");

assert_eq!(&format!("{b1}"), "abc");
assert_eq!(&format!("{b2}"), "�(��");

assert_eq!(&format!("{b1:<7}!"), "abc !");
assert_eq!(&format!("{b1:>7}!"), " abc!");
assert_eq!(&format!("{b1:^7}!"), " abc !");
assert_eq!(&format!("{b1:^6}!"), " abc !");
assert_eq!(&format!("{b1:-<7}!"), "abc----!");
assert_eq!(&format!("{b1:->7}!"), "----abc!");
assert_eq!(&format!("{b1:-^7}!"), "--abc--!");
assert_eq!(&format!("{b1:-^6}!"), "-abc--!");

assert_eq!(&format!("{b2:<7}!"), "�(�� !");
assert_eq!(&format!("{b2:>7}!"), " �(��!");
assert_eq!(&format!("{b2:^7}!"), " �(�� !");
assert_eq!(&format!("{b2:^6}!"), " �(�� !");
assert_eq!(&format!("{b2:-<7}!"), "�(��---!");
assert_eq!(&format!("{b2:->7}!"), "---�(��!");
assert_eq!(&format!("{b2:-^7}!"), "-�(��--!");
assert_eq!(&format!("{b2:-^6}!"), "-�(��-!");

assert_eq!(&format!("{b1:<2}!"), "abc!");
assert_eq!(&format!("{b1:>2}!"), "abc!");
assert_eq!(&format!("{b1:^2}!"), "abc!");
assert_eq!(&format!("{b1:-<2}!"), "abc!");
assert_eq!(&format!("{b1:->2}!"), "abc!");
assert_eq!(&format!("{b1:-^2}!"), "abc!");

assert_eq!(&format!("{b2:<3}!"), "�(��!");
assert_eq!(&format!("{b2:>3}!"), "�(��!");
assert_eq!(&format!("{b2:^3}!"), "�(��!");
assert_eq!(&format!("{b2:^2}!"), "�(��!");
assert_eq!(&format!("{b2:-<3}!"), "�(��!");
assert_eq!(&format!("{b2:->3}!"), "�(��!");
assert_eq!(&format!("{b2:-^3}!"), "�(��!");
assert_eq!(&format!("{b2:-^2}!"), "�(��!");
}
4 changes: 4 additions & 0 deletions library/std/src/bstr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//! The `ByteStr` and `ByteString` types and trait implementations.
#[unstable(feature = "bstr", issue = "134915")]
pub use alloc::bstr::{ByteStr, ByteString};
4 changes: 4 additions & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
@@ -320,6 +320,8 @@
// Library features (core):
// tidy-alphabetical-start
#![feature(array_chunks)]
#![feature(bstr)]
#![feature(bstr_internals)]
#![feature(c_str_module)]
#![feature(char_internals)]
#![feature(clone_to_uninit)]
@@ -580,6 +582,8 @@ pub mod f64;
pub mod thread;
pub mod ascii;
pub mod backtrace;
#[unstable(feature = "bstr", issue = "134915")]
pub mod bstr;
pub mod collections;
pub mod env;
pub mod error;
23 changes: 23 additions & 0 deletions src/tools/linkchecker/main.rs
Original file line number Diff line number Diff line change
@@ -50,6 +50,29 @@ const LINKCHECK_EXCEPTIONS: &[(&str, &[&str])] = &[
("alloc/slice/trait.Concat.html", &["#method.concat"]),
("alloc/slice/index.html", &["#method.concat", "#method.join"]),
("alloc/vec/struct.Vec.html", &["#method.sort_by_key", "#method.sort_by_cached_key"]),
("alloc/bstr/struct.ByteStr.html", &[
"#method.to_ascii_uppercase",
"#method.to_ascii_lowercase",
"core/slice::sort_by_key",
"core\\slice::sort_by_key",
"#method.sort_by_cached_key",
"#method.sort_by_key"
]),
("alloc/bstr/struct.ByteString.html", &[
"#method.to_ascii_uppercase",
"#method.to_ascii_lowercase",
"core/slice::sort_by_key",
"core\\slice::sort_by_key",
"#method.sort_by_cached_key",
"#method.sort_by_key"
]),
("core/bstr/struct.ByteStr.html", &[
"#method.to_ascii_uppercase",
"#method.to_ascii_lowercase",
"core/bstr/slice::sort_by_key",
"core\\bstr\\slice::sort_by_key",
"#method.sort_by_cached_key"
]),
("core/primitive.str.html", &["#method.to_ascii_uppercase", "#method.to_ascii_lowercase"]),
("core/primitive.slice.html", &["#method.to_ascii_uppercase", "#method.to_ascii_lowercase",
"core/slice::sort_by_key", "core\\slice::sort_by_key",
Original file line number Diff line number Diff line change
@@ -40,14 +40,14 @@ LL | type X = std::ops::Deref::Target;
|
help: use fully-qualified syntax
|
LL | type X = <ByteStr as Deref>::Target;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | type X = <ByteString as Deref>::Target;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | type X = <CString as Deref>::Target;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | type X = <IoSlice<'_> as Deref>::Target;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | type X = <IoSliceMut<'_> as Deref>::Target;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | type X = <OsString as Deref>::Target;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~
and N other candidates

error: aborting due to 5 previous errors
10 changes: 5 additions & 5 deletions tests/ui/consts/too_generic_eval_ice.stderr
Original file line number Diff line number Diff line change
@@ -32,13 +32,13 @@ LL | [5; Self::HOST_SIZE] == [6; 0]
= help: the following other types implement trait `PartialEq<Rhs>`:
`&[T]` implements `PartialEq<Vec<U, A>>`
`&[T]` implements `PartialEq<[U; N]>`
`&[u8; N]` implements `PartialEq<ByteStr>`
`&[u8; N]` implements `PartialEq<ByteString>`
`&[u8]` implements `PartialEq<ByteStr>`
`&[u8]` implements `PartialEq<ByteString>`
`&mut [T]` implements `PartialEq<Vec<U, A>>`
`&mut [T]` implements `PartialEq<[U; N]>`
`[T; N]` implements `PartialEq<&[U]>`
`[T; N]` implements `PartialEq<&mut [U]>`
`[T; N]` implements `PartialEq<[U; N]>`
`[T; N]` implements `PartialEq<[U]>`
and 3 others
and 11 others

error: aborting due to 4 previous errors

13 changes: 8 additions & 5 deletions tests/ui/inference/issue-72616.stderr
Original file line number Diff line number Diff line change
@@ -6,11 +6,14 @@ LL | if String::from("a") == "a".try_into().unwrap() {}
| |
| type must be known at this point
|
= note: multiple `impl`s satisfying `String: PartialEq<_>` found in the `alloc` crate:
- impl PartialEq for String;
- impl<'a, 'b> PartialEq<&'a str> for String;
- impl<'a, 'b> PartialEq<Cow<'a, str>> for String;
- impl<'a, 'b> PartialEq<str> for String;
= note: cannot satisfy `String: PartialEq<_>`
= help: the following types implement trait `PartialEq<Rhs>`:
`String` implements `PartialEq<&str>`
`String` implements `PartialEq<ByteStr>`
`String` implements `PartialEq<ByteString>`
`String` implements `PartialEq<Cow<'_, str>>`
`String` implements `PartialEq<str>`
`String` implements `PartialEq`
help: try using a fully qualified path to specify the expected types
|
LL | if String::from("a") == <&str as TryInto<T>>::try_into("a").unwrap() {}
9 changes: 9 additions & 0 deletions tests/ui/inference/issue-72690.stderr
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@ LL | String::from("x".as_ref());
| ^^^^^^
|
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
- impl AsRef<ByteStr> for str;
- impl AsRef<OsStr> for str;
- impl AsRef<Path> for str;
- impl AsRef<[u8]> for str;
@@ -41,6 +42,7 @@ LL | |x| String::from("x".as_ref());
| ^^^^^^
|
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
- impl AsRef<ByteStr> for str;
- impl AsRef<OsStr> for str;
- impl AsRef<Path> for str;
- impl AsRef<[u8]> for str;
@@ -57,6 +59,7 @@ LL | let _ = "x".as_ref();
| ^ ------ type must be known at this point
|
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
- impl AsRef<ByteStr> for str;
- impl AsRef<OsStr> for str;
- impl AsRef<Path> for str;
- impl AsRef<[u8]> for str;
@@ -83,6 +86,7 @@ LL | String::from("x".as_ref());
| ^^^^^^
|
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
- impl AsRef<ByteStr> for str;
- impl AsRef<OsStr> for str;
- impl AsRef<Path> for str;
- impl AsRef<[u8]> for str;
@@ -109,6 +113,7 @@ LL | String::from("x".as_ref());
| ^^^^^^
|
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
- impl AsRef<ByteStr> for str;
- impl AsRef<OsStr> for str;
- impl AsRef<Path> for str;
- impl AsRef<[u8]> for str;
@@ -135,6 +140,7 @@ LL | String::from("x".as_ref());
| ^^^^^^
|
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
- impl AsRef<ByteStr> for str;
- impl AsRef<OsStr> for str;
- impl AsRef<Path> for str;
- impl AsRef<[u8]> for str;
@@ -161,6 +167,7 @@ LL | String::from("x".as_ref());
| ^^^^^^
|
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
- impl AsRef<ByteStr> for str;
- impl AsRef<OsStr> for str;
- impl AsRef<Path> for str;
- impl AsRef<[u8]> for str;
@@ -187,6 +194,7 @@ LL | String::from("x".as_ref());
| ^^^^^^
|
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
- impl AsRef<ByteStr> for str;
- impl AsRef<OsStr> for str;
- impl AsRef<Path> for str;
- impl AsRef<[u8]> for str;
@@ -213,6 +221,7 @@ LL | String::from("x".as_ref());
| ^^^^^^
|
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
- impl AsRef<ByteStr> for str;
- impl AsRef<OsStr> for str;
- impl AsRef<Path> for str;
- impl AsRef<[u8]> for str;