Merge branch 'trunk' into format-annotations

This commit is contained in:
Folkert de Vries 2020-07-09 18:10:20 +02:00 committed by GitHub
commit 3a6edd6594
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 83 additions and 7 deletions

View file

@ -121,8 +121,13 @@ pub fn finish_parsing_float(raw: &str) -> Result<f64, (&str, FloatErrorKind)> {
}
}
/// Integer parsing code taken from the rust stdlib,
/// Integer parsing code taken from the rust libcore,
/// pulled in so we can give custom error messages
///
/// The Rust Project is dual-licensed under Apache 2.0 and MIT terms.
/// As roc is Apache licensed, we use this rust code under the apache 2.0 license
///
/// Thanks to the rust-lang project and its contributors
trait FromStrRadixHelper: PartialOrd + Copy {
fn min_value() -> Self;

View file

@ -68,6 +68,7 @@ pub enum IntErrorKind {
/// Value being parsed is empty.
///
/// Among other causes, this variant will be constructed when parsing an empty string.
/// In roc, this can happen with non-base-10 literals, e.g. `0x` or `0b` without any digits
Empty,
/// Contains an invalid digit.
///

View file

@ -430,12 +430,22 @@ fn pretty_runtime_error<'b>(
hint,
])
}
RuntimeError::InvalidInt(IntErrorKind::Empty, _base, _region, _raw_str) => {
unreachable!("would never parse an empty int literal")
}
RuntimeError::InvalidInt(IntErrorKind::InvalidDigit, base, region, _raw_str) => {
RuntimeError::InvalidInt(error @ IntErrorKind::InvalidDigit, base, region, _raw_str)
| RuntimeError::InvalidInt(error @ IntErrorKind::Empty, base, region, _raw_str) => {
use roc_parse::ast::Base::*;
let (problem, contains) = if let IntErrorKind::InvalidDigit = error {
(
"an invalid digit",
alloc.reflow(" can only contain the digits "),
)
} else {
(
"no digits",
alloc.reflow(" must contain at least one of the digits "),
)
};
let name = match base {
Decimal => "integer",
Octal => "octal integer",
@ -465,12 +475,14 @@ fn pretty_runtime_error<'b>(
alloc.concat(vec![
alloc.reflow("This "),
alloc.text(name),
alloc.reflow(" literal contains an invalid digit:"),
alloc.reflow(" literal contains "),
alloc.text(problem),
alloc.text(":"),
]),
alloc.region(region),
alloc.concat(vec![
alloc.text(plurals),
alloc.reflow(" can only contain the digits "),
contains,
alloc.text(charset),
alloc.text("."),
]),

View file

@ -3310,6 +3310,64 @@ mod test_reporting {
)
}
#[test]
fn integer_empty() {
report_problem_as(
indoc!(
r#"
dec = 20
hex = 0x
oct = 0o
bin = 0b
dec + hex + oct + bin
"#
),
indoc!(
r#"
-- SYNTAX PROBLEM --------------------------------------------------------------
This hex integer literal contains no digits:
3 hex = 0x
^^
Hexadecimal (base-16) integer literals must contain at least one of
the digits 0-9, a-f and A-F.
Hint: Learn more about number literals at TODO
-- SYNTAX PROBLEM --------------------------------------------------------------
This octal integer literal contains no digits:
5 oct = 0o
^^
Octal (base-8) integer literals must contain at least one of the
digits 0-7.
Hint: Learn more about number literals at TODO
-- SYNTAX PROBLEM --------------------------------------------------------------
This binary integer literal contains no digits:
7 bin = 0b
^^
Binary (base-2) integer literals must contain at least one of the
digits 0 and 1.
Hint: Learn more about number literals at TODO
"#
),
)
}
#[test]
fn float_malformed() {
report_problem_as(