diff --git a/compiler/can/tests/test_can.rs b/compiler/can/tests/test_can.rs index 00014c9ce8..e90768c12c 100644 --- a/compiler/can/tests/test_can.rs +++ b/compiler/can/tests/test_can.rs @@ -139,6 +139,21 @@ mod test_can { ); } + #[test] + fn float_double_dot() { + let string = "1.1.1"; + let region = Region::zero(); + + assert_can( + &string.clone(), + RuntimeError(RuntimeError::InvalidFloat( + FloatErrorKind::Error, + region, + string.into(), + )), + ); + } + #[test] fn zero() { assert_can_num("0", 0); diff --git a/compiler/parse/src/number_literal.rs b/compiler/parse/src/number_literal.rs index 9f151731b8..f38a700f6f 100644 --- a/compiler/parse/src/number_literal.rs +++ b/compiler/parse/src/number_literal.rs @@ -40,11 +40,10 @@ fn chomp_number_base<'a>( bytes: &'a [u8], state: State<'a>, ) -> ParseResult<'a, Expr<'a>, Number> { - let (_is_float, mut chomped) = chomp_number(bytes); - chomped += 2 + (is_negative as usize); + let (_is_float, chomped) = chomp_number(bytes); match parse_utf8(&bytes[0..chomped]) { - Ok(string) => match state.advance_without_indenting(chomped) { + Ok(string) => match state.advance_without_indenting(chomped + 2 + is_negative as usize) { Ok(new) => { // all is well Ok(( @@ -73,7 +72,7 @@ fn chomp_number_dec<'a>( bytes: &'a [u8], state: State<'a>, ) -> ParseResult<'a, Expr<'a>, Number> { - let (is_float, mut chomped) = chomp_number(bytes); + let (is_float, chomped) = chomp_number(bytes); if is_negative && chomped == 0 { // we're probably actually looking at unary negation here @@ -85,11 +84,9 @@ fn chomp_number_dec<'a>( return Err((Progress::NoProgress, Number::End, state)); } - chomped += is_negative as usize; + let string = unsafe { from_utf8_unchecked(&state.bytes[0..chomped + is_negative as usize]) }; - let string = unsafe { from_utf8_unchecked(&state.bytes[0..chomped]) }; - - match state.advance_without_indenting(chomped) { + match state.advance_without_indenting(chomped + is_negative as usize) { Ok(new) => { // all is well Ok(( diff --git a/compiler/reporting/tests/test_reporting.rs b/compiler/reporting/tests/test_reporting.rs index ef03df1c88..254bb66f16 100644 --- a/compiler/reporting/tests/test_reporting.rs +++ b/compiler/reporting/tests/test_reporting.rs @@ -5134,4 +5134,30 @@ mod test_reporting { ), ) } + + #[test] + fn number_double_dot() { + report_problem_as( + indoc!( + r#" + 1.1.1 + "# + ), + indoc!( + r#" + ── SYNTAX PROBLEM ────────────────────────────────────────────────────────────── + + This float literal contains an invalid digit: + + 1│ 1.1.1 + ^^^^^ + + Floating point literals can only contain the digits 0-9, or use + scientific notation 10e4 + + Tip: Learn more about number literals at TODO + "# + ), + ) + } }