mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 04:08:19 +00:00
parent
8c32900e19
commit
b46392311e
2 changed files with 85 additions and 41 deletions
|
@ -1782,7 +1782,7 @@ fn constrain_function_def(
|
|||
|
||||
let signature_index = constraints.push_type(types, signature);
|
||||
|
||||
let (arg_types, signature_closure_type, ret_type) = match types[signature] {
|
||||
let (arg_types, _signature_closure_type, ret_type) = match types[signature] {
|
||||
TypeTag::Function(signature_closure_type, ret_type) => (
|
||||
types.get_type_arguments(signature),
|
||||
signature_closure_type,
|
||||
|
@ -1888,13 +1888,12 @@ fn constrain_function_def(
|
|||
delayed_is_open_constraints: vec![],
|
||||
};
|
||||
let mut vars = Vec::with_capacity(argument_pattern_state.vars.capacity() + 1);
|
||||
let ret_var = function_def.return_type;
|
||||
let closure_var = function_def.closure_type;
|
||||
|
||||
let ret_type_index = constraints.push_type(types, ret_type);
|
||||
|
||||
vars.push(ret_var);
|
||||
vars.push(closure_var);
|
||||
vars.push(function_def.return_type);
|
||||
vars.push(function_def.closure_type);
|
||||
|
||||
let mut def_pattern_state = PatternState::default();
|
||||
|
||||
|
@ -1913,21 +1912,22 @@ fn constrain_function_def(
|
|||
|
||||
// TODO see if we can get away with not adding this constraint at all
|
||||
def_pattern_state.vars.push(expr_var);
|
||||
let annotation_expected = FromAnnotation(
|
||||
loc_pattern.clone(),
|
||||
arity,
|
||||
AnnotationSource::TypedBody {
|
||||
region: annotation.region,
|
||||
},
|
||||
signature_index,
|
||||
);
|
||||
let annotation_expected = {
|
||||
constraints.push_expected_type(FromAnnotation(
|
||||
loc_pattern.clone(),
|
||||
arity,
|
||||
AnnotationSource::TypedBody {
|
||||
region: annotation.region,
|
||||
},
|
||||
signature_index,
|
||||
))
|
||||
};
|
||||
|
||||
{
|
||||
let expr_type_index = constraints.push_variable(expr_var);
|
||||
let expected_index = constraints.push_expected_type(annotation_expected);
|
||||
def_pattern_state.constraints.push(constraints.equal_types(
|
||||
expr_type_index,
|
||||
expected_index,
|
||||
annotation_expected,
|
||||
Category::Storage(std::file!(), std::line!()),
|
||||
Region::span_across(&annotation.region, &loc_body_expr.region),
|
||||
));
|
||||
|
@ -1955,7 +1955,7 @@ fn constrain_function_def(
|
|||
&mut vars,
|
||||
);
|
||||
|
||||
let annotation_expected = constraints.push_expected_type(FromAnnotation(
|
||||
let return_type_annotation_expected = constraints.push_expected_type(FromAnnotation(
|
||||
loc_pattern.clone(),
|
||||
arity,
|
||||
AnnotationSource::TypedBody {
|
||||
|
@ -1964,31 +1964,34 @@ fn constrain_function_def(
|
|||
ret_type_index,
|
||||
));
|
||||
|
||||
let ret_constraint = constrain_expr(
|
||||
types,
|
||||
constraints,
|
||||
env,
|
||||
loc_body_expr.region,
|
||||
&loc_body_expr.value,
|
||||
annotation_expected,
|
||||
);
|
||||
let ret_constraint = attach_resolution_constraints(constraints, env, ret_constraint);
|
||||
let solved_fn_type = {
|
||||
// TODO(types-soa) optimize for Variable
|
||||
let pattern_types = types.from_old_type_slice(
|
||||
function_def.arguments.iter().map(|a| Type::Variable(a.0)),
|
||||
);
|
||||
let lambda_set = types.from_old_type(&Type::Variable(function_def.closure_type));
|
||||
let ret_var = types.from_old_type(&Type::Variable(function_def.return_type));
|
||||
|
||||
let fn_type = types.function(pattern_types, lambda_set, ret_var);
|
||||
constraints.push_type(types, fn_type)
|
||||
};
|
||||
|
||||
let ret_constraint = {
|
||||
let con = constrain_expr(
|
||||
types,
|
||||
constraints,
|
||||
env,
|
||||
loc_body_expr.region,
|
||||
&loc_body_expr.value,
|
||||
return_type_annotation_expected,
|
||||
);
|
||||
attach_resolution_constraints(constraints, env, con)
|
||||
};
|
||||
|
||||
vars.push(expr_var);
|
||||
|
||||
let defs_constraint = constraints.and_constraint(argument_pattern_state.constraints);
|
||||
|
||||
let signature_closure_type = {
|
||||
let signature_closure_type_index =
|
||||
constraints.push_type(types, signature_closure_type);
|
||||
constraints.push_expected_type(Expected::FromAnnotation(
|
||||
loc_pattern,
|
||||
arity,
|
||||
AnnotationSource::TypedBody {
|
||||
region: annotation.region,
|
||||
},
|
||||
signature_closure_type_index,
|
||||
))
|
||||
};
|
||||
let cons = [
|
||||
constraints.let_constraint(
|
||||
[],
|
||||
|
@ -1999,14 +2002,24 @@ fn constrain_function_def(
|
|||
// This is a syntactic function, it can be generalized
|
||||
Generalizable(true),
|
||||
),
|
||||
constraints.equal_types_var(
|
||||
closure_var,
|
||||
signature_closure_type,
|
||||
Category::ClosureSize,
|
||||
// Store the inferred ret var into the function type now, so that
|
||||
// when we check that the solved function type matches the annotation, we can
|
||||
// display the fully inferred return variable.
|
||||
constraints.store(
|
||||
ret_type_index,
|
||||
function_def.return_type,
|
||||
std::file!(),
|
||||
std::line!(),
|
||||
),
|
||||
// Now, check the solved function type matches the annotation.
|
||||
constraints.equal_types(
|
||||
solved_fn_type,
|
||||
annotation_expected,
|
||||
Category::Lambda,
|
||||
region,
|
||||
),
|
||||
// Finally put the solved closure type into the dedicated def expr variable.
|
||||
constraints.store(signature_index, expr_var, std::file!(), std::line!()),
|
||||
constraints.store(ret_type_index, ret_var, std::file!(), std::line!()),
|
||||
closure_constraint,
|
||||
];
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue