mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 11:52:19 +00:00
parent
f2fc6e16ec
commit
59ab1da83f
4 changed files with 78 additions and 19 deletions
|
@ -5187,7 +5187,7 @@ pub fn with_hole<'a>(
|
|||
}
|
||||
}
|
||||
TypedHole(_) => Stmt::RuntimeError("Hit a blank"),
|
||||
RuntimeError(e) => Stmt::RuntimeError(env.arena.alloc(format!("{:?}", e))),
|
||||
RuntimeError(e) => Stmt::RuntimeError(env.arena.alloc(e.runtime_message())),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6047,7 +6047,9 @@ fn to_opt_branches<'a>(
|
|||
for loc_pattern in when_branch.patterns {
|
||||
match from_can_pattern(env, procs, layout_cache, &loc_pattern.pattern.value) {
|
||||
Ok((mono_pattern, assignments)) => {
|
||||
let loc_expr = if !loc_pattern.degenerate {
|
||||
let mut loc_expr = when_branch.value.clone();
|
||||
|
||||
let region = loc_pattern.pattern.region;
|
||||
for (symbol, variable, expr) in assignments.into_iter().rev() {
|
||||
let def = roc_can::def::Def {
|
||||
|
@ -6065,6 +6067,15 @@ fn to_opt_branches<'a>(
|
|||
loc_expr = Loc::at(region, new_expr);
|
||||
}
|
||||
|
||||
loc_expr
|
||||
} else {
|
||||
// This pattern is degenerate; when it's reached we must emit a runtime
|
||||
// error.
|
||||
Loc::at_zero(roc_can::expr::Expr::RuntimeError(
|
||||
RuntimeError::DegenerateBranch(loc_pattern.pattern.region),
|
||||
))
|
||||
};
|
||||
|
||||
// TODO remove clone?
|
||||
opt_branches.push((mono_pattern, when_branch.guard.clone(), loc_expr.value));
|
||||
}
|
||||
|
|
|
@ -329,6 +329,24 @@ pub enum RuntimeError {
|
|||
EmptySingleQuote(Region),
|
||||
/// where 'aa'
|
||||
MultipleCharsInSingleQuote(Region),
|
||||
|
||||
DegenerateBranch(Region),
|
||||
}
|
||||
|
||||
impl RuntimeError {
|
||||
pub fn runtime_message(self) -> String {
|
||||
use RuntimeError::*;
|
||||
|
||||
match self {
|
||||
DegenerateBranch(region) => {
|
||||
format!(
|
||||
"Hit a branch pattern that does not bind all symbols its body needs, at {:?}",
|
||||
region
|
||||
)
|
||||
}
|
||||
err => format!("{:?}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
|
|
|
@ -3690,6 +3690,28 @@ fn symbol_not_bound_in_all_patterns_runs_when_bound_pattern_reached() {
|
|||
"#
|
||||
),
|
||||
15u8,
|
||||
u8
|
||||
u8,
|
||||
|x| x,
|
||||
true // allow errors
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
#[should_panic(
|
||||
expected = r#"Roc failed with message: "Hit a branch pattern that does not bind all symbols its body needs"#
|
||||
)]
|
||||
fn runtime_error_when_degenerate_pattern_reached() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
when B 15u8 is
|
||||
A x | B y -> x + 5u8
|
||||
"#
|
||||
),
|
||||
15u8,
|
||||
u8,
|
||||
|x| x,
|
||||
true // allow errors
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1899,6 +1899,14 @@ fn pretty_runtime_error<'b>(
|
|||
|
||||
title = OPAQUE_OVER_APPLIED;
|
||||
}
|
||||
RuntimeError::DegenerateBranch(region) => {
|
||||
doc = alloc.stack([
|
||||
alloc.reflow("This branch pattern does not bind all symbols its body needs:"),
|
||||
alloc.region(lines.convert_region(region)),
|
||||
]);
|
||||
|
||||
title = "DEGENERATE BRANCH";
|
||||
}
|
||||
}
|
||||
|
||||
(doc, title)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue