@@ -1,6 +1,7 @@ |
|
|
1 |
1 |
//! impl char {} |
2 |
2 |
|
3 |
3 |
use super::*; |
|
4 |
+use crate::intrinsics::const_eval_select; |
4 |
5 |
use crate::slice; |
5 |
6 |
use crate::str::from_utf8_unchecked_mut; |
6 |
7 |
use crate::unicode::printable::is_printable; |
@@ -1762,6 +1763,15 @@ const fn len_utf8(code: u32) -> usize { |
|
|
1762 |
1763 |
#[doc(hidden)] |
1763 |
1764 |
#[inline] |
1764 |
1765 |
pub const fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] { |
|
1766 |
+const fn panic_at_const(_code: u32, _len: usize, _dst_len: usize) { |
|
1767 |
+// Note that we cannot format in constant expressions. |
|
1768 |
+panic!("encode_utf8: buffer does not have enough bytes to encode code point"); |
|
1769 |
+} |
|
1770 |
+fn panic_at_rt(code: u32, len: usize, dst_len: usize) { |
|
1771 |
+panic!( |
|
1772 |
+"encode_utf8: need {len} bytes to encode U+{code:04X} but buffer has just {dst_len}", |
|
1773 |
+); |
|
1774 |
+} |
1765 |
1775 |
let len = len_utf8(code); |
1766 |
1776 |
match (len, &mut *dst) { |
1767 |
1777 |
(1, [a, ..]) => { |
@@ -1782,8 +1792,8 @@ pub const fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] { |
|
|
1782 |
1792 |
*c = (code >> 6 & 0x3F) as u8 | TAG_CONT; |
1783 |
1793 |
*d = (code & 0x3F) as u8 | TAG_CONT; |
1784 |
1794 |
} |
1785 |
|
-// Note that we cannot format in constant expressions. |
1786 |
|
- _ => panic!("encode_utf8: buffer does not have enough bytes to encode code point"), |
|
1795 |
+// FIXME(const-hack): We would prefer to have streamlined panics when formatters become const-friendly. |
|
1796 |
+ _ => const_eval_select((code, len, dst.len()), panic_at_const, panic_at_rt), |
1787 |
1797 |
}; |
1788 |
1798 |
// SAFETY: `<&mut [u8]>::as_mut_ptr` is guaranteed to return a valid pointer and `len` has been tested to be within bounds. |
1789 |
1799 |
unsafe { slice::from_raw_parts_mut(dst.as_mut_ptr(), len) } |