|
1 | 1 | //! impl char {}
|
2 | 2 |
|
3 | 3 | use super::*;
|
| 4 | +use crate::hint::unreachable_unchecked; |
4 | 5 | use crate::slice;
|
5 | 6 | use crate::str::from_utf8_unchecked_mut;
|
6 | 7 | use crate::unicode::printable::is_printable;
|
@@ -673,7 +674,7 @@ impl char {
|
673 | 674 | /// ```
|
674 | 675 | #[stable(feature = "unicode_encode_char", since = "1.15.0")]
|
675 | 676 | #[inline]
|
676 |
| - pub fn encode_utf8(self, dst: &mut [u8]) -> &mut str { |
| 677 | + pub const fn encode_utf8(self, dst: &mut [u8]) -> &mut str { |
677 | 678 | // SAFETY: `char` is not a surrogate, so this is valid UTF-8.
|
678 | 679 | unsafe { from_utf8_unchecked_mut(encode_utf8_raw(self as u32, dst)) }
|
679 | 680 | }
|
@@ -1762,35 +1763,35 @@ const fn len_utf8(code: u32) -> usize {
|
1762 | 1763 | #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
|
1763 | 1764 | #[doc(hidden)]
|
1764 | 1765 | #[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] { |
1766 | 1767 | 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; |
1770 | 1776 | }
|
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; |
1774 | 1780 | }
|
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; |
1779 | 1785 | }
|
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; |
1785 | 1791 | }
|
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() }, |
1792 | 1793 | };
|
1793 |
| - &mut dst[..len] |
| 1794 | + unsafe { slice::from_raw_parts_mut(dst.as_mut_ptr(), len) } |
1794 | 1795 | }
|
1795 | 1796 |
|
1796 | 1797 | /// Encodes a raw u32 value as UTF-16 into the provided `u16` buffer,
|
|
0 commit comments