implement mono / lowering for tuples

This commit is contained in:
Joshua Warner 2023-01-24 20:23:17 -08:00
parent 65f8bb3d0d
commit 5a6be05ead
No known key found for this signature in database
GPG key ID: 89AD497003F93FDD
42 changed files with 1773 additions and 290 deletions

View file

@ -17,7 +17,7 @@ use roc_can::expected::PExpected;
use roc_can::expr::Expr::{self, *};
use roc_can::expr::{
AnnotatedMark, ClosureData, DeclarationTag, Declarations, DestructureDef, ExpectLookup, Field,
FunctionDef, OpaqueWrapFunctionData, RecordAccessorData, TupleAccessorData, WhenBranch,
FunctionDef, OpaqueWrapFunctionData, StructAccessorData, WhenBranch,
};
use roc_can::pattern::Pattern;
use roc_can::traverse::symbols_introduced_from_pattern;
@ -30,7 +30,7 @@ use roc_region::all::{Loc, Region};
use roc_types::subs::{IllegalCycleMark, Variable};
use roc_types::types::Type::{self, *};
use roc_types::types::{
AliasKind, AnnotationSource, Category, OptAbleType, PReason, Reason, RecordField,
AliasKind, AnnotationSource, Category, IndexOrField, OptAbleType, PReason, Reason, RecordField,
TypeExtension, TypeTag, Types,
};
@ -1162,7 +1162,7 @@ pub fn constrain_expr(
[constraint, eq, record_con],
)
}
RecordAccessor(RecordAccessorData {
RecordAccessor(StructAccessorData {
name: closure_name,
function_var,
field,
@ -1176,19 +1176,32 @@ pub fn constrain_expr(
let field_var = *field_var;
let field_type = Variable(field_var);
let mut field_types = SendMap::default();
let label = field.clone();
field_types.insert(label, RecordField::Demanded(field_type.clone()));
let record_type = Type::Record(
field_types,
TypeExtension::from_non_annotation_type(ext_type),
);
let record_type = match field {
IndexOrField::Field(field) => {
let mut field_types = SendMap::default();
let label = field.clone();
field_types.insert(label, RecordField::Demanded(field_type.clone()));
Type::Record(
field_types,
TypeExtension::from_non_annotation_type(ext_type),
)
}
IndexOrField::Index(index) => {
let mut field_types = VecMap::with_capacity(1);
field_types.insert(*index, field_type.clone());
Type::Tuple(
field_types,
TypeExtension::from_non_annotation_type(ext_type),
)
}
};
let record_type_index = {
let typ = types.from_old_type(&record_type);
constraints.push_type(types, typ)
};
let category = Category::RecordAccessor(field.clone());
let category = Category::Accessor(field.clone());
let record_expected = constraints.push_expected_type(NoExpectation(record_type_index));
let record_con =
@ -1288,88 +1301,6 @@ pub fn constrain_expr(
let eq = constraints.equal_types_var(elem_var, expected, category, region);
constraints.exists_many([*tuple_var, elem_var, ext_var], [constraint, eq, tuple_con])
}
TupleAccessor(TupleAccessorData {
name: closure_name,
function_var,
tuple_var,
closure_var,
ext_var,
elem_var,
index,
}) => {
let ext_var = *ext_var;
let ext_type = Variable(ext_var);
let elem_var = *elem_var;
let elem_type = Variable(elem_var);
let mut elem_types = VecMap::with_capacity(1);
elem_types.insert(*index, elem_type.clone());
let record_type = Type::Tuple(
elem_types,
TypeExtension::from_non_annotation_type(ext_type),
);
let record_type_index = {
let typ = types.from_old_type(&record_type);
constraints.push_type(types, typ)
};
let category = Category::TupleAccessor(*index);
let record_expected = constraints.push_expected_type(NoExpectation(record_type_index));
let record_con =
constraints.equal_types_var(*tuple_var, record_expected, category.clone(), region);
let expected_lambda_set = {
let lambda_set_ty = {
let typ = types.from_old_type(&Type::ClosureTag {
name: *closure_name,
captures: vec![],
ambient_function: *function_var,
});
constraints.push_type(types, typ)
};
constraints.push_expected_type(NoExpectation(lambda_set_ty))
};
let closure_type = Type::Variable(*closure_var);
let function_type_index = {
let typ = types.from_old_type(&Type::Function(
vec![record_type],
Box::new(closure_type),
Box::new(elem_type),
));
constraints.push_type(types, typ)
};
let cons = [
constraints.equal_types_var(
*closure_var,
expected_lambda_set,
category.clone(),
region,
),
constraints.equal_types(function_type_index, expected, category.clone(), region),
{
let store_fn_var_index = constraints.push_variable(*function_var);
let store_fn_var_expected =
constraints.push_expected_type(NoExpectation(store_fn_var_index));
constraints.equal_types(
function_type_index,
store_fn_var_expected,
category,
region,
)
},
record_con,
];
constraints.exists_many(
[*tuple_var, *function_var, *closure_var, elem_var, ext_var],
cons,
)
}
LetRec(defs, loc_ret, cycle_mark) => {
let body_con = constrain_expr(
types,
@ -4001,10 +3932,6 @@ fn is_generalizable_expr(mut expr: &Expr) -> bool {
// RecordAccessor functions `.field` are equivalent to closures `\r -> r.field`, no need to weaken them.
return true;
}
TupleAccessor(_) => {
// TupleAccessor functions `.0` are equivalent to closures `\r -> r.0`, no need to weaken them.
return true;
}
OpaqueWrapFunction(_) => {
// Opaque wrapper functions `@Q` are equivalent to closures `\x -> @Q x`, no need to weaken them.
return true;