| ... | ... | @@ -1430,10 +1430,10 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) { |
| 1430 | 1430 | case TypeTableEntryIdBoundFn: |
| 1431 | 1431 | case TypeTableEntryIdArgTuple: |
| 1432 | 1432 | case TypeTableEntryIdPromise: |
| 1433 | case TypeTableEntryIdVoid: |
| 1433 | 1434 | return false; |
| 1434 | 1435 | case TypeTableEntryIdOpaque: |
| 1435 | 1436 | case TypeTableEntryIdUnreachable: |
| 1436 | | case TypeTableEntryIdVoid: |
| 1437 | 1437 | case TypeTableEntryIdBool: |
| 1438 | 1438 | return true; |
| 1439 | 1439 | case TypeTableEntryIdInt: |
| ... | ... | @@ -1460,7 +1460,10 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) { |
| 1460 | 1460 | case TypeTableEntryIdOptional: |
| 1461 | 1461 | { |
| 1462 | 1462 | TypeTableEntry *child_type = type_entry->data.maybe.child_type; |
| 1463 | | return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn; |
| 1463 | if (child_type->id != TypeTableEntryIdPointer && child_type->id != TypeTableEntryIdFn) { |
| 1464 | return false; |
| 1465 | } |
| 1466 | return type_allowed_in_extern(g, child_type); |
| 1464 | 1467 | } |
| 1465 | 1468 | case TypeTableEntryIdEnum: |
| 1466 | 1469 | return type_entry->data.enumeration.layout == ContainerLayoutExtern || type_entry->data.enumeration.layout == ContainerLayoutPacked; |
| ... | ... | @@ -1637,7 +1640,10 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c |
| 1637 | 1640 | fn_type_id.return_type = specified_return_type; |
| 1638 | 1641 | } |
| 1639 | 1642 | |
| 1640 | | if (!calling_convention_allows_zig_types(fn_type_id.cc) && !type_allowed_in_extern(g, fn_type_id.return_type)) { |
| 1643 | if (!calling_convention_allows_zig_types(fn_type_id.cc) && |
| 1644 | fn_type_id.return_type->id != TypeTableEntryIdVoid && |
| 1645 | !type_allowed_in_extern(g, fn_type_id.return_type)) |
| 1646 | { |
| 1641 | 1647 | add_node_error(g, fn_proto->return_type, |
| 1642 | 1648 | buf_sprintf("return type '%s' not allowed in function with calling convention '%s'", |
| 1643 | 1649 | buf_ptr(&fn_type_id.return_type->name), |
| ... | ... | @@ -1939,6 +1945,17 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { |
| 1939 | 1945 | break; |
| 1940 | 1946 | } |
| 1941 | 1947 | |
| 1948 | if (struct_type->data.structure.layout == ContainerLayoutExtern) { |
| 1949 | if (!type_allowed_in_extern(g, field_type)) { |
| 1950 | AstNode *field_source_node = decl_node->data.container_decl.fields.at(i); |
| 1951 | add_node_error(g, field_source_node, |
| 1952 | buf_sprintf("extern structs cannot contain fields of type '%s'", |
| 1953 | buf_ptr(&field_type->name))); |
| 1954 | struct_type->data.structure.is_invalid = true; |
| 1955 | break; |
| 1956 | } |
| 1957 | } |
| 1958 | |
| 1942 | 1959 | if (!type_has_bits(field_type)) |
| 1943 | 1960 | continue; |
| 1944 | 1961 | |