mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-22 00:09:33 +03:00
Fix regression with ZeroArgumentTag constraint gen
Turns out it can't share quite that much code with Tag, because doing so skips the important function-based constraints.
This commit is contained in:
parent
b2ff785a5e
commit
dd56fdb61c
@ -880,31 +880,70 @@ pub fn constrain_expr(
|
||||
ext_var,
|
||||
name,
|
||||
arguments,
|
||||
} => constrain_tag(
|
||||
constraints,
|
||||
env,
|
||||
expected,
|
||||
region,
|
||||
*variant_var,
|
||||
*ext_var,
|
||||
name,
|
||||
arguments,
|
||||
),
|
||||
} => {
|
||||
// +2 because we push all the arguments, plus variant_var and ext_var
|
||||
let num_vars = arguments.len() + 2;
|
||||
let mut vars = Vec::with_capacity(num_vars);
|
||||
let mut types = Vec::with_capacity(arguments.len());
|
||||
let mut arg_cons = Vec::with_capacity(arguments.len());
|
||||
|
||||
for (var, loc_expr) in arguments {
|
||||
let arg_con = constrain_expr(
|
||||
constraints,
|
||||
env,
|
||||
loc_expr.region,
|
||||
&loc_expr.value,
|
||||
Expected::NoExpectation(Type::Variable(*var)),
|
||||
);
|
||||
|
||||
arg_cons.push(arg_con);
|
||||
vars.push(*var);
|
||||
types.push(Type::Variable(*var));
|
||||
}
|
||||
|
||||
let union_con = constraints.equal_types_with_storage(
|
||||
Type::TagUnion(
|
||||
vec![(name.clone(), types)],
|
||||
TypeExtension::from_type(Type::Variable(*ext_var)),
|
||||
),
|
||||
expected.clone(),
|
||||
Category::TagApply {
|
||||
tag_name: name.clone(),
|
||||
args_count: arguments.len(),
|
||||
},
|
||||
region,
|
||||
*variant_var,
|
||||
);
|
||||
|
||||
vars.push(*variant_var);
|
||||
vars.push(*ext_var);
|
||||
arg_cons.push(union_con);
|
||||
|
||||
constraints.exists_many(vars, arg_cons)
|
||||
}
|
||||
ZeroArgumentTag {
|
||||
variant_var,
|
||||
ext_var,
|
||||
name,
|
||||
closure_name: _,
|
||||
} => constrain_tag(
|
||||
constraints,
|
||||
env,
|
||||
expected,
|
||||
region,
|
||||
*variant_var,
|
||||
*ext_var,
|
||||
name,
|
||||
&[],
|
||||
),
|
||||
closure_name,
|
||||
} => {
|
||||
let union_con = constraints.equal_types_with_storage(
|
||||
Type::FunctionOrTagUnion(
|
||||
name.clone(),
|
||||
*closure_name,
|
||||
TypeExtension::from_type(Type::Variable(*ext_var)),
|
||||
),
|
||||
expected.clone(),
|
||||
Category::TagApply {
|
||||
tag_name: name.clone(),
|
||||
args_count: 0,
|
||||
},
|
||||
region,
|
||||
*variant_var,
|
||||
);
|
||||
|
||||
constraints.exists_many(vec![*variant_var, *ext_var], vec![union_con])
|
||||
}
|
||||
OpaqueRef {
|
||||
opaque_var,
|
||||
name,
|
||||
@ -1986,56 +2025,3 @@ fn constrain_field_update(
|
||||
|
||||
(var, field_type, con)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn constrain_tag(
|
||||
constraints: &mut Constraints,
|
||||
env: &Env,
|
||||
expected: Expected<Type>,
|
||||
region: Region,
|
||||
variant_var: Variable,
|
||||
ext_var: Variable,
|
||||
name: &TagName,
|
||||
arguments: &[(Variable, Loc<Expr>)],
|
||||
) -> Constraint {
|
||||
// +2 because we push all the arguments, plus variant_var and ext_var
|
||||
let num_vars = arguments.len() + 2;
|
||||
|
||||
let mut vars = Vec::with_capacity(num_vars);
|
||||
let mut types = Vec::with_capacity(arguments.len());
|
||||
let mut arg_cons = Vec::with_capacity(arguments.len());
|
||||
|
||||
for (var, loc_expr) in arguments {
|
||||
let arg_con = constrain_expr(
|
||||
constraints,
|
||||
env,
|
||||
loc_expr.region,
|
||||
&loc_expr.value,
|
||||
Expected::NoExpectation(Type::Variable(*var)),
|
||||
);
|
||||
|
||||
arg_cons.push(arg_con);
|
||||
vars.push(*var);
|
||||
types.push(Type::Variable(*var));
|
||||
}
|
||||
|
||||
let union_con = constraints.equal_types_with_storage(
|
||||
Type::TagUnion(
|
||||
vec![(name.clone(), types)],
|
||||
TypeExtension::from_type(Type::Variable(ext_var)),
|
||||
),
|
||||
expected,
|
||||
Category::TagApply {
|
||||
tag_name: name.clone(),
|
||||
args_count: arguments.len(),
|
||||
},
|
||||
region,
|
||||
variant_var,
|
||||
);
|
||||
|
||||
vars.push(variant_var);
|
||||
vars.push(ext_var);
|
||||
arg_cons.push(union_con);
|
||||
|
||||
constraints.exists_many(vars, arg_cons)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user