remove RuntimeError panics in canonicalization

This commit is contained in:
Folkert 2020-03-30 15:59:00 +02:00
parent e05bad3c72
commit 4947e2638c
4 changed files with 55 additions and 44 deletions

View File

@ -14,7 +14,7 @@ use roc_module::symbol::Symbol;
use roc_parse::ast; use roc_parse::ast;
use roc_parse::operator::CalledVia; use roc_parse::operator::CalledVia;
use roc_parse::pattern::PatternType::*; use roc_parse::pattern::PatternType::*;
use roc_problem::can::{Problem, RuntimeError}; use roc_problem::can::{PrecedenceProblem, Problem, RuntimeError};
use roc_region::all::{Located, Region}; use roc_region::all::{Located, Region};
use roc_types::subs::{VarStore, Variable}; use roc_types::subs::{VarStore, Variable};
use roc_types::types::Alias; use roc_types::types::Alias;
@ -582,14 +582,26 @@ pub fn canonicalize_expr<'a>(
) )
} }
ast::Expr::MalformedIdent(_) ast::Expr::PrecedenceConflict(binop1, binop2, _expr) => {
| ast::Expr::MalformedClosure use roc_problem::can::RuntimeError::*;
| ast::Expr::PrecedenceConflict(_, _, _) => { (
panic!( RuntimeError(InvalidPrecedence(
"TODO restore the rest of canonicalize()'s branches {:?} {:?}", PrecedenceProblem::BothNonAssociative(binop1.clone(), binop2.clone()),
&expr, region,
local_successors(&References::new(), &env.closures) )),
); Output::default(),
)
}
ast::Expr::MalformedClosure => {
use roc_problem::can::RuntimeError::*;
(RuntimeError(MalformedClosure(region)), Output::default())
}
ast::Expr::MalformedIdent(name) => {
use roc_problem::can::RuntimeError::*;
(
RuntimeError(MalformedIdentifier((*name).into(), region)),
Output::default(),
)
} }
ast::Expr::Nested(sub_expr) => { ast::Expr::Nested(sub_expr) => {
let (answer, output) = canonicalize_expr(env, var_store, scope, region, sub_expr); let (answer, output) = canonicalize_expr(env, var_store, scope, region, sub_expr);

View File

@ -25,7 +25,7 @@ pub enum Problem {
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum PrecedenceProblem { pub enum PrecedenceProblem {
BothNonAssociative(Symbol, Located<BinOp>, Symbol, Located<BinOp>, Symbol), BothNonAssociative(Located<BinOp>, Located<BinOp>),
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
@ -47,6 +47,8 @@ pub enum RuntimeError {
region: Region, region: Region,
}, },
InvalidPrecedence(PrecedenceProblem, Region), InvalidPrecedence(PrecedenceProblem, Region),
MalformedIdentifier(Box<str>, Region),
MalformedClosure(Region),
FloatOutsideRange(Box<str>), FloatOutsideRange(Box<str>),
IntOutsideRange(Box<str>), IntOutsideRange(Box<str>),
InvalidHex(std::num::ParseIntError, Box<str>), InvalidHex(std::num::ParseIntError, Box<str>),

View File

@ -120,13 +120,9 @@ pub fn can_problem(filename: PathBuf, problem: Problem) -> Report {
texts.push(Value(argument_symbol)); texts.push(Value(argument_symbol));
texts.push(plain_text("\". Adding an underscore at the start of a variable name is a way of saying that the variable is not used.")); texts.push(plain_text("\". Adding an underscore at the start of a variable name is a way of saying that the variable is not used."));
} }
Problem::PrecedenceProblem(BothNonAssociative( Problem::PrecedenceProblem(BothNonAssociative(_left_bin_op, _right_bin_op)) => {
_left_symbol, panic!("TODO implement precedence problem report")
_left_bin_op, }
_middle_symbol,
_right_bin_op,
_right_symbol,
)) => panic!("TODO implement precedence problem report"),
Problem::UnsupportedPattern(_pattern_type, _region) => { Problem::UnsupportedPattern(_pattern_type, _region) => {
panic!("TODO implement unsupported pattern report") panic!("TODO implement unsupported pattern report")
} }

View File

@ -289,6 +289,7 @@ mod test_report {
) )
} }
// hits a TODO in reporting
// #[test] // #[test]
// fn report_shadow() { // fn report_shadow() {
// report_problem_as( // report_problem_as(
@ -322,33 +323,33 @@ mod test_report {
// ) // )
// } // }
// #[test] #[test]
// fn report_precedence_problem() { fn report_precedence_problem() {
// report_problem_as( report_problem_as(
// indoc!( indoc!(
// r#" r#"
// x = 1 x = 1
// y = y =
// if selecteId == thisId == adminsId then if selecteId == thisId == adminsId then
// 4 4
//
// else else
// 5 5
//
// x { x, y }
// "# "#
// ), ),
// indoc!( indoc!(
// r#" r#"
// Which expression should I evaluate first? "selectedId == thisId" or "thisId == adminsId"? Which expression should I evaluate first? "selectedId == thisId" or "thisId == adminsId"?
//
// 3 ┆ if selecteId == thisId == adminsId then 3 if selecteId == thisId == adminsId then
// ┆ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//
// Please clarify this for me by adding some parentheses. Either "(selectedId == thisId) == adminsId" or "selectedId == (thisId == adminsId)" would work."# Please clarify this for me by adding some parentheses. Either "(selectedId == thisId) == adminsId" or "selectedId == (thisId == adminsId)" would work."#
// ), ),
// ) )
// } }
// #[test] // #[test]
// fn report_unused_argument() { // fn report_unused_argument() {