Implement return keyword

This commit is contained in:
Sam Mohr 2024-10-20 04:50:12 -07:00
parent 20a539a96d
commit b3e60f9d3a
No known key found for this signature in database
GPG key ID: EA41D161A3C1BC99
39 changed files with 594 additions and 80 deletions

View file

@ -113,6 +113,7 @@ fn constrain_untyped_closure(
fn_var: Variable,
closure_var: Variable,
ret_var: Variable,
early_returns: &[(Variable, Region)],
arguments: &[(Variable, AnnotatedMark, Loc<Pattern>)],
loc_body_expr: &Loc<Expr>,
captured_symbols: &[(Symbol, Variable)],
@ -134,7 +135,12 @@ fn constrain_untyped_closure(
vars.push(closure_var);
vars.push(fn_var);
let body_type = constraints.push_expected_type(NoExpectation(return_type_index));
let body_type = constraints.push_expected_type(ForReason(
Reason::Return,
return_type_index,
loc_body_expr.region,
));
let ret_constraint = constrain_expr(
types,
constraints,
@ -144,6 +150,21 @@ fn constrain_untyped_closure(
body_type,
);
let mut early_return_constraints = Vec::with_capacity(early_returns.len());
for (early_return_variable, early_return_region) in early_returns {
let early_return_var = constraints.push_variable(*early_return_variable);
let early_return_con = constraints.equal_types(
early_return_var,
body_type,
Category::Return,
*early_return_region,
);
early_return_constraints.push(early_return_con);
}
let early_returns_constraint = constraints.and_constraint(early_return_constraints);
// make sure the captured symbols are sorted!
debug_assert_eq!(captured_symbols.to_vec(), {
let mut copy = captured_symbols.to_vec();
@ -185,6 +206,7 @@ fn constrain_untyped_closure(
region,
fn_var,
),
early_returns_constraint,
closure_constraint,
];
@ -624,6 +646,7 @@ pub fn constrain_expr(
function_type: fn_var,
closure_type: closure_var,
return_type: ret_var,
early_returns,
arguments,
loc_body: boxed,
captured_symbols,
@ -640,6 +663,7 @@ pub fn constrain_expr(
*fn_var,
*closure_var,
*ret_var,
early_returns,
arguments,
boxed,
captured_symbols,
@ -1378,6 +1402,29 @@ pub fn constrain_expr(
body_con
}
Return {
return_value,
return_var,
} => {
let return_type_index = constraints.push_variable(*return_var);
let expected_return_value = constraints.push_expected_type(ForReason(
Reason::Return,
return_type_index,
return_value.region,
));
let return_con = constrain_expr(
types,
constraints,
env,
return_value.region,
&return_value.value,
expected_return_value,
);
constraints.exists([*return_var], return_con)
}
Tag {
tag_union_var: variant_var,
ext_var,
@ -1870,6 +1917,7 @@ fn constrain_function_def(
expr_var,
function_def.closure_type,
function_def.return_type,
&function_def.early_returns,
&function_def.arguments,
loc_body_expr,
&function_def.captured_symbols,
@ -2071,6 +2119,7 @@ fn constrain_function_def(
expr_var,
function_def.closure_type,
function_def.return_type,
&function_def.early_returns,
&function_def.arguments,
loc_expr,
&function_def.captured_symbols,
@ -3651,6 +3700,7 @@ fn constraint_recursive_function(
expr_var,
function_def.closure_type,
function_def.return_type,
&function_def.early_returns,
&function_def.arguments,
loc_expr,
&function_def.captured_symbols,
@ -4133,6 +4183,7 @@ fn is_generalizable_expr(mut expr: &Expr) -> bool {
| Expect { .. }
| ExpectFx { .. }
| Dbg { .. }
| Return { .. }
| TypedHole(_)
| RuntimeError(..)
| ZeroArgumentTag { .. }