@@ -1983,29 +1983,23 @@ fn do_cast_string_to_int<
19831983 let trimmed_str = & str[ start..end] ;
19841984 let len = trimmed_str. len ( ) ;
19851985 let trimmed_bytes = trimmed_str. as_bytes ( ) ;
1986-
19871986 let mut result: T = T :: zero ( ) ;
1988- let mut negative = false ;
1987+ let mut idx = 0 ;
1988+ let first_char = trimmed_bytes[ 0 ] ;
1989+ let negative = first_char == b'-' ;
1990+ if negative || first_char == b'+' {
1991+ idx = 1 ;
1992+ if len == 1 {
1993+ return none_or_err ( eval_mode, type_name, str) ;
1994+ }
1995+ }
1996+
19891997 let radix = T :: from ( 10 ) ;
19901998 let stop_value = min_value / radix;
19911999 let mut parse_sign_and_digits = true ;
19922000
1993- for i in 0 ..len {
1994- let ch = trimmed_bytes[ i] ;
2001+ for & ch in & trimmed_bytes[ idx..] {
19952002 if parse_sign_and_digits {
1996- if i == 0 {
1997- negative = ch == b'-' ;
1998- let positive = ch == b'+' ;
1999- if negative || positive {
2000- if i + 1 == len {
2001- // input string is just "+" or "-"
2002- return none_or_err ( eval_mode, type_name, str) ;
2003- }
2004- // consume this char
2005- continue ;
2006- }
2007- }
2008-
20092003 if ch == b'.' {
20102004 if eval_mode == EvalMode :: Legacy {
20112005 // truncate decimal in legacy mode
@@ -2016,11 +2010,11 @@ fn do_cast_string_to_int<
20162010 }
20172011 }
20182012
2019- let digit = if ch. is_ascii_digit ( ) {
2020- ( ch as u32 ) - ( '0' as u32 )
2021- } else {
2013+ if !ch. is_ascii_digit ( ) {
20222014 return none_or_err ( eval_mode, type_name, str) ;
2023- } ;
2015+ }
2016+ let digit = T :: from ( ( ch - b'0' ) as i32 ) ;
2017+ result = result * radix - digit;
20242018
20252019 // We are going to process the new digit and accumulate the result. However, before
20262020 // doing this, if the result is already smaller than the
@@ -2029,17 +2023,11 @@ fn do_cast_string_to_int<
20292023 if result < stop_value {
20302024 return none_or_err ( eval_mode, type_name, str) ;
20312025 }
2032-
20332026 // Since the previous result is greater than or equal to stopValue(Integer.MIN_VALUE /
20342027 // radix), we can just use `result > 0` to check overflow. If result
20352028 // overflows, we should stop
2036- let v = result * radix;
2037- let digit = ( digit as i32 ) . into ( ) ;
2038- match v. checked_sub ( & digit) {
2039- Some ( x) if x <= T :: zero ( ) => result = x,
2040- _ => {
2041- return none_or_err ( eval_mode, type_name, str) ;
2042- }
2029+ if result > T :: zero ( ) {
2030+ return none_or_err ( eval_mode, type_name, str) ;
20432031 }
20442032 } else {
20452033 // make sure fractional digits are valid digits but ignore them
0 commit comments