This repository was archived by the owner on May 28, 2025. It is now read-only.
File tree Expand file tree Collapse file tree 1 file changed +14
-1
lines changed Expand file tree Collapse file tree 1 file changed +14
-1
lines changed Original file line number Diff line number Diff line change @@ -271,7 +271,20 @@ impl FromStr for char {
271271
272272#[ inline]
273273const fn char_try_from_u32 ( i : u32 ) -> Result < char , CharTryFromError > {
274- if ( i > MAX as u32 ) || ( i >= 0xD800 && i <= 0xDFFF ) {
274+ // This is an optimized version of the check
275+ // (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF),
276+ // which can also be written as
277+ // i >= 0x110000 || (i >= 0xD800 && i < 0xE000).
278+ //
279+ // The XOR with 0xD800 permutes the ranges such that 0xD800..0xE000 is
280+ // mapped to 0x0000..0x0800, while keeping all the high bits outside 0xFFFF the same.
281+ // In particular, numbers >= 0x110000 stay in this range.
282+ //
283+ // Subtracting 0x800 causes 0x0000..0x0800 to wrap, meaning that a single
284+ // unsigned comparison against 0x110000 - 0x800 will detect both the wrapped
285+ // surrogate range as well as the numbers originally larger than 0x110000.
286+ //
287+ if ( i ^ 0xD800 ) . wrapping_sub ( 0x800 ) >= 0x110000 - 0x800 {
275288 Err ( CharTryFromError ( ( ) ) )
276289 } else {
277290 // SAFETY: checked that it's a legal unicode value
You can’t perform that action at this time.
0 commit comments