mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 16:44:33 +00:00
factor out closure constraint generation
This commit is contained in:
parent
4db09b10aa
commit
e446ecd9a9
1 changed files with 60 additions and 24 deletions
|
@ -782,33 +782,22 @@ pub fn constrain_expr(
|
||||||
|
|
||||||
let defs_constraint = And(state.constraints);
|
let defs_constraint = And(state.constraints);
|
||||||
|
|
||||||
let mut tag_arguments = Vec::with_capacity(captured_symbols.len());
|
let closure_constraint = constrain_closure_size(
|
||||||
let mut captured_symbols_constraints = Vec::with_capacity(captured_symbols.len());
|
*name,
|
||||||
|
region,
|
||||||
for (symbol, var) in captured_symbols {
|
captured_symbols,
|
||||||
// make sure the variable is registered
|
closure_var,
|
||||||
vars.push(*var);
|
closure_ext_var,
|
||||||
|
&mut vars,
|
||||||
// this symbol is captured, so it must be part of the closure type
|
|
||||||
tag_arguments.push(Type::Variable(*var));
|
|
||||||
|
|
||||||
// make the variable equal to the looked-up type of symbol
|
|
||||||
captured_symbols_constraints.push(Constraint::Lookup(
|
|
||||||
*symbol,
|
|
||||||
Expected::NoExpectation(Type::Variable(*var)),
|
|
||||||
Region::zero(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let tag_name = roc_module::ident::TagName::Closure(*name);
|
|
||||||
let closure_type = Type::TagUnion(
|
|
||||||
vec![(tag_name, tag_arguments)],
|
|
||||||
Box::new(Type::Variable(closure_ext_var)),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let fn_type = attr_type(
|
let fn_type = attr_type(
|
||||||
fn_uniq_type,
|
fn_uniq_type,
|
||||||
Type::Function(pattern_types, Box::new(closure_type), Box::new(ret_type)),
|
Type::Function(
|
||||||
|
pattern_types,
|
||||||
|
Box::new(Type::Variable(closure_var)),
|
||||||
|
Box::new(ret_type),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
exists(
|
exists(
|
||||||
|
@ -831,7 +820,7 @@ pub fn constrain_expr(
|
||||||
Category::Lambda,
|
Category::Lambda,
|
||||||
region,
|
region,
|
||||||
),
|
),
|
||||||
Constraint::And(captured_symbols_constraints),
|
closure_constraint,
|
||||||
]),
|
]),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2295,6 +2284,53 @@ fn constrain_def(
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn constrain_closure_size(
|
||||||
|
name: Symbol,
|
||||||
|
region: Region,
|
||||||
|
captured_symbols: &[(Symbol, Variable)],
|
||||||
|
closure_var: Variable,
|
||||||
|
closure_ext_var: Variable,
|
||||||
|
variables: &mut Vec<Variable>,
|
||||||
|
) -> Constraint {
|
||||||
|
debug_assert!(variables.iter().any(|s| *s == closure_var));
|
||||||
|
debug_assert!(variables.iter().any(|s| *s == closure_ext_var));
|
||||||
|
|
||||||
|
let mut tag_arguments = Vec::with_capacity(captured_symbols.len());
|
||||||
|
let mut captured_symbols_constraints = Vec::with_capacity(captured_symbols.len());
|
||||||
|
|
||||||
|
for (symbol, var) in captured_symbols {
|
||||||
|
// make sure the variable is registered
|
||||||
|
variables.push(*var);
|
||||||
|
|
||||||
|
// this symbol is captured, so it must be part of the closure type
|
||||||
|
tag_arguments.push(Type::Variable(*var));
|
||||||
|
|
||||||
|
// make the variable equal to the looked-up type of symbol
|
||||||
|
captured_symbols_constraints.push(Constraint::Lookup(
|
||||||
|
*symbol,
|
||||||
|
Expected::NoExpectation(Type::Variable(*var)),
|
||||||
|
Region::zero(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let tag_name = roc_module::ident::TagName::Closure(name);
|
||||||
|
let closure_type = Type::TagUnion(
|
||||||
|
vec![(tag_name, tag_arguments)],
|
||||||
|
Box::new(Type::Variable(closure_ext_var)),
|
||||||
|
);
|
||||||
|
|
||||||
|
let finalizer = Eq(
|
||||||
|
Type::Variable(closure_var),
|
||||||
|
Expected::NoExpectation(closure_type),
|
||||||
|
Category::ClosureSize,
|
||||||
|
region,
|
||||||
|
);
|
||||||
|
|
||||||
|
captured_symbols_constraints.push(finalizer);
|
||||||
|
|
||||||
|
Constraint::And(captured_symbols_constraints)
|
||||||
|
}
|
||||||
|
|
||||||
fn instantiate_rigids(
|
fn instantiate_rigids(
|
||||||
var_store: &mut VarStore,
|
var_store: &mut VarStore,
|
||||||
annotation: &Type,
|
annotation: &Type,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue