mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 00:24:34 +00:00
bring parse errors into the reporting tests
This commit is contained in:
parent
5e500f55ae
commit
e21cdfc689
4 changed files with 91 additions and 138 deletions
|
@ -1247,7 +1247,11 @@ pub fn ident_etc<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
|
|||
(Some(_loc_args), Some((_spaces_before_equals, Either::First(_equals_indent)))) => {
|
||||
// We got args with an '=' after them, e.g. `foo a b = ...`
|
||||
// This is a syntax error!
|
||||
panic!("TODO gracefully handle parse error for defs like `foo a b = ...`");
|
||||
let fail = Fail {
|
||||
attempting: state.attempting,
|
||||
reason: FailReason::ArgumentsBeforeEquals,
|
||||
};
|
||||
Err((fail, state))
|
||||
}
|
||||
(None, Some((spaces_before_equals, Either::First(equals_indent)))) => {
|
||||
// We got '=' with no args before it
|
||||
|
|
|
@ -190,6 +190,7 @@ pub enum FailReason {
|
|||
Eof(Region),
|
||||
InvalidPattern,
|
||||
ReservedKeyword(Region),
|
||||
ArgumentsBeforeEquals,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
|
|
|
@ -103,96 +103,10 @@ pub fn parse_loc_with<'a>(arena: &'a Bump, input: &'a str) -> Result<Located<ast
|
|||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn can_expr(expr_str: &str) -> CanExprOut {
|
||||
pub fn can_expr(expr_str: &str) -> Result<CanExprOut, Fail> {
|
||||
can_expr_with(&Bump::new(), test_home(), expr_str)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn uniq_expr(
|
||||
expr_str: &str,
|
||||
) -> (
|
||||
Located<Expr>,
|
||||
Output,
|
||||
Vec<Problem>,
|
||||
Subs,
|
||||
Variable,
|
||||
Constraint,
|
||||
ModuleId,
|
||||
Interns,
|
||||
) {
|
||||
let declared_idents: &ImMap<Ident, (Symbol, Region)> = &ImMap::default();
|
||||
|
||||
uniq_expr_with(&Bump::new(), expr_str, declared_idents)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn uniq_expr_with(
|
||||
arena: &Bump,
|
||||
expr_str: &str,
|
||||
declared_idents: &ImMap<Ident, (Symbol, Region)>,
|
||||
) -> (
|
||||
Located<Expr>,
|
||||
Output,
|
||||
Vec<Problem>,
|
||||
Subs,
|
||||
Variable,
|
||||
Constraint,
|
||||
ModuleId,
|
||||
Interns,
|
||||
) {
|
||||
let home = test_home();
|
||||
let CanExprOut {
|
||||
loc_expr,
|
||||
output,
|
||||
problems,
|
||||
var_store: old_var_store,
|
||||
var,
|
||||
interns,
|
||||
..
|
||||
} = can_expr_with(arena, home, expr_str);
|
||||
|
||||
// double check
|
||||
let var_store = VarStore::new(old_var_store.fresh());
|
||||
|
||||
let expected2 = Expected::NoExpectation(Type::Variable(var));
|
||||
let constraint = roc_constrain::uniq::constrain_declaration(
|
||||
home,
|
||||
&var_store,
|
||||
Region::zero(),
|
||||
&loc_expr,
|
||||
declared_idents,
|
||||
expected2,
|
||||
);
|
||||
|
||||
let stdlib = uniq_stdlib();
|
||||
|
||||
let types = stdlib.types;
|
||||
let imports: Vec<_> = types
|
||||
.iter()
|
||||
.map(|(symbol, (solved_type, region))| Import {
|
||||
loc_symbol: Located::at(*region, *symbol),
|
||||
solved_type: solved_type,
|
||||
})
|
||||
.collect();
|
||||
|
||||
// load builtin values
|
||||
|
||||
// TODO what to do with those rigids?
|
||||
let (_introduced_rigids, constraint) =
|
||||
constrain_imported_values(imports, constraint, &var_store);
|
||||
|
||||
// load builtin types
|
||||
let mut constraint = load_builtin_aliases(&stdlib.aliases, constraint, &var_store);
|
||||
|
||||
constraint.instantiate_aliases(&var_store);
|
||||
|
||||
let subs2 = Subs::new(var_store.into());
|
||||
|
||||
(
|
||||
loc_expr, output, problems, subs2, var, constraint, home, interns,
|
||||
)
|
||||
}
|
||||
|
||||
pub struct CanExprOut {
|
||||
pub loc_expr: Located<Expr>,
|
||||
pub output: Output,
|
||||
|
@ -205,13 +119,13 @@ pub struct CanExprOut {
|
|||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut {
|
||||
let loc_expr = parse_loc_with(&arena, expr_str).unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"can_expr_with() got a parse error when attempting to canonicalize:\n\n{:?} {:?}",
|
||||
expr_str, e
|
||||
)
|
||||
});
|
||||
pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> Result<CanExprOut, Fail> {
|
||||
let loc_expr = match parse_loc_with(&arena, expr_str) {
|
||||
Ok(e) => e,
|
||||
Err(fail) => {
|
||||
return Err(fail);
|
||||
}
|
||||
};
|
||||
|
||||
let var_store = VarStore::default();
|
||||
let var = var_store.fresh();
|
||||
|
@ -283,7 +197,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
|
|||
all_ident_ids,
|
||||
};
|
||||
|
||||
CanExprOut {
|
||||
Ok(CanExprOut {
|
||||
loc_expr,
|
||||
output,
|
||||
problems: env.problems,
|
||||
|
@ -292,7 +206,7 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
|
|||
interns,
|
||||
var,
|
||||
constraint,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
|
|
@ -23,6 +23,7 @@ mod test_reporting {
|
|||
use std::path::PathBuf;
|
||||
// use roc_region::all;
|
||||
use crate::helpers::{can_expr, infer_expr, CanExprOut};
|
||||
use roc_parse::parser::Fail;
|
||||
use roc_reporting::report::{RocDocAllocator, RocDocBuilder};
|
||||
use roc_solve::solve;
|
||||
|
||||
|
@ -43,13 +44,16 @@ mod test_reporting {
|
|||
|
||||
fn infer_expr_help(
|
||||
expr_src: &str,
|
||||
) -> (
|
||||
) -> Result<
|
||||
(
|
||||
Vec<solve::TypeError>,
|
||||
Vec<roc_problem::can::Problem>,
|
||||
Vec<roc_mono::expr::MonoProblem>,
|
||||
ModuleId,
|
||||
Interns,
|
||||
) {
|
||||
),
|
||||
Fail,
|
||||
> {
|
||||
let CanExprOut {
|
||||
loc_expr,
|
||||
output,
|
||||
|
@ -60,7 +64,7 @@ mod test_reporting {
|
|||
mut interns,
|
||||
problems: can_problems,
|
||||
..
|
||||
} = can_expr(expr_src);
|
||||
} = can_expr(expr_src)?;
|
||||
let mut subs = Subs::new(var_store.into());
|
||||
|
||||
for (var, name) in output.introduced_variables.name_by_var {
|
||||
|
@ -99,7 +103,7 @@ mod test_reporting {
|
|||
);
|
||||
}
|
||||
|
||||
(unify_problems, can_problems, mono_problems, home, interns)
|
||||
Ok((unify_problems, can_problems, mono_problems, home, interns))
|
||||
}
|
||||
|
||||
fn list_reports<F>(src: &str, buf: &mut String, callback: F)
|
||||
|
@ -108,8 +112,9 @@ mod test_reporting {
|
|||
{
|
||||
use ven_pretty::DocAllocator;
|
||||
|
||||
let (type_problems, can_problems, mono_problems, home, interns) = infer_expr_help(src);
|
||||
|
||||
match infer_expr_help(src) {
|
||||
Err(fail) => todo!(),
|
||||
Ok((type_problems, can_problems, mono_problems, home, interns)) => {
|
||||
let src_lines: Vec<&str> = src.split('\n').collect();
|
||||
let alloc = RocDocAllocator::new(&src_lines, home, &interns);
|
||||
|
||||
|
@ -143,6 +148,8 @@ mod test_reporting {
|
|||
|
||||
callback(doc, buf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn report_problem_as(src: &str, expected_rendering: &str) {
|
||||
let mut buf: String = String::new();
|
||||
|
@ -491,7 +498,8 @@ mod test_reporting {
|
|||
"#
|
||||
);
|
||||
|
||||
let (_type_problems, _can_problems, _mono_problems, home, interns) = infer_expr_help(src);
|
||||
let (_type_problems, _can_problems, _mono_problems, home, interns) =
|
||||
infer_expr_help(src).expect("parse error");
|
||||
|
||||
let mut buf = String::new();
|
||||
let src_lines: Vec<&str> = src.split('\n').collect();
|
||||
|
@ -521,7 +529,7 @@ mod test_reporting {
|
|||
);
|
||||
|
||||
let (_type_problems, _can_problems, _mono_problems, home, mut interns) =
|
||||
infer_expr_help(src);
|
||||
infer_expr_help(src).expect("parse error");
|
||||
|
||||
let mut buf = String::new();
|
||||
let src_lines: Vec<&str> = src.split('\n').collect();
|
||||
|
@ -2671,4 +2679,30 @@ mod test_reporting {
|
|||
),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn elm_function_syntax() {
|
||||
report_problem_as(
|
||||
indoc!(
|
||||
r#"
|
||||
f x y = x
|
||||
"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
-- SYNTAX PROBLEM --------------------------------------------------------------
|
||||
|
||||
The `a` type variable is not used in the `Foo` alias definition:
|
||||
|
||||
1 ┆ Foo a : [ Foo ]
|
||||
┆ ^
|
||||
|
||||
Roc does not allow unused type parameters!
|
||||
|
||||
Hint: If you want an unused type parameter (a so-called "phantom
|
||||
type"), read the guide section on phantom data.
|
||||
"#
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue