@@ -620,8 +620,8 @@ impl<'a> StringReader<'a> {
620
620
let base = 10 ;
621
621
622
622
// find the integer representing the name
623
- self . scan_digits ( base) ;
624
- let encoded_name: u32 = self . with_str_from ( start_bpos, |s| {
623
+ self . scan_digits ( base, base ) ;
624
+ let encoded_name : u32 = self . with_str_from ( start_bpos, |s| {
625
625
u32:: from_str_radix ( s, 10 ) . unwrap_or_else ( |_| {
626
626
panic ! ( "expected digits representing a name, got {:?}, {}, range [{:?},{:?}]" ,
627
627
s, whence, start_bpos, self . last_pos) ;
@@ -638,7 +638,7 @@ impl<'a> StringReader<'a> {
638
638
639
639
// find the integer representing the ctxt
640
640
let start_bpos = self . last_pos ;
641
- self . scan_digits ( base) ;
641
+ self . scan_digits ( base, base ) ;
642
642
let encoded_ctxt : ast:: SyntaxContext = self . with_str_from ( start_bpos, |s| {
643
643
u32:: from_str_radix ( s, 10 ) . unwrap_or_else ( |_| {
644
644
panic ! ( "expected digits representing a ctxt, got {:?}, {}" , s, whence) ;
@@ -652,16 +652,28 @@ impl<'a> StringReader<'a> {
652
652
ctxt : encoded_ctxt, }
653
653
}
654
654
655
- /// Scan through any digits (base `radix`) or underscores, and return how
656
- /// many digits there were.
657
- fn scan_digits ( & mut self , radix : u32 ) -> usize {
655
+ /// Scan through any digits (base `scan_radix`) or underscores,
656
+ /// and return how many digits there were.
657
+ ///
658
+ /// `real_radix` represents the true radix of the number we're
659
+ /// interested in, and errors will be emitted for any digits
660
+ /// between `real_radix` and `scan_radix`.
661
+ fn scan_digits ( & mut self , real_radix : u32 , scan_radix : u32 ) -> usize {
662
+ assert ! ( real_radix <= scan_radix) ;
658
663
let mut len = 0 ;
659
664
loop {
660
665
let c = self . curr ;
661
666
if c == Some ( '_' ) { debug ! ( "skipping a _" ) ; self . bump ( ) ; continue ; }
662
- match c. and_then ( |cc| cc. to_digit ( radix ) ) {
667
+ match c. and_then ( |cc| cc. to_digit ( scan_radix ) ) {
663
668
Some ( _) => {
664
669
debug ! ( "{:?} in scan_digits" , c) ;
670
+ // check that the hypothetical digit is actually
671
+ // in range for the true radix
672
+ if c. unwrap ( ) . to_digit ( real_radix) . is_none ( ) {
673
+ self . err_span_ ( self . last_pos , self . pos ,
674
+ & format ! ( "invalid digit for a base {} literal" ,
675
+ real_radix) ) ;
676
+ }
665
677
len += 1 ;
666
678
self . bump ( ) ;
667
679
}
@@ -680,19 +692,19 @@ impl<'a> StringReader<'a> {
680
692
681
693
if c == '0' {
682
694
match self . curr . unwrap_or ( '\0' ) {
683
- 'b' => { self . bump ( ) ; base = 2 ; num_digits = self . scan_digits ( 2 ) ; }
684
- 'o' => { self . bump ( ) ; base = 8 ; num_digits = self . scan_digits ( 8 ) ; }
685
- 'x' => { self . bump ( ) ; base = 16 ; num_digits = self . scan_digits ( 16 ) ; }
695
+ 'b' => { self . bump ( ) ; base = 2 ; num_digits = self . scan_digits ( 2 , 10 ) ; }
696
+ 'o' => { self . bump ( ) ; base = 8 ; num_digits = self . scan_digits ( 8 , 10 ) ; }
697
+ 'x' => { self . bump ( ) ; base = 16 ; num_digits = self . scan_digits ( 16 , 16 ) ; }
686
698
'0' ...'9' | '_' | '.' => {
687
- num_digits = self . scan_digits ( 10 ) + 1 ;
699
+ num_digits = self . scan_digits ( 10 , 10 ) + 1 ;
688
700
}
689
701
_ => {
690
702
// just a 0
691
703
return token:: Integer ( self . name_from ( start_bpos) ) ;
692
704
}
693
705
}
694
706
} else if c. is_digit ( 10 ) {
695
- num_digits = self . scan_digits ( 10 ) + 1 ;
707
+ num_digits = self . scan_digits ( 10 , 10 ) + 1 ;
696
708
} else {
697
709
num_digits = 0 ;
698
710
}
@@ -711,7 +723,7 @@ impl<'a> StringReader<'a> {
711
723
// with a number
712
724
self . bump ( ) ;
713
725
if self . curr . unwrap_or ( '\0' ) . is_digit ( 10 ) {
714
- self . scan_digits ( 10 ) ;
726
+ self . scan_digits ( 10 , 10 ) ;
715
727
self . scan_float_exponent ( ) ;
716
728
}
717
729
let last_pos = self . last_pos ;
@@ -934,7 +946,7 @@ impl<'a> StringReader<'a> {
934
946
if self . curr_is ( '-' ) || self . curr_is ( '+' ) {
935
947
self . bump ( ) ;
936
948
}
937
- if self . scan_digits ( 10 ) == 0 {
949
+ if self . scan_digits ( 10 , 10 ) == 0 {
938
950
self . err_span_ ( self . last_pos , self . pos , "expected at least one digit in exponent" )
939
951
}
940
952
}
0 commit comments