@@ -301,7 +301,7 @@ impl char {
301
301
///
302
302
/// # Panics
303
303
///
304
- /// Panics if given a radix larger than 36.
304
+ /// Panics if given a radix smaller than 2 or larger than 36.
305
305
///
306
306
/// # Examples
307
307
///
@@ -319,6 +319,13 @@ impl char {
319
319
/// // this panics
320
320
/// '1'.is_digit(37);
321
321
/// ```
322
+ ///
323
+ /// Passing a small radix, causing a panic:
324
+ ///
325
+ /// ```should_panic
326
+ /// // this panics
327
+ /// '1'.is_digit(1);
328
+ /// ```
322
329
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
323
330
#[ rustc_const_unstable( feature = "const_char_classify" , issue = "132241" ) ]
324
331
#[ inline]
@@ -345,7 +352,7 @@ impl char {
345
352
///
346
353
/// # Panics
347
354
///
348
- /// Panics if given a radix larger than 36.
355
+ /// Panics if given a radix smaller than 2 or larger than 36.
349
356
///
350
357
/// # Examples
351
358
///
@@ -369,24 +376,35 @@ impl char {
369
376
/// // this panics
370
377
/// let _ = '1'.to_digit(37);
371
378
/// ```
379
+ /// Passing a small radix, causing a panic:
380
+ ///
381
+ /// ```should_panic
382
+ /// // this panics
383
+ /// let _ = '1'.to_digit(1);
384
+ /// ```
372
385
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
373
386
#[ rustc_const_stable( feature = "const_char_convert" , since = "1.67.0" ) ]
374
387
#[ must_use = "this returns the result of the operation, \
375
388
without modifying the original"]
376
389
#[ inline]
377
390
pub const fn to_digit ( self , radix : u32 ) -> Option < u32 > {
378
- // If not a digit, a number greater than radix will be created.
379
- let mut digit = ( self as u32 ) . wrapping_sub ( '0' as u32 ) ;
380
- if radix > 10 {
381
- assert ! ( radix <= 36 , "to_digit: radix is too high (maximum 36)" ) ;
382
- if digit < 10 {
383
- return Some ( digit) ;
384
- }
385
- // Force the 6th bit to be set to ensure ascii is lower case.
386
- digit = ( self as u32 | 0b10_0000 ) . wrapping_sub ( 'a' as u32 ) . saturating_add ( 10 ) ;
387
- }
391
+ assert ! (
392
+ radix >= 2 && radix <= 36 ,
393
+ "to_digit: invalid radix -- radix must be in the range 2 to 36 inclusive"
394
+ ) ;
395
+ // check radix to remove letter handling code when radix is a known constant
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
402
+ } else {
403
+ // convert digit to value, non-digits wrap to values > 36
404
+ ( self as u32 ) . wrapping_sub ( '0' as u32 ) as u64
405
+ } ;
388
406
// FIXME(const-hack): once then_some is const fn, use it here
389
- if digit < radix { Some ( digit ) } else { None }
407
+ if value < radix as u64 { Some ( value as u32 ) } else { None }
390
408
}
391
409
392
410
/// Returns an iterator that yields the hexadecimal Unicode escape of a
0 commit comments