mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 08:11:12 +00:00
Recursive functions must be shared
This commit is contained in:
parent
dbe615b4c5
commit
50f8bf1856
3 changed files with 58 additions and 13 deletions
|
@ -459,7 +459,9 @@ pub fn constrain_expr(
|
|||
expected,
|
||||
)
|
||||
}
|
||||
Closure(fn_var, _symbol, _recursion, args, boxed) => {
|
||||
Closure(fn_var, _symbol, recursion, args, boxed) => {
|
||||
use crate::can::expr::Recursive;
|
||||
|
||||
let (loc_body_expr, ret_var) = &**boxed;
|
||||
let mut state = PatternState {
|
||||
headers: SendMap::default(),
|
||||
|
@ -485,11 +487,18 @@ pub fn constrain_expr(
|
|||
vars.push(*pattern_var);
|
||||
}
|
||||
|
||||
let fn_uniq_var = var_store.fresh();
|
||||
vars.push(fn_uniq_var);
|
||||
let fn_uniq_type;
|
||||
if let Recursive::NotRecursive = recursion {
|
||||
let fn_uniq_var = var_store.fresh();
|
||||
vars.push(fn_uniq_var);
|
||||
fn_uniq_type = Bool::Variable(fn_uniq_var);
|
||||
} else {
|
||||
// recursive definitions MUST be Shared
|
||||
fn_uniq_type = Bool::Zero
|
||||
}
|
||||
|
||||
let fn_type = constrain::attr_type(
|
||||
Bool::Variable(fn_uniq_var),
|
||||
fn_uniq_type,
|
||||
Type::Function(pattern_types, Box::new(ret_type.clone())),
|
||||
);
|
||||
let body_type = Expected::NoExpectation(ret_type);
|
||||
|
|
|
@ -1246,12 +1246,12 @@ mod test_infer {
|
|||
);
|
||||
}
|
||||
|
||||
// TODO add more realistic function when able
|
||||
#[test]
|
||||
fn integer_sum() {
|
||||
with_larger_debug_stack(|| {
|
||||
infer_eq_without_problem(
|
||||
indoc!(
|
||||
r#"
|
||||
infer_eq_without_problem(
|
||||
indoc!(
|
||||
r#"
|
||||
f = \n ->
|
||||
when n is
|
||||
0 -> 0
|
||||
|
@ -1259,10 +1259,9 @@ mod test_infer {
|
|||
|
||||
f
|
||||
"#
|
||||
),
|
||||
"Int -> Int",
|
||||
);
|
||||
});
|
||||
),
|
||||
"Int -> Int",
|
||||
);
|
||||
}
|
||||
|
||||
// currently fails, the rank of Cons's ext_var is 3, where 2 is the highest pool
|
||||
|
|
|
@ -1231,4 +1231,41 @@ mod test_infer_uniq {
|
|||
"Attr.Attr * Int",
|
||||
);
|
||||
}
|
||||
|
||||
// TODO add more realistic recursive example when able
|
||||
#[test]
|
||||
fn factorial_is_shared() {
|
||||
infer_eq_without_problem(
|
||||
indoc!(
|
||||
r#"
|
||||
factorial = \n ->
|
||||
when n is
|
||||
0 -> 1
|
||||
1 -> 1
|
||||
m -> factorial m
|
||||
|
||||
factorial
|
||||
"#
|
||||
),
|
||||
"Attr.Attr Attr.Shared (Attr.Attr * Int -> Attr.Attr * Int)",
|
||||
);
|
||||
}
|
||||
|
||||
// TODO add more realistic recursive example when able
|
||||
#[test]
|
||||
fn factorial_without_recursive_case_can_be_unique() {
|
||||
infer_eq_without_problem(
|
||||
indoc!(
|
||||
r#"
|
||||
factorial = \n ->
|
||||
when n is
|
||||
0 -> 1
|
||||
_ -> 1
|
||||
|
||||
factorial
|
||||
"#
|
||||
),
|
||||
"Attr.Attr * (Attr.Attr * Int -> Attr.Attr * Int)",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue