cover all parsed patterns with an error message

but, some invalid patterns are not parsed as expected. See https://github.com/rtfeldman/roc/issues/399
This commit is contained in:
Folkert 2020-07-04 20:18:03 +02:00
parent 0c7a4179aa
commit b7d689226c
4 changed files with 53 additions and 24 deletions

View File

@ -175,14 +175,12 @@ pub fn canonicalize_pattern<'a>(
}
Ok(float) => Pattern::FloatLiteral(float),
},
ptype @ DefExpr | ptype @ TopLevelDef | ptype @ FunctionArg => {
unsupported_pattern(env, ptype, region)
}
ptype => unsupported_pattern(env, ptype, region),
},
Underscore => match pattern_type {
WhenBranch | FunctionArg => Pattern::Underscore,
ptype @ DefExpr | ptype @ TopLevelDef => unsupported_pattern(env, ptype, region),
ptype => unsupported_pattern(env, ptype, region),
},
NumLiteral(string) => match pattern_type {
@ -193,9 +191,7 @@ pub fn canonicalize_pattern<'a>(
}
Ok(int) => Pattern::NumLiteral(var_store.fresh(), int),
},
ptype @ DefExpr | ptype @ TopLevelDef | ptype @ FunctionArg => {
unsupported_pattern(env, ptype, region)
}
ptype => unsupported_pattern(env, ptype, region),
},
NonBase10Literal {
@ -216,19 +212,20 @@ pub fn canonicalize_pattern<'a>(
}
}
},
ptype @ DefExpr | ptype @ TopLevelDef | ptype @ FunctionArg => {
unsupported_pattern(env, ptype, region)
}
ptype => unsupported_pattern(env, ptype, region),
},
StrLiteral(_string) => match pattern_type {
StrLiteral(string) => match pattern_type {
WhenBranch => {
// TODO report whether string was malformed
Pattern::StrLiteral((*string).into())
}
ptype @ DefExpr | ptype @ TopLevelDef | ptype @ FunctionArg => {
unsupported_pattern(env, ptype, region)
}
ptype => unsupported_pattern(env, ptype, region),
},
BlockStrLiteral(_lines) => match pattern_type {
WhenBranch => todo!("TODO block string literal pattern"),
ptype => unsupported_pattern(env, ptype, region),
},
SpaceBefore(sub_pattern, _) | SpaceAfter(sub_pattern, _) | Nested(sub_pattern) => {
@ -296,7 +293,7 @@ pub fn canonicalize_pattern<'a>(
},
});
}
_ => panic!("invalid pattern in record"),
_ => unreachable!("Any other pattern should have given a parse error"),
}
}
@ -312,7 +309,15 @@ pub fn canonicalize_pattern<'a>(
unreachable!("should have been handled in RecordDestructure");
}
_ => panic!("TODO finish restoring can_pattern branch for {:?}", pattern),
Malformed(_str) => {
let problem = MalformedPatternProblem::Unknown;
malformed_pattern(env, problem, region)
}
QualifiedIdentifier { .. } => {
let problem = MalformedPatternProblem::QualifiedIdentifier;
malformed_pattern(env, problem, region)
}
};
Located {

View File

@ -92,7 +92,6 @@ pub enum RuntimeError {
InvalidHex(std::num::ParseIntError, Box<str>),
InvalidOctal(std::num::ParseIntError, Box<str>),
InvalidBinary(std::num::ParseIntError, Box<str>),
QualifiedPatternIdent(InlinableString),
CircularDef(Vec<Symbol>, Vec<(Region /* pattern */, Region /* expr */)>),
/// When the author specifies a type annotation but no implementation
@ -104,4 +103,6 @@ pub enum MalformedPatternProblem {
MalformedInt,
MalformedFloat,
MalformedBase(Base),
Unknown,
QualifiedIdentifier,
}

View File

@ -343,20 +343,33 @@ fn pretty_runtime_error<'b>(
use roc_problem::can::MalformedPatternProblem::*;
let name = match problem {
MalformedInt => "integer",
MalformedFloat => "float",
MalformedBase(Base::Hex) => "hex integer",
MalformedBase(Base::Binary) => "binary integer",
MalformedBase(Base::Octal) => "octal integer",
MalformedInt => " integer ",
MalformedFloat => " float ",
MalformedBase(Base::Hex) => " hex integer ",
MalformedBase(Base::Binary) => " binary integer ",
MalformedBase(Base::Octal) => " octal integer ",
Unknown => " ",
QualifiedIdentifier => " qualified ",
};
let hint = match problem {
MalformedInt | MalformedFloat | MalformedBase(_) => alloc
.hint()
.append(alloc.reflow("Learn more about number literals at TODO")),
Unknown => alloc.nil(),
QualifiedIdentifier => alloc.hint().append(
alloc.reflow("In patterns, only private and global tags can be qualified"),
),
};
alloc.stack(vec![
alloc.concat(vec![
alloc.reflow("This "),
alloc.reflow("This"),
alloc.text(name),
alloc.reflow(" pattern is malformed:"),
alloc.reflow("pattern is malformed:"),
]),
alloc.region(region),
hint,
])
}

View File

@ -1486,6 +1486,8 @@ mod test_reporting {
2 100A -> 3
^^^^
Hint: Learn more about number literals at TODO
"#
),
)
@ -1509,6 +1511,8 @@ mod test_reporting {
2 2.X -> 3
^^^
Hint: Learn more about number literals at TODO
"#
),
)
@ -1532,6 +1536,8 @@ mod test_reporting {
2 0xZ -> 3
^^^
Hint: Learn more about number literals at TODO
"#
),
)
@ -1555,6 +1561,8 @@ mod test_reporting {
2 0o9 -> 3
^^^
Hint: Learn more about number literals at TODO
"#
),
)
@ -1578,6 +1586,8 @@ mod test_reporting {
2 0b4 -> 3
^^^
Hint: Learn more about number literals at TODO
"#
),
)