Skip to content

Commit eee1d47

Browse files
author
Robert Bastian
committed
str
1 parent 7caad69 commit eee1d47

35 files changed

+292
-74
lines changed

compiler/rustc_feature/src/unstable.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,8 @@ declare_features! (
497497
(unstable, impl_trait_in_fn_trait_return, "1.64.0", Some(99697)),
498498
/// Allows associated types in inherent impls.
499499
(incomplete, inherent_associated_types, "1.52.0", Some(8995)),
500+
/// Adds `from_utf8*` functions as inherent methods on the `str` type.
501+
(unstable, inherent_str_constructors, "1.82.0", Some(131114)),
500502
/// Allow anonymous constants from an inline `const` block in pattern position
501503
(unstable, inline_const_pat, "1.58.0", Some(76001)),
502504
/// Allows using `pointer` and `reference` in intra-doc links

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,7 @@ symbols! {
10671067
infer_outlives_requirements,
10681068
infer_static_outlives_requirements,
10691069
inherent_associated_types,
1070+
inherent_str_constructors,
10701071
inherit,
10711072
inlateout,
10721073
inline,

library/alloc/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@
127127
#![feature(fmt_internals)]
128128
#![feature(fn_traits)]
129129
#![feature(hasher_prefixfree_extras)]
130+
#![feature(inherent_str_constructors)]
130131
#![feature(inplace_iteration)]
131132
#![feature(iter_advance_by)]
132133
#![feature(iter_next_chunk)]

library/alloc/src/str.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use core::iter::FusedIterator;
1212
use core::mem::MaybeUninit;
1313
#[stable(feature = "encode_utf16", since = "1.8.0")]
1414
pub use core::str::EncodeUtf16;
15+
#[stable(feature = "rust1", since = "1.0.0")]
16+
pub use core::str::ParseBoolError;
1517
#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
1618
pub use core::str::SplitAsciiWhitespace;
1719
#[stable(feature = "split_inclusive", since = "1.51.0")]
@@ -22,7 +24,7 @@ pub use core::str::SplitWhitespace;
2224
pub use core::str::pattern;
2325
use core::str::pattern::{DoubleEndedSearcher, Pattern, ReverseSearcher, Searcher};
2426
#[stable(feature = "rust1", since = "1.0.0")]
25-
pub use core::str::{Bytes, CharIndices, Chars, from_utf8, from_utf8_mut};
27+
pub use core::str::{Bytes, CharIndices, Chars};
2628
#[stable(feature = "str_escape", since = "1.34.0")]
2729
pub use core::str::{EscapeDebug, EscapeDefault, EscapeUnicode};
2830
#[stable(feature = "rust1", since = "1.0.0")]
@@ -35,8 +37,6 @@ pub use core::str::{MatchIndices, RMatchIndices};
3537
#[stable(feature = "rust1", since = "1.0.0")]
3638
pub use core::str::{Matches, RMatches};
3739
#[stable(feature = "rust1", since = "1.0.0")]
38-
pub use core::str::{ParseBoolError, from_utf8_unchecked, from_utf8_unchecked_mut};
39-
#[stable(feature = "rust1", since = "1.0.0")]
4040
pub use core::str::{RSplit, Split};
4141
#[stable(feature = "rust1", since = "1.0.0")]
4242
pub use core::str::{RSplitN, SplitN};
@@ -46,6 +46,9 @@ pub use core::str::{RSplitTerminator, SplitTerminator};
4646
pub use core::str::{Utf8Chunk, Utf8Chunks};
4747
#[unstable(feature = "str_from_raw_parts", issue = "119206")]
4848
pub use core::str::{from_raw_parts, from_raw_parts_mut};
49+
#[allow(deprecated_in_future)]
50+
#[stable(feature = "rust1", since = "1.0.0")]
51+
pub use core::str::{from_utf8, from_utf8_mut, from_utf8_unchecked, from_utf8_unchecked_mut};
4952
use core::unicode::conversions;
5053
use core::{mem, ptr};
5154

@@ -681,7 +684,7 @@ pub fn convert_while_ascii(s: &str, convert: fn(&u8) -> u8) -> (String, &str) {
681684

682685
// SAFETY: we know this is a valid char boundary
683686
// since we only skipped over leading ascii bytes
684-
let rest = core::str::from_utf8_unchecked(slice);
687+
let rest = str::from_utf8_unchecked(slice);
685688

686689
(ascii_string, rest)
687690
}

library/alloc/src/string.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ use crate::alloc::Allocator;
6262
use crate::borrow::{Cow, ToOwned};
6363
use crate::boxed::Box;
6464
use crate::collections::TryReserveError;
65-
use crate::str::{self, Chars, Utf8Error, from_utf8_unchecked_mut};
65+
use crate::str::{Chars, Utf8Error};
6666
#[cfg(not(no_global_oom_handling))]
6767
use crate::str::{FromStr, from_boxed_utf8_unchecked};
6868
use crate::vec::Vec;
@@ -2055,7 +2055,7 @@ impl String {
20552055
#[inline]
20562056
pub fn leak<'a>(self) -> &'a mut str {
20572057
let slice = self.vec.leak();
2058-
unsafe { from_utf8_unchecked_mut(slice) }
2058+
unsafe { str::from_utf8_unchecked_mut(slice) }
20592059
}
20602060
}
20612061

library/alloc/src/sync.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3482,7 +3482,7 @@ impl Default for Arc<str> {
34823482
#[inline]
34833483
fn default() -> Self {
34843484
let arc: Arc<[u8]> = Default::default();
3485-
debug_assert!(core::str::from_utf8(&*arc).is_ok());
3485+
debug_assert!(str::from_utf8(&*arc).is_ok());
34863486
let (ptr, alloc) = Arc::into_inner_with_allocator(arc);
34873487
unsafe { Arc::from_ptr_in(ptr.as_ptr() as *mut ArcInner<str>, alloc) }
34883488
}

library/core/src/char/methods.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
use super::*;
44
use crate::intrinsics::const_eval_select;
55
use crate::slice;
6-
use crate::str::from_utf8_unchecked_mut;
76
use crate::unicode::printable::is_printable;
87
use crate::unicode::{self, conversions};
98

@@ -678,7 +677,7 @@ impl char {
678677
#[inline]
679678
pub const fn encode_utf8(self, dst: &mut [u8]) -> &mut str {
680679
// SAFETY: `char` is not a surrogate, so this is valid UTF-8.
681-
unsafe { from_utf8_unchecked_mut(encode_utf8_raw(self as u32, dst)) }
680+
unsafe { str::from_utf8_unchecked_mut(encode_utf8_raw(self as u32, dst)) }
682681
}
683682

684683
/// Encodes this character as UTF-16 into the provided `u16` buffer,

library/core/src/ffi/c_str.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::iter::FusedIterator;
77
use crate::marker::PhantomData;
88
use crate::ptr::NonNull;
99
use crate::slice::memchr;
10-
use crate::{fmt, intrinsics, ops, slice, str};
10+
use crate::{fmt, intrinsics, ops, slice};
1111

1212
// FIXME: because this is doc(inline)d, we *have* to use intra-doc links because the actual link
1313
// depends on where the item is being documented. however, since this is libcore, we can't
@@ -664,7 +664,7 @@ impl CStr {
664664
/// ```
665665
#[stable(feature = "cstr_to_str", since = "1.4.0")]
666666
#[rustc_const_stable(feature = "const_cstr_methods", since = "1.72.0")]
667-
pub const fn to_str(&self) -> Result<&str, str::Utf8Error> {
667+
pub const fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
668668
// N.B., when `CStr` is changed to perform the length check in `.to_bytes()`
669669
// instead of in `from_ptr()`, it may be worth considering if this should
670670
// be rewritten to do the UTF-8 check inline with the length calculation

library/core/src/fmt/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::char::EscapeDebugExtArgs;
77
use crate::marker::PhantomData;
88
use crate::num::fmt as numfmt;
99
use crate::ops::Deref;
10-
use crate::{iter, mem, result, str};
10+
use crate::{iter, mem, result};
1111

1212
mod builders;
1313
#[cfg(not(no_fp_fmt_parse))]

library/core/src/fmt/num.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use crate::mem::MaybeUninit;
44
use crate::num::fmt as numfmt;
55
use crate::ops::{Div, Rem, Sub};
6-
use crate::{fmt, ptr, slice, str};
6+
use crate::{fmt, ptr, slice};
77

88
#[doc(hidden)]
99
trait DisplayInt:

library/core/src/net/display_buffer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
use crate::fmt;
12
use crate::mem::MaybeUninit;
2-
use crate::{fmt, str};
33

44
/// Used for slow path in `Display` implementations when alignment is required.
55
pub struct DisplayBuffer<const SIZE: usize> {

library/core/src/slice/ascii.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ impl<'a> fmt::Display for EscapeAscii<'a> {
280280
// SAFETY: prefix length was derived by counting bytes in the same splice, so it's in-bounds
281281
let (prefix, remainder) = unsafe { bytes.split_at_unchecked(prefix) };
282282
// SAFETY: prefix is a valid utf8 sequence, as it's a subset of ASCII
283-
let prefix = unsafe { crate::str::from_utf8_unchecked(prefix) };
283+
let prefix = unsafe { str::from_utf8_unchecked(prefix) };
284284

285285
f.write_str(prefix)?; // the fast part
286286

library/core/src/str/converts.rs

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
//! Ways to create a `str` from bytes slice.
22
33
use super::Utf8Error;
4-
use super::validations::run_utf8_validation;
5-
use crate::{mem, ptr};
4+
use crate::ptr;
65

76
/// Converts a slice of bytes to a string slice.
87
///
@@ -83,16 +82,10 @@ use crate::{mem, ptr};
8382
#[stable(feature = "rust1", since = "1.0.0")]
8483
#[rustc_const_stable(feature = "const_str_from_utf8_shared", since = "1.63.0")]
8584
#[rustc_allow_const_fn_unstable(str_internals)]
86-
#[rustc_diagnostic_item = "str_from_utf8"]
85+
#[deprecated(since = "TBD", note = "replaced by the `from_utf8` method on the `str` type")]
86+
// #[rustc_diagnostic_item = "str_from_utf8"]
8787
pub const fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
88-
// FIXME(const-hack): This should use `?` again, once it's `const`
89-
match run_utf8_validation(v) {
90-
Ok(_) => {
91-
// SAFETY: validation succeeded.
92-
Ok(unsafe { from_utf8_unchecked(v) })
93-
}
94-
Err(err) => Err(err),
95-
}
88+
str::from_utf8(v)
9689
}
9790

9891
/// Converts a mutable slice of bytes to a mutable string slice.
@@ -127,13 +120,14 @@ pub const fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
127120
/// errors that can be returned.
128121
#[stable(feature = "str_mut_extras", since = "1.20.0")]
129122
#[rustc_const_unstable(feature = "const_str_from_utf8", issue = "91006")]
130-
#[rustc_diagnostic_item = "str_from_utf8_mut"]
123+
#[deprecated(since = "TBD", note = "replaced by the `from_utf8_mut` method on the `str` type")]
124+
// #[rustc_diagnostic_item = "str_from_utf8_mut"]
131125
pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
132126
// FIXME(const-hack): This should use `?` again, once it's `const`
133-
match run_utf8_validation(v) {
127+
match super::run_utf8_validation(v) {
134128
Ok(_) => {
135129
// SAFETY: validation succeeded.
136-
Ok(unsafe { from_utf8_unchecked_mut(v) })
130+
Ok(unsafe { str::from_utf8_unchecked_mut(v) })
137131
}
138132
Err(err) => Err(err),
139133
}
@@ -168,11 +162,14 @@ pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
168162
#[must_use]
169163
#[stable(feature = "rust1", since = "1.0.0")]
170164
#[rustc_const_stable(feature = "const_str_from_utf8_unchecked", since = "1.55.0")]
171-
#[rustc_diagnostic_item = "str_from_utf8_unchecked"]
165+
#[deprecated(
166+
since = "TBD",
167+
note = "replaced by the `from_utf8_unchecked` method on the `str` type"
168+
)]
169+
// #[rustc_diagnostic_item = "str_from_utf8_unchecked"]
172170
pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
173-
// SAFETY: the caller must guarantee that the bytes `v` are valid UTF-8.
174-
// Also relies on `&str` and `&[u8]` having the same layout.
175-
unsafe { mem::transmute(v) }
171+
// SAFETY: same requirements
172+
unsafe { str::from_utf8_unchecked(v) }
176173
}
177174

178175
/// Converts a slice of bytes to a string slice without checking
@@ -200,13 +197,14 @@ pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
200197
feature = "const_str_from_utf8_unchecked_mut",
201198
since = "CURRENT_RUSTC_VERSION"
202199
)]
203-
#[rustc_diagnostic_item = "str_from_utf8_unchecked_mut"]
200+
#[deprecated(
201+
since = "TBD",
202+
note = "replaced by the `from_utf8_unchecked_mut` method on the `str` type"
203+
)]
204+
// #[rustc_diagnostic_item = "str_from_utf8_unchecked_mut"]
204205
pub const unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str {
205-
// SAFETY: the caller must guarantee that the bytes `v`
206-
// are valid UTF-8, thus the cast to `*mut str` is safe.
207-
// Also, the pointer dereference is safe because that pointer
208-
// comes from a reference which is guaranteed to be valid for writes.
209-
unsafe { &mut *(v as *mut [u8] as *mut str) }
206+
// SAFETY: same requirements
207+
unsafe { str::from_utf8_unchecked_mut(v) }
210208
}
211209

212210
/// Creates a `&str` from a pointer and a length.

library/core/src/str/iter.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use super::pattern::{DoubleEndedSearcher, Pattern, ReverseSearcher, Searcher};
44
use super::validations::{next_code_point, next_code_point_reverse};
55
use super::{
66
BytesIsNotEmpty, CharEscapeDebugContinue, CharEscapeDefault, CharEscapeUnicode,
7-
IsAsciiWhitespace, IsNotEmpty, IsWhitespace, LinesMap, UnsafeBytesToStr, from_utf8_unchecked,
7+
IsAsciiWhitespace, IsNotEmpty, IsWhitespace, LinesMap, UnsafeBytesToStr,
88
};
99
use crate::fmt::{self, Write};
1010
use crate::iter::{
@@ -158,7 +158,7 @@ impl<'a> Chars<'a> {
158158
#[inline]
159159
pub fn as_str(&self) -> &'a str {
160160
// SAFETY: `Chars` is only made from a str, which guarantees the iter is valid UTF-8.
161-
unsafe { from_utf8_unchecked(self.iter.as_slice()) }
161+
unsafe { str::from_utf8_unchecked(self.iter.as_slice()) }
162162
}
163163
}
164164

@@ -1413,7 +1413,7 @@ impl<'a> SplitAsciiWhitespace<'a> {
14131413
}
14141414

14151415
// SAFETY: Slice is created from str.
1416-
Some(unsafe { crate::str::from_utf8_unchecked(&self.inner.iter.iter.v) })
1416+
Some(unsafe { str::from_utf8_unchecked(&self.inner.iter.iter.v) })
14171417
}
14181418
}
14191419

library/core/src/str/lossy.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use super::from_utf8_unchecked;
21
use super::validations::utf8_char_width;
32
use crate::fmt;
43
use crate::fmt::{Formatter, Write};
@@ -281,7 +280,7 @@ impl<'a> Iterator for Utf8Chunks<'a> {
281280

282281
Some(Utf8Chunk {
283282
// SAFETY: All bytes up to `valid_up_to` are valid UTF-8.
284-
valid: unsafe { from_utf8_unchecked(valid) },
283+
valid: unsafe { str::from_utf8_unchecked(valid) },
285284
invalid,
286285
})
287286
}

0 commit comments

Comments
 (0)