@@ -301,7 +301,7 @@ impl char {
301301 ///
302302 /// # Panics
303303 ///
304- /// Panics if given a radix larger than 36.
304+ /// Panics if given a radix smaller than 2 or larger than 36.
305305 ///
306306 /// # Examples
307307 ///
@@ -319,6 +319,13 @@ impl char {
319319 /// // this panics
320320 /// '1'.is_digit(37);
321321 /// ```
322+ ///
323+ /// Passing a small radix, causing a panic:
324+ ///
325+ /// ```should_panic
326+ /// // this panics
327+ /// '1'.is_digit(1);
328+ /// ```
322329 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
323330 #[ rustc_const_unstable( feature = "const_char_classify" , issue = "132241" ) ]
324331 #[ inline]
@@ -345,7 +352,7 @@ impl char {
345352 ///
346353 /// # Panics
347354 ///
348- /// Panics if given a radix larger than 36.
355+ /// Panics if given a radix smaller than 2 or larger than 36.
349356 ///
350357 /// # Examples
351358 ///
@@ -369,24 +376,35 @@ impl char {
369376 /// // this panics
370377 /// let _ = '1'.to_digit(37);
371378 /// ```
379+ /// Passing a small radix, causing a panic:
380+ ///
381+ /// ```should_panic
382+ /// // this panics
383+ /// let _ = '1'.to_digit(1);
384+ /// ```
372385 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
373386 #[ rustc_const_stable( feature = "const_char_convert" , since = "1.67.0" ) ]
374387 #[ must_use = "this returns the result of the operation, \
375388 without modifying the original"]
376389 #[ inline]
377390 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+ } ;
388406 // 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 }
390408 }
391409
392410 /// Returns an iterator that yields the hexadecimal Unicode escape of a
0 commit comments