mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 08:34:33 +00:00
Store lookups for expect report in Expr::Expect
This commit is contained in:
parent
b777b88e1c
commit
af7eda34a0
4 changed files with 143 additions and 20 deletions
|
@ -189,7 +189,11 @@ pub enum Expr {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Test
|
// Test
|
||||||
Expect(Box<Loc<Expr>>, Box<Loc<Expr>>),
|
Expect {
|
||||||
|
loc_condition: Box<Loc<Expr>>,
|
||||||
|
loc_continuation: Box<Loc<Expr>>,
|
||||||
|
lookups_in_cond: Vec<Symbol>,
|
||||||
|
},
|
||||||
|
|
||||||
// Compiles, but will crash if reached
|
// Compiles, but will crash if reached
|
||||||
RuntimeError(RuntimeError),
|
RuntimeError(RuntimeError),
|
||||||
|
@ -852,6 +856,12 @@ pub fn canonicalize_expr<'a>(
|
||||||
let (loc_condition, output1) =
|
let (loc_condition, output1) =
|
||||||
canonicalize_expr(env, var_store, scope, condition.region, &condition.value);
|
canonicalize_expr(env, var_store, scope, condition.region, &condition.value);
|
||||||
|
|
||||||
|
let mut lookups_in_cond = Vec::new();
|
||||||
|
|
||||||
|
// Get all the lookups that were referenced in the condition,
|
||||||
|
// so we can print their values later.
|
||||||
|
add_lookup_symbols(&loc_condition.value, &mut lookups_in_cond);
|
||||||
|
|
||||||
let (loc_continuation, output2) = canonicalize_expr(
|
let (loc_continuation, output2) = canonicalize_expr(
|
||||||
env,
|
env,
|
||||||
var_store,
|
var_store,
|
||||||
|
@ -864,7 +874,11 @@ pub fn canonicalize_expr<'a>(
|
||||||
output.union(output2);
|
output.union(output2);
|
||||||
|
|
||||||
(
|
(
|
||||||
Expect(Box::new(loc_condition), Box::new(loc_continuation)),
|
Expect {
|
||||||
|
loc_condition: Box::new(loc_condition),
|
||||||
|
loc_continuation: Box::new(loc_continuation),
|
||||||
|
lookups_in_cond,
|
||||||
|
},
|
||||||
output,
|
output,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1407,18 +1421,26 @@ pub fn inline_calls(var_store: &mut VarStore, scope: &mut Scope, expr: Expr) ->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Expect(loc_condition, loc_expr) => {
|
Expect {
|
||||||
|
loc_condition,
|
||||||
|
loc_continuation,
|
||||||
|
lookups_in_cond,
|
||||||
|
} => {
|
||||||
let loc_condition = Loc {
|
let loc_condition = Loc {
|
||||||
region: loc_condition.region,
|
region: loc_condition.region,
|
||||||
value: inline_calls(var_store, scope, loc_condition.value),
|
value: inline_calls(var_store, scope, loc_condition.value),
|
||||||
};
|
};
|
||||||
|
|
||||||
let loc_expr = Loc {
|
let loc_continuation = Loc {
|
||||||
region: loc_expr.region,
|
region: loc_continuation.region,
|
||||||
value: inline_calls(var_store, scope, loc_expr.value),
|
value: inline_calls(var_store, scope, loc_continuation.value),
|
||||||
};
|
};
|
||||||
|
|
||||||
Expect(Box::new(loc_condition), Box::new(loc_expr))
|
Expect {
|
||||||
|
loc_condition: Box::new(loc_condition),
|
||||||
|
loc_continuation: Box::new(loc_continuation),
|
||||||
|
lookups_in_cond,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LetRec(defs, loc_expr, var) => {
|
LetRec(defs, loc_expr, var) => {
|
||||||
|
@ -1820,3 +1842,92 @@ pub fn unescape_char(escaped: &EscapedChar) -> char {
|
||||||
Newline => '\n',
|
Newline => '\n',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_lookup_symbols(expr: &Expr, symbols: &mut Vec<Symbol>) {
|
||||||
|
match expr {
|
||||||
|
Expr::Var(symbol) | Expr::Update { symbol, .. } => {
|
||||||
|
symbols.push(*symbol);
|
||||||
|
}
|
||||||
|
Expr::List { loc_elems, .. } => {
|
||||||
|
for loc_elem in loc_elems {
|
||||||
|
add_lookup_symbols(&loc_elem.value, symbols);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::When {
|
||||||
|
loc_cond, branches, ..
|
||||||
|
} => {
|
||||||
|
add_lookup_symbols(&loc_cond.value, symbols);
|
||||||
|
|
||||||
|
for branch in branches {
|
||||||
|
add_lookup_symbols(&branch.value.value, symbols);
|
||||||
|
|
||||||
|
if let Some(guard) = &branch.guard {
|
||||||
|
add_lookup_symbols(&guard.value, symbols);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::If {
|
||||||
|
branches,
|
||||||
|
final_else,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
for (loc_cond, loc_body) in branches {
|
||||||
|
add_lookup_symbols(&loc_cond.value, symbols);
|
||||||
|
add_lookup_symbols(&loc_body.value, symbols);
|
||||||
|
}
|
||||||
|
|
||||||
|
add_lookup_symbols(&final_else.value, symbols);
|
||||||
|
}
|
||||||
|
Expr::LetRec(_, _, _) => todo!(),
|
||||||
|
Expr::LetNonRec(_, _, _) => todo!(),
|
||||||
|
Expr::Call(boxed_expr, args, _called_via) => {
|
||||||
|
// add the expr being called
|
||||||
|
add_lookup_symbols(&boxed_expr.1.value, symbols);
|
||||||
|
|
||||||
|
for (_var, loc_arg) in args {
|
||||||
|
add_lookup_symbols(&loc_arg.value, symbols);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::Tag { arguments, .. } => {
|
||||||
|
for (_var, loc_expr) in arguments {
|
||||||
|
add_lookup_symbols(&loc_expr.value, symbols);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::RunLowLevel { args, .. } | Expr::ForeignCall { args, .. } => {
|
||||||
|
for (_var, arg) in args {
|
||||||
|
add_lookup_symbols(arg, symbols);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::OpaqueRef { argument, .. } => {
|
||||||
|
add_lookup_symbols(&argument.1.value, symbols);
|
||||||
|
}
|
||||||
|
Expr::Access { loc_expr, .. }
|
||||||
|
| Expr::Closure(ClosureData {
|
||||||
|
loc_body: loc_expr, ..
|
||||||
|
}) => {
|
||||||
|
add_lookup_symbols(&loc_expr.value, symbols);
|
||||||
|
}
|
||||||
|
Expr::Record { fields, .. } => {
|
||||||
|
for field in fields.values() {
|
||||||
|
add_lookup_symbols(&field.loc_expr.value, symbols);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::Expect {
|
||||||
|
loc_continuation, ..
|
||||||
|
} => {
|
||||||
|
add_lookup_symbols(&(*loc_continuation).value, symbols);
|
||||||
|
|
||||||
|
// Intentionally ignore the lookups in the nested `expect` condition itself,
|
||||||
|
// because they couldn't possibly influence the outcome of this `expect`!
|
||||||
|
}
|
||||||
|
Expr::Num(_, _, _, _)
|
||||||
|
| Expr::Float(_, _, _, _, _)
|
||||||
|
| Expr::Int(_, _, _, _, _)
|
||||||
|
| Expr::Str(_)
|
||||||
|
| Expr::ZeroArgumentTag { .. }
|
||||||
|
| Expr::Accessor(_)
|
||||||
|
| Expr::SingleQuote(_)
|
||||||
|
| Expr::EmptyRecord
|
||||||
|
| Expr::RuntimeError(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -611,9 +611,13 @@ fn fix_values_captured_in_closure_expr(
|
||||||
fix_values_captured_in_closure_expr(&mut loc_expr.value, no_capture_symbols);
|
fix_values_captured_in_closure_expr(&mut loc_expr.value, no_capture_symbols);
|
||||||
}
|
}
|
||||||
|
|
||||||
Expect(condition, loc_expr) => {
|
Expect {
|
||||||
fix_values_captured_in_closure_expr(&mut condition.value, no_capture_symbols);
|
loc_condition,
|
||||||
fix_values_captured_in_closure_expr(&mut loc_expr.value, no_capture_symbols);
|
loc_continuation,
|
||||||
|
lookups_in_cond: _,
|
||||||
|
} => {
|
||||||
|
fix_values_captured_in_closure_expr(&mut loc_condition.value, no_capture_symbols);
|
||||||
|
fix_values_captured_in_closure_expr(&mut loc_continuation.value, no_capture_symbols);
|
||||||
}
|
}
|
||||||
|
|
||||||
Closure(ClosureData {
|
Closure(ClosureData {
|
||||||
|
|
|
@ -413,7 +413,11 @@ pub fn constrain_expr(
|
||||||
constraints.exists_many(vars, cons)
|
constraints.exists_many(vars, cons)
|
||||||
}
|
}
|
||||||
|
|
||||||
Expect(loc_cond, continuation) => {
|
Expect {
|
||||||
|
loc_condition,
|
||||||
|
loc_continuation,
|
||||||
|
lookups_in_cond: _,
|
||||||
|
} => {
|
||||||
let expect_bool = |region| {
|
let expect_bool = |region| {
|
||||||
let bool_type = Type::Variable(Variable::BOOL);
|
let bool_type = Type::Variable(Variable::BOOL);
|
||||||
Expected::ForReason(Reason::ExpectCondition, bool_type, region)
|
Expected::ForReason(Reason::ExpectCondition, bool_type, region)
|
||||||
|
@ -422,16 +426,16 @@ pub fn constrain_expr(
|
||||||
let cond_con = constrain_expr(
|
let cond_con = constrain_expr(
|
||||||
constraints,
|
constraints,
|
||||||
env,
|
env,
|
||||||
loc_cond.region,
|
loc_condition.region,
|
||||||
&loc_cond.value,
|
&loc_condition.value,
|
||||||
expect_bool(loc_cond.region),
|
expect_bool(loc_condition.region),
|
||||||
);
|
);
|
||||||
|
|
||||||
let continuation_con = constrain_expr(
|
let continuation_con = constrain_expr(
|
||||||
constraints,
|
constraints,
|
||||||
env,
|
env,
|
||||||
continuation.region,
|
loc_continuation.region,
|
||||||
&continuation.value,
|
&loc_continuation.value,
|
||||||
expected,
|
expected,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -3586,7 +3586,7 @@ pub fn with_hole<'a>(
|
||||||
|
|
||||||
EmptyRecord => let_empty_struct(assigned, hole),
|
EmptyRecord => let_empty_struct(assigned, hole),
|
||||||
|
|
||||||
Expect(_, _) => unreachable!("I think this is unreachable"),
|
Expect { .. } => unreachable!("I think this is unreachable"),
|
||||||
|
|
||||||
If {
|
If {
|
||||||
cond_var,
|
cond_var,
|
||||||
|
@ -5408,8 +5408,12 @@ pub fn from_can<'a>(
|
||||||
stmt
|
stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
Expect(condition, rest) => {
|
Expect {
|
||||||
let rest = from_can(env, variable, rest.value, procs, layout_cache);
|
loc_condition,
|
||||||
|
loc_continuation,
|
||||||
|
lookups_in_cond,
|
||||||
|
} => {
|
||||||
|
let rest = from_can(env, variable, loc_continuation.value, procs, layout_cache);
|
||||||
|
|
||||||
let bool_layout = Layout::Builtin(Builtin::Bool);
|
let bool_layout = Layout::Builtin(Builtin::Bool);
|
||||||
let cond_symbol = env.unique_symbol();
|
let cond_symbol = env.unique_symbol();
|
||||||
|
@ -5434,7 +5438,7 @@ pub fn from_can<'a>(
|
||||||
|
|
||||||
with_hole(
|
with_hole(
|
||||||
env,
|
env,
|
||||||
condition.value,
|
loc_condition.value,
|
||||||
variable,
|
variable,
|
||||||
procs,
|
procs,
|
||||||
layout_cache,
|
layout_cache,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue