[skip-ci] Fix borrow issues in constraining

This commit is contained in:
Ayaz Hafiz 2022-11-08 16:49:40 -06:00
parent 59d2de5a55
commit 6b5f632364
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
7 changed files with 288 additions and 224 deletions

View file

@ -56,9 +56,10 @@ pub fn add_numeric_bound_constr(
} }
NumericBound::Range(range) => { NumericBound::Range(range) => {
let precision_type = constraints.push_variable(precision_var); let precision_type = constraints.push_variable(precision_var);
let expected = Expected::NoExpectation( let expected = {
constraints.push_type(types, types.from_old_type(&RangedNumber(range))), let typ = types.from_old_type(&RangedNumber(range));
); Expected::NoExpectation(constraints.push_type(types, typ))
};
let expected_index = constraints.push_expected_type(expected); let expected_index = constraints.push_expected_type(expected);
let constr = constraints.equal_types(precision_type, expected_index, category, region); let constr = constraints.equal_types(precision_type, expected_index, category, region);
@ -94,11 +95,14 @@ pub fn int_literal(
Category::Num, Category::Num,
); );
let num_type_index = constraints.push_type(types, types.from_old_type(&num_type)); let num_type_index = {
let int_precision_type = constraints.push_type( let typ = types.from_old_type(&num_type);
types, constraints.push_type(types, typ)
types.from_old_type(&num_int(Type::Variable(precision_var))), };
); let int_precision_type = {
let typ = types.from_old_type(&num_int(Type::Variable(precision_var)));
constraints.push_type(types, typ)
};
let expect_precision_var = let expect_precision_var =
constraints.push_expected_type(ForReason(reason, int_precision_type, region)); constraints.push_expected_type(ForReason(reason, int_precision_type, region));
@ -137,11 +141,14 @@ pub fn single_quote_literal(
Category::Character, Category::Character,
); );
let num_type_index = constraints.push_type(types, types.from_old_type(&num_type)); let num_type_index = {
let int_precision_type = constraints.push_type( let typ = types.from_old_type(&num_type);
types, constraints.push_type(types, typ)
types.from_old_type(&num_int(Type::Variable(precision_var))), };
); let int_precision_type = {
let typ = types.from_old_type(&num_int(Type::Variable(precision_var)));
constraints.push_type(types, typ)
};
let expect_precision_var = let expect_precision_var =
constraints.push_expected_type(ForReason(reason, int_precision_type, region)); constraints.push_expected_type(ForReason(reason, int_precision_type, region));
@ -184,11 +191,14 @@ pub fn float_literal(
Category::Frac, Category::Frac,
); );
let num_type_index = constraints.push_type(types, types.from_old_type(&num_type)); let num_type_index = {
let float_precision_type = constraints.push_type( let typ = types.from_old_type(&num_type);
types, constraints.push_type(types, typ)
types.from_old_type(&num_float(Type::Variable(precision_var))), };
); let float_precision_type = {
let typ = types.from_old_type(&num_float(Type::Variable(precision_var)));
constraints.push_type(types, typ)
};
let expect_precision_var = let expect_precision_var =
constraints.push_expected_type(ForReason(reason, float_precision_type, region)); constraints.push_expected_type(ForReason(reason, float_precision_type, region));
@ -223,7 +233,10 @@ pub fn num_literal(
Category::Num, Category::Num,
); );
let type_index = constraints.push_type(types, types.from_old_type(&num_type)); let type_index = {
let typ = types.from_old_type(&num_type);
constraints.push_type(types, typ)
};
constrs.extend([constraints.equal_types(type_index, expected, Category::Num, region)]); constrs.extend([constraints.equal_types(type_index, expected, Category::Num, region)]);
let and_constraint = constraints.and_constraint(constrs); let and_constraint = constraints.and_constraint(constrs);

View file

@ -164,7 +164,10 @@ fn constrain_untyped_closure(
let pattern_state_constraints = constraints.and_constraint(pattern_state.constraints); let pattern_state_constraints = constraints.and_constraint(pattern_state.constraints);
let function_type = constraints.push_type(&types, types.from_old_type(&function_type)); let function_type = {
let typ = types.from_old_type(&function_type);
constraints.push_type(&types, typ)
};
let cons = [ let cons = [
constraints.let_constraint( constraints.let_constraint(
@ -227,10 +230,11 @@ pub fn constrain_expr(
rec_constraints.push(field_con); rec_constraints.push(field_con);
} }
let record_type = constraints.push_type( let record_type = {
&types, let typ =
types.from_old_type(&Type::Record(field_types, TypeExtension::Closed)), types.from_old_type(&Type::Record(field_types, TypeExtension::Closed));
); constraints.push_type(&types, typ)
};
let record_con = constraints.equal_types_with_storage( let record_con = constraints.equal_types_with_storage(
record_type, record_type,
@ -271,15 +275,17 @@ pub fn constrain_expr(
cons.push(con); cons.push(con);
} }
let fields_type = constraints.push_type( let fields_type = {
&types, let typ = types.from_old_type(&Type::Record(
types.from_old_type(&Type::Record(
fields, fields,
TypeExtension::from_type(Type::Variable(*ext_var)), TypeExtension::from_type(Type::Variable(*ext_var)),
)), ));
); constraints.push_type(&types, typ)
let record_type = };
constraints.push_type(&types, types.from_old_type(&Type::Variable(*record_var))); let record_type = {
let typ = types.from_old_type(&Type::Variable(*record_var));
constraints.push_type(&types, typ)
};
// NOTE from elm compiler: fields_type is separate so that Error propagates better // NOTE from elm compiler: fields_type is separate so that Error propagates better
let fields_type_expected = constraints.push_expected_type(NoExpectation(fields_type)); let fields_type_expected = constraints.push_expected_type(NoExpectation(fields_type));
@ -337,8 +343,10 @@ pub fn constrain_expr(
loc_elems, loc_elems,
} => { } => {
if loc_elems.is_empty() { if loc_elems.is_empty() {
let elem_type_index = let elem_type_index = {
constraints.push_type(types, types.from_old_type(&empty_list_type(*elem_var))); let typ = types.from_old_type(&empty_list_type(*elem_var));
constraints.push_type(types, typ)
};
let eq = constraints.equal_types(elem_type_index, expected, Category::List, region); let eq = constraints.equal_types(elem_type_index, expected, Category::List, region);
constraints.exists(vec![*elem_var], eq) constraints.exists(vec![*elem_var], eq)
} else { } else {
@ -366,8 +374,10 @@ pub fn constrain_expr(
list_constraints.push(constraint); list_constraints.push(constraint);
} }
let elem_type_index = let elem_type_index = {
constraints.push_type(&types, types.from_old_type(&list_type(list_elem_type))); let typ = types.from_old_type(&list_type(list_elem_type));
constraints.push_type(&types, typ)
};
list_constraints.push(constraints.equal_types( list_constraints.push(constraints.equal_types(
elem_type_index, elem_type_index,
expected, expected,
@ -448,14 +458,13 @@ pub fn constrain_expr(
arg_cons.push(arg_con); arg_cons.push(arg_con);
} }
let expected_fn_index = constraints.push_type( let expected_fn_index = {
types, let arguments = types.from_old_type_slice(arg_types.iter());
types.function( let lambda_set = types.from_old_type(&closure_type);
types.from_old_type_slice(arg_types.iter()), let ret = types.from_old_type(&ret_type);
types.from_old_type(&closure_type), let typ = types.function(arguments, lambda_set, ret);
types.from_old_type(&ret_type), constraints.push_type(types, typ)
), };
);
let expected_fn_type = let expected_fn_type =
constraints.push_expected_type(ForReason(fn_reason, expected_fn_index, region)); constraints.push_expected_type(ForReason(fn_reason, expected_fn_index, region));
@ -1023,13 +1032,13 @@ pub fn constrain_expr(
let label = field.clone(); let label = field.clone();
rec_field_types.insert(label, RecordField::Demanded(field_type)); rec_field_types.insert(label, RecordField::Demanded(field_type));
let record_type = constraints.push_type( let record_type = {
types, let typ = types.from_old_type(&Type::Record(
types.from_old_type(&Type::Record(
rec_field_types, rec_field_types,
TypeExtension::from_type(ext_type), TypeExtension::from_type(ext_type),
)), ));
); constraints.push_type(types, typ)
};
let record_expected = constraints.push_expected_type(NoExpectation(record_type)); let record_expected = constraints.push_expected_type(NoExpectation(record_type));
let category = Category::Access(field.clone()); let category = Category::Access(field.clone());
@ -1071,7 +1080,10 @@ pub fn constrain_expr(
let label = field.clone(); let label = field.clone();
field_types.insert(label, RecordField::Demanded(field_type.clone())); field_types.insert(label, RecordField::Demanded(field_type.clone()));
let record_type = Type::Record(field_types, TypeExtension::from_type(ext_type)); let record_type = Type::Record(field_types, TypeExtension::from_type(ext_type));
let record_type_index = constraints.push_type(types, types.from_old_type(&record_type)); let record_type_index = {
let typ = types.from_old_type(&record_type);
constraints.push_type(types, typ)
};
let category = Category::Accessor(field.clone()); let category = Category::Accessor(field.clone());
@ -1080,27 +1092,27 @@ pub fn constrain_expr(
constraints.equal_types_var(*record_var, record_expected, category.clone(), region); constraints.equal_types_var(*record_var, record_expected, category.clone(), region);
let expected_lambda_set = { let expected_lambda_set = {
let lambda_set_ty = constraints.push_type( let lambda_set_ty = {
types, let typ = types.from_old_type(&Type::ClosureTag {
types.from_old_type(&Type::ClosureTag {
name: *closure_name, name: *closure_name,
captures: vec![], captures: vec![],
ambient_function: *function_var, ambient_function: *function_var,
}), });
); constraints.push_type(types, typ)
};
constraints.push_expected_type(NoExpectation(lambda_set_ty)) constraints.push_expected_type(NoExpectation(lambda_set_ty))
}; };
let closure_type = Type::Variable(*closure_var); let closure_type = Type::Variable(*closure_var);
let function_type_index = constraints.push_type( let function_type_index = {
types, let typ = types.from_old_type(&Type::Function(
types.from_old_type(&Type::Function(
vec![record_type], vec![record_type],
Box::new(closure_type), Box::new(closure_type),
Box::new(field_type), Box::new(field_type),
)), ));
); constraints.push_type(types, typ)
};
let cons = [ let cons = [
constraints.equal_types_var( constraints.equal_types_var(
@ -1197,13 +1209,13 @@ pub fn constrain_expr(
payload_types.push(Type::Variable(*var)); payload_types.push(Type::Variable(*var));
} }
let tag_union_type = constraints.push_type( let tag_union_type = {
types, let typ = types.from_old_type(&Type::TagUnion(
types.from_old_type(&Type::TagUnion(
vec![(name.clone(), payload_types)], vec![(name.clone(), payload_types)],
TypeExtension::from_type(Type::Variable(*ext_var)), TypeExtension::from_type(Type::Variable(*ext_var)),
)), ));
); constraints.push_type(types, typ)
};
let union_con = constraints.equal_types_with_storage( let union_con = constraints.equal_types_with_storage(
tag_union_type, tag_union_type,
@ -1228,14 +1240,14 @@ pub fn constrain_expr(
name, name,
closure_name, closure_name,
} => { } => {
let function_or_tag_union = constraints.push_type( let function_or_tag_union = {
types, let typ = types.from_old_type(&Type::FunctionOrTagUnion(
types.from_old_type(&Type::FunctionOrTagUnion(
name.clone(), name.clone(),
*closure_name, *closure_name,
TypeExtension::from_type(Type::Variable(*ext_var)), TypeExtension::from_type(Type::Variable(*ext_var)),
)), ));
); constraints.push_type(types, typ)
};
let union_con = constraints.equal_types_with_storage( let union_con = constraints.equal_types_with_storage(
function_or_tag_union, function_or_tag_union,
expected, expected,
@ -1261,9 +1273,8 @@ pub fn constrain_expr(
let arg_type = Type::Variable(*arg_var); let arg_type = Type::Variable(*arg_var);
let arg_type_index = constraints.push_variable(*arg_var); let arg_type_index = constraints.push_variable(*arg_var);
let opaque_type = constraints.push_type( let opaque_type = {
types, let typ = types.from_old_type(&Type::Alias {
types.from_old_type(&Type::Alias {
symbol: *name, symbol: *name,
type_arguments: type_arguments type_arguments: type_arguments
.iter() .iter()
@ -1276,8 +1287,9 @@ pub fn constrain_expr(
infer_ext_in_output_types: vec![], infer_ext_in_output_types: vec![],
actual: Box::new(arg_type), actual: Box::new(arg_type),
kind: AliasKind::Opaque, kind: AliasKind::Opaque,
}), });
); constraints.push_type(types, typ)
};
// Constrain the argument // Constrain the argument
let expected_arg = let expected_arg =
@ -1305,8 +1317,10 @@ pub fn constrain_expr(
// variables of the opaque type // variables of the opaque type
// TODO: better expectation here // TODO: better expectation here
let link_type_variables_con = { let link_type_variables_con = {
let specialized_type_index = let specialized_type_index = {
constraints.push_type(types, types.from_old_type(&**specialized_def_type)); let typ = types.from_old_type(&**specialized_def_type);
constraints.push_type(types, typ)
};
let expected_index = let expected_index =
constraints.push_expected_type(Expected::NoExpectation(specialized_type_index)); constraints.push_expected_type(Expected::NoExpectation(specialized_type_index));
constraints.equal_types( constraints.equal_types(
@ -1339,9 +1353,8 @@ pub fn constrain_expr(
}) => { }) => {
let argument_type = Type::Variable(*argument_var); let argument_type = Type::Variable(*argument_var);
let opaque_type = constraints.push_type( let opaque_type = {
types, let typ = types.from_old_type(&Type::Alias {
types.from_old_type(&Type::Alias {
symbol: *opaque_name, symbol: *opaque_name,
type_arguments: type_arguments type_arguments: type_arguments
.iter() .iter()
@ -1354,8 +1367,9 @@ pub fn constrain_expr(
infer_ext_in_output_types: vec![], infer_ext_in_output_types: vec![],
actual: Box::new(argument_type.clone()), actual: Box::new(argument_type.clone()),
kind: AliasKind::Opaque, kind: AliasKind::Opaque,
}), });
); constraints.push_type(types, typ)
};
let expected_opaque_type = constraints.push_expected_type(NoExpectation(opaque_type)); let expected_opaque_type = constraints.push_expected_type(NoExpectation(opaque_type));
@ -1369,10 +1383,14 @@ pub fn constrain_expr(
// Tie the type of the value wrapped by the opaque to the opaque's type variables. // Tie the type of the value wrapped by the opaque to the opaque's type variables.
let link_type_variables_con = { let link_type_variables_con = {
let arg_type_index = let arg_type_index = {
constraints.push_type(types, types.from_old_type(&argument_type)); let typ = types.from_old_type(&argument_type);
let specialized_type_index = constraints.push_type(types, typ)
constraints.push_type(types, types.from_old_type(&(*specialized_def_type))); };
let specialized_type_index = {
let typ = types.from_old_type(&(*specialized_def_type));
constraints.push_type(types, typ)
};
let expected_specialized = let expected_specialized =
constraints.push_expected_type(Expected::NoExpectation(specialized_type_index)); constraints.push_expected_type(Expected::NoExpectation(specialized_type_index));
constraints.equal_types( constraints.equal_types(
@ -1384,14 +1402,14 @@ pub fn constrain_expr(
}; };
let lambda_set = { let lambda_set = {
let lambda_set_index = constraints.push_type( let lambda_set_index = {
types, let typ = types.from_old_type(&Type::ClosureTag {
types.from_old_type(&Type::ClosureTag {
name: *function_name, name: *function_name,
captures: vec![], captures: vec![],
ambient_function: *function_var, ambient_function: *function_var,
}), });
); constraints.push_type(types, typ)
};
constraints.push_expected_type(NoExpectation(lambda_set_index)) constraints.push_expected_type(NoExpectation(lambda_set_index))
}; };
@ -1400,14 +1418,14 @@ pub fn constrain_expr(
let opaque_type = Type::Variable(*opaque_var); let opaque_type = Type::Variable(*opaque_var);
let expected_function_type = { let expected_function_type = {
let fn_type = constraints.push_type( let fn_type = {
types, let typ = types.from_old_type(&Type::Function(
types.from_old_type(&Type::Function(
vec![argument_type], vec![argument_type],
Box::new(closure_type), Box::new(closure_type),
Box::new(opaque_type), Box::new(opaque_type),
)), ));
); constraints.push_type(types, typ)
};
constraints.push_expected_type(NoExpectation(fn_type)) constraints.push_expected_type(NoExpectation(fn_type))
}; };
@ -1699,11 +1717,11 @@ fn constrain_function_def(
let ret_var = function_def.return_type; let ret_var = function_def.return_type;
let closure_var = function_def.closure_type; let closure_var = function_def.closure_type;
let ret_type_index = constraints.push_type( let ret_type_index = {
types,
// TODO(types-soa) get rid of clone // TODO(types-soa) get rid of clone
types.clone_with_variable_substitutions(ret_type, &Default::default()), let typ = types.clone_with_variable_substitutions(ret_type, &Default::default());
); constraints.push_type(types, typ)
};
vars.push(ret_var); vars.push(ret_var);
vars.push(closure_var); vars.push(closure_var);
@ -1790,14 +1808,14 @@ fn constrain_function_def(
let defs_constraint = constraints.and_constraint(argument_pattern_state.constraints); let defs_constraint = constraints.and_constraint(argument_pattern_state.constraints);
let signature_closure_type = { let signature_closure_type = {
let signature_closure_type_index = constraints.push_type( let signature_closure_type_index = {
types,
// TODO(types-soa) get rid of clone // TODO(types-soa) get rid of clone
types.clone_with_variable_substitutions( let typ = types.clone_with_variable_substitutions(
signature_closure_type, signature_closure_type,
&Default::default(), &Default::default(),
), );
); constraints.push_type(types, typ)
};
constraints.push_expected_type(Expected::FromAnnotation( constraints.push_expected_type(Expected::FromAnnotation(
loc_pattern, loc_pattern,
arity, arity,
@ -2472,11 +2490,11 @@ fn constrain_typed_def(
rigids: ftv, rigids: ftv,
}; };
let signature_index = constraints.push_type( let signature_index = {
types,
// TODO(types-soa) get rid of clone // TODO(types-soa) get rid of clone
types.clone_with_variable_substitutions(signature.clone(), &Default::default()), let typ = types.clone_with_variable_substitutions(signature.clone(), &Default::default());
); constraints.push_type(types, typ)
};
let annotation_expected = constraints.push_expected_type(FromAnnotation( let annotation_expected = constraints.push_expected_type(FromAnnotation(
def.loc_pattern.clone(), def.loc_pattern.clone(),
@ -2530,11 +2548,11 @@ fn constrain_typed_def(
let mut vars = Vec::with_capacity(argument_pattern_state.vars.capacity() + 1); let mut vars = Vec::with_capacity(argument_pattern_state.vars.capacity() + 1);
let ret_var = *ret_var; let ret_var = *ret_var;
let closure_var = *closure_var; let closure_var = *closure_var;
let ret_type_index = constraints.push_type( let ret_type_index = {
types,
// TODO(types-soa) get rid of clone // TODO(types-soa) get rid of clone
types.clone_with_variable_substitutions(ret_type, &Default::default()), let typ = types.clone_with_variable_substitutions(ret_type, &Default::default());
); constraints.push_type(types, typ)
};
vars.push(ret_var); vars.push(ret_var);
vars.push(closure_var); vars.push(closure_var);
@ -2584,14 +2602,14 @@ fn constrain_typed_def(
let defs_constraint = constraints.and_constraint(argument_pattern_state.constraints); let defs_constraint = constraints.and_constraint(argument_pattern_state.constraints);
let signature_closure_type = { let signature_closure_type = {
let signature_closure_type_index = constraints.push_type( let signature_closure_type_index = {
types,
// TODO(types-soa) get rid of clone // TODO(types-soa) get rid of clone
types.clone_with_variable_substitutions( let typ = types.clone_with_variable_substitutions(
signature_closure_type, signature_closure_type,
&Default::default(), &Default::default(),
), );
); constraints.push_type(types, typ)
};
constraints.push_expected_type(Expected::FromAnnotation( constraints.push_expected_type(Expected::FromAnnotation(
def.loc_pattern.clone(), def.loc_pattern.clone(),
arity, arity,
@ -2685,11 +2703,11 @@ fn constrain_typed_function_arguments(
let it = arguments.iter().zip(arg_types.into_iter()).enumerate(); let it = arguments.iter().zip(arg_types.into_iter()).enumerate();
for (index, ((pattern_var, annotated_mark, loc_pattern), ann)) in it { for (index, ((pattern_var, annotated_mark, loc_pattern), ann)) in it {
let pattern_var_index = constraints.push_variable(*pattern_var); let pattern_var_index = constraints.push_variable(*pattern_var);
let ann_index = constraints.push_type( let ann_index = {
types,
// TODO(types-soa) remove clone // TODO(types-soa) remove clone
types.clone_with_variable_substitutions(ann.clone(), &Default::default()), let typ = types.clone_with_variable_substitutions(ann.clone(), &Default::default());
); constraints.push_type(types, typ)
};
if loc_pattern.value.surely_exhaustive() { if loc_pattern.value.surely_exhaustive() {
// OPT: we don't need to perform any type-level exhaustiveness checking. // OPT: we don't need to perform any type-level exhaustiveness checking.
@ -3087,14 +3105,14 @@ fn constrain_closure_size(
let finalizer = { let finalizer = {
// pick a more efficient representation if we don't actually capture anything // pick a more efficient representation if we don't actually capture anything
let closure_type = constraints.push_type( let closure_type = {
types, let typ = types.from_old_type(&Type::ClosureTag {
types.from_old_type(&Type::ClosureTag {
name, name,
captures: captured_types, captures: captured_types,
ambient_function, ambient_function,
}), });
); constraints.push_type(types, typ)
};
let clos_type = constraints.push_expected_type(NoExpectation(closure_type)); let clos_type = constraints.push_expected_type(NoExpectation(closure_type));
constraints.equal_types_var(closure_var, clos_type, Category::ClosureSize, region) constraints.equal_types_var(closure_var, clos_type, Category::ClosureSize, region)
}; };
@ -3163,7 +3181,10 @@ fn instantiate_rigids(
// Skipping all of this cloning here would be neat! // Skipping all of this cloning here would be neat!
let loc_annotation_ref = Loc::at(loc_pattern.region, &annotation); let loc_annotation_ref = Loc::at(loc_pattern.region, &annotation);
if let Pattern::Identifier(symbol) = loc_pattern.value { if let Pattern::Identifier(symbol) = loc_pattern.value {
let annotation_index = constraints.push_type(types, types.from_old_type(&annotation)); let annotation_index = {
let typ = types.from_old_type(&annotation);
constraints.push_type(types, typ)
};
headers.insert(symbol, Loc::at(loc_pattern.region, annotation_index)); headers.insert(symbol, Loc::at(loc_pattern.region, annotation_index));
} else if let Some(new_headers) = crate::pattern::headers_from_annotation( } else if let Some(new_headers) = crate::pattern::headers_from_annotation(
types, types,
@ -3369,10 +3390,11 @@ fn constraint_recursive_function(
// This doesn't yet work; needs investigation as to why. // This doesn't yet work; needs investigation as to why.
// My guess is that when types SoA lands, this might just resolve itself, since // My guess is that when types SoA lands, this might just resolve itself, since
// types will be composed from variables to begin with. // types will be composed from variables to begin with.
value: constraints.push_type( value: {
types, let typ =
types.clone_with_variable_substitutions(signature, &Default::default()), types.clone_with_variable_substitutions(signature, &Default::default());
), constraints.push_type(types, typ)
},
}, },
); );
@ -3388,7 +3410,7 @@ fn constraint_recursive_function(
); );
let pattern_types = types let pattern_types = types
.from_old_type_slice(function_def.arguments.iter().map(|a| &Type::Variable(a.0))); .from_old_type_slice(function_def.arguments.iter().map(|a| Type::Variable(a.0)));
let closure_constraint = constrain_closure_size( let closure_constraint = constrain_closure_size(
types, types,
@ -3401,16 +3423,14 @@ fn constraint_recursive_function(
&mut vars, &mut vars,
); );
let fn_type = constraints.push_type( let fn_type = {
types, // TODO(types-soa) optimize for Variable
types.function( let lambda_set = types.from_old_type(&Type::Variable(closure_var));
pattern_types, // TODO(types-soa) remove clone
// TODO(types-soa) optimize for Variable let ret = types.clone_with_variable_substitutions(ret_type, &Default::default());
types.from_old_type(&Type::Variable(closure_var)), let typ = types.function(pattern_types, lambda_set, ret);
// TODO(types-soa) remove clone constraints.push_type(types, typ)
types.clone_with_variable_substitutions(ret_type, &Default::default()), };
),
);
let expr_con = { let expr_con = {
let expected = constraints.push_expected_type(NoExpectation(ret_type_index)); let expected = constraints.push_expected_type(NoExpectation(ret_type_index));
@ -3545,14 +3565,14 @@ pub fn rec_defs_help_simple(
hybrid_and_flex_info.vars.extend(new_infer_variables); hybrid_and_flex_info.vars.extend(new_infer_variables);
let signature_index = constraints.push_type( let signature_index = {
types,
// TODO(types-soa) remove clone // TODO(types-soa) remove clone
types.clone_with_variable_substitutions( let typ = types.clone_with_variable_substitutions(
signature.clone(), signature.clone(),
&Default::default(), &Default::default(),
), );
); constraints.push_type(types, typ)
};
let annotation_expected = FromAnnotation( let annotation_expected = FromAnnotation(
loc_pattern.clone(), loc_pattern.clone(),
@ -3771,11 +3791,14 @@ fn rec_defs_help(
hybrid_and_flex_info.vars.extend(new_infer_variables); hybrid_and_flex_info.vars.extend(new_infer_variables);
let signature_index = constraints.push_type( let signature_index = {
types, let typ = types
// TODO(types-soa) remove clone .clone_with_variable_substitutions(signature.clone(), &Default::default());
types.clone_with_variable_substitutions(signature.clone(), &Default::default()), constraints.push_type(
); types, // TODO(types-soa) remove clone
typ,
)
};
let annotation_expected = FromAnnotation( let annotation_expected = FromAnnotation(
def.loc_pattern.clone(), def.loc_pattern.clone(),
@ -3823,11 +3846,14 @@ fn rec_defs_help(
let mut vars = Vec::with_capacity(state.vars.capacity() + 1); let mut vars = Vec::with_capacity(state.vars.capacity() + 1);
let ret_var = *ret_var; let ret_var = *ret_var;
let closure_var = *closure_var; let closure_var = *closure_var;
let ret_type_index = constraints.push_type( let ret_type_index = {
types, let typ = types
// TODO(types-soa) remove clone .clone_with_variable_substitutions(ret_type, &Default::default());
types.clone_with_variable_substitutions(ret_type, &Default::default()), constraints.push_type(
); types, // TODO(types-soa) remove clone
typ,
)
};
vars.push(ret_var); vars.push(ret_var);
vars.push(closure_var); vars.push(closure_var);
@ -3843,7 +3869,7 @@ fn rec_defs_help(
arg_types, arg_types,
); );
let pattern_types = types let pattern_types = types
.from_old_type_slice(arguments.iter().map(|a| &Type::Variable(a.0))); .from_old_type_slice(arguments.iter().map(|a| Type::Variable(a.0)));
let closure_constraint = constrain_closure_size( let closure_constraint = constrain_closure_size(
types, types,
@ -3856,18 +3882,14 @@ fn rec_defs_help(
&mut vars, &mut vars,
); );
let fn_type_index = constraints.push_type( let fn_type_index = {
types, let lambda_set = types.from_old_type(&Type::Variable(closure_var));
types.function( // TODO(types-soa) remove clone
pattern_types, let ret = types
types.from_old_type(&Type::Variable(closure_var)), .clone_with_variable_substitutions(ret_type, &Default::default());
// TODO(types-soa) remove clone let typ = types.function(pattern_types, lambda_set, ret);
types.clone_with_variable_substitutions( constraints.push_type(types, typ)
ret_type, };
&Default::default(),
),
),
);
let body_type = let body_type =
constraints.push_expected_type(NoExpectation(ret_type_index)); constraints.push_expected_type(NoExpectation(ret_type_index));
let expr_con = constrain_expr( let expr_con = constrain_expr(

View file

@ -58,7 +58,10 @@ fn constrain_symbols_from_requires(
}; };
let pattern = Loc::at_zero(roc_can::pattern::Pattern::Identifier(loc_symbol.value)); let pattern = Loc::at_zero(roc_can::pattern::Pattern::Identifier(loc_symbol.value));
let type_index = constraints.push_type(types, types.from_old_type(&loc_type.value)); let type_index = {
let typ = types.from_old_type(&loc_type.value);
constraints.push_type(types, typ)
};
let def_pattern_state = let def_pattern_state =
constrain_def_pattern(types, constraints, &mut env, &pattern, type_index); constrain_def_pattern(types, constraints, &mut env, &pattern, type_index);
@ -79,7 +82,10 @@ fn constrain_symbols_from_requires(
// provided by the app is in fact what the package module requires. // provided by the app is in fact what the package module requires.
let arity = loc_type.value.arity(); let arity = loc_type.value.arity();
let typ = loc_type.value; let typ = loc_type.value;
let type_index = constraints.push_type(types, types.from_old_type(&typ)); let type_index = {
let typ = types.from_old_type(&typ);
constraints.push_type(types, typ)
};
let expected = constraints.push_expected_type(Expected::FromAnnotation( let expected = constraints.push_expected_type(Expected::FromAnnotation(
loc_symbol.map(|&s| Pattern::Identifier(s)), loc_symbol.map(|&s| Pattern::Identifier(s)),
arity, arity,
@ -118,8 +124,10 @@ pub fn frontload_ability_constraints(
}; };
let pattern = Loc::at_zero(roc_can::pattern::Pattern::Identifier(*member_name)); let pattern = Loc::at_zero(roc_can::pattern::Pattern::Identifier(*member_name));
let signature_index = let signature_index = {
constraints.push_type(types, types.from_old_type(&signature.clone())); let typ = types.from_old_type(&signature.clone());
constraints.push_type(types, typ)
};
let mut def_pattern_state = let mut def_pattern_state =
constrain_def_pattern(types, constraints, &mut env, &pattern, signature_index); constrain_def_pattern(types, constraints, &mut env, &pattern, signature_index);

View file

@ -65,7 +65,7 @@ fn headers_from_annotation_help(
ident: symbol, ident: symbol,
specializes: _, specializes: _,
} => { } => {
let annotation_index = constraints.push_type(types, types.from_old_type(&annotation.value)); let annotation_index = { let typ = types.from_old_type(&annotation.value); constraints.push_type(types, typ) };
let typ = Loc::at(annotation.region, annotation_index); let typ = Loc::at(annotation.region, annotation_index);
headers.insert(*symbol, typ); headers.insert(*symbol, typ);
true true
@ -93,7 +93,7 @@ fn headers_from_annotation_help(
// `{ x ? 0 } = rec` or `{ x: 5 } -> ...` in all cases // `{ x ? 0 } = rec` or `{ x: 5 } -> ...` in all cases
// the type of `x` within the binding itself is the same. // the type of `x` within the binding itself is the same.
if let Some(field_type) = fields.get(&destruct.label) { if let Some(field_type) = fields.get(&destruct.label) {
let field_type_index = constraints.push_type(types, types.from_old_type(&field_type.as_inner().clone())); let field_type_index = { let typ = types.from_old_type(&field_type.as_inner().clone()); constraints.push_type(types, typ) };
headers.insert( headers.insert(
destruct.symbol, destruct.symbol,
Loc::at(annotation.region, field_type_index), Loc::at(annotation.region, field_type_index),
@ -165,7 +165,7 @@ fn headers_from_annotation_help(
&& type_arguments.len() == pat_type_arguments.len() && type_arguments.len() == pat_type_arguments.len()
&& lambda_set_variables.len() == pat_lambda_set_variables.len() => && lambda_set_variables.len() == pat_lambda_set_variables.len() =>
{ {
let annotation_index = constraints.push_type(types, types.from_old_type( &annotation.value )); let annotation_index = { let typ = types.from_old_type( &annotation.value ); constraints.push_type(types, typ) };
let typ = Loc::at(annotation.region, annotation_index); let typ = Loc::at(annotation.region, annotation_index);
headers.insert(*opaque, typ); headers.insert(*opaque, typ);
@ -266,7 +266,10 @@ pub fn constrain_pattern(
region, region,
Category::Num, Category::Num,
); );
let num_type = constraints.push_type(types, types.from_old_type(&num_type)); let num_type = {
let typ = types.from_old_type(&num_type);
constraints.push_type(types, typ)
};
state.constraints.push(constraints.equal_pattern_types( state.constraints.push(constraints.equal_pattern_types(
num_type, num_type,
@ -289,13 +292,16 @@ pub fn constrain_pattern(
region, region,
Category::Int, Category::Int,
); );
let num_type = constraints.push_type(types, types.from_old_type(&num_type)); let num_type = {
let typ = types.from_old_type(&num_type);
constraints.push_type(types, typ)
};
// Link the free num var with the int var and our expectation. // Link the free num var with the int var and our expectation.
let int_type = constraints.push_type( let int_type = {
types, let typ = types.from_old_type(&builtins::num_int(Type::Variable(precision_var)));
types.from_old_type(&builtins::num_int(Type::Variable(precision_var))), constraints.push_type(types, typ)
); };
state.constraints.push({ state.constraints.push({
let expected_index = let expected_index =
@ -325,13 +331,16 @@ pub fn constrain_pattern(
region, region,
Category::Frac, Category::Frac,
); );
let num_type_index = constraints.push_type(types, types.from_old_type(&num_type)); // NOTE: check me if something breaks! let num_type_index = {
let typ = types.from_old_type(&num_type);
constraints.push_type(types, typ)
}; // NOTE: check me if something breaks!
// Link the free num var with the float var and our expectation. // Link the free num var with the float var and our expectation.
let float_type = constraints.push_type( let float_type = {
types, let typ = types.from_old_type(&builtins::num_float(Type::Variable(precision_var)));
types.from_old_type(&builtins::num_float(Type::Variable(precision_var))), constraints.push_type(types, typ)
); };
state.constraints.push({ state.constraints.push({
let expected_index = let expected_index =
@ -350,7 +359,10 @@ pub fn constrain_pattern(
StrLiteral(_) => { StrLiteral(_) => {
// TODO(types-soa) use Types::STR // TODO(types-soa) use Types::STR
let str_type = constraints.push_type(types, types.from_old_type(&builtins::str_type())); let str_type = {
let typ = types.from_old_type(&builtins::str_type());
constraints.push_type(types, typ)
};
state.constraints.push(constraints.equal_pattern_types( state.constraints.push(constraints.equal_pattern_types(
str_type, str_type,
expected, expected,
@ -373,13 +385,16 @@ pub fn constrain_pattern(
Category::Int, Category::Int,
); );
let num_type_index = constraints.push_type(types, types.from_old_type(&num_type)); let num_type_index = {
let typ = types.from_old_type(&num_type);
constraints.push_type(types, typ)
};
// Link the free num var with the int var and our expectation. // Link the free num var with the int var and our expectation.
let int_type = constraints.push_type( let int_type = {
types, let typ = types.from_old_type(&builtins::num_int(Type::Variable(precision_var)));
types.from_old_type(&builtins::num_int(Type::Variable(precision_var))), constraints.push_type(types, typ)
); };
state.constraints.push({ state.constraints.push({
let expected_index = let expected_index =
@ -426,7 +441,7 @@ pub fn constrain_pattern(
let pat_type = Type::Variable(*var); let pat_type = Type::Variable(*var);
let pat_type_index = let pat_type_index =
// TODO(types-soa) use variable here instead // TODO(types-soa) use variable here instead
constraints.push_type(types, types.from_old_type(&pat_type.clone())); { let typ = types.from_old_type(&pat_type.clone()); constraints.push_type(types, typ) };
let expected = let expected =
constraints.push_pat_expected_type(PExpected::NoExpectation(pat_type_index)); constraints.push_pat_expected_type(PExpected::NoExpectation(pat_type_index));
@ -513,13 +528,13 @@ pub fn constrain_pattern(
state.vars.push(*var); state.vars.push(*var);
} }
let record_type = constraints.push_type( let record_type = {
types, let typ = types.from_old_type(&Type::Record(
types.from_old_type(&Type::Record(
field_types, field_types,
TypeExtension::from_type(ext_type), TypeExtension::from_type(ext_type),
)), ));
); constraints.push_type(types, typ)
};
let whole_var_index = constraints.push_variable(*whole_var); let whole_var_index = constraints.push_variable(*whole_var);
let expected_record = let expected_record =
@ -572,14 +587,14 @@ pub fn constrain_pattern(
} }
let list_var_index = constraints.push_variable(*list_var); let list_var_index = constraints.push_variable(*list_var);
let solved_list = constraints.push_type( let solved_list = {
types, let typ = types.from_old_type(&Type::Apply(
types.from_old_type(&Type::Apply(
Symbol::LIST_LIST, Symbol::LIST_LIST,
vec![Loc::at(region, Type::Variable(*elem_var))], vec![Loc::at(region, Type::Variable(*elem_var))],
region, region,
)), ));
); constraints.push_type(types, typ)
};
let store_solved_list = constraints.store(solved_list, *list_var, file!(), line!()); let store_solved_list = constraints.store(solved_list, *list_var, file!(), line!());
let expected_constraint = constraints.pattern_presence( let expected_constraint = constraints.pattern_presence(
@ -661,9 +676,8 @@ pub fn constrain_pattern(
let arg_pattern_type = Type::Variable(*arg_pattern_var); let arg_pattern_type = Type::Variable(*arg_pattern_var);
let arg_pattern_type_index = constraints.push_variable(*arg_pattern_var); let arg_pattern_type_index = constraints.push_variable(*arg_pattern_var);
let opaque_type = constraints.push_type( let opaque_type = {
types, let typ = types.from_old_type(&Type::Alias {
types.from_old_type(&Type::Alias {
symbol: *opaque, symbol: *opaque,
type_arguments: type_arguments type_arguments: type_arguments
.iter() .iter()
@ -676,8 +690,9 @@ pub fn constrain_pattern(
infer_ext_in_output_types: vec![], infer_ext_in_output_types: vec![],
actual: Box::new(arg_pattern_type.clone()), actual: Box::new(arg_pattern_type.clone()),
kind: AliasKind::Opaque, kind: AliasKind::Opaque,
}), });
); constraints.push_type(types, typ)
};
// First, add a constraint for the argument "who" // First, add a constraint for the argument "who"
let arg_pattern_expected = constraints let arg_pattern_expected = constraints
@ -716,13 +731,15 @@ pub fn constrain_pattern(
// This must **always** be a presence constraint, that is enforcing // This must **always** be a presence constraint, that is enforcing
// `[A k1, B k1] += typeof (A s)`, because we are in a destructure position and not // `[A k1, B k1] += typeof (A s)`, because we are in a destructure position and not
// all constructors are covered in this branch! // all constructors are covered in this branch!
let arg_pattern_type = constraints.push_type( let arg_pattern_type = {
types,
// TODO(types-soa) this is just a variable // TODO(types-soa) this is just a variable
types.from_old_type(&arg_pattern_type), let typ = types.from_old_type(&arg_pattern_type);
); constraints.push_type(types, typ)
let specialized_type_index = };
constraints.push_type(types, types.from_old_type(&(**specialized_def_type))); let specialized_type_index = {
let typ = types.from_old_type(&(**specialized_def_type));
constraints.push_type(types, typ)
};
let specialized_type_expected = constraints let specialized_type_expected = constraints
.push_pat_expected_type(PExpected::NoExpectation(specialized_type_index)); .push_pat_expected_type(PExpected::NoExpectation(specialized_type_index));

View file

@ -4308,7 +4308,7 @@ pub fn add_imports(
}; };
let copied_import = exposed_types.storage_subs.export_variable_to($subs, variable); let copied_import = exposed_types.storage_subs.export_variable_to($subs, variable);
let copied_import_index = constraints.push_type(Type::Variable(copied_import.variable)); let copied_import_index = constraints.push_variable(copied_import.variable);
def_types.push(( def_types.push((
$symbol, $symbol,
@ -4343,7 +4343,7 @@ pub fn add_imports(
if my_module == ModuleId::NUM { if my_module == ModuleId::NUM {
// Num needs List.len, but List imports Num. // Num needs List.len, but List imports Num.
let list_len_type_var = synth_list_len_type(subs); let list_len_type_var = synth_list_len_type(subs);
let list_len_type_index = constraints.push_type(Type::Variable(list_len_type_var)); let list_len_type_index = constraints.push_variable(list_len_type_var);
def_types.push((Symbol::LIST_LEN, Loc::at_zero(list_len_type_index))); def_types.push((Symbol::LIST_LEN, Loc::at_zero(list_len_type_index)));
import_variables.push(list_len_type_var); import_variables.push(list_len_type_var);
} }
@ -4757,6 +4757,7 @@ fn canonicalize_and_constrain<'a>(
roc_can::constraint::Constraint::True roc_can::constraint::Constraint::True
} else { } else {
constrain_module( constrain_module(
&mut types,
&mut constraints, &mut constraints,
module_output.symbols_from_requires, module_output.symbols_from_requires,
&module_output.scope.abilities_store, &module_output.scope.abilities_store,

View file

@ -2263,7 +2263,7 @@ fn type_cell_to_var(
pools: &mut Pools, pools: &mut Pools,
types: &mut Types, types: &mut Types,
aliases: &mut Aliases, aliases: &mut Aliases,
typ_cell: &Cell<Type>, typ_cell: &Cell<Index<TypeTag>>,
) -> Variable { ) -> Variable {
let typ = typ_cell.replace(Type::EmptyTagUnion); let typ = typ_cell.replace(Type::EmptyTagUnion);
let var = type_to_var( let var = type_to_var(

View file

@ -375,7 +375,7 @@ pub struct AliasShared {
} }
/// The tag (head constructor) of a canonical type stored in [Types]. /// The tag (head constructor) of a canonical type stored in [Types].
#[derive(Debug, Clone)] #[derive(Debug, Clone, Copy)]
pub enum TypeTag { pub enum TypeTag {
EmptyRecord, EmptyRecord,
EmptyTagUnion, EmptyTagUnion,
@ -613,14 +613,17 @@ impl Types {
} }
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
pub fn from_old_type_slice<'a>( pub fn from_old_type_slice<'a, B>(
&mut self, &mut self,
old: impl ExactSizeIterator<Item = &'a Type>, old: impl ExactSizeIterator<Item = B>,
) -> Slice<TypeTag> { ) -> Slice<TypeTag>
where
B: std::borrow::Borrow<Type>,
{
let slice = self.reserve_type_tags(old.len()); let slice = self.reserve_type_tags(old.len());
for (index, argument) in slice.into_iter().zip(old) { for (index, argument) in slice.into_iter().zip(old) {
self.from_old_type_at(index, argument); self.from_old_type_at(index, argument.borrow());
} }
slice slice