Skip to content

Commit e94c080

Browse files
bjoernagerdtolnay
authored andcommitted
Mark and implement 'char::encode_utf8' as const.
1 parent 8a5922f commit e94c080

File tree

2 files changed

+15
-18
lines changed

2 files changed

+15
-18
lines changed

core/src/char/methods.rs

+14-18
Original file line numberDiff line numberDiff line change
@@ -672,8 +672,9 @@ impl char {
672672
/// 'ß'.encode_utf8(&mut b);
673673
/// ```
674674
#[stable(feature = "unicode_encode_char", since = "1.15.0")]
675+
#[rustc_const_unstable(feature = "const_char_encode_utf8", issue = "130512")]
675676
#[inline]
676-
pub fn encode_utf8(self, dst: &mut [u8]) -> &mut str {
677+
pub const fn encode_utf8(self, dst: &mut [u8]) -> &mut str {
677678
// SAFETY: `char` is not a surrogate, so this is valid UTF-8.
678679
unsafe { from_utf8_unchecked_mut(encode_utf8_raw(self as u32, dst)) }
679680
}
@@ -1735,14 +1736,11 @@ impl EscapeDebugExtArgs {
17351736

17361737
#[inline]
17371738
const fn len_utf8(code: u32) -> usize {
1738-
if code < MAX_ONE_B {
1739-
1
1740-
} else if code < MAX_TWO_B {
1741-
2
1742-
} else if code < MAX_THREE_B {
1743-
3
1744-
} else {
1745-
4
1739+
match code {
1740+
..MAX_ONE_B => 1,
1741+
..MAX_TWO_B => 2,
1742+
..MAX_THREE_B => 3,
1743+
_ => 4,
17461744
}
17471745
}
17481746

@@ -1760,11 +1758,12 @@ const fn len_utf8(code: u32) -> usize {
17601758
/// Panics if the buffer is not large enough.
17611759
/// A buffer of length four is large enough to encode any `char`.
17621760
#[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
1761+
#[rustc_const_unstable(feature = "const_char_encode_utf8", issue = "130512")]
17631762
#[doc(hidden)]
17641763
#[inline]
1765-
pub fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] {
1764+
pub const fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] {
17661765
let len = len_utf8(code);
1767-
match (len, &mut dst[..]) {
1766+
match (len, &mut *dst) {
17681767
(1, [a, ..]) => {
17691768
*a = code as u8;
17701769
}
@@ -1783,14 +1782,11 @@ pub fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] {
17831782
*c = (code >> 6 & 0x3F) as u8 | TAG_CONT;
17841783
*d = (code & 0x3F) as u8 | TAG_CONT;
17851784
}
1786-
_ => panic!(
1787-
"encode_utf8: need {} bytes to encode U+{:X}, but the buffer has {}",
1788-
len,
1789-
code,
1790-
dst.len(),
1791-
),
1785+
// Note that we cannot format in constant expressions.
1786+
_ => panic!("encode_utf8: buffer does not have enough bytes to encode code point"),
17921787
};
1793-
&mut dst[..len]
1788+
// SAFETY: `<&mut [u8]>::as_mut_ptr` is guaranteed to return a valid pointer and `len` has been tested to be within bounds.
1789+
unsafe { slice::from_raw_parts_mut(dst.as_mut_ptr(), len) }
17941790
}
17951791

17961792
/// Encodes a raw u32 value as UTF-16 into the provided `u16` buffer,

core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
#![feature(const_bigint_helper_methods)]
120120
#![feature(const_black_box)]
121121
#![feature(const_cell_into_inner)]
122+
#![feature(const_char_encode_utf8)]
122123
#![feature(const_eval_select)]
123124
#![feature(const_exact_div)]
124125
#![feature(const_float_classify)]

0 commit comments

Comments
 (0)