mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
functions in structs, in general
This commit is contained in:
parent
b7119e9b3a
commit
9a6f9ad26e
7 changed files with 42 additions and 13 deletions
|
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
"#),
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue