Skip to content

Commit 28e9756

Browse files
committed
Mark and implement 'char::encode_utf8' as const.
1 parent e9e13a6 commit 28e9756

File tree

1 file changed

+25
-24
lines changed

1 file changed

+25
-24
lines changed

library/core/src/char/methods.rs

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! impl char {}
22
33
use super::*;
4+
use crate::hint::unreachable_unchecked;
45
use crate::slice;
56
use crate::str::from_utf8_unchecked_mut;
67
use crate::unicode::printable::is_printable;
@@ -673,7 +674,7 @@ impl char {
673674
/// ```
674675
#[stable(feature = "unicode_encode_char", since = "1.15.0")]
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
}
@@ -1762,35 +1763,35 @@ const fn len_utf8(code: u32) -> usize {
17621763
#[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
17631764
#[doc(hidden)]
17641765
#[inline]
1765-
pub fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] {
1766+
pub const fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] {
17661767
let len = len_utf8(code);
1767-
match (len, &mut dst[..]) {
1768-
(1, [a, ..]) => {
1769-
*a = code as u8;
1768+
// Note that the original message is not const-compatible due to formatting.
1769+
assert!(
1770+
len <= dst.len(),
1771+
"encode_utf8: buffer does not have enough bytes to encode code point",
1772+
);
1773+
match len {
1774+
1 => {
1775+
dst[0x0] = code as u8;
17701776
}
1771-
(2, [a, b, ..]) => {
1772-
*a = (code >> 6 & 0x1F) as u8 | TAG_TWO_B;
1773-
*b = (code & 0x3F) as u8 | TAG_CONT;
1777+
2 => {
1778+
dst[0x0] = (code >> 6 & 0x1F) as u8 | TAG_TWO_B;
1779+
dst[0x1] = (code & 0x3F) as u8 | TAG_CONT;
17741780
}
1775-
(3, [a, b, c, ..]) => {
1776-
*a = (code >> 12 & 0x0F) as u8 | TAG_THREE_B;
1777-
*b = (code >> 6 & 0x3F) as u8 | TAG_CONT;
1778-
*c = (code & 0x3F) as u8 | TAG_CONT;
1781+
3 => {
1782+
dst[0x0] = (code >> 12 & 0x0F) as u8 | TAG_THREE_B;
1783+
dst[0x1] = (code >> 6 & 0x3F) as u8 | TAG_CONT;
1784+
dst[0x2] = (code & 0x3F) as u8 | TAG_CONT;
17791785
}
1780-
(4, [a, b, c, d, ..]) => {
1781-
*a = (code >> 18 & 0x07) as u8 | TAG_FOUR_B;
1782-
*b = (code >> 12 & 0x3F) as u8 | TAG_CONT;
1783-
*c = (code >> 6 & 0x3F) as u8 | TAG_CONT;
1784-
*d = (code & 0x3F) as u8 | TAG_CONT;
1786+
4 => {
1787+
dst[0x0] = (code >> 18 & 0x07) as u8 | TAG_FOUR_B;
1788+
dst[0x1] = (code >> 12 & 0x3F) as u8 | TAG_CONT;
1789+
dst[0x2] = (code >> 6 & 0x3F) as u8 | TAG_CONT;
1790+
dst[0x3] = (code & 0x3F) as u8 | TAG_CONT;
17851791
}
1786-
_ => panic!(
1787-
"encode_utf8: need {} bytes to encode U+{:X}, but the buffer has {}",
1788-
len,
1789-
code,
1790-
dst.len(),
1791-
),
1792+
_ => unsafe { unreachable_unchecked() },
17921793
};
1793-
&mut dst[..len]
1794+
unsafe { slice::from_raw_parts_mut(dst.as_mut_ptr(), len) }
17941795
}
17951796

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

0 commit comments

Comments
 (0)