@@ -394,17 +394,21 @@ impl char {
394
394
) ;
395
395
// check radix to remove letter handling code when radix is a known constant
396
396
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
402
406
} else {
403
407
// 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 )
405
409
} ;
406
410
// 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 }
408
412
}
409
413
410
414
/// Returns an iterator that yields the hexadecimal Unicode escape of a
0 commit comments