mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 22:34:45 +00:00
don't even create a type if we only need a variable
This commit is contained in:
parent
eccb461b01
commit
8b2c1707d4
3 changed files with 81 additions and 76 deletions
|
@ -136,8 +136,8 @@ pub fn constrain_expr(
|
|||
rec_constraints.push(record_con);
|
||||
|
||||
// variable to store in the AST
|
||||
let stored_con = constraints.equal_types(
|
||||
Type::Variable(*record_var),
|
||||
let stored_con = constraints.equal_types_var(
|
||||
*record_var,
|
||||
expected,
|
||||
Category::Storage(std::file!(), std::line!()),
|
||||
region,
|
||||
|
@ -177,14 +177,14 @@ pub fn constrain_expr(
|
|||
let record_type = Type::Variable(*record_var);
|
||||
|
||||
// NOTE from elm compiler: fields_type is separate so that Error propagates better
|
||||
let fields_con = constraints.equal_types(
|
||||
record_type.clone(),
|
||||
let fields_con = constraints.equal_types_var(
|
||||
*record_var,
|
||||
NoExpectation(fields_type),
|
||||
Category::Record,
|
||||
region,
|
||||
);
|
||||
let record_con =
|
||||
constraints.equal_types(record_type.clone(), expected, Category::Record, region);
|
||||
constraints.equal_types_var(*record_var, expected, Category::Record, region);
|
||||
|
||||
vars.push(*record_var);
|
||||
vars.push(*ext_var);
|
||||
|
@ -273,7 +273,7 @@ pub fn constrain_expr(
|
|||
|
||||
let fn_type = Variable(*fn_var);
|
||||
let fn_region = loc_fn.region;
|
||||
let fn_expected = NoExpectation(fn_type.clone());
|
||||
let fn_expected = NoExpectation(fn_type);
|
||||
|
||||
let fn_reason = Reason::FnCall {
|
||||
name: opt_symbol,
|
||||
|
@ -323,11 +323,7 @@ pub fn constrain_expr(
|
|||
|
||||
let expected_fn_type = ForReason(
|
||||
fn_reason,
|
||||
Function(
|
||||
arg_types,
|
||||
Box::new(closure_type),
|
||||
Box::new(ret_type.clone()),
|
||||
),
|
||||
Function(arg_types, Box::new(closure_type), Box::new(ret_type)),
|
||||
region,
|
||||
);
|
||||
|
||||
|
@ -335,9 +331,9 @@ pub fn constrain_expr(
|
|||
|
||||
let and_cons = [
|
||||
fn_con,
|
||||
constraints.equal_types(fn_type, expected_fn_type, category.clone(), fn_region),
|
||||
constraints.equal_types_var(*fn_var, expected_fn_type, category.clone(), fn_region),
|
||||
constraints.and_constraint(arg_cons),
|
||||
constraints.equal_types(ret_type, expected, category, region),
|
||||
constraints.equal_types_var(*ret_var, expected, category, region),
|
||||
];
|
||||
|
||||
let and_constraint = constraints.and_constraint(and_cons);
|
||||
|
@ -418,8 +414,8 @@ pub fn constrain_expr(
|
|||
// "the closure's type is equal to expected type"
|
||||
constraints.equal_types(function_type.clone(), expected, Category::Lambda, region),
|
||||
// "fn_var is equal to the closure's type" - fn_var is used in code gen
|
||||
constraints.equal_types(
|
||||
Type::Variable(*fn_var),
|
||||
constraints.equal_types_var(
|
||||
*fn_var,
|
||||
NoExpectation(function_type),
|
||||
Category::Storage(std::file!(), std::line!()),
|
||||
region,
|
||||
|
@ -469,8 +465,8 @@ pub fn constrain_expr(
|
|||
|
||||
// TODO why does this cond var exist? is it for error messages?
|
||||
let first_cond_region = branches[0].0.region;
|
||||
let cond_var_is_bool_con = constraints.equal_types(
|
||||
Type::Variable(*cond_var),
|
||||
let cond_var_is_bool_con = constraints.equal_types_var(
|
||||
*cond_var,
|
||||
expect_bool(first_cond_region),
|
||||
Category::If,
|
||||
first_cond_region,
|
||||
|
@ -528,8 +524,8 @@ pub fn constrain_expr(
|
|||
),
|
||||
);
|
||||
|
||||
let ast_con = constraints.equal_types(
|
||||
Type::Variable(*branch_var),
|
||||
let ast_con = constraints.equal_types_var(
|
||||
*branch_var,
|
||||
NoExpectation(tipe),
|
||||
Category::Storage(std::file!(), std::line!()),
|
||||
region,
|
||||
|
@ -583,8 +579,8 @@ pub fn constrain_expr(
|
|||
),
|
||||
);
|
||||
|
||||
branch_cons.push(constraints.equal_types(
|
||||
Type::Variable(*branch_var),
|
||||
branch_cons.push(constraints.equal_types_var(
|
||||
*branch_var,
|
||||
expected,
|
||||
Category::Storage(std::file!(), std::line!()),
|
||||
region,
|
||||
|
@ -654,8 +650,8 @@ pub fn constrain_expr(
|
|||
branch_constraints.push(branch_con);
|
||||
}
|
||||
|
||||
branch_constraints.push(constraints.equal_types(
|
||||
typ,
|
||||
branch_constraints.push(constraints.equal_types_var(
|
||||
*expr_var,
|
||||
expected,
|
||||
Category::When,
|
||||
region,
|
||||
|
@ -665,7 +661,8 @@ pub fn constrain_expr(
|
|||
}
|
||||
|
||||
_ => {
|
||||
let branch_type = Variable(*expr_var);
|
||||
let branch_var = *expr_var;
|
||||
let branch_type = Variable(branch_var);
|
||||
let mut branch_cons = Vec::with_capacity(branches.len());
|
||||
|
||||
for (index, when_branch) in branches.iter().enumerate() {
|
||||
|
@ -703,8 +700,8 @@ pub fn constrain_expr(
|
|||
//
|
||||
// The return type of each branch must equal the return type of
|
||||
// the entire when-expression.
|
||||
branch_cons.push(constraints.equal_types(
|
||||
branch_type,
|
||||
branch_cons.push(constraints.equal_types_var(
|
||||
branch_var,
|
||||
expected,
|
||||
Category::When,
|
||||
region,
|
||||
|
@ -731,15 +728,15 @@ pub fn constrain_expr(
|
|||
let mut rec_field_types = SendMap::default();
|
||||
|
||||
let label = field.clone();
|
||||
rec_field_types.insert(label, RecordField::Demanded(field_type.clone()));
|
||||
rec_field_types.insert(label, RecordField::Demanded(field_type));
|
||||
|
||||
let record_type = Type::Record(rec_field_types, Box::new(ext_type));
|
||||
let record_expected = Expected::NoExpectation(record_type);
|
||||
|
||||
let category = Category::Access(field.clone());
|
||||
|
||||
let record_con = constraints.equal_types(
|
||||
Type::Variable(*record_var),
|
||||
let record_con = constraints.equal_types_var(
|
||||
*record_var,
|
||||
record_expected.clone(),
|
||||
category.clone(),
|
||||
region,
|
||||
|
@ -756,7 +753,7 @@ pub fn constrain_expr(
|
|||
record_expected,
|
||||
);
|
||||
|
||||
let eq = constraints.equal_types(field_type, expected, category, region);
|
||||
let eq = constraints.equal_types_var(field_var, expected, category, region);
|
||||
constraints.exists_many(
|
||||
[*record_var, field_var, ext_var],
|
||||
[constraint, eq, record_con],
|
||||
|
@ -785,12 +782,8 @@ pub fn constrain_expr(
|
|||
let category = Category::Accessor(field.clone());
|
||||
|
||||
let record_expected = Expected::NoExpectation(record_type.clone());
|
||||
let record_con = constraints.equal_types(
|
||||
Type::Variable(*record_var),
|
||||
record_expected,
|
||||
category.clone(),
|
||||
region,
|
||||
);
|
||||
let record_con =
|
||||
constraints.equal_types_var(*record_var, record_expected, category.clone(), region);
|
||||
|
||||
let lambda_set = Type::ClosureTag {
|
||||
name: *closure_name,
|
||||
|
@ -801,13 +794,13 @@ pub fn constrain_expr(
|
|||
|
||||
let function_type = Type::Function(
|
||||
vec![record_type],
|
||||
Box::new(closure_type.clone()),
|
||||
Box::new(closure_type),
|
||||
Box::new(field_type),
|
||||
);
|
||||
|
||||
let cons = [
|
||||
constraints.equal_types(
|
||||
closure_type,
|
||||
constraints.equal_types_var(
|
||||
*closure_var,
|
||||
NoExpectation(lambda_set),
|
||||
category.clone(),
|
||||
region,
|
||||
|
@ -847,8 +840,8 @@ pub fn constrain_expr(
|
|||
constrain_recursive_defs(constraints, env, defs, body_con),
|
||||
// Record the type of tne entire def-expression in the variable.
|
||||
// Code gen will need that later!
|
||||
constraints.equal_types(
|
||||
Type::Variable(*var),
|
||||
constraints.equal_types_var(
|
||||
*var,
|
||||
expected,
|
||||
Category::Storage(std::file!(), std::line!()),
|
||||
loc_ret.region,
|
||||
|
@ -882,8 +875,8 @@ pub fn constrain_expr(
|
|||
constrain_def(constraints, env, def, body_con),
|
||||
// Record the type of the entire def-expression in the variable.
|
||||
// Code gen will need that later!
|
||||
constraints.equal_types(
|
||||
Type::Variable(*var),
|
||||
constraints.equal_types_var(
|
||||
*var,
|
||||
expected.clone(),
|
||||
Category::Storage(std::file!(), std::line!()),
|
||||
ret_region,
|
||||
|
@ -931,8 +924,8 @@ pub fn constrain_expr(
|
|||
},
|
||||
region,
|
||||
);
|
||||
let ast_con = constraints.equal_types(
|
||||
Type::Variable(*variant_var),
|
||||
let ast_con = constraints.equal_types_var(
|
||||
*variant_var,
|
||||
expected,
|
||||
Category::Storage(std::file!(), std::line!()),
|
||||
region,
|
||||
|
@ -983,8 +976,8 @@ pub fn constrain_expr(
|
|||
},
|
||||
region,
|
||||
);
|
||||
let ast_con = constraints.equal_types(
|
||||
Type::Variable(*variant_var),
|
||||
let ast_con = constraints.equal_types_var(
|
||||
*variant_var,
|
||||
expected,
|
||||
Category::Storage(std::file!(), std::line!()),
|
||||
region,
|
||||
|
@ -1046,8 +1039,8 @@ pub fn constrain_expr(
|
|||
);
|
||||
|
||||
// Store the entire wrapped opaque type in `opaque_var`
|
||||
let storage_con = constraints.equal_types(
|
||||
Type::Variable(*opaque_var),
|
||||
let storage_con = constraints.equal_types_var(
|
||||
*opaque_var,
|
||||
expected,
|
||||
Category::Storage(std::file!(), std::line!()),
|
||||
region,
|
||||
|
@ -1071,9 +1064,6 @@ pub fn constrain_expr(
|
|||
RunLowLevel { args, ret_var, op } => {
|
||||
// This is a modified version of what we do for function calls.
|
||||
|
||||
// The operation's return type
|
||||
let ret_type = Variable(*ret_var);
|
||||
|
||||
// This will be used in the occurs check
|
||||
let mut vars = Vec::with_capacity(1 + args.len());
|
||||
|
||||
|
@ -1103,7 +1093,7 @@ pub fn constrain_expr(
|
|||
let category = Category::LowLevelOpResult(*op);
|
||||
|
||||
// Deviation: elm uses an additional And here
|
||||
let eq = constraints.equal_types(ret_type, expected, category, region);
|
||||
let eq = constraints.equal_types_var(*ret_var, expected, category, region);
|
||||
arg_cons.push(eq);
|
||||
constraints.exists_many(vars, arg_cons)
|
||||
}
|
||||
|
@ -1114,9 +1104,6 @@ pub fn constrain_expr(
|
|||
} => {
|
||||
// This is a modified version of what we do for function calls.
|
||||
|
||||
// The operation's return type
|
||||
let ret_type = Variable(*ret_var);
|
||||
|
||||
// This will be used in the occurs check
|
||||
let mut vars = Vec::with_capacity(1 + args.len());
|
||||
|
||||
|
@ -1146,7 +1133,7 @@ pub fn constrain_expr(
|
|||
let category = Category::ForeignCall;
|
||||
|
||||
// Deviation: elm uses an additional And here
|
||||
let eq = constraints.equal_types(ret_type, expected, category, region);
|
||||
let eq = constraints.equal_types_var(*ret_var, expected, category, region);
|
||||
arg_cons.push(eq);
|
||||
constraints.exists_many(vars, arg_cons)
|
||||
}
|
||||
|
@ -1448,8 +1435,8 @@ fn constrain_def(
|
|||
def_pattern_state.vars.push(*pattern_var);
|
||||
pattern_types.push(Type::Variable(*pattern_var));
|
||||
|
||||
let pattern_con = constraints.equal_types(
|
||||
Type::Variable(*pattern_var),
|
||||
let pattern_con = constraints.equal_types_var(
|
||||
*pattern_var,
|
||||
Expected::NoExpectation(loc_ann.clone()),
|
||||
Category::Storage(std::file!(), std::line!()),
|
||||
loc_pattern.region,
|
||||
|
@ -1497,8 +1484,8 @@ fn constrain_def(
|
|||
defs_constraint,
|
||||
ret_constraint,
|
||||
),
|
||||
constraints.equal_types(
|
||||
Type::Variable(closure_var),
|
||||
constraints.equal_types_var(
|
||||
closure_var,
|
||||
Expected::FromAnnotation(
|
||||
def.loc_pattern.clone(),
|
||||
arity,
|
||||
|
@ -1658,8 +1645,8 @@ fn constrain_closure_size(
|
|||
)
|
||||
};
|
||||
|
||||
let finalizer = constraints.equal_types(
|
||||
Type::Variable(closure_var),
|
||||
let finalizer = constraints.equal_types_var(
|
||||
closure_var,
|
||||
NoExpectation(closure_type),
|
||||
Category::ClosureSize,
|
||||
region,
|
||||
|
@ -1901,8 +1888,8 @@ pub fn rec_defs_help(
|
|||
def_pattern_state.vars.push(*pattern_var);
|
||||
pattern_types.push(Type::Variable(*pattern_var));
|
||||
|
||||
let pattern_con = constraints.equal_types(
|
||||
Type::Variable(*pattern_var),
|
||||
let pattern_con = constraints.equal_types_var(
|
||||
*pattern_var,
|
||||
Expected::NoExpectation(loc_ann.clone()),
|
||||
Category::Storage(std::file!(), std::line!()),
|
||||
loc_pattern.region,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue