mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-24 06:55:15 +00:00
Unapplied record builder error
This commit is contained in:
parent
6670fbb1ab
commit
d2a57112fd
10 changed files with 82 additions and 11 deletions
|
@ -1367,6 +1367,14 @@ pub fn canonicalize_expr<'a>(
|
|||
|
||||
(RuntimeError(problem), Output::default())
|
||||
}
|
||||
ast::Expr::UnappliedRecordBuilder(sub_expr) => {
|
||||
use roc_problem::can::RuntimeError::*;
|
||||
|
||||
let problem = UnappliedRecordBuilder(sub_expr.region);
|
||||
env.problem(Problem::RuntimeError(problem.clone()));
|
||||
|
||||
(RuntimeError(problem), Output::default())
|
||||
}
|
||||
&ast::Expr::NonBase10Int {
|
||||
string,
|
||||
base,
|
||||
|
|
|
@ -138,6 +138,7 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
|||
| MalformedClosure
|
||||
| PrecedenceConflict { .. }
|
||||
| MultipleRecordBuilders { .. }
|
||||
| UnappliedRecordBuilder { .. }
|
||||
| Tag(_)
|
||||
| OpaqueRef(_)
|
||||
| IngestedFile(_, _)
|
||||
|
@ -253,9 +254,10 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
|||
}
|
||||
}
|
||||
}
|
||||
RecordBuilder(_) => {
|
||||
todo!("Compiler error: Record builders must be applied to functions")
|
||||
}
|
||||
RecordBuilder(_) => arena.alloc(Loc {
|
||||
value: UnappliedRecordBuilder(loc_expr),
|
||||
region: loc_expr.region,
|
||||
}),
|
||||
BinOps(lefts, right) => desugar_bin_ops(arena, loc_expr.region, lefts, right),
|
||||
Defs(defs, loc_ret) => {
|
||||
let mut defs = (*defs).clone();
|
||||
|
|
|
@ -799,6 +799,30 @@ mod test_can {
|
|||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hanging_record_builder() {
|
||||
let src = indoc!(
|
||||
r#"
|
||||
{ a <- apply "a" }
|
||||
"#
|
||||
);
|
||||
let arena = Bump::new();
|
||||
let CanExprOut {
|
||||
problems, loc_expr, ..
|
||||
} = can_expr_with(&arena, test_home(), src);
|
||||
|
||||
assert_eq!(problems.len(), 1);
|
||||
assert!(problems.iter().all(|problem| matches!(
|
||||
problem,
|
||||
Problem::RuntimeError(roc_problem::can::RuntimeError::UnappliedRecordBuilder { .. })
|
||||
)));
|
||||
|
||||
assert!(matches!(
|
||||
loc_expr.value,
|
||||
Expr::RuntimeError(roc_problem::can::RuntimeError::UnappliedRecordBuilder { .. })
|
||||
));
|
||||
}
|
||||
|
||||
// TAIL CALLS
|
||||
fn get_closure(expr: &Expr, i: usize) -> roc_can::expr::Recursive {
|
||||
match expr {
|
||||
|
|
|
@ -79,7 +79,8 @@ impl<'a> Formattable for Expr<'a> {
|
|||
| PrecedenceConflict(roc_parse::ast::PrecedenceConflict {
|
||||
expr: loc_subexpr, ..
|
||||
})
|
||||
| MultipleRecordBuilders(loc_subexpr) => loc_subexpr.is_multiline(),
|
||||
| MultipleRecordBuilders(loc_subexpr)
|
||||
| UnappliedRecordBuilder(loc_subexpr) => loc_subexpr.is_multiline(),
|
||||
|
||||
ParensAround(subexpr) => subexpr.is_multiline(),
|
||||
|
||||
|
@ -499,9 +500,8 @@ impl<'a> Formattable for Expr<'a> {
|
|||
}
|
||||
MalformedClosure => {}
|
||||
PrecedenceConflict { .. } => {}
|
||||
MultipleRecordBuilders(sub_expr) => {
|
||||
sub_expr.format_with_options(buf, parens, newlines, indent)
|
||||
}
|
||||
MultipleRecordBuilders { .. } => {}
|
||||
UnappliedRecordBuilder { .. } => {}
|
||||
IngestedFile(_, _) => {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -747,9 +747,8 @@ impl<'a> RemoveSpaces<'a> for Expr<'a> {
|
|||
Expr::MalformedIdent(a, b) => Expr::MalformedIdent(a, remove_spaces_bad_ident(b)),
|
||||
Expr::MalformedClosure => Expr::MalformedClosure,
|
||||
Expr::PrecedenceConflict(a) => Expr::PrecedenceConflict(a),
|
||||
Expr::MultipleRecordBuilders(a) => {
|
||||
Expr::MultipleRecordBuilders(arena.alloc(a.remove_spaces(arena)))
|
||||
}
|
||||
Expr::MultipleRecordBuilders(a) => Expr::MultipleRecordBuilders(a),
|
||||
Expr::UnappliedRecordBuilder(a) => Expr::UnappliedRecordBuilder(a),
|
||||
Expr::SpaceBefore(a, _) => a.remove_spaces(arena),
|
||||
Expr::SpaceAfter(a, _) => a.remove_spaces(arena),
|
||||
Expr::SingleQuote(a) => Expr::Num(a),
|
||||
|
|
|
@ -328,6 +328,7 @@ pub enum Expr<'a> {
|
|||
// We should tell the author to disambiguate by grouping them with parens.
|
||||
PrecedenceConflict(&'a PrecedenceConflict<'a>),
|
||||
MultipleRecordBuilders(&'a Loc<Expr<'a>>),
|
||||
UnappliedRecordBuilder(&'a Loc<Expr<'a>>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
|
@ -1535,7 +1536,8 @@ impl<'a> Malformed for Expr<'a> {
|
|||
MalformedIdent(_, _) |
|
||||
MalformedClosure |
|
||||
PrecedenceConflict(_) |
|
||||
MultipleRecordBuilders(_) => true,
|
||||
MultipleRecordBuilders(_) |
|
||||
UnappliedRecordBuilder(_) => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1929,6 +1929,7 @@ fn expr_to_pattern_help<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result<Pattern<
|
|||
| Expr::MalformedClosure
|
||||
| Expr::PrecedenceConflict { .. }
|
||||
| Expr::MultipleRecordBuilders { .. }
|
||||
| Expr::UnappliedRecordBuilder { .. }
|
||||
| Expr::RecordUpdate { .. }
|
||||
| Expr::UnaryOp(_, _)
|
||||
| Expr::Crash => return Err(()),
|
||||
|
|
|
@ -362,6 +362,7 @@ impl Problem {
|
|||
| Problem::RuntimeError(RuntimeError::MultipleCharsInSingleQuote(region))
|
||||
| Problem::RuntimeError(RuntimeError::DegenerateBranch(region))
|
||||
| Problem::RuntimeError(RuntimeError::MultipleRecordBuilders(region))
|
||||
| Problem::RuntimeError(RuntimeError::UnappliedRecordBuilder(region))
|
||||
| Problem::InvalidAliasRigid { region, .. }
|
||||
| Problem::InvalidInterpolation(region)
|
||||
| Problem::InvalidHexadecimal(region)
|
||||
|
@ -591,6 +592,7 @@ pub enum RuntimeError {
|
|||
DegenerateBranch(Region),
|
||||
|
||||
MultipleRecordBuilders(Region),
|
||||
UnappliedRecordBuilder(Region),
|
||||
}
|
||||
|
||||
impl RuntimeError {
|
||||
|
|
|
@ -2147,6 +2147,18 @@ fn pretty_runtime_error<'b>(
|
|||
|
||||
title = "MULTIPLE RECORD BUILDERS";
|
||||
}
|
||||
RuntimeError::UnappliedRecordBuilder(region) => {
|
||||
doc = alloc.stack([
|
||||
alloc.reflow("This record builder was not applied to a function:"),
|
||||
alloc.region(lines.convert_region(region)),
|
||||
alloc.reflow("However, we need a function to construct the record."),
|
||||
alloc.note(
|
||||
"Functions must be applied directly. The pipe operator (|>) cannot be used.",
|
||||
),
|
||||
]);
|
||||
|
||||
title = "UNAPPLIED RECORD BUILDER";
|
||||
}
|
||||
}
|
||||
|
||||
(doc, title)
|
||||
|
|
|
@ -10204,6 +10204,27 @@ I recommend using camelCase. It's the standard style in Roc code!
|
|||
"###
|
||||
);
|
||||
|
||||
test_report!(
|
||||
unapplied_record_builder,
|
||||
indoc!(
|
||||
r#"
|
||||
{ a <- apply "a" }
|
||||
"#
|
||||
),
|
||||
@r###"
|
||||
── UNAPPLIED RECORD BUILDER ────────────────────────────── /code/proj/Main.roc ─
|
||||
|
||||
This record builder was not applied to a function:
|
||||
|
||||
4│ { a <- apply "a" }
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
However, we need a function to construct the record.
|
||||
|
||||
Note: Functions must be applied directly. The pipe operator (|>) cannot be used.
|
||||
"###
|
||||
);
|
||||
|
||||
test_report!(
|
||||
destructure_assignment_introduces_no_variables_nested,
|
||||
indoc!(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue