Skip to content

Commit edaf2b2

Browse files
Marcondirogitbot
authored and
gitbot
committed
char to_digit: avoid unnecessary casts to u64
1 parent 59efb72 commit edaf2b2

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

core/src/char/methods.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -394,17 +394,21 @@ impl char {
394394
);
395395
// check radix to remove letter handling code when radix is a known constant
396396
let value = if self > '9' && radix > 10 {
397-
// convert ASCII letters to lowercase
398-
let lower = self as u32 | 0x20;
399-
// convert an ASCII letter to the corresponding value,
400-
// non-letters convert to values > 36
401-
lower.wrapping_sub('a' as u32) as u64 + 10
397+
// mask to convert ASCII letters to uppercase
398+
const TO_UPPERCASE_MASK: u32 = !0b0010_0000;
399+
// Converts an ASCII letter to its corresponding integer value:
400+
// A-Z => 10-35, a-z => 10-35. Other characters produce values >= 36.
401+
//
402+
// Add Overflow Safety:
403+
// By applying the mask after the subtraction, the first addendum is
404+
// constrained such that it never exceeds u32::MAX - 0x20.
405+
((self as u32).wrapping_sub('A' as u32) & TO_UPPERCASE_MASK) + 10
402406
} else {
403407
// convert digit to value, non-digits wrap to values > 36
404-
(self as u32).wrapping_sub('0' as u32) as u64
408+
(self as u32).wrapping_sub('0' as u32)
405409
};
406410
// FIXME(const-hack): once then_some is const fn, use it here
407-
if value < radix as u64 { Some(value as u32) } else { None }
411+
if value < radix { Some(value) } else { None }
408412
}
409413

410414
/// Returns an iterator that yields the hexadecimal Unicode escape of a

0 commit comments

Comments
 (0)