functions in structs, in general

This commit is contained in:
Folkert 2023-04-04 11:47:37 +02:00
parent b7119e9b3a
commit 9a6f9ad26e
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
7 changed files with 42 additions and 13 deletions

View file

@ -387,7 +387,28 @@ impl<'a> Copy for InLayout<'a> {}
impl std::fmt::Debug for InLayout<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("InLayout").field(&self.0).finish()
match *self {
Layout::VOID => f.write_str("InLayout(VOID)"),
Layout::UNIT => f.write_str("InLayout(UNIT)"),
Layout::BOOL => f.write_str("InLayout(BOOL)"),
Layout::U8 => f.write_str("InLayout(U8)"),
Layout::U16 => f.write_str("InLayout(U16)"),
Layout::U32 => f.write_str("InLayout(U32)"),
Layout::U64 => f.write_str("InLayout(U64)"),
Layout::U128 => f.write_str("InLayout(U128)"),
Layout::I8 => f.write_str("InLayout(I8)"),
Layout::I16 => f.write_str("InLayout(I16)"),
Layout::I32 => f.write_str("InLayout(I32)"),
Layout::I64 => f.write_str("InLayout(I64)"),
Layout::I128 => f.write_str("InLayout(I128)"),
Layout::F32 => f.write_str("InLayout(F32)"),
Layout::F64 => f.write_str("InLayout(F64)"),
Layout::DEC => f.write_str("InLayout(DEC)"),
Layout::STR => f.write_str("InLayout(STR)"),
Layout::OPAQUE_PTR => f.write_str("InLayout(OPAQUE_PTR)"),
Layout::NAKED_RECURSIVE_PTR => f.write_str("InLayout(NAKED_RECURSIVE_PTR)"),
_ => f.debug_tuple("InLayout").field(&self.0).finish(),
}
}
}

View file

@ -260,8 +260,8 @@ generateStructFields = \buf, types, visibility, structFields ->
HasNoClosure fields ->
List.walk fields buf (generateStructFieldWithoutClosure types visibility)
HasClosure _ ->
Str.concat buf "// TODO: Struct fields with closures"
HasClosure fields ->
List.walk fields buf (generateStructFieldWithoutClosure types visibility)
generateStructFieldWithoutClosure = \types, visibility ->
\accum, { name: fieldName, id } ->
@ -911,7 +911,7 @@ cannotDeriveCopy = \types, type ->
cannotDeriveDefault = \types, type ->
when type is
Unit | Unsized | EmptyTagUnion | TagUnion _ | RocResult _ _ | RecursivePointer _ | Function _ -> Bool.true
RocStr | Bool | Num _ | Struct { fields: HasClosure _ } | TagUnionPayload { fields: HasClosure _ } -> Bool.false
RocStr | Bool | Num _ | TagUnionPayload { fields: HasClosure _ } -> Bool.false
RocList id | RocSet id | RocBox id ->
cannotDeriveDefault types (Types.shape types id)
@ -919,6 +919,8 @@ cannotDeriveDefault = \types, type ->
cannotDeriveCopy types (Types.shape types keyId)
|| cannotDeriveCopy types (Types.shape types valId)
Struct { fields: HasClosure _ } -> Bool.true
Struct { fields: HasNoClosure fields } | TagUnionPayload { fields: HasNoClosure fields } ->
List.any fields \{ id } -> cannotDeriveDefault types (Types.shape types id)

View file

@ -1359,6 +1359,8 @@ fn add_function_type<'a>(
.from_var(env.arena, closure_var, env.subs)
.expect("Something weird ended up in the content");
// TODO this treats any lambda set as unsized. We should be able to figure out whether a
// lambda set is unsized in practice, and use the runtime representation otherwise.
add_type_help(env, lambda_set_layout, closure_var, None, types)
};

View file

@ -3,8 +3,11 @@ app "app"
imports []
provides [main] to pf
main : { f: I64, I64 -> I64 }
main = { f: increment }
main : { f: I64, I64 -> I64, g: I64, I64 -> I64 }
main = { f: add, g: sub }
increment : I64, I64 -> I64
increment = \x, y -> x + y
add : I64, I64 -> I64
add = \x, y -> x + y
sub : I64, I64 -> I64
sub = \x, y -> x - y

View file

@ -1,9 +1,9 @@
platform "test-platform"
requires {} { main : { f: I64, I64 -> I64 } }
requires {} { main : { f: I64, I64 -> I64, g: I64, I64 -> I64 } }
exposes []
packages {}
imports []
provides [mainForHost]
mainForHost : { f: I64, I64 -> I64 }
mainForHost : { f: I64, I64 -> I64, g: I64, I64 -> I64 }
mainForHost = main

View file

@ -3,9 +3,10 @@ mod test_glue;
#[no_mangle]
pub extern "C" fn rust_main() -> i32 {
let record = test_glue::mainForHost();
let answer = record.f.force_thunk(42i64, 1);
let answer1 = record.f.force_thunk(42i64, 1);
let answer2 = record.g.force_thunk(42i64, 1);
println!("Answer was: {:?}", answer); // Debug
println!("Answer was: {:?} {:?}", answer1, answer2);
// Exit code
0

View file

@ -134,7 +134,7 @@ mod glue_cli_run {
Answer was: discriminant_U1::None
"#),
return_function:"return-function" => indoc!(r#"
Answer was: 43
Answer was: 43 41
"#),
}