authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-31 01:51:15-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-31 01:51:31-05:00
log5161d70620342749b1995fdaabb39220654cc941
treeba940c1a85386f1866cd75aab67809b4c0c95755
parent40ca39d3d5a556e3b5d7298e3a5182f4351bdd17

*WIP* error sets


14 files changed, 949 insertions(+), 499 deletions(-)

doc/langref.html.in+8-8
...@@ -1281,7 +1281,7 @@ const ptr = &amp;x;...@@ -1281,7 +1281,7 @@ const ptr = &amp;x;
1281 <pre><code>x() x[] x.y1281 <pre><code>x() x[] x.y
1282!x -x -%x ~x *x &amp;x ?x %x ??x1282!x -x -%x ~x *x &amp;x ?x %x ??x
1283x{}1283x{}
1284* / % ** *%1284! * / % ** *%
1285+ - ++ +% -%1285+ - ++ +% -%
1286&lt;&lt; &gt;&gt;1286&lt;&lt; &gt;&gt;
1287&amp;1287&amp;
...@@ -5566,14 +5566,12 @@ fn readU32Be() u32 {}...@@ -5566,14 +5566,12 @@ fn readU32Be() u32 {}
5566 {#header_open|Grammar#}5566 {#header_open|Grammar#}
5567 <pre><code class="nohighlight">Root = many(TopLevelItem) EOF5567 <pre><code class="nohighlight">Root = many(TopLevelItem) EOF
55685568
5569TopLevelItem = ErrorValueDecl | CompTimeExpression(Block) | TopLevelDecl | TestDecl5569TopLevelItem = CompTimeExpression(Block) | TopLevelDecl | TestDecl
55705570
5571TestDecl = "test" String Block5571TestDecl = "test" String Block
55725572
5573TopLevelDecl = option("pub") (FnDef | ExternDecl | GlobalVarDecl | UseDecl)5573TopLevelDecl = option("pub") (FnDef | ExternDecl | GlobalVarDecl | UseDecl)
55745574
5575ErrorValueDecl = "error" Symbol ";"
5576
5577GlobalVarDecl = option("export") VariableDeclaration ";"5575GlobalVarDecl = option("export") VariableDeclaration ";"
55785576
5579LocalVarDecl = option("comptime") VariableDeclaration5577LocalVarDecl = option("comptime") VariableDeclaration
...@@ -5588,7 +5586,7 @@ UseDecl = "use" Expression ";"...@@ -5588,7 +5586,7 @@ UseDecl = "use" Expression ";"
55885586
5589ExternDecl = "extern" option(String) (FnProto | VariableDeclaration) ";"5587ExternDecl = "extern" option(String) (FnProto | VariableDeclaration) ";"
55905588
5591FnProto = option("nakedcc" | "stdcallcc" | "extern") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") TypeExpr5589FnProto = option("nakedcc" | "stdcallcc" | "extern") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("!") TypeExpr
55925590
5593FnDef = option("inline" | "export") FnProto Block5591FnDef = option("inline" | "export") FnProto Block
55945592
...@@ -5682,7 +5680,7 @@ MultiplyExpression = CurlySuffixExpression MultiplyOperator MultiplyExpression |...@@ -5682,7 +5680,7 @@ MultiplyExpression = CurlySuffixExpression MultiplyOperator MultiplyExpression |
56825680
5683CurlySuffixExpression = TypeExpr option(ContainerInitExpression)5681CurlySuffixExpression = TypeExpr option(ContainerInitExpression)
56845682
5685MultiplyOperator = "*" | "/" | "%" | "**" | "*%"5683MultiplyOperator = "!" | "*" | "/" | "%" | "**" | "*%"
56865684
5687PrefixOpExpression = PrefixOp PrefixOpExpression | SuffixOpExpression5685PrefixOpExpression = PrefixOp PrefixOpExpression | SuffixOpExpression
56885686
...@@ -5702,9 +5700,9 @@ ContainerInitBody = list(StructLiteralField, ",") | list(Expression, ",")...@@ -5702,9 +5700,9 @@ ContainerInitBody = list(StructLiteralField, ",") | list(Expression, ",")
57025700
5703StructLiteralField = "." Symbol "=" Expression5701StructLiteralField = "." Symbol "=" Expression
57045702
5705PrefixOp = "!" | "-" | "~" | "*" | ("&amp;" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "%" | "??" | "-%" | "try"5703PrefixOp = "!" | "-" | "~" | "*" | ("&amp;" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "??" | "-%" | "try"
57065704
5707PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." Symbol) | ContainerDecl | ("continue" option(":" Symbol))5705PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ContainerDecl | ("continue" option(":" Symbol)) | ErrorSetDecl
57085706
5709ArrayType : "[" option(Expression) "]" option("align" "(" Expression option(":" Integer ":" Integer) ")")) option("const") option("volatile") TypeExpr5707ArrayType : "[" option(Expression) "]" option("align" "(" Expression option(":" Integer ":" Integer) ")")) option("const") option("volatile") TypeExpr
57105708
...@@ -5712,6 +5710,8 @@ GroupedExpression = "(" Expression ")"...@@ -5712,6 +5710,8 @@ GroupedExpression = "(" Expression ")"
57125710
5713KeywordLiteral = "true" | "false" | "null" | "undefined" | "error" | "this" | "unreachable"5711KeywordLiteral = "true" | "false" | "null" | "undefined" | "error" | "this" | "unreachable"
57145712
5713ErrorSetDecl = "error" "{" list(Symbol, ",") "}"
5714
5715ContainerDecl = option("extern" | "packed")5715ContainerDecl = option("extern" | "packed")
5716 ("struct" option(GroupedExpression) | "union" option("enum" option(GroupedExpression) | GroupedExpression) | ("enum" option(GroupedExpression)))5716 ("struct" option(GroupedExpression) | "union" option("enum" option(GroupedExpression) | GroupedExpression) | ("enum" option(GroupedExpression)))
5717 "{" many(ContainerMember) "}"</code></pre>5717 "{" many(ContainerMember) "}"</code></pre>
src/all_types.hpp+41-19
...@@ -236,7 +236,7 @@ struct ConstExprValue {...@@ -236,7 +236,7 @@ struct ConstExprValue {
236 TypeTableEntry *x_type;236 TypeTableEntry *x_type;
237 ConstExprValue *x_maybe;237 ConstExprValue *x_maybe;
238 ConstErrValue x_err_union;238 ConstErrValue x_err_union;
239 ErrorTableEntry *x_pure_err;239 ErrorTableEntry *x_err_set;
240 BigInt x_enum_tag;240 BigInt x_enum_tag;
241 ConstStructValue x_struct;241 ConstStructValue x_struct;
242 ConstUnionValue x_union;242 ConstUnionValue x_union;
...@@ -353,7 +353,6 @@ enum NodeType {...@@ -353,7 +353,6 @@ enum NodeType {
353 NodeTypeReturnExpr,353 NodeTypeReturnExpr,
354 NodeTypeDefer,354 NodeTypeDefer,
355 NodeTypeVariableDeclaration,355 NodeTypeVariableDeclaration,
356 NodeTypeErrorValueDecl,
357 NodeTypeTestDecl,356 NodeTypeTestDecl,
358 NodeTypeBinOpExpr,357 NodeTypeBinOpExpr,
359 NodeTypeUnwrapErrorExpr,358 NodeTypeUnwrapErrorExpr,
...@@ -393,6 +392,7 @@ enum NodeType {...@@ -393,6 +392,7 @@ enum NodeType {
393 NodeTypeVarLiteral,392 NodeTypeVarLiteral,
394 NodeTypeIfErrorExpr,393 NodeTypeIfErrorExpr,
395 NodeTypeTestExpr,394 NodeTypeTestExpr,
395 NodeTypeErrorSetDecl,
396};396};
397397
398struct AstNodeRoot {398struct AstNodeRoot {
...@@ -424,6 +424,8 @@ struct AstNodeFnProto {...@@ -424,6 +424,8 @@ struct AstNodeFnProto {
424 AstNode *align_expr;424 AstNode *align_expr;
425 // populated if the "section(S)" is present425 // populated if the "section(S)" is present
426 AstNode *section_expr;426 AstNode *section_expr;
427
428 bool auto_err_set;
427};429};
428430
429struct AstNodeFnDef {431struct AstNodeFnDef {
...@@ -486,12 +488,6 @@ struct AstNodeVariableDeclaration {...@@ -486,12 +488,6 @@ struct AstNodeVariableDeclaration {
486 AstNode *section_expr;488 AstNode *section_expr;
487};489};
488490
489struct AstNodeErrorValueDecl {
490 Buf *name;
491
492 ErrorTableEntry *err;
493};
494
495struct AstNodeTestDecl {491struct AstNodeTestDecl {
496 Buf *name;492 Buf *name;
497493
...@@ -540,6 +536,7 @@ enum BinOpType {...@@ -540,6 +536,7 @@ enum BinOpType {
540 BinOpTypeUnwrapMaybe,536 BinOpTypeUnwrapMaybe,
541 BinOpTypeArrayCat,537 BinOpTypeArrayCat,
542 BinOpTypeArrayMult,538 BinOpTypeArrayMult,
539 BinOpTypeErrorUnion,
543};540};
544541
545struct AstNodeBinOpExpr {542struct AstNodeBinOpExpr {
...@@ -595,7 +592,6 @@ enum PrefixOp {...@@ -595,7 +592,6 @@ enum PrefixOp {
595 PrefixOpNegationWrap,592 PrefixOpNegationWrap,
596 PrefixOpDereference,593 PrefixOpDereference,
597 PrefixOpMaybe,594 PrefixOpMaybe,
598 PrefixOpError,
599 PrefixOpUnwrapMaybe,595 PrefixOpUnwrapMaybe,
600};596};
601597
...@@ -762,6 +758,10 @@ struct AstNodeContainerDecl {...@@ -762,6 +758,10 @@ struct AstNodeContainerDecl {
762 bool auto_enum; // union(enum)758 bool auto_enum; // union(enum)
763};759};
764760
761struct AstNodeErrorSetDecl {
762 ZigList<AstNode *> decls;
763};
764
765struct AstNodeStructField {765struct AstNodeStructField {
766 VisibMod visib_mod;766 VisibMod visib_mod;
767 Buf *name;767 Buf *name;
...@@ -858,7 +858,6 @@ struct AstNode {...@@ -858,7 +858,6 @@ struct AstNode {
858 AstNodeReturnExpr return_expr;858 AstNodeReturnExpr return_expr;
859 AstNodeDefer defer;859 AstNodeDefer defer;
860 AstNodeVariableDeclaration variable_declaration;860 AstNodeVariableDeclaration variable_declaration;
861 AstNodeErrorValueDecl error_value_decl;
862 AstNodeTestDecl test_decl;861 AstNodeTestDecl test_decl;
863 AstNodeBinOpExpr bin_op_expr;862 AstNodeBinOpExpr bin_op_expr;
864 AstNodeCatchExpr unwrap_err_expr;863 AstNodeCatchExpr unwrap_err_expr;
...@@ -899,6 +898,7 @@ struct AstNode {...@@ -899,6 +898,7 @@ struct AstNode {
899 AstNodeArrayType array_type;898 AstNodeArrayType array_type;
900 AstNodeErrorType error_type;899 AstNodeErrorType error_type;
901 AstNodeVarLiteral var_literal;900 AstNodeVarLiteral var_literal;
901 AstNodeErrorSetDecl err_set_decl;
902 } data;902 } data;
903};903};
904904
...@@ -993,8 +993,15 @@ struct TypeTableEntryMaybe {...@@ -993,8 +993,15 @@ struct TypeTableEntryMaybe {
993 TypeTableEntry *child_type;993 TypeTableEntry *child_type;
994};994};
995995
996struct TypeTableEntryError {996struct TypeTableEntryErrorUnion {
997 TypeTableEntry *child_type;997 TypeTableEntry *err_set_type;
998 TypeTableEntry *payload_type;
999};
1000
1001struct TypeTableEntryErrorSet {
1002 uint32_t err_count;
1003 ErrorTableEntry **errors;
1004 FnTableEntry *infer_fn;
998};1005};
9991006
1000struct TypeTableEntryEnum {1007struct TypeTableEntryEnum {
...@@ -1097,7 +1104,7 @@ enum TypeTableEntryId {...@@ -1097,7 +1104,7 @@ enum TypeTableEntryId {
1097 TypeTableEntryIdNullLit,1104 TypeTableEntryIdNullLit,
1098 TypeTableEntryIdMaybe,1105 TypeTableEntryIdMaybe,
1099 TypeTableEntryIdErrorUnion,1106 TypeTableEntryIdErrorUnion,
1100 TypeTableEntryIdPureError,1107 TypeTableEntryIdErrorSet,
1101 TypeTableEntryIdEnum,1108 TypeTableEntryIdEnum,
1102 TypeTableEntryIdUnion,1109 TypeTableEntryIdUnion,
1103 TypeTableEntryIdFn,1110 TypeTableEntryIdFn,
...@@ -1126,7 +1133,8 @@ struct TypeTableEntry {...@@ -1126,7 +1133,8 @@ struct TypeTableEntry {
1126 TypeTableEntryArray array;1133 TypeTableEntryArray array;
1127 TypeTableEntryStruct structure;1134 TypeTableEntryStruct structure;
1128 TypeTableEntryMaybe maybe;1135 TypeTableEntryMaybe maybe;
1129 TypeTableEntryError error;1136 TypeTableEntryErrorUnion error_union;
1137 TypeTableEntryErrorSet error_set;
1130 TypeTableEntryEnum enumeration;1138 TypeTableEntryEnum enumeration;
1131 TypeTableEntryUnion unionation;1139 TypeTableEntryUnion unionation;
1132 TypeTableEntryFn fn;1140 TypeTableEntryFn fn;
...@@ -1136,7 +1144,6 @@ struct TypeTableEntry {...@@ -1136,7 +1144,6 @@ struct TypeTableEntry {
1136 // use these fields to make sure we don't duplicate type table entries for the same type1144 // use these fields to make sure we don't duplicate type table entries for the same type
1137 TypeTableEntry *pointer_parent[2]; // [0 - mut, 1 - const]1145 TypeTableEntry *pointer_parent[2]; // [0 - mut, 1 - const]
1138 TypeTableEntry *maybe_parent;1146 TypeTableEntry *maybe_parent;
1139 TypeTableEntry *error_parent;
1140 // If we generate a constant name value for this type, we memoize it here.1147 // If we generate a constant name value for this type, we memoize it here.
1141 // The type of this is array1148 // The type of this is array
1142 ConstExprValue *cached_const_name_val;1149 ConstExprValue *cached_const_name_val;
...@@ -1340,6 +1347,10 @@ struct TypeId {...@@ -1340,6 +1347,10 @@ struct TypeId {
1340 bool is_signed;1347 bool is_signed;
1341 uint32_t bit_count;1348 uint32_t bit_count;
1342 } integer;1349 } integer;
1350 struct {
1351 TypeTableEntry *err_set_type;
1352 TypeTableEntry *payload_type;
1353 } error_union;
1343 } data;1354 } data;
1344};1355};
13451356
...@@ -1481,7 +1492,7 @@ struct CodeGen {...@@ -1481,7 +1492,7 @@ struct CodeGen {
1481 TypeTableEntry *entry_undef;1492 TypeTableEntry *entry_undef;
1482 TypeTableEntry *entry_null;1493 TypeTableEntry *entry_null;
1483 TypeTableEntry *entry_var;1494 TypeTableEntry *entry_var;
1484 TypeTableEntry *entry_pure_error;1495 TypeTableEntry *entry_global_error_set;
1485 TypeTableEntry *entry_arg_tuple;1496 TypeTableEntry *entry_arg_tuple;
1486 } builtin_types;1497 } builtin_types;
14871498
...@@ -1570,7 +1581,6 @@ struct CodeGen {...@@ -1570,7 +1581,6 @@ struct CodeGen {
1570 LLVMValueRef return_address_fn_val;1581 LLVMValueRef return_address_fn_val;
1571 LLVMValueRef frame_address_fn_val;1582 LLVMValueRef frame_address_fn_val;
1572 bool error_during_imports;1583 bool error_during_imports;
1573 TypeTableEntry *err_tag_type;
15741584
1575 const char **clang_argv;1585 const char **clang_argv;
1576 size_t clang_argv_len;1586 size_t clang_argv_len;
...@@ -1584,7 +1594,9 @@ struct CodeGen {...@@ -1584,7 +1594,9 @@ struct CodeGen {
15841594
1585 bool each_lib_rpath;1595 bool each_lib_rpath;
15861596
1587 ZigList<AstNode *> error_decls;1597 TypeTableEntry *err_tag_type;
1598 ZigList<ZigLLVMDIEnumerator *> err_enumerators;
1599 ZigList<ErrorTableEntry *> errors_by_index;
1588 bool generate_error_name_table;1600 bool generate_error_name_table;
1589 LLVMValueRef err_name_table;1601 LLVMValueRef err_name_table;
1590 size_t largest_err_name_len;1602 size_t largest_err_name_len;
...@@ -1617,6 +1629,8 @@ struct CodeGen {...@@ -1617,6 +1629,8 @@ struct CodeGen {
1617 TypeTableEntry *align_amt_type;1629 TypeTableEntry *align_amt_type;
1618 TypeTableEntry *stack_trace_type;1630 TypeTableEntry *stack_trace_type;
1619 TypeTableEntry *ptr_to_stack_trace_type;1631 TypeTableEntry *ptr_to_stack_trace_type;
1632
1633 ZigList<ZigLLVMDIType **> error_di_types;
1620};1634};
16211635
1622enum VarLinkage {1636enum VarLinkage {
...@@ -1653,6 +1667,7 @@ struct ErrorTableEntry {...@@ -1653,6 +1667,7 @@ struct ErrorTableEntry {
1653 Buf name;1667 Buf name;
1654 uint32_t value;1668 uint32_t value;
1655 AstNode *decl_node;1669 AstNode *decl_node;
1670 TypeTableEntry *set_with_only_this_in_it;
1656 // If we generate a constant error name value for this error, we memoize it here.1671 // If we generate a constant error name value for this error, we memoize it here.
1657 // The type of this is array1672 // The type of this is array
1658 ConstExprValue *cached_error_name_val;1673 ConstExprValue *cached_error_name_val;
...@@ -1920,6 +1935,7 @@ enum IrInstructionId {...@@ -1920,6 +1935,7 @@ enum IrInstructionId {
1920 IrInstructionIdArgType,1935 IrInstructionIdArgType,
1921 IrInstructionIdExport,1936 IrInstructionIdExport,
1922 IrInstructionIdErrorReturnTrace,1937 IrInstructionIdErrorReturnTrace,
1938 IrInstructionIdErrorUnion,
1923};1939};
19241940
1925struct IrInstruction {1941struct IrInstruction {
...@@ -1996,7 +2012,6 @@ enum IrUnOp {...@@ -1996,7 +2012,6 @@ enum IrUnOp {
1996 IrUnOpNegation,2012 IrUnOpNegation,
1997 IrUnOpNegationWrap,2013 IrUnOpNegationWrap,
1998 IrUnOpDereference,2014 IrUnOpDereference,
1999 IrUnOpError,
2000 IrUnOpMaybe,2015 IrUnOpMaybe,
2001};2016};
20022017
...@@ -2750,6 +2765,13 @@ struct IrInstructionErrorReturnTrace {...@@ -2750,6 +2765,13 @@ struct IrInstructionErrorReturnTrace {
2750 IrInstruction base;2765 IrInstruction base;
2751};2766};
27522767
2768struct IrInstructionErrorUnion {
2769 IrInstruction base;
2770
2771 IrInstruction *err_set;
2772 IrInstruction *payload;
2773};
2774
2753static const size_t slice_ptr_index = 0;2775static const size_t slice_ptr_index = 0;
2754static const size_t slice_len_index = 1;2776static const size_t slice_len_index = 1;
27552777
src/analyze.cpp+124-88
...@@ -224,7 +224,7 @@ bool type_is_complete(TypeTableEntry *type_entry) {...@@ -224,7 +224,7 @@ bool type_is_complete(TypeTableEntry *type_entry) {
224 case TypeTableEntryIdNullLit:224 case TypeTableEntryIdNullLit:
225 case TypeTableEntryIdMaybe:225 case TypeTableEntryIdMaybe:
226 case TypeTableEntryIdErrorUnion:226 case TypeTableEntryIdErrorUnion:
227 case TypeTableEntryIdPureError:227 case TypeTableEntryIdErrorSet:
228 case TypeTableEntryIdFn:228 case TypeTableEntryIdFn:
229 case TypeTableEntryIdNamespace:229 case TypeTableEntryIdNamespace:
230 case TypeTableEntryIdBlock:230 case TypeTableEntryIdBlock:
...@@ -260,7 +260,7 @@ bool type_has_zero_bits_known(TypeTableEntry *type_entry) {...@@ -260,7 +260,7 @@ bool type_has_zero_bits_known(TypeTableEntry *type_entry) {
260 case TypeTableEntryIdNullLit:260 case TypeTableEntryIdNullLit:
261 case TypeTableEntryIdMaybe:261 case TypeTableEntryIdMaybe:
262 case TypeTableEntryIdErrorUnion:262 case TypeTableEntryIdErrorUnion:
263 case TypeTableEntryIdPureError:263 case TypeTableEntryIdErrorSet:
264 case TypeTableEntryIdFn:264 case TypeTableEntryIdFn:
265 case TypeTableEntryIdNamespace:265 case TypeTableEntryIdNamespace:
266 case TypeTableEntryIdBlock:266 case TypeTableEntryIdBlock:
...@@ -514,29 +514,39 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {...@@ -514,29 +514,39 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {
514 }514 }
515}515}
516516
517TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {517TypeTableEntry *get_error_union_type(CodeGen *g, TypeTableEntry *err_set_type, TypeTableEntry *payload_type) {
518 if (child_type->error_parent)518 assert(err_set_type->id == TypeTableEntryIdErrorSet);
519 return child_type->error_parent;519
520 TypeId type_id = {};
521 type_id.id = TypeTableEntryIdErrorUnion;
522 type_id.data.error_union.err_set_type = err_set_type;
523 type_id.data.error_union.payload_type = payload_type;
524
525 auto existing_entry = g->type_table.maybe_get(type_id);
526 if (existing_entry) {
527 return existing_entry->value;
528 }
520529
521 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdErrorUnion);530 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdErrorUnion);
522 entry->is_copyable = true;531 entry->is_copyable = true;
523 assert(child_type->type_ref);532 assert(payload_type->type_ref);
524 assert(child_type->di_type);533 assert(payload_type->di_type);
525 ensure_complete_type(g, child_type);534 ensure_complete_type(g, payload_type);
526535
527 buf_resize(&entry->name, 0);536 buf_resize(&entry->name, 0);
528 buf_appendf(&entry->name, "%%%s", buf_ptr(&child_type->name));537 buf_appendf(&entry->name, "%s!%s", buf_ptr(&err_set_type->name), buf_ptr(&payload_type->name));
529538
530 entry->data.error.child_type = child_type;539 entry->data.error_union.err_set_type = err_set_type;
540 entry->data.error_union.payload_type = payload_type;
531541
532 if (!type_has_bits(child_type)) {542 if (!type_has_bits(payload_type)) {
533 entry->type_ref = g->err_tag_type->type_ref;543 entry->type_ref = err_set_type->type_ref;
534 entry->di_type = g->err_tag_type->di_type;544 entry->di_type = err_set_type->di_type;
535545
536 } else {546 } else {
537 LLVMTypeRef elem_types[] = {547 LLVMTypeRef elem_types[] = {
538 g->err_tag_type->type_ref,548 err_set_type->type_ref,
539 child_type->type_ref,549 payload_type->type_ref,
540 };550 };
541 entry->type_ref = LLVMStructType(elem_types, 2, false);551 entry->type_ref = LLVMStructType(elem_types, 2, false);
542552
...@@ -547,12 +557,12 @@ TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {...@@ -547,12 +557,12 @@ TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
547 ZigLLVMTag_DW_structure_type(), buf_ptr(&entry->name),557 ZigLLVMTag_DW_structure_type(), buf_ptr(&entry->name),
548 compile_unit_scope, di_file, line);558 compile_unit_scope, di_file, line);
549559
550 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, g->err_tag_type->type_ref);560 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, err_set_type->type_ref);
551 uint64_t tag_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, g->err_tag_type->type_ref);561 uint64_t tag_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, err_set_type->type_ref);
552 uint64_t tag_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, err_union_err_index);562 uint64_t tag_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, err_union_err_index);
553563
554 uint64_t value_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, child_type->type_ref);564 uint64_t value_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, payload_type->type_ref);
555 uint64_t value_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, child_type->type_ref);565 uint64_t value_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, payload_type->type_ref);
556 uint64_t value_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref,566 uint64_t value_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref,
557 err_union_payload_index);567 err_union_payload_index);
558568
...@@ -565,13 +575,13 @@ TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {...@@ -565,13 +575,13 @@ TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
565 tag_debug_size_in_bits,575 tag_debug_size_in_bits,
566 tag_debug_align_in_bits,576 tag_debug_align_in_bits,
567 tag_offset_in_bits,577 tag_offset_in_bits,
568 0, child_type->di_type),578 0, err_set_type->di_type),
569 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type),579 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type),
570 "value", di_file, line,580 "value", di_file, line,
571 value_debug_size_in_bits,581 value_debug_size_in_bits,
572 value_debug_align_in_bits,582 value_debug_align_in_bits,
573 value_offset_in_bits,583 value_offset_in_bits,
574 0, child_type->di_type),584 0, payload_type->di_type),
575 };585 };
576586
577 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,587 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
...@@ -587,7 +597,7 @@ TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {...@@ -587,7 +597,7 @@ TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
587 entry->di_type = replacement_di_type;597 entry->di_type = replacement_di_type;
588 }598 }
589599
590 child_type->error_parent = entry;600 g->type_table.put(type_id, entry);
591 return entry;601 return entry;
592}602}
593603
...@@ -937,7 +947,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {...@@ -937,7 +947,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
937 handle_is_ptr(fn_type_id->return_type);947 handle_is_ptr(fn_type_id->return_type);
938 bool prefix_arg_error_return_trace = g->have_err_ret_tracing &&948 bool prefix_arg_error_return_trace = g->have_err_ret_tracing &&
939 (fn_type_id->return_type->id == TypeTableEntryIdErrorUnion || 949 (fn_type_id->return_type->id == TypeTableEntryIdErrorUnion ||
940 fn_type_id->return_type->id == TypeTableEntryIdPureError);950 fn_type_id->return_type->id == TypeTableEntryIdErrorSet);
941 // +1 for maybe making the first argument the return value951 // +1 for maybe making the first argument the return value
942 // +1 for maybe last argument the error return trace952 // +1 for maybe last argument the error return trace
943 LLVMTypeRef *gen_param_types = allocate<LLVMTypeRef>(2 + fn_type_id->param_count);953 LLVMTypeRef *gen_param_types = allocate<LLVMTypeRef>(2 + fn_type_id->param_count);
...@@ -1177,7 +1187,7 @@ static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {...@@ -1177,7 +1187,7 @@ static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
1177 case TypeTableEntryIdUndefLit:1187 case TypeTableEntryIdUndefLit:
1178 case TypeTableEntryIdNullLit:1188 case TypeTableEntryIdNullLit:
1179 case TypeTableEntryIdErrorUnion:1189 case TypeTableEntryIdErrorUnion:
1180 case TypeTableEntryIdPureError:1190 case TypeTableEntryIdErrorSet:
1181 case TypeTableEntryIdNamespace:1191 case TypeTableEntryIdNamespace:
1182 case TypeTableEntryIdBlock:1192 case TypeTableEntryIdBlock:
1183 case TypeTableEntryIdBoundFn:1193 case TypeTableEntryIdBoundFn:
...@@ -1218,7 +1228,7 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {...@@ -1218,7 +1228,7 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {
1218 case TypeTableEntryIdUndefLit:1228 case TypeTableEntryIdUndefLit:
1219 case TypeTableEntryIdNullLit:1229 case TypeTableEntryIdNullLit:
1220 case TypeTableEntryIdErrorUnion:1230 case TypeTableEntryIdErrorUnion:
1221 case TypeTableEntryIdPureError:1231 case TypeTableEntryIdErrorSet:
1222 case TypeTableEntryIdNamespace:1232 case TypeTableEntryIdNamespace:
1223 case TypeTableEntryIdBlock:1233 case TypeTableEntryIdBlock:
1224 case TypeTableEntryIdBoundFn:1234 case TypeTableEntryIdBoundFn:
...@@ -1263,7 +1273,23 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {...@@ -1263,7 +1273,23 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {
1263 zig_unreachable();1273 zig_unreachable();
1264}1274}
12651275
1266static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope) {1276static TypeTableEntry *get_auto_err_set_type(CodeGen *g, FnTableEntry *fn_entry) {
1277 TypeTableEntry *err_set_type = new_type_table_entry(TypeTableEntryIdErrorSet);
1278 buf_resize(&err_set_type->name, 0);
1279 buf_appendf(&err_set_type->name, "%s.errors", buf_ptr(&fn_entry->symbol_name));
1280 err_set_type->is_copyable = true;
1281 err_set_type->type_ref = g->builtin_types.entry_global_error_set->type_ref;
1282 err_set_type->di_type = g->builtin_types.entry_global_error_set->di_type;
1283 err_set_type->data.error_set.err_count = 0;
1284 err_set_type->data.error_set.errors = nullptr;
1285 err_set_type->data.error_set.infer_fn = fn_entry;
1286
1287 g->error_di_types.append(&err_set_type->di_type);
1288
1289 return err_set_type;
1290}
1291
1292static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope, FnTableEntry *fn_entry) {
1267 assert(proto_node->type == NodeTypeFnProto);1293 assert(proto_node->type == NodeTypeFnProto);
1268 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;1294 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
12691295
...@@ -1359,7 +1385,7 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c...@@ -1359,7 +1385,7 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
1359 case TypeTableEntryIdStruct:1385 case TypeTableEntryIdStruct:
1360 case TypeTableEntryIdMaybe:1386 case TypeTableEntryIdMaybe:
1361 case TypeTableEntryIdErrorUnion:1387 case TypeTableEntryIdErrorUnion:
1362 case TypeTableEntryIdPureError:1388 case TypeTableEntryIdErrorSet:
1363 case TypeTableEntryIdEnum:1389 case TypeTableEntryIdEnum:
1364 case TypeTableEntryIdUnion:1390 case TypeTableEntryIdUnion:
1365 case TypeTableEntryIdFn:1391 case TypeTableEntryIdFn:
...@@ -1382,8 +1408,13 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c...@@ -1382,8 +1408,13 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
1382 }1408 }
1383 }1409 }
13841410
1385 fn_type_id.return_type = (fn_proto->return_type == nullptr) ?1411 TypeTableEntry *specified_return_type = analyze_type_expr(g, child_scope, fn_proto->return_type);
1386 g->builtin_types.entry_void : analyze_type_expr(g, child_scope, fn_proto->return_type);1412 if (fn_proto->auto_err_set) {
1413 TypeTableEntry *inferred_err_set_type = get_auto_err_set_type(g, fn_entry);
1414 fn_type_id.return_type = get_error_union_type(g, inferred_err_set_type, specified_return_type);
1415 } else {
1416 fn_type_id.return_type = specified_return_type;
1417 }
13871418
1388 if (type_is_invalid(fn_type_id.return_type)) {1419 if (type_is_invalid(fn_type_id.return_type)) {
1389 return g->builtin_types.entry_invalid;1420 return g->builtin_types.entry_invalid;
...@@ -1434,7 +1465,7 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c...@@ -1434,7 +1465,7 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
1434 case TypeTableEntryIdStruct:1465 case TypeTableEntryIdStruct:
1435 case TypeTableEntryIdMaybe:1466 case TypeTableEntryIdMaybe:
1436 case TypeTableEntryIdErrorUnion:1467 case TypeTableEntryIdErrorUnion:
1437 case TypeTableEntryIdPureError:1468 case TypeTableEntryIdErrorSet:
1438 case TypeTableEntryIdEnum:1469 case TypeTableEntryIdEnum:
1439 case TypeTableEntryIdUnion:1470 case TypeTableEntryIdUnion:
1440 case TypeTableEntryIdFn:1471 case TypeTableEntryIdFn:
...@@ -2756,7 +2787,8 @@ TypeTableEntry *get_test_fn_type(CodeGen *g) {...@@ -2756,7 +2787,8 @@ TypeTableEntry *get_test_fn_type(CodeGen *g) {
2756 return g->test_fn_type;2787 return g->test_fn_type;
27572788
2758 FnTypeId fn_type_id = {0};2789 FnTypeId fn_type_id = {0};
2759 fn_type_id.return_type = get_error_type(g, g->builtin_types.entry_void);2790 fn_type_id.return_type = get_error_union_type(g, g->builtin_types.entry_global_error_set,
2791 g->builtin_types.entry_void);
2760 g->test_fn_type = get_fn_type(g, &fn_type_id);2792 g->test_fn_type = get_fn_type(g, &fn_type_id);
2761 return g->test_fn_type;2793 return g->test_fn_type;
2762}2794}
...@@ -2824,7 +2856,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -2824,7 +2856,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
28242856
2825 Scope *child_scope = fn_table_entry->fndef_scope ? &fn_table_entry->fndef_scope->base : tld_fn->base.parent_scope;2857 Scope *child_scope = fn_table_entry->fndef_scope ? &fn_table_entry->fndef_scope->base : tld_fn->base.parent_scope;
28262858
2827 fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope);2859 fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope, fn_table_entry);
28282860
2829 if (fn_proto->section_expr != nullptr) {2861 if (fn_proto->section_expr != nullptr) {
2830 if (fn_table_entry->body_node == nullptr) {2862 if (fn_table_entry->body_node == nullptr) {
...@@ -2949,29 +2981,6 @@ static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope...@@ -2949,29 +2981,6 @@ static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope
2949 g->resolve_queue.append(&tld_fn->base);2981 g->resolve_queue.append(&tld_fn->base);
2950}2982}
29512983
2952static void preview_error_value_decl(CodeGen *g, AstNode *node) {
2953 assert(node->type == NodeTypeErrorValueDecl);
2954
2955 ErrorTableEntry *err = allocate<ErrorTableEntry>(1);
2956
2957 err->decl_node = node;
2958 buf_init_from_buf(&err->name, node->data.error_value_decl.name);
2959
2960 auto existing_entry = g->error_table.maybe_get(&err->name);
2961 if (existing_entry) {
2962 // duplicate error definitions allowed and they get the same value
2963 err->value = existing_entry->value->value;
2964 } else {
2965 size_t error_value_count = g->error_decls.length;
2966 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)g->err_tag_type->data.integral.bit_count));
2967 err->value = (uint32_t)error_value_count;
2968 g->error_decls.append(node);
2969 g->error_table.put(&err->name, err);
2970 }
2971
2972 node->data.error_value_decl.err = err;
2973}
2974
2975static void preview_comptime_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {2984static void preview_comptime_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
2976 assert(node->type == NodeTypeCompTime);2985 assert(node->type == NodeTypeCompTime);
29772986
...@@ -3045,10 +3054,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {...@@ -3045,10 +3054,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
3045 import->use_decls.append(node);3054 import->use_decls.append(node);
3046 break;3055 break;
3047 }3056 }
3048 case NodeTypeErrorValueDecl:
3049 // error value declarations do not depend on other top level decls
3050 preview_error_value_decl(g, node);
3051 break;
3052 case NodeTypeTestDecl:3057 case NodeTypeTestDecl:
3053 preview_test_decl(g, node, decls_scope);3058 preview_test_decl(g, node, decls_scope);
3054 break;3059 break;
...@@ -3097,6 +3102,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {...@@ -3097,6 +3102,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
3097 case NodeTypeVarLiteral:3102 case NodeTypeVarLiteral:
3098 case NodeTypeIfErrorExpr:3103 case NodeTypeIfErrorExpr:
3099 case NodeTypeTestExpr:3104 case NodeTypeTestExpr:
3105 case NodeTypeErrorSetDecl:
3100 zig_unreachable();3106 zig_unreachable();
3101 }3107 }
3102}3108}
...@@ -3147,7 +3153,7 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt...@@ -3147,7 +3153,7 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt
3147 case TypeTableEntryIdStruct:3153 case TypeTableEntryIdStruct:
3148 case TypeTableEntryIdMaybe:3154 case TypeTableEntryIdMaybe:
3149 case TypeTableEntryIdErrorUnion:3155 case TypeTableEntryIdErrorUnion:
3150 case TypeTableEntryIdPureError:3156 case TypeTableEntryIdErrorSet:
3151 case TypeTableEntryIdEnum:3157 case TypeTableEntryIdEnum:
3152 case TypeTableEntryIdUnion:3158 case TypeTableEntryIdUnion:
3153 case TypeTableEntryIdFn:3159 case TypeTableEntryIdFn:
...@@ -3403,13 +3409,16 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *...@@ -3403,13 +3409,16 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
3403 actual_type->data.maybe.child_type);3409 actual_type->data.maybe.child_type);
3404 }3410 }
34053411
3406 // error3412 // error union
3407 if (expected_type->id == TypeTableEntryIdErrorUnion &&3413 if (expected_type->id == TypeTableEntryIdErrorUnion &&
3408 actual_type->id == TypeTableEntryIdErrorUnion)3414 actual_type->id == TypeTableEntryIdErrorUnion)
3409 {3415 {
3410 return types_match_const_cast_only(3416 return types_match_const_cast_only(
3411 expected_type->data.error.child_type,3417 expected_type->data.error_union.payload_type,
3412 actual_type->data.error.child_type);3418 actual_type->data.error_union.payload_type) &&
3419 types_match_const_cast_only(
3420 expected_type->data.error_union.err_set_type,
3421 actual_type->data.error_union.err_set_type);
3413 }3422 }
34143423
3415 // fn3424 // fn
...@@ -3625,7 +3634,7 @@ static bool is_container(TypeTableEntry *type_entry) {...@@ -3625,7 +3634,7 @@ static bool is_container(TypeTableEntry *type_entry) {
3625 case TypeTableEntryIdNullLit:3634 case TypeTableEntryIdNullLit:
3626 case TypeTableEntryIdMaybe:3635 case TypeTableEntryIdMaybe:
3627 case TypeTableEntryIdErrorUnion:3636 case TypeTableEntryIdErrorUnion:
3628 case TypeTableEntryIdPureError:3637 case TypeTableEntryIdErrorSet:
3629 case TypeTableEntryIdFn:3638 case TypeTableEntryIdFn:
3630 case TypeTableEntryIdNamespace:3639 case TypeTableEntryIdNamespace:
3631 case TypeTableEntryIdBlock:3640 case TypeTableEntryIdBlock:
...@@ -3673,7 +3682,7 @@ void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {...@@ -3673,7 +3682,7 @@ void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {
3673 case TypeTableEntryIdNullLit:3682 case TypeTableEntryIdNullLit:
3674 case TypeTableEntryIdMaybe:3683 case TypeTableEntryIdMaybe:
3675 case TypeTableEntryIdErrorUnion:3684 case TypeTableEntryIdErrorUnion:
3676 case TypeTableEntryIdPureError:3685 case TypeTableEntryIdErrorSet:
3677 case TypeTableEntryIdFn:3686 case TypeTableEntryIdFn:
3678 case TypeTableEntryIdNamespace:3687 case TypeTableEntryIdNamespace:
3679 case TypeTableEntryIdBlock:3688 case TypeTableEntryIdBlock:
...@@ -3774,14 +3783,36 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ...@@ -3774,14 +3783,36 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ
3774 &fn_table_entry->analyzed_executable, fn_type_id->return_type, return_type_node);3783 &fn_table_entry->analyzed_executable, fn_type_id->return_type, return_type_node);
3775 fn_table_entry->implicit_return_type = block_return_type;3784 fn_table_entry->implicit_return_type = block_return_type;
37763785
3777 if (block_return_type->id == TypeTableEntryIdInvalid ||3786 if (type_is_invalid(block_return_type) || fn_table_entry->analyzed_executable.invalid) {
3778 fn_table_entry->analyzed_executable.invalid)
3779 {
3780 assert(g->errors.length > 0);3787 assert(g->errors.length > 0);
3781 fn_table_entry->anal_state = FnAnalStateInvalid;3788 fn_table_entry->anal_state = FnAnalStateInvalid;
3782 return;3789 return;
3783 }3790 }
37843791
3792 if (fn_type_id->return_type->id == TypeTableEntryIdErrorUnion) {
3793 TypeTableEntry *return_err_set_type = fn_type_id->return_type->data.error_union.err_set_type;
3794 if (return_err_set_type->data.error_set.infer_fn != nullptr) {
3795 TypeTableEntry *inferred_err_set_type;
3796 if (fn_table_entry->implicit_return_type->id == TypeTableEntryIdErrorSet) {
3797 inferred_err_set_type = fn_table_entry->implicit_return_type;
3798 } else if (fn_table_entry->implicit_return_type->id == TypeTableEntryIdErrorUnion) {
3799 inferred_err_set_type = fn_table_entry->implicit_return_type->data.error_union.err_set_type;
3800 } else {
3801 add_node_error(g, return_type_node,
3802 buf_sprintf("function with inferred error set must return at least one possible error"));
3803 fn_table_entry->anal_state = FnAnalStateInvalid;
3804 return;
3805 }
3806
3807 return_err_set_type->data.error_set.infer_fn = nullptr;
3808 return_err_set_type->data.error_set.err_count = inferred_err_set_type->data.error_set.err_count;
3809 return_err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(inferred_err_set_type->data.error_set.err_count);
3810 for (uint32_t i = 0; i < inferred_err_set_type->data.error_set.err_count; i += 1) {
3811 return_err_set_type->data.error_set.errors[i] = inferred_err_set_type->data.error_set.errors[i];
3812 }
3813 }
3814 }
3815
3785 if (g->verbose_ir) {3816 if (g->verbose_ir) {
3786 fprintf(stderr, "{ // (analyzed)\n");3817 fprintf(stderr, "{ // (analyzed)\n");
3787 ir_print(g, stderr, &fn_table_entry->analyzed_executable, 4);3818 ir_print(g, stderr, &fn_table_entry->analyzed_executable, 4);
...@@ -3791,7 +3822,7 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ...@@ -3791,7 +3822,7 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ
3791 fn_table_entry->anal_state = FnAnalStateComplete;3822 fn_table_entry->anal_state = FnAnalStateComplete;
3792}3823}
37933824
3794static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {3825void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
3795 assert(fn_table_entry->anal_state != FnAnalStateProbing);3826 assert(fn_table_entry->anal_state != FnAnalStateProbing);
3796 if (fn_table_entry->anal_state != FnAnalStateReady)3827 if (fn_table_entry->anal_state != FnAnalStateReady)
3797 return;3828 return;
...@@ -4022,7 +4053,8 @@ void semantic_analyze(CodeGen *g) {...@@ -4022,7 +4053,8 @@ void semantic_analyze(CodeGen *g) {
4022 for (; g->resolve_queue_index < g->resolve_queue.length; g->resolve_queue_index += 1) {4053 for (; g->resolve_queue_index < g->resolve_queue.length; g->resolve_queue_index += 1) {
4023 Tld *tld = g->resolve_queue.at(g->resolve_queue_index);4054 Tld *tld = g->resolve_queue.at(g->resolve_queue_index);
4024 bool pointer_only = false;4055 bool pointer_only = false;
4025 resolve_top_level_decl(g, tld, pointer_only, nullptr);4056 AstNode *source_node = nullptr;
4057 resolve_top_level_decl(g, tld, pointer_only, source_node);
4026 }4058 }
40274059
4028 for (; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) {4060 for (; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) {
...@@ -4114,7 +4146,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {...@@ -4114,7 +4146,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
4114 case TypeTableEntryIdInt:4146 case TypeTableEntryIdInt:
4115 case TypeTableEntryIdFloat:4147 case TypeTableEntryIdFloat:
4116 case TypeTableEntryIdPointer:4148 case TypeTableEntryIdPointer:
4117 case TypeTableEntryIdPureError:4149 case TypeTableEntryIdErrorSet:
4118 case TypeTableEntryIdFn:4150 case TypeTableEntryIdFn:
4119 case TypeTableEntryIdEnum:4151 case TypeTableEntryIdEnum:
4120 return false;4152 return false;
...@@ -4122,7 +4154,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {...@@ -4122,7 +4154,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
4122 case TypeTableEntryIdStruct:4154 case TypeTableEntryIdStruct:
4123 return type_has_bits(type_entry);4155 return type_has_bits(type_entry);
4124 case TypeTableEntryIdErrorUnion:4156 case TypeTableEntryIdErrorUnion:
4125 return type_has_bits(type_entry->data.error.child_type);4157 return type_has_bits(type_entry->data.error_union.payload_type);
4126 case TypeTableEntryIdMaybe:4158 case TypeTableEntryIdMaybe:
4127 return type_has_bits(type_entry->data.maybe.child_type) &&4159 return type_has_bits(type_entry->data.maybe.child_type) &&
4128 type_entry->data.maybe.child_type->id != TypeTableEntryIdPointer &&4160 type_entry->data.maybe.child_type->id != TypeTableEntryIdPointer &&
...@@ -4386,9 +4418,9 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {...@@ -4386,9 +4418,9 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
4386 case TypeTableEntryIdErrorUnion:4418 case TypeTableEntryIdErrorUnion:
4387 // TODO better hashing algorithm4419 // TODO better hashing algorithm
4388 return 3415065496;4420 return 3415065496;
4389 case TypeTableEntryIdPureError:4421 case TypeTableEntryIdErrorSet:
4390 // TODO better hashing algorithm4422 assert(const_val->data.x_err_set != nullptr);
4391 return 2630160122;4423 return const_val->data.x_err_set->value ^ 2630160122;
4392 case TypeTableEntryIdFn:4424 case TypeTableEntryIdFn:
4393 return 4133894920 ^ hash_ptr(const_val->data.x_fn.fn_entry);4425 return 4133894920 ^ hash_ptr(const_val->data.x_fn.fn_entry);
4394 case TypeTableEntryIdNamespace:4426 case TypeTableEntryIdNamespace:
...@@ -4515,7 +4547,7 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {...@@ -4515,7 +4547,7 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {
4515 case TypeTableEntryIdMaybe:4547 case TypeTableEntryIdMaybe:
4516 case TypeTableEntryIdErrorUnion:4548 case TypeTableEntryIdErrorUnion:
4517 case TypeTableEntryIdEnum:4549 case TypeTableEntryIdEnum:
4518 case TypeTableEntryIdPureError:4550 case TypeTableEntryIdErrorSet:
4519 case TypeTableEntryIdFn:4551 case TypeTableEntryIdFn:
4520 case TypeTableEntryIdBool:4552 case TypeTableEntryIdBool:
4521 case TypeTableEntryIdInt:4553 case TypeTableEntryIdInt:
...@@ -4894,8 +4926,8 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {...@@ -4894,8 +4926,8 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
4894 return a->data.x_type == b->data.x_type;4926 return a->data.x_type == b->data.x_type;
4895 case TypeTableEntryIdVoid:4927 case TypeTableEntryIdVoid:
4896 return true;4928 return true;
4897 case TypeTableEntryIdPureError:4929 case TypeTableEntryIdErrorSet:
4898 return a->data.x_pure_err == b->data.x_pure_err;4930 return a->data.x_err_set->value == b->data.x_err_set->value;
4899 case TypeTableEntryIdFn:4931 case TypeTableEntryIdFn:
4900 return a->data.x_fn.fn_entry == b->data.x_fn.fn_entry;4932 return a->data.x_fn.fn_entry == b->data.x_fn.fn_entry;
4901 case TypeTableEntryIdBool:4933 case TypeTableEntryIdBool:
...@@ -5256,9 +5288,9 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {...@@ -5256,9 +5288,9 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
5256 buf_appendf(buf, "(union %s constant)", buf_ptr(&type_entry->name));5288 buf_appendf(buf, "(union %s constant)", buf_ptr(&type_entry->name));
5257 return;5289 return;
5258 }5290 }
5259 case TypeTableEntryIdPureError:5291 case TypeTableEntryIdErrorSet:
5260 {5292 {
5261 buf_appendf(buf, "(pure error constant)");5293 buf_appendf(buf, "%s.%s", buf_ptr(&type_entry->name), buf_ptr(&const_val->data.x_err_set->name));
5262 return;5294 return;
5263 }5295 }
5264 case TypeTableEntryIdArgTuple:5296 case TypeTableEntryIdArgTuple:
...@@ -5319,8 +5351,7 @@ uint32_t type_id_hash(TypeId x) {...@@ -5319,8 +5351,7 @@ uint32_t type_id_hash(TypeId x) {
5319 case TypeTableEntryIdUndefLit:5351 case TypeTableEntryIdUndefLit:
5320 case TypeTableEntryIdNullLit:5352 case TypeTableEntryIdNullLit:
5321 case TypeTableEntryIdMaybe:5353 case TypeTableEntryIdMaybe:
5322 case TypeTableEntryIdErrorUnion:5354 case TypeTableEntryIdErrorSet:
5323 case TypeTableEntryIdPureError:
5324 case TypeTableEntryIdEnum:5355 case TypeTableEntryIdEnum:
5325 case TypeTableEntryIdUnion:5356 case TypeTableEntryIdUnion:
5326 case TypeTableEntryIdFn:5357 case TypeTableEntryIdFn:
...@@ -5329,6 +5360,8 @@ uint32_t type_id_hash(TypeId x) {...@@ -5329,6 +5360,8 @@ uint32_t type_id_hash(TypeId x) {
5329 case TypeTableEntryIdBoundFn:5360 case TypeTableEntryIdBoundFn:
5330 case TypeTableEntryIdArgTuple:5361 case TypeTableEntryIdArgTuple:
5331 zig_unreachable();5362 zig_unreachable();
5363 case TypeTableEntryIdErrorUnion:
5364 return hash_ptr(x.data.error_union.err_set_type) ^ hash_ptr(x.data.error_union.payload_type);
5332 case TypeTableEntryIdPointer:5365 case TypeTableEntryIdPointer:
5333 return hash_ptr(x.data.pointer.child_type) +5366 return hash_ptr(x.data.pointer.child_type) +
5334 (x.data.pointer.is_const ? (uint32_t)2749109194 : (uint32_t)4047371087) +5367 (x.data.pointer.is_const ? (uint32_t)2749109194 : (uint32_t)4047371087) +
...@@ -5363,8 +5396,7 @@ bool type_id_eql(TypeId a, TypeId b) {...@@ -5363,8 +5396,7 @@ bool type_id_eql(TypeId a, TypeId b) {
5363 case TypeTableEntryIdUndefLit:5396 case TypeTableEntryIdUndefLit:
5364 case TypeTableEntryIdNullLit:5397 case TypeTableEntryIdNullLit:
5365 case TypeTableEntryIdMaybe:5398 case TypeTableEntryIdMaybe:
5366 case TypeTableEntryIdErrorUnion:5399 case TypeTableEntryIdErrorSet:
5367 case TypeTableEntryIdPureError:
5368 case TypeTableEntryIdEnum:5400 case TypeTableEntryIdEnum:
5369 case TypeTableEntryIdUnion:5401 case TypeTableEntryIdUnion:
5370 case TypeTableEntryIdFn:5402 case TypeTableEntryIdFn:
...@@ -5374,6 +5406,10 @@ bool type_id_eql(TypeId a, TypeId b) {...@@ -5374,6 +5406,10 @@ bool type_id_eql(TypeId a, TypeId b) {
5374 case TypeTableEntryIdArgTuple:5406 case TypeTableEntryIdArgTuple:
5375 case TypeTableEntryIdOpaque:5407 case TypeTableEntryIdOpaque:
5376 zig_unreachable();5408 zig_unreachable();
5409 case TypeTableEntryIdErrorUnion:
5410 return a.data.error_union.err_set_type == b.data.error_union.err_set_type &&
5411 a.data.error_union.payload_type == b.data.error_union.payload_type;
5412
5377 case TypeTableEntryIdPointer:5413 case TypeTableEntryIdPointer:
5378 return a.data.pointer.child_type == b.data.pointer.child_type &&5414 return a.data.pointer.child_type == b.data.pointer.child_type &&
5379 a.data.pointer.is_const == b.data.pointer.is_const &&5415 a.data.pointer.is_const == b.data.pointer.is_const &&
...@@ -5478,7 +5514,7 @@ static const TypeTableEntryId all_type_ids[] = {...@@ -5478,7 +5514,7 @@ static const TypeTableEntryId all_type_ids[] = {
5478 TypeTableEntryIdNullLit,5514 TypeTableEntryIdNullLit,
5479 TypeTableEntryIdMaybe,5515 TypeTableEntryIdMaybe,
5480 TypeTableEntryIdErrorUnion,5516 TypeTableEntryIdErrorUnion,
5481 TypeTableEntryIdPureError,5517 TypeTableEntryIdErrorSet,
5482 TypeTableEntryIdEnum,5518 TypeTableEntryIdEnum,
5483 TypeTableEntryIdUnion,5519 TypeTableEntryIdUnion,
5484 TypeTableEntryIdFn,5520 TypeTableEntryIdFn,
...@@ -5533,7 +5569,7 @@ size_t type_id_index(TypeTableEntryId id) {...@@ -5533,7 +5569,7 @@ size_t type_id_index(TypeTableEntryId id) {
5533 return 13;5569 return 13;
5534 case TypeTableEntryIdErrorUnion:5570 case TypeTableEntryIdErrorUnion:
5535 return 14;5571 return 14;
5536 case TypeTableEntryIdPureError:5572 case TypeTableEntryIdErrorSet:
5537 return 15;5573 return 15;
5538 case TypeTableEntryIdEnum:5574 case TypeTableEntryIdEnum:
5539 return 16;5575 return 16;
...@@ -5590,8 +5626,8 @@ const char *type_id_name(TypeTableEntryId id) {...@@ -5590,8 +5626,8 @@ const char *type_id_name(TypeTableEntryId id) {
5590 return "Nullable";5626 return "Nullable";
5591 case TypeTableEntryIdErrorUnion:5627 case TypeTableEntryIdErrorUnion:
5592 return "ErrorUnion";5628 return "ErrorUnion";
5593 case TypeTableEntryIdPureError:5629 case TypeTableEntryIdErrorSet:
5594 return "Error";5630 return "ErrorSet";
5595 case TypeTableEntryIdEnum:5631 case TypeTableEntryIdEnum:
5596 return "Enum";5632 return "Enum";
5597 case TypeTableEntryIdUnion:5633 case TypeTableEntryIdUnion:
src/analyze.hpp+2-2
...@@ -30,7 +30,7 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *ptr_type);...@@ -30,7 +30,7 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *ptr_type);
30TypeTableEntry *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind,30TypeTableEntry *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind,
31 AstNode *decl_node, const char *name, ContainerLayout layout);31 AstNode *decl_node, const char *name, ContainerLayout layout);
32TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x);32TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x);
33TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type);33TypeTableEntry *get_error_union_type(CodeGen *g, TypeTableEntry *err_set_type, TypeTableEntry *payload_type);
34TypeTableEntry *get_bound_fn_type(CodeGen *g, FnTableEntry *fn_entry);34TypeTableEntry *get_bound_fn_type(CodeGen *g, FnTableEntry *fn_entry);
35TypeTableEntry *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *name);35TypeTableEntry *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *name);
36TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],36TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
...@@ -46,7 +46,6 @@ bool type_has_bits(TypeTableEntry *type_entry);...@@ -46,7 +46,6 @@ bool type_has_bits(TypeTableEntry *type_entry);
46ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code);46ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code);
4747
4848
49// TODO move these over, these used to be static
50bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *actual_type);49bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *actual_type);
51VariableTableEntry *find_variable(CodeGen *g, Scope *orig_context, Buf *name);50VariableTableEntry *find_variable(CodeGen *g, Scope *orig_context, Buf *name);
52Tld *find_decl(CodeGen *g, Scope *scope, Buf *name);51Tld *find_decl(CodeGen *g, Scope *scope, Buf *name);
...@@ -188,6 +187,7 @@ void add_fn_export(CodeGen *g, FnTableEntry *fn_table_entry, Buf *symbol_name, G...@@ -188,6 +187,7 @@ void add_fn_export(CodeGen *g, FnTableEntry *fn_table_entry, Buf *symbol_name, G
188187
189ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name);188ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name);
190TypeTableEntry *get_ptr_to_stack_trace_type(CodeGen *g);189TypeTableEntry *get_ptr_to_stack_trace_type(CodeGen *g);
190void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry);
191191
192192
193#endif193#endif
src/ast_render.cpp+24-5
...@@ -54,6 +54,7 @@ static const char *bin_op_str(BinOpType bin_op) {...@@ -54,6 +54,7 @@ static const char *bin_op_str(BinOpType bin_op) {
54 case BinOpTypeUnwrapMaybe: return "??";54 case BinOpTypeUnwrapMaybe: return "??";
55 case BinOpTypeArrayCat: return "++";55 case BinOpTypeArrayCat: return "++";
56 case BinOpTypeArrayMult: return "**";56 case BinOpTypeArrayMult: return "**";
57 case BinOpTypeErrorUnion: return "!";
57 }58 }
58 zig_unreachable();59 zig_unreachable();
59}60}
...@@ -67,7 +68,6 @@ static const char *prefix_op_str(PrefixOp prefix_op) {...@@ -67,7 +68,6 @@ static const char *prefix_op_str(PrefixOp prefix_op) {
67 case PrefixOpBinNot: return "~";68 case PrefixOpBinNot: return "~";
68 case PrefixOpDereference: return "*";69 case PrefixOpDereference: return "*";
69 case PrefixOpMaybe: return "?";70 case PrefixOpMaybe: return "?";
70 case PrefixOpError: return "%";
71 case PrefixOpUnwrapMaybe: return "??";71 case PrefixOpUnwrapMaybe: return "??";
72 }72 }
73 zig_unreachable();73 zig_unreachable();
...@@ -174,8 +174,6 @@ static const char *node_type_str(NodeType node_type) {...@@ -174,8 +174,6 @@ static const char *node_type_str(NodeType node_type) {
174 return "Defer";174 return "Defer";
175 case NodeTypeVariableDeclaration:175 case NodeTypeVariableDeclaration:
176 return "VariableDeclaration";176 return "VariableDeclaration";
177 case NodeTypeErrorValueDecl:
178 return "ErrorValueDecl";
179 case NodeTypeTestDecl:177 case NodeTypeTestDecl:
180 return "TestDecl";178 return "TestDecl";
181 case NodeTypeIntLiteral:179 case NodeTypeIntLiteral:
...@@ -244,6 +242,8 @@ static const char *node_type_str(NodeType node_type) {...@@ -244,6 +242,8 @@ static const char *node_type_str(NodeType node_type) {
244 return "IfErrorExpr";242 return "IfErrorExpr";
245 case NodeTypeTestExpr:243 case NodeTypeTestExpr:
246 return "TestExpr";244 return "TestExpr";
245 case NodeTypeErrorSetDecl:
246 return "ErrorSetDecl";
247 }247 }
248 zig_unreachable();248 zig_unreachable();
249}249}
...@@ -396,7 +396,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -396,7 +396,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
396396
397 if (child->type == NodeTypeUse ||397 if (child->type == NodeTypeUse ||
398 child->type == NodeTypeVariableDeclaration ||398 child->type == NodeTypeVariableDeclaration ||
399 child->type == NodeTypeErrorValueDecl ||
400 child->type == NodeTypeFnProto)399 child->type == NodeTypeFnProto)
401 {400 {
402 fprintf(ar->f, ";");401 fprintf(ar->f, ";");
...@@ -452,6 +451,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -452,6 +451,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
452 AstNode *return_type_node = node->data.fn_proto.return_type;451 AstNode *return_type_node = node->data.fn_proto.return_type;
453 assert(return_type_node != nullptr);452 assert(return_type_node != nullptr);
454 fprintf(ar->f, " ");453 fprintf(ar->f, " ");
454 if (node->data.fn_proto.auto_err_set) {
455 fprintf(ar->f, "!");
456 }
455 render_node_grouped(ar, return_type_node);457 render_node_grouped(ar, return_type_node);
456 break;458 break;
457 }459 }
...@@ -1017,9 +1019,26 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -1017,9 +1019,26 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
1017 render_node_ungrouped(ar, node->data.unwrap_err_expr.op2);1019 render_node_ungrouped(ar, node->data.unwrap_err_expr.op2);
1018 break;1020 break;
1019 }1021 }
1022 case NodeTypeErrorSetDecl:
1023 {
1024 fprintf(ar->f, "error {\n");
1025 ar->indent += ar->indent_size;
1026
1027 for (size_t i = 0; i < node->data.err_set_decl.decls.length; i += 1) {
1028 AstNode *field_node = node->data.err_set_decl.decls.at(i);
1029 assert(field_node->type == NodeTypeSymbol);
1030 print_indent(ar);
1031 print_symbol(ar, field_node->data.symbol_expr.symbol);
1032 fprintf(ar->f, ",\n");
1033 }
1034
1035 ar->indent -= ar->indent_size;
1036 print_indent(ar);
1037 fprintf(ar->f, "}");
1038 break;
1039 }
1020 case NodeTypeFnDecl:1040 case NodeTypeFnDecl:
1021 case NodeTypeParamDecl:1041 case NodeTypeParamDecl:
1022 case NodeTypeErrorValueDecl:
1023 case NodeTypeTestDecl:1042 case NodeTypeTestDecl:
1024 case NodeTypeStructField:1043 case NodeTypeStructField:
1025 case NodeTypeUse:1044 case NodeTypeUse:
src/codegen.cpp+76-51
...@@ -92,9 +92,6 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out...@@ -92,9 +92,6 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out
92 g->want_h_file = (out_type == OutTypeObj || out_type == OutTypeLib);92 g->want_h_file = (out_type == OutTypeObj || out_type == OutTypeLib);
93 buf_resize(&g->global_asm, 0);93 buf_resize(&g->global_asm, 0);
9494
95 // reserve index 0 to indicate no error
96 g->error_decls.append(nullptr);
97
98 if (root_src_path) {95 if (root_src_path) {
99 Buf *src_basename = buf_alloc();96 Buf *src_basename = buf_alloc();
100 Buf *src_dir = buf_alloc();97 Buf *src_dir = buf_alloc();
...@@ -410,7 +407,7 @@ static uint32_t get_err_ret_trace_arg_index(CodeGen *g, FnTableEntry *fn_table_e...@@ -410,7 +407,7 @@ static uint32_t get_err_ret_trace_arg_index(CodeGen *g, FnTableEntry *fn_table_e
410 }407 }
411 TypeTableEntry *fn_type = fn_table_entry->type_entry;408 TypeTableEntry *fn_type = fn_table_entry->type_entry;
412 TypeTableEntry *return_type = fn_type->data.fn.fn_type_id.return_type;409 TypeTableEntry *return_type = fn_type->data.fn.fn_type_id.return_type;
413 if (return_type->id != TypeTableEntryIdErrorUnion && return_type->id != TypeTableEntryIdPureError) {410 if (return_type->id != TypeTableEntryIdErrorUnion && return_type->id != TypeTableEntryIdErrorSet) {
414 return UINT32_MAX;411 return UINT32_MAX;
415 }412 }
416 bool first_arg_ret = type_has_bits(return_type) && handle_is_ptr(return_type);413 bool first_arg_ret = type_has_bits(return_type) && handle_is_ptr(return_type);
...@@ -1442,7 +1439,7 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns...@@ -1442,7 +1439,7 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns
1442 is_err_return = return_instruction->value->value.data.rh_error_union == RuntimeHintErrorUnionError;1439 is_err_return = return_instruction->value->value.data.rh_error_union == RuntimeHintErrorUnionError;
1443 // TODO: emit a branch to check if the return value is an error1440 // TODO: emit a branch to check if the return value is an error
1444 }1441 }
1445 } else if (return_type->id == TypeTableEntryIdPureError) {1442 } else if (return_type->id == TypeTableEntryIdErrorSet) {
1446 is_err_return = true;1443 is_err_return = true;
1447 }1444 }
1448 if (is_err_return) {1445 if (is_err_return) {
...@@ -1823,7 +1820,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,...@@ -1823,7 +1820,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
1823 } else if (type_entry->id == TypeTableEntryIdEnum) {1820 } else if (type_entry->id == TypeTableEntryIdEnum) {
1824 LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, false);1821 LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, false);
1825 return LLVMBuildICmp(g->builder, pred, op1_value, op2_value, "");1822 return LLVMBuildICmp(g->builder, pred, op1_value, op2_value, "");
1826 } else if (type_entry->id == TypeTableEntryIdPureError ||1823 } else if (type_entry->id == TypeTableEntryIdErrorSet ||
1827 type_entry->id == TypeTableEntryIdPointer ||1824 type_entry->id == TypeTableEntryIdPointer ||
1828 type_entry->id == TypeTableEntryIdBool)1825 type_entry->id == TypeTableEntryIdBool)
1829 {1826 {
...@@ -2139,7 +2136,7 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutable *executable,...@@ -2139,7 +2136,7 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutable *executable,
21392136
2140static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, IrInstructionIntToErr *instruction) {2137static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, IrInstructionIntToErr *instruction) {
2141 TypeTableEntry *wanted_type = instruction->base.value.type;2138 TypeTableEntry *wanted_type = instruction->base.value.type;
2142 assert(wanted_type->id == TypeTableEntryIdPureError);2139 assert(wanted_type->id == TypeTableEntryIdErrorSet);
21432140
2144 TypeTableEntry *actual_type = instruction->target->value.type;2141 TypeTableEntry *actual_type = instruction->target->value.type;
2145 assert(actual_type->id == TypeTableEntryIdInt);2142 assert(actual_type->id == TypeTableEntryIdInt);
...@@ -2156,11 +2153,11 @@ static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, I...@@ -2156,11 +2153,11 @@ static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, I
2156 eval_min_max_value_int(g, actual_type, &biggest_possible_err_val, true);2153 eval_min_max_value_int(g, actual_type, &biggest_possible_err_val, true);
21572154
2158 if (bigint_fits_in_bits(&biggest_possible_err_val, 64, false) &&2155 if (bigint_fits_in_bits(&biggest_possible_err_val, 64, false) &&
2159 bigint_as_unsigned(&biggest_possible_err_val) < g->error_decls.length)2156 bigint_as_unsigned(&biggest_possible_err_val) < g->errors_by_index.length)
2160 {2157 {
2161 ok_bit = neq_zero_bit;2158 ok_bit = neq_zero_bit;
2162 } else {2159 } else {
2163 LLVMValueRef error_value_count = LLVMConstInt(actual_type->type_ref, g->error_decls.length, false);2160 LLVMValueRef error_value_count = LLVMConstInt(actual_type->type_ref, g->errors_by_index.length, false);
2164 LLVMValueRef in_bounds_bit = LLVMBuildICmp(g->builder, LLVMIntULT, target_val, error_value_count, "");2161 LLVMValueRef in_bounds_bit = LLVMBuildICmp(g->builder, LLVMIntULT, target_val, error_value_count, "");
2165 ok_bit = LLVMBuildAnd(g->builder, neq_zero_bit, in_bounds_bit, "");2162 ok_bit = LLVMBuildAnd(g->builder, neq_zero_bit, in_bounds_bit, "");
2166 }2163 }
...@@ -2187,15 +2184,15 @@ static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutable *executable, I...@@ -2187,15 +2184,15 @@ static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutable *executable, I
2187 TypeTableEntry *actual_type = instruction->target->value.type;2184 TypeTableEntry *actual_type = instruction->target->value.type;
2188 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);2185 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
21892186
2190 if (actual_type->id == TypeTableEntryIdPureError) {2187 if (actual_type->id == TypeTableEntryIdErrorSet) {
2191 return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base),2188 return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base),
2192 g->err_tag_type, wanted_type, target_val);2189 g->err_tag_type, wanted_type, target_val);
2193 } else if (actual_type->id == TypeTableEntryIdErrorUnion) {2190 } else if (actual_type->id == TypeTableEntryIdErrorUnion) {
2194 if (!type_has_bits(actual_type->data.error.child_type)) {2191 if (!type_has_bits(actual_type->data.error_union.payload_type)) {
2195 return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base),2192 return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base),
2196 g->err_tag_type, wanted_type, target_val);2193 g->err_tag_type, wanted_type, target_val);
2197 } else {2194 } else {
2198 zig_panic("TODO");2195 zig_panic("TODO err to int when error union payload type not void");
2199 }2196 }
2200 } else {2197 } else {
2201 zig_unreachable();2198 zig_unreachable();
...@@ -2235,7 +2232,6 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst...@@ -2235,7 +2232,6 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst
22352232
2236 switch (op_id) {2233 switch (op_id) {
2237 case IrUnOpInvalid:2234 case IrUnOpInvalid:
2238 case IrUnOpError:
2239 case IrUnOpMaybe:2235 case IrUnOpMaybe:
2240 case IrUnOpDereference:2236 case IrUnOpDereference:
2241 zig_unreachable();2237 zig_unreachable();
...@@ -2489,7 +2485,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -2489,7 +2485,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
2489 TypeTableEntry *src_return_type = fn_type_id->return_type;2485 TypeTableEntry *src_return_type = fn_type_id->return_type;
2490 bool ret_has_bits = type_has_bits(src_return_type);2486 bool ret_has_bits = type_has_bits(src_return_type);
2491 bool first_arg_ret = ret_has_bits && handle_is_ptr(src_return_type);2487 bool first_arg_ret = ret_has_bits && handle_is_ptr(src_return_type);
2492 bool prefix_arg_err_ret_stack = g->have_err_ret_tracing && (src_return_type->id == TypeTableEntryIdErrorUnion || src_return_type->id == TypeTableEntryIdPureError);2488 bool prefix_arg_err_ret_stack = g->have_err_ret_tracing && (src_return_type->id == TypeTableEntryIdErrorUnion || src_return_type->id == TypeTableEntryIdErrorSet);
2493 size_t actual_param_count = instruction->arg_count + (first_arg_ret ? 1 : 0) + (prefix_arg_err_ret_stack ? 1 : 0);2489 size_t actual_param_count = instruction->arg_count + (first_arg_ret ? 1 : 0) + (prefix_arg_err_ret_stack ? 1 : 0);
2494 bool is_var_args = fn_type_id->is_var_args;2490 bool is_var_args = fn_type_id->is_var_args;
2495 LLVMValueRef *gen_param_values = allocate<LLVMValueRef>(actual_param_count);2491 LLVMValueRef *gen_param_values = allocate<LLVMValueRef>(actual_param_count);
...@@ -2907,7 +2903,7 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstru...@@ -2907,7 +2903,7 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstru
2907static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutable *executable, IrInstructionErrName *instruction) {2903static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutable *executable, IrInstructionErrName *instruction) {
2908 assert(g->generate_error_name_table);2904 assert(g->generate_error_name_table);
29092905
2910 if (g->error_decls.length == 1) {2906 if (g->errors_by_index.length == 1) {
2911 LLVMBuildUnreachable(g->builder);2907 LLVMBuildUnreachable(g->builder);
2912 return nullptr;2908 return nullptr;
2913 }2909 }
...@@ -2915,7 +2911,7 @@ static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutable *executable, IrI...@@ -2915,7 +2911,7 @@ static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutable *executable, IrI
2915 LLVMValueRef err_val = ir_llvm_value(g, instruction->value);2911 LLVMValueRef err_val = ir_llvm_value(g, instruction->value);
2916 if (ir_want_runtime_safety(g, &instruction->base)) {2912 if (ir_want_runtime_safety(g, &instruction->base)) {
2917 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(err_val));2913 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(err_val));
2918 LLVMValueRef end_val = LLVMConstInt(LLVMTypeOf(err_val), g->error_decls.length, false);2914 LLVMValueRef end_val = LLVMConstInt(LLVMTypeOf(err_val), g->errors_by_index.length, false);
2919 add_bounds_check(g, err_val, LLVMIntNE, zero, LLVMIntULT, end_val);2915 add_bounds_check(g, err_val, LLVMIntNE, zero, LLVMIntULT, end_val);
2920 }2916 }
29212917
...@@ -3393,11 +3389,11 @@ static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutable *executable,...@@ -3393,11 +3389,11 @@ static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutable *executable,
33933389
3394static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrInstructionTestErr *instruction) {3390static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrInstructionTestErr *instruction) {
3395 TypeTableEntry *err_union_type = instruction->value->value.type;3391 TypeTableEntry *err_union_type = instruction->value->value.type;
3396 TypeTableEntry *child_type = err_union_type->data.error.child_type;3392 TypeTableEntry *payload_type = err_union_type->data.error_union.payload_type;
3397 LLVMValueRef err_union_handle = ir_llvm_value(g, instruction->value);3393 LLVMValueRef err_union_handle = ir_llvm_value(g, instruction->value);
33983394
3399 LLVMValueRef err_val;3395 LLVMValueRef err_val;
3400 if (type_has_bits(child_type)) {3396 if (type_has_bits(payload_type)) {
3401 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");3397 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
3402 err_val = gen_load_untyped(g, err_val_ptr, 0, false, "");3398 err_val = gen_load_untyped(g, err_val_ptr, 0, false, "");
3403 } else {3399 } else {
...@@ -3412,11 +3408,11 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executab...@@ -3412,11 +3408,11 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executab
3412 TypeTableEntry *ptr_type = instruction->value->value.type;3408 TypeTableEntry *ptr_type = instruction->value->value.type;
3413 assert(ptr_type->id == TypeTableEntryIdPointer);3409 assert(ptr_type->id == TypeTableEntryIdPointer);
3414 TypeTableEntry *err_union_type = ptr_type->data.pointer.child_type;3410 TypeTableEntry *err_union_type = ptr_type->data.pointer.child_type;
3415 TypeTableEntry *child_type = err_union_type->data.error.child_type;3411 TypeTableEntry *payload_type = err_union_type->data.error_union.payload_type;
3416 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value);3412 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value);
3417 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type);3413 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type);
34183414
3419 if (type_has_bits(child_type)) {3415 if (type_has_bits(payload_type)) {
3420 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");3416 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
3421 return gen_load_untyped(g, err_val_ptr, 0, false, "");3417 return gen_load_untyped(g, err_val_ptr, 0, false, "");
3422 } else {3418 } else {
...@@ -3428,13 +3424,13 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu...@@ -3428,13 +3424,13 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu
3428 TypeTableEntry *ptr_type = instruction->value->value.type;3424 TypeTableEntry *ptr_type = instruction->value->value.type;
3429 assert(ptr_type->id == TypeTableEntryIdPointer);3425 assert(ptr_type->id == TypeTableEntryIdPointer);
3430 TypeTableEntry *err_union_type = ptr_type->data.pointer.child_type;3426 TypeTableEntry *err_union_type = ptr_type->data.pointer.child_type;
3431 TypeTableEntry *child_type = err_union_type->data.error.child_type;3427 TypeTableEntry *payload_type = err_union_type->data.error_union.payload_type;
3432 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value);3428 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value);
3433 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type);3429 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type);
34343430
3435 if (ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on && g->error_decls.length > 1) {3431 if (ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on && g->errors_by_index.length > 1) {
3436 LLVMValueRef err_val;3432 LLVMValueRef err_val;
3437 if (type_has_bits(child_type)) {3433 if (type_has_bits(payload_type)) {
3438 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");3434 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
3439 err_val = gen_load_untyped(g, err_val_ptr, 0, false, "");3435 err_val = gen_load_untyped(g, err_val_ptr, 0, false, "");
3440 } else {3436 } else {
...@@ -3452,7 +3448,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu...@@ -3452,7 +3448,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu
3452 LLVMPositionBuilderAtEnd(g->builder, ok_block);3448 LLVMPositionBuilderAtEnd(g->builder, ok_block);
3453 }3449 }
34543450
3455 if (type_has_bits(child_type)) {3451 if (type_has_bits(payload_type)) {
3456 return LLVMBuildStructGEP(g->builder, err_union_handle, err_union_payload_index, "");3452 return LLVMBuildStructGEP(g->builder, err_union_handle, err_union_payload_index, "");
3457 } else {3453 } else {
3458 return nullptr;3454 return nullptr;
...@@ -3493,10 +3489,10 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable...@@ -3493,10 +3489,10 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable
34933489
3494 assert(wanted_type->id == TypeTableEntryIdErrorUnion);3490 assert(wanted_type->id == TypeTableEntryIdErrorUnion);
34953491
3496 TypeTableEntry *child_type = wanted_type->data.error.child_type;3492 TypeTableEntry *payload_type = wanted_type->data.error_union.payload_type;
3497 LLVMValueRef err_val = ir_llvm_value(g, instruction->value);3493 LLVMValueRef err_val = ir_llvm_value(g, instruction->value);
34983494
3499 if (!type_has_bits(child_type))3495 if (!type_has_bits(payload_type))
3500 return err_val;3496 return err_val;
35013497
3502 assert(instruction->tmp_ptr);3498 assert(instruction->tmp_ptr);
...@@ -3512,11 +3508,11 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa...@@ -3512,11 +3508,11 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa
35123508
3513 assert(wanted_type->id == TypeTableEntryIdErrorUnion);3509 assert(wanted_type->id == TypeTableEntryIdErrorUnion);
35143510
3515 TypeTableEntry *child_type = wanted_type->data.error.child_type;3511 TypeTableEntry *payload_type = wanted_type->data.error_union.payload_type;
35163512
3517 LLVMValueRef ok_err_val = LLVMConstNull(g->err_tag_type->type_ref);3513 LLVMValueRef ok_err_val = LLVMConstNull(g->err_tag_type->type_ref);
35183514
3519 if (!type_has_bits(child_type))3515 if (!type_has_bits(payload_type))
3520 return ok_err_val;3516 return ok_err_val;
35213517
3522 assert(instruction->tmp_ptr);3518 assert(instruction->tmp_ptr);
...@@ -3527,7 +3523,7 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa...@@ -3527,7 +3523,7 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa
3527 gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false);3523 gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false);
35283524
3529 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_payload_index, "");3525 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_payload_index, "");
3530 gen_assign_raw(g, payload_ptr, get_pointer_to_type(g, child_type, false), payload_val);3526 gen_assign_raw(g, payload_ptr, get_pointer_to_type(g, payload_type, false), payload_val);
35313527
3532 return instruction->tmp_ptr;3528 return instruction->tmp_ptr;
3533}3529}
...@@ -3700,6 +3696,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -3700,6 +3696,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
3700 case IrInstructionIdArgType:3696 case IrInstructionIdArgType:
3701 case IrInstructionIdTagType:3697 case IrInstructionIdTagType:
3702 case IrInstructionIdExport:3698 case IrInstructionIdExport:
3699 case IrInstructionIdErrorUnion:
3703 zig_unreachable();3700 zig_unreachable();
3704 case IrInstructionIdReturn:3701 case IrInstructionIdReturn:
3705 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);3702 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
...@@ -3933,7 +3930,7 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con...@@ -3933,7 +3930,7 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
3933 case TypeTableEntryIdUndefLit:3930 case TypeTableEntryIdUndefLit:
3934 case TypeTableEntryIdNullLit:3931 case TypeTableEntryIdNullLit:
3935 case TypeTableEntryIdErrorUnion:3932 case TypeTableEntryIdErrorUnion:
3936 case TypeTableEntryIdPureError:3933 case TypeTableEntryIdErrorSet:
3937 case TypeTableEntryIdNamespace:3934 case TypeTableEntryIdNamespace:
3938 case TypeTableEntryIdBlock:3935 case TypeTableEntryIdBlock:
3939 case TypeTableEntryIdBoundFn:3936 case TypeTableEntryIdBoundFn:
...@@ -4026,10 +4023,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -4026,10 +4023,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
4026 switch (type_entry->id) {4023 switch (type_entry->id) {
4027 case TypeTableEntryIdInt:4024 case TypeTableEntryIdInt:
4028 return bigint_to_llvm_const(type_entry->type_ref, &const_val->data.x_bigint);4025 return bigint_to_llvm_const(type_entry->type_ref, &const_val->data.x_bigint);
4029 case TypeTableEntryIdPureError:4026 case TypeTableEntryIdErrorSet:
4030 assert(const_val->data.x_pure_err);4027 assert(const_val->data.x_err_set != nullptr);
4031 return LLVMConstInt(g->builtin_types.entry_pure_error->type_ref,4028 return LLVMConstInt(g->builtin_types.entry_global_error_set->type_ref,
4032 const_val->data.x_pure_err->value, false);4029 const_val->data.x_err_set->value, false);
4033 case TypeTableEntryIdFloat:4030 case TypeTableEntryIdFloat:
4034 switch (type_entry->data.floating.bit_count) {4031 switch (type_entry->data.floating.bit_count) {
4035 case 32:4032 case 32:
...@@ -4330,8 +4327,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -4330,8 +4327,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
4330 }4327 }
4331 case TypeTableEntryIdErrorUnion:4328 case TypeTableEntryIdErrorUnion:
4332 {4329 {
4333 TypeTableEntry *child_type = type_entry->data.error.child_type;4330 TypeTableEntry *payload_type = type_entry->data.error_union.payload_type;
4334 if (!type_has_bits(child_type)) {4331 if (!type_has_bits(payload_type)) {
4335 uint64_t value = const_val->data.x_err_union.err ? const_val->data.x_err_union.err->value : 0;4332 uint64_t value = const_val->data.x_err_union.err ? const_val->data.x_err_union.err->value : 0;
4336 return LLVMConstInt(g->err_tag_type->type_ref, value, false);4333 return LLVMConstInt(g->err_tag_type->type_ref, value, false);
4337 } else {4334 } else {
...@@ -4340,7 +4337,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -4340,7 +4337,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
4340 bool make_unnamed_struct;4337 bool make_unnamed_struct;
4341 if (const_val->data.x_err_union.err) {4338 if (const_val->data.x_err_union.err) {
4342 err_tag_value = LLVMConstInt(g->err_tag_type->type_ref, const_val->data.x_err_union.err->value, false);4339 err_tag_value = LLVMConstInt(g->err_tag_type->type_ref, const_val->data.x_err_union.err->value, false);
4343 err_payload_value = LLVMConstNull(child_type->type_ref);4340 err_payload_value = LLVMConstNull(payload_type->type_ref);
4344 make_unnamed_struct = false;4341 make_unnamed_struct = false;
4345 } else {4342 } else {
4346 err_tag_value = LLVMConstNull(g->err_tag_type->type_ref);4343 err_tag_value = LLVMConstNull(g->err_tag_type->type_ref);
...@@ -4410,21 +4407,20 @@ static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const...@@ -4410,21 +4407,20 @@ static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const
4410}4407}
44114408
4412static void generate_error_name_table(CodeGen *g) {4409static void generate_error_name_table(CodeGen *g) {
4413 if (g->err_name_table != nullptr || !g->generate_error_name_table || g->error_decls.length == 1) {4410 if (g->err_name_table != nullptr || !g->generate_error_name_table || g->errors_by_index.length == 1) {
4414 return;4411 return;
4415 }4412 }
44164413
4417 assert(g->error_decls.length > 0);4414 assert(g->errors_by_index.length > 0);
44184415
4419 TypeTableEntry *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);4416 TypeTableEntry *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);
4420 TypeTableEntry *str_type = get_slice_type(g, u8_ptr_type);4417 TypeTableEntry *str_type = get_slice_type(g, u8_ptr_type);
44214418
4422 LLVMValueRef *values = allocate<LLVMValueRef>(g->error_decls.length);4419 LLVMValueRef *values = allocate<LLVMValueRef>(g->errors_by_index.length);
4423 values[0] = LLVMGetUndef(str_type->type_ref);4420 values[0] = LLVMGetUndef(str_type->type_ref);
4424 for (size_t i = 1; i < g->error_decls.length; i += 1) {4421 for (size_t i = 1; i < g->errors_by_index.length; i += 1) {
4425 AstNode *error_decl_node = g->error_decls.at(i);4422 ErrorTableEntry *err_entry = g->errors_by_index.at(i);
4426 assert(error_decl_node->type == NodeTypeErrorValueDecl);4423 Buf *name = &err_entry->name;
4427 Buf *name = error_decl_node->data.error_value_decl.name;
44284424
4429 g->largest_err_name_len = max(g->largest_err_name_len, buf_len(name));4425 g->largest_err_name_len = max(g->largest_err_name_len, buf_len(name));
44304426
...@@ -4443,7 +4439,7 @@ static void generate_error_name_table(CodeGen *g) {...@@ -4443,7 +4439,7 @@ static void generate_error_name_table(CodeGen *g) {
4443 values[i] = LLVMConstNamedStruct(str_type->type_ref, fields, 2);4439 values[i] = LLVMConstNamedStruct(str_type->type_ref, fields, 2);
4444 }4440 }
44454441
4446 LLVMValueRef err_name_table_init = LLVMConstArray(str_type->type_ref, values, (unsigned)g->error_decls.length);4442 LLVMValueRef err_name_table_init = LLVMConstArray(str_type->type_ref, values, (unsigned)g->errors_by_index.length);
44474443
4448 g->err_name_table = LLVMAddGlobal(g->module, LLVMTypeOf(err_name_table_init),4444 g->err_name_table = LLVMAddGlobal(g->module, LLVMTypeOf(err_name_table_init),
4449 buf_ptr(get_mangled_name(g, buf_create_from_str("__zig_err_name_table"), false)));4445 buf_ptr(get_mangled_name(g, buf_create_from_str("__zig_err_name_table"), false)));
...@@ -4573,6 +4569,28 @@ static void validate_inline_fns(CodeGen *g) {...@@ -4573,6 +4569,28 @@ static void validate_inline_fns(CodeGen *g) {
4573static void do_code_gen(CodeGen *g) {4569static void do_code_gen(CodeGen *g) {
4574 assert(!g->errors.length);4570 assert(!g->errors.length);
45754571
4572 {
4573 // create debug type for error sets
4574 assert(g->err_enumerators.length == g->errors_by_index.length);
4575 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, g->err_tag_type->type_ref);
4576 uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, g->err_tag_type->type_ref);
4577 ZigLLVMDIFile *err_set_di_file = nullptr;
4578 ZigLLVMDIType *err_set_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
4579 ZigLLVMCompileUnitToScope(g->compile_unit), buf_ptr(&g->builtin_types.entry_global_error_set->name),
4580 err_set_di_file, 0,
4581 tag_debug_size_in_bits,
4582 tag_debug_align_in_bits,
4583 g->err_enumerators.items, g->err_enumerators.length,
4584 g->err_tag_type->di_type, "");
4585 ZigLLVMReplaceTemporary(g->dbuilder, g->builtin_types.entry_global_error_set->di_type, err_set_di_type);
4586 g->builtin_types.entry_global_error_set->di_type = err_set_di_type;
4587
4588 for (size_t i = 0; i < g->error_di_types.length; i += 1) {
4589 ZigLLVMDIType **di_type_ptr = g->error_di_types.at(i);
4590 *di_type_ptr = err_set_di_type;
4591 }
4592 }
4593
4576 codegen_add_time_event(g, "Code Generation");4594 codegen_add_time_event(g, "Code Generation");
45774595
4578 generate_error_name_table(g);4596 generate_error_name_table(g);
...@@ -5176,16 +5194,23 @@ static void define_builtin_types(CodeGen *g) {...@@ -5176,16 +5194,23 @@ static void define_builtin_types(CodeGen *g) {
5176 }5194 }
51775195
5178 {5196 {
5179 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPureError);5197 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdErrorSet);
5180 buf_init_from_str(&entry->name, "error");5198 buf_init_from_str(&entry->name, "error");
51815199
5182 // TODO allow overriding this type and keep track of max value and emit an5200 // TODO allow overriding this type and keep track of max value and emit an
5183 // error if there are too many errors declared5201 // error if there are too many errors declared
5184 g->err_tag_type = g->builtin_types.entry_u16;5202 g->err_tag_type = g->builtin_types.entry_u16;
51855203
5186 g->builtin_types.entry_pure_error = entry;5204 g->builtin_types.entry_global_error_set = entry;
5187 entry->type_ref = g->err_tag_type->type_ref;5205 entry->type_ref = g->err_tag_type->type_ref;
5188 entry->di_type = g->err_tag_type->di_type;5206
5207 entry->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
5208 ZigLLVMTag_DW_enumeration_type(), "error",
5209 ZigLLVMCompileUnitToScope(g->compile_unit), nullptr, 0);
5210
5211 // reserve index 0 to indicate no error
5212 g->err_enumerators.append(ZigLLVMCreateDebugEnumerator(g->dbuilder, "(none)", 0));
5213 g->errors_by_index.append(nullptr);
51895214
5190 g->primitive_type_table.put(&entry->name, entry);5215 g->primitive_type_table.put(&entry->name, entry);
5191 }5216 }
...@@ -5815,7 +5840,7 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, TypeTableEntry...@@ -5815,7 +5840,7 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, TypeTableEntry
5815 case TypeTableEntryIdBoundFn:5840 case TypeTableEntryIdBoundFn:
5816 case TypeTableEntryIdArgTuple:5841 case TypeTableEntryIdArgTuple:
5817 case TypeTableEntryIdErrorUnion:5842 case TypeTableEntryIdErrorUnion:
5818 case TypeTableEntryIdPureError:5843 case TypeTableEntryIdErrorSet:
5819 zig_unreachable();5844 zig_unreachable();
5820 case TypeTableEntryIdVoid:5845 case TypeTableEntryIdVoid:
5821 case TypeTableEntryIdUnreachable:5846 case TypeTableEntryIdUnreachable:
...@@ -5988,7 +6013,7 @@ static void get_c_type(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry, Buf...@@ -5988,7 +6013,7 @@ static void get_c_type(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry, Buf
5988 return;6013 return;
5989 }6014 }
5990 case TypeTableEntryIdErrorUnion:6015 case TypeTableEntryIdErrorUnion:
5991 case TypeTableEntryIdPureError:6016 case TypeTableEntryIdErrorSet:
5992 case TypeTableEntryIdFn:6017 case TypeTableEntryIdFn:
5993 zig_panic("TODO implement get_c_type for more types");6018 zig_panic("TODO implement get_c_type for more types");
5994 case TypeTableEntryIdInvalid:6019 case TypeTableEntryIdInvalid:
...@@ -6155,7 +6180,7 @@ static void gen_h_file(CodeGen *g) {...@@ -6155,7 +6180,7 @@ static void gen_h_file(CodeGen *g) {
6155 case TypeTableEntryIdUndefLit:6180 case TypeTableEntryIdUndefLit:
6156 case TypeTableEntryIdNullLit:6181 case TypeTableEntryIdNullLit:
6157 case TypeTableEntryIdErrorUnion:6182 case TypeTableEntryIdErrorUnion:
6158 case TypeTableEntryIdPureError:6183 case TypeTableEntryIdErrorSet:
6159 case TypeTableEntryIdNamespace:6184 case TypeTableEntryIdNamespace:
6160 case TypeTableEntryIdBlock:6185 case TypeTableEntryIdBlock:
6161 case TypeTableEntryIdBoundFn:6186 case TypeTableEntryIdBoundFn:
src/ir.cpp+533-163
...@@ -580,6 +580,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorReturnTrace...@@ -580,6 +580,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorReturnTrace
580 return IrInstructionIdErrorReturnTrace;580 return IrInstructionIdErrorReturnTrace;
581}581}
582582
583static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorUnion *) {
584 return IrInstructionIdErrorUnion;
585}
586
583template<typename T>587template<typename T>
584static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {588static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
585 T *special_instruction = allocate<T>(1);589 T *special_instruction = allocate<T>(1);
...@@ -2326,6 +2330,19 @@ static IrInstruction *ir_build_error_return_trace(IrBuilder *irb, Scope *scope,...@@ -2326,6 +2330,19 @@ static IrInstruction *ir_build_error_return_trace(IrBuilder *irb, Scope *scope,
2326 return &instruction->base;2330 return &instruction->base;
2327}2331}
23282332
2333static IrInstruction *ir_build_error_union(IrBuilder *irb, Scope *scope, AstNode *source_node,
2334 IrInstruction *err_set, IrInstruction *payload)
2335{
2336 IrInstructionErrorUnion *instruction = ir_build_instruction<IrInstructionErrorUnion>(irb, scope, source_node);
2337 instruction->err_set = err_set;
2338 instruction->payload = payload;
2339
2340 ir_ref_instruction(err_set, irb->current_basic_block);
2341 ir_ref_instruction(payload, irb->current_basic_block);
2342
2343 return &instruction->base;
2344}
2345
2329static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {2346static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
2330 results[ReturnKindUnconditional] = 0;2347 results[ReturnKindUnconditional] = 0;
2331 results[ReturnKindError] = 0;2348 results[ReturnKindError] = 0;
...@@ -2800,6 +2817,23 @@ static IrInstruction *ir_gen_maybe_ok_or(IrBuilder *irb, Scope *parent_scope, As...@@ -2800,6 +2817,23 @@ static IrInstruction *ir_gen_maybe_ok_or(IrBuilder *irb, Scope *parent_scope, As
2800 return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values);2817 return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values);
2801}2818}
28022819
2820static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
2821 assert(node->type == NodeTypeBinOpExpr);
2822
2823 AstNode *op1_node = node->data.bin_op_expr.op1;
2824 AstNode *op2_node = node->data.bin_op_expr.op2;
2825
2826 IrInstruction *err_set = ir_gen_node(irb, op1_node, parent_scope);
2827 if (err_set == irb->codegen->invalid_instruction)
2828 return irb->codegen->invalid_instruction;
2829
2830 IrInstruction *payload = ir_gen_node(irb, op2_node, parent_scope);
2831 if (payload == irb->codegen->invalid_instruction)
2832 return irb->codegen->invalid_instruction;
2833
2834 return ir_build_error_union(irb, parent_scope, node, err_set, payload);
2835}
2836
2803static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) {2837static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) {
2804 assert(node->type == NodeTypeBinOpExpr);2838 assert(node->type == NodeTypeBinOpExpr);
28052839
...@@ -2887,6 +2921,8 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node)...@@ -2887,6 +2921,8 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node)
2887 return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult);2921 return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult);
2888 case BinOpTypeUnwrapMaybe:2922 case BinOpTypeUnwrapMaybe:
2889 return ir_gen_maybe_ok_or(irb, scope, node);2923 return ir_gen_maybe_ok_or(irb, scope, node);
2924 case BinOpTypeErrorUnion:
2925 return ir_gen_error_union(irb, scope, node);
2890 }2926 }
2891 zig_unreachable();2927 zig_unreachable();
2892}2928}
...@@ -3990,8 +4026,6 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod...@@ -3990,8 +4026,6 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod
3990 return ir_gen_prefix_op_id_lval(irb, scope, node, IrUnOpDereference, lval);4026 return ir_gen_prefix_op_id_lval(irb, scope, node, IrUnOpDereference, lval);
3991 case PrefixOpMaybe:4027 case PrefixOpMaybe:
3992 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpMaybe), lval);4028 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpMaybe), lval);
3993 case PrefixOpError:
3994 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpError), lval);
3995 case PrefixOpUnwrapMaybe:4029 case PrefixOpUnwrapMaybe:
3996 return ir_gen_maybe_assert_ok(irb, scope, node, lval);4030 return ir_gen_maybe_assert_ok(irb, scope, node, lval);
3997 }4031 }
...@@ -5165,7 +5199,7 @@ static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *continue_scope, Ast...@@ -5165,7 +5199,7 @@ static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *continue_scope, Ast
51655199
5166static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *node) {5200static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *node) {
5167 assert(node->type == NodeTypeErrorType);5201 assert(node->type == NodeTypeErrorType);
5168 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_pure_error);5202 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_global_error_set);
5169}5203}
51705204
5171static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) {5205static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
...@@ -5249,8 +5283,6 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN...@@ -5249,8 +5283,6 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN
5249 Scope *err_scope;5283 Scope *err_scope;
5250 if (var_node) {5284 if (var_node) {
5251 assert(var_node->type == NodeTypeSymbol);5285 assert(var_node->type == NodeTypeSymbol);
5252 IrInstruction *var_type = ir_build_const_type(irb, parent_scope, node,
5253 irb->codegen->builtin_types.entry_pure_error);
5254 Buf *var_name = var_node->data.symbol_expr.symbol;5286 Buf *var_name = var_node->data.symbol_expr.symbol;
5255 bool is_const = true;5287 bool is_const = true;
5256 bool is_shadowable = false;5288 bool is_shadowable = false;
...@@ -5258,7 +5290,7 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN...@@ -5258,7 +5290,7 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN
5258 is_const, is_const, is_shadowable, is_comptime);5290 is_const, is_const, is_shadowable, is_comptime);
5259 err_scope = var->child_scope;5291 err_scope = var->child_scope;
5260 IrInstruction *err_val = ir_build_unwrap_err_code(irb, err_scope, node, err_union_ptr);5292 IrInstruction *err_val = ir_build_unwrap_err_code(irb, err_scope, node, err_union_ptr);
5261 ir_build_var_decl(irb, err_scope, var_node, var, var_type, nullptr, err_val);5293 ir_build_var_decl(irb, err_scope, var_node, var, nullptr, nullptr, err_val);
5262 } else {5294 } else {
5263 err_scope = parent_scope;5295 err_scope = parent_scope;
5264 }5296 }
...@@ -5348,6 +5380,70 @@ static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope,...@@ -5348,6 +5380,70 @@ static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope,
5348 return ir_build_const_type(irb, parent_scope, node, container_type);5380 return ir_build_const_type(irb, parent_scope, node, container_type);
5349}5381}
53505382
5383static TypeTableEntry *make_err_set_with_one_item(CodeGen *g, Scope *parent_scope, AstNode *node,
5384 ErrorTableEntry *err_entry)
5385{
5386 TypeTableEntry *err_set_type = new_type_table_entry(TypeTableEntryIdErrorSet);
5387 buf_resize(&err_set_type->name, 0);
5388 buf_appendf(&err_set_type->name, "@typeOf(error.%s)", buf_ptr(&err_entry->name));
5389 err_set_type->is_copyable = true;
5390 err_set_type->type_ref = g->builtin_types.entry_global_error_set->type_ref;
5391 err_set_type->di_type = g->builtin_types.entry_global_error_set->di_type;
5392 err_set_type->data.error_set.err_count = 1;
5393 err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(1);
5394
5395 g->error_di_types.append(&err_set_type->di_type);
5396
5397 err_set_type->data.error_set.errors[0] = err_entry;
5398
5399 return err_set_type;
5400}
5401
5402static IrInstruction *ir_gen_err_set_decl(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
5403 assert(node->type == NodeTypeErrorSetDecl);
5404
5405 uint32_t err_count = node->data.err_set_decl.decls.length;
5406
5407 if (err_count == 0) {
5408 add_node_error(irb->codegen, node, buf_sprintf("empty error set"));
5409 return irb->codegen->invalid_instruction;
5410 }
5411
5412 Buf *type_name = get_anon_type_name(irb->codegen, irb->exec, "error set", node);
5413 TypeTableEntry *err_set_type = new_type_table_entry(TypeTableEntryIdErrorSet);
5414 buf_init_from_buf(&err_set_type->name, type_name);
5415 err_set_type->is_copyable = true;
5416 err_set_type->type_ref = irb->codegen->builtin_types.entry_global_error_set->type_ref;
5417 err_set_type->di_type = irb->codegen->builtin_types.entry_global_error_set->di_type;
5418 err_set_type->data.error_set.err_count = err_count;
5419 err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(err_count);
5420
5421 irb->codegen->error_di_types.append(&err_set_type->di_type);
5422
5423 for (uint32_t i = 0; i < err_count; i += 1) {
5424 AstNode *symbol_node = node->data.err_set_decl.decls.at(i);
5425 assert(symbol_node->type == NodeTypeSymbol);
5426 Buf *err_name = symbol_node->data.symbol_expr.symbol;
5427 ErrorTableEntry *err = allocate<ErrorTableEntry>(1);
5428 err->decl_node = symbol_node;
5429 buf_init_from_buf(&err->name, err_name);
5430
5431 auto existing_entry = irb->codegen->error_table.put_unique(err_name, err);
5432 if (existing_entry) {
5433 err->value = existing_entry->value->value;
5434 } else {
5435 size_t error_value_count = irb->codegen->errors_by_index.length;
5436 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)irb->codegen->err_tag_type->data.integral.bit_count));
5437 err->value = error_value_count;
5438 irb->codegen->errors_by_index.append(err);
5439 irb->codegen->err_enumerators.append(ZigLLVMCreateDebugEnumerator(irb->codegen->dbuilder,
5440 buf_ptr(err_name), error_value_count));
5441 }
5442 err_set_type->data.error_set.errors[i] = err;
5443 }
5444 return ir_build_const_type(irb, parent_scope, node, err_set_type);
5445}
5446
5351static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNode *node) {5447static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
5352 assert(node->type == NodeTypeFnProto);5448 assert(node->type == NodeTypeFnProto);
53535449
...@@ -5401,7 +5497,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop...@@ -5401,7 +5497,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
5401 case NodeTypeStructField:5497 case NodeTypeStructField:
5402 case NodeTypeFnDef:5498 case NodeTypeFnDef:
5403 case NodeTypeFnDecl:5499 case NodeTypeFnDecl:
5404 case NodeTypeErrorValueDecl:
5405 case NodeTypeTestDecl:5500 case NodeTypeTestDecl:
5406 zig_unreachable();5501 zig_unreachable();
5407 case NodeTypeBlock:5502 case NodeTypeBlock:
...@@ -5482,6 +5577,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop...@@ -5482,6 +5577,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
5482 return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval);5577 return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval);
5483 case NodeTypeFnProto:5578 case NodeTypeFnProto:
5484 return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval);5579 return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval);
5580 case NodeTypeErrorSetDecl:
5581 return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval);
5485 }5582 }
5486 zig_unreachable();5583 zig_unreachable();
5487}5584}
...@@ -6301,25 +6398,32 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -6301,25 +6398,32 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
6301 return ImplicitCastMatchResultYes;6398 return ImplicitCastMatchResultYes;
6302 }6399 }
63036400
6304 // implicit T to %T6401 // implicit T to U!T
6305 if (expected_type->id == TypeTableEntryIdErrorUnion &&6402 if (expected_type->id == TypeTableEntryIdErrorUnion &&
6306 ir_types_match_with_implicit_cast(ira, expected_type->data.error.child_type, actual_type, value))6403 ir_types_match_with_implicit_cast(ira, expected_type->data.error_union.payload_type, actual_type, value))
6307 {6404 {
6308 return ImplicitCastMatchResultYes;6405 return ImplicitCastMatchResultYes;
6309 }6406 }
63106407
6311 // implicit conversion from pure error to error union type6408 // implicit conversion from error set to error union type
6312 if (expected_type->id == TypeTableEntryIdErrorUnion &&6409 if (expected_type->id == TypeTableEntryIdErrorUnion &&
6313 actual_type->id == TypeTableEntryIdPureError)6410 actual_type->id == TypeTableEntryIdErrorSet)
6411 {
6412 return ImplicitCastMatchResultYes;
6413 }
6414
6415 // implicit conversion from error set to another error set
6416 if (expected_type->id == TypeTableEntryIdErrorSet &&
6417 actual_type->id == TypeTableEntryIdErrorSet)
6314 {6418 {
6315 return ImplicitCastMatchResultYes;6419 return ImplicitCastMatchResultYes;
6316 }6420 }
63176421
6318 // implicit conversion from T to %?T6422 // implicit conversion from T to U!?T
6319 if (expected_type->id == TypeTableEntryIdErrorUnion &&6423 if (expected_type->id == TypeTableEntryIdErrorUnion &&
6320 expected_type->data.error.child_type->id == TypeTableEntryIdMaybe &&6424 expected_type->data.error_union.payload_type->id == TypeTableEntryIdMaybe &&
6321 ir_types_match_with_implicit_cast(ira,6425 ir_types_match_with_implicit_cast(ira,
6322 expected_type->data.error.child_type->data.maybe.child_type,6426 expected_type->data.error_union.payload_type->data.maybe.child_type,
6323 actual_type, value))6427 actual_type, value))
6324 {6428 {
6325 return ImplicitCastMatchResultYes;6429 return ImplicitCastMatchResultYes;
...@@ -6503,7 +6607,19 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6503,7 +6607,19 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
6503 if (type_is_invalid(prev_inst->value.type)) {6607 if (type_is_invalid(prev_inst->value.type)) {
6504 return ira->codegen->builtin_types.entry_invalid;6608 return ira->codegen->builtin_types.entry_invalid;
6505 }6609 }
6506 bool any_are_pure_error = (prev_inst->value.type->id == TypeTableEntryIdPureError);6610 ErrorTableEntry **errors = nullptr;
6611 TypeTableEntry *err_set_type = nullptr;
6612 if (prev_inst->value.type == ira->codegen->builtin_types.entry_global_error_set) {
6613 err_set_type = ira->codegen->builtin_types.entry_global_error_set;
6614 } else if (prev_inst->value.type->id == TypeTableEntryIdErrorSet) {
6615 err_set_type = prev_inst->value.type;
6616 errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length);
6617 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) {
6618 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i];
6619 errors[error_entry->value] = error_entry;
6620 }
6621 }
6622
6507 bool any_are_null = (prev_inst->value.type->id == TypeTableEntryIdNullLit);6623 bool any_are_null = (prev_inst->value.type->id == TypeTableEntryIdNullLit);
6508 bool convert_to_const_slice = false;6624 bool convert_to_const_slice = false;
6509 for (size_t i = 1; i < instruction_count; i += 1) {6625 for (size_t i = 1; i < instruction_count; i += 1) {
...@@ -6524,27 +6640,133 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6524,27 +6640,133 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
6524 continue;6640 continue;
6525 }6641 }
65266642
6527 if (prev_type->id == TypeTableEntryIdPureError) {6643 if (prev_type->id == TypeTableEntryIdNullLit) {
6528 prev_inst = cur_inst;6644 prev_inst = cur_inst;
6529 continue;6645 continue;
6530 }6646 }
65316647
6532 if (prev_type->id == TypeTableEntryIdNullLit) {6648 if (cur_type->id == TypeTableEntryIdNullLit) {
6533 prev_inst = cur_inst;6649 any_are_null = true;
6534 continue;6650 continue;
6535 }6651 }
65366652
6537 if (cur_type->id == TypeTableEntryIdPureError) {6653 if (prev_type->id == TypeTableEntryIdErrorSet) {
6538 if (prev_type->id == TypeTableEntryIdArray) {6654 assert(err_set_type != nullptr);
6539 convert_to_const_slice = true;6655 if (cur_type->id == TypeTableEntryIdErrorSet) {
6656 if (err_set_type == ira->codegen->builtin_types.entry_global_error_set) {
6657 continue;
6658 }
6659 if (cur_type == ira->codegen->builtin_types.entry_global_error_set) {
6660 err_set_type = ira->codegen->builtin_types.entry_global_error_set;
6661 prev_inst = cur_inst;
6662 continue;
6663 }
6664 // if err_set_type is a superset of cur_type, keep err_set_type.
6665 // if cur_type is a superset of err_set_type, switch err_set_type to cur_type
6666 // otherwise emit a compile error
6667 bool prev_is_superset = true;
6668 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) {
6669 ErrorTableEntry *contained_error_entry = cur_type->data.error_set.errors[i];
6670 ErrorTableEntry *error_entry = errors[contained_error_entry->value];
6671 if (error_entry == nullptr) {
6672 prev_is_superset = false;
6673 break;
6674 }
6675 }
6676 if (prev_is_superset) {
6677 continue;
6678 }
6679
6680 // unset everything in errors
6681 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) {
6682 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i];
6683 errors[error_entry->value] = nullptr;
6684 }
6685 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) {
6686 ErrorTableEntry *error_entry = cur_type->data.error_set.errors[i];
6687 errors[error_entry->value] = error_entry;
6688 }
6689 bool cur_is_superset = true;
6690 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) {
6691 ErrorTableEntry *contained_error_entry = err_set_type->data.error_set.errors[i];
6692 ErrorTableEntry *error_entry = errors[contained_error_entry->value];
6693 if (error_entry == nullptr) {
6694 cur_is_superset = false;
6695 break;
6696 }
6697 }
6698 if (cur_is_superset) {
6699 err_set_type = cur_inst->value.type;
6700 prev_inst = cur_inst;
6701 continue;
6702 }
6703 } else if (cur_type->id == TypeTableEntryIdErrorUnion) {
6704 // err_set_type must be a subset of cur_type's error set
6705 // unset everything in errors
6706 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) {
6707 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i];
6708 errors[error_entry->value] = nullptr;
6709 }
6710 TypeTableEntry *cur_err_set_type = cur_type->data.error_union.err_set_type;
6711 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) {
6712 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i];
6713 errors[error_entry->value] = error_entry;
6714 }
6715 bool cur_is_superset = true;
6716 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) {
6717 ErrorTableEntry *contained_error_entry = err_set_type->data.error_set.errors[i];
6718 ErrorTableEntry *error_entry = errors[contained_error_entry->value];
6719 if (error_entry == nullptr) {
6720 cur_is_superset = false;
6721 break;
6722 }
6723 }
6724 if (cur_is_superset) {
6725 err_set_type = cur_err_set_type;
6726 prev_inst = cur_inst;
6727 continue;
6728 }
6729 } else {
6730 prev_inst = cur_inst;
6731 continue;
6540 }6732 }
6541 any_are_pure_error = true;
6542 continue;
6543 }6733 }
65446734
6545 if (cur_type->id == TypeTableEntryIdNullLit) {6735 if (cur_type->id == TypeTableEntryIdErrorSet) {
6546 any_are_null = true;6736 if (prev_type->id == TypeTableEntryIdArray) {
6547 continue;6737 convert_to_const_slice = true;
6738 }
6739 if (cur_type == ira->codegen->builtin_types.entry_global_error_set) {
6740 err_set_type = ira->codegen->builtin_types.entry_global_error_set;
6741 continue;
6742 }
6743 if (err_set_type == ira->codegen->builtin_types.entry_global_error_set) {
6744 continue;
6745 }
6746 if (err_set_type == nullptr) {
6747 err_set_type = cur_type;
6748 errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length);
6749 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) {
6750 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i];
6751 errors[error_entry->value] = error_entry;
6752 }
6753 continue;
6754 }
6755 if (prev_type->id == TypeTableEntryIdErrorUnion) {
6756 // the cur type error set must be a subset
6757 bool prev_is_superset = true;
6758 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) {
6759 ErrorTableEntry *contained_error_entry = cur_type->data.error_set.errors[i];
6760 ErrorTableEntry *error_entry = errors[contained_error_entry->value];
6761 if (error_entry == nullptr) {
6762 prev_is_superset = false;
6763 break;
6764 }
6765 }
6766 if (prev_is_superset) {
6767 continue;
6768 }
6769 }
6548 }6770 }
65496771
6550 if (types_match_const_cast_only(prev_type, cur_type)) {6772 if (types_match_const_cast_only(prev_type, cur_type)) {
...@@ -6574,20 +6796,20 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6574,20 +6796,20 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
6574 }6796 }
65756797
6576 if (prev_type->id == TypeTableEntryIdErrorUnion &&6798 if (prev_type->id == TypeTableEntryIdErrorUnion &&
6577 types_match_const_cast_only(prev_type->data.error.child_type, cur_type))6799 types_match_const_cast_only(prev_type->data.error_union.payload_type, cur_type))
6578 {6800 {
6579 continue;6801 continue;
6580 }6802 }
65816803
6582 if (cur_type->id == TypeTableEntryIdErrorUnion &&6804 if (cur_type->id == TypeTableEntryIdErrorUnion &&
6583 types_match_const_cast_only(cur_type->data.error.child_type, prev_type))6805 types_match_const_cast_only(cur_type->data.error_union.payload_type, prev_type))
6584 {6806 {
6585 prev_inst = cur_inst;6807 prev_inst = cur_inst;
6586 continue;6808 continue;
6587 }6809 }
65886810
6589 if (prev_type->id == TypeTableEntryIdMaybe &&6811 if (prev_type->id == TypeTableEntryIdMaybe &&
6590 types_match_const_cast_only(prev_type->data.maybe.child_type, cur_type))6812 types_match_const_cast_only(prev_type->data.maybe.child_type, cur_type))
6591 {6813 {
6592 continue;6814 continue;
6593 }6815 }
...@@ -6700,16 +6922,19 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6700,16 +6922,19 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
67006922
6701 return ira->codegen->builtin_types.entry_invalid;6923 return ira->codegen->builtin_types.entry_invalid;
6702 }6924 }
6925
6926 free(errors);
6927
6703 if (convert_to_const_slice) {6928 if (convert_to_const_slice) {
6704 assert(prev_inst->value.type->id == TypeTableEntryIdArray);6929 assert(prev_inst->value.type->id == TypeTableEntryIdArray);
6705 TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, prev_inst->value.type->data.array.child_type, true);6930 TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, prev_inst->value.type->data.array.child_type, true);
6706 TypeTableEntry *slice_type = get_slice_type(ira->codegen, ptr_type);6931 TypeTableEntry *slice_type = get_slice_type(ira->codegen, ptr_type);
6707 if (any_are_pure_error) {6932 if (err_set_type != nullptr) {
6708 return get_error_type(ira->codegen, slice_type);6933 return get_error_union_type(ira->codegen, err_set_type, slice_type);
6709 } else {6934 } else {
6710 return slice_type;6935 return slice_type;
6711 }6936 }
6712 } else if (any_are_pure_error && prev_inst->value.type->id != TypeTableEntryIdPureError) {6937 } else if (err_set_type != nullptr && prev_inst->value.type->id != TypeTableEntryIdErrorSet) {
6713 if (prev_inst->value.type->id == TypeTableEntryIdNumLitInt ||6938 if (prev_inst->value.type->id == TypeTableEntryIdNumLitInt ||
6714 prev_inst->value.type->id == TypeTableEntryIdNumLitFloat)6939 prev_inst->value.type->id == TypeTableEntryIdNumLitFloat)
6715 {6940 {
...@@ -6723,7 +6948,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6723,7 +6948,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
6723 } else if (prev_inst->value.type->id == TypeTableEntryIdErrorUnion) {6948 } else if (prev_inst->value.type->id == TypeTableEntryIdErrorUnion) {
6724 return prev_inst->value.type;6949 return prev_inst->value.type;
6725 } else {6950 } else {
6726 return get_error_type(ira->codegen, prev_inst->value.type);6951 return get_error_union_type(ira->codegen, err_set_type, prev_inst->value.type);
6727 }6952 }
6728 } else if (any_are_null && prev_inst->value.type->id != TypeTableEntryIdNullLit) {6953 } else if (any_are_null && prev_inst->value.type->id != TypeTableEntryIdNullLit) {
6729 if (prev_inst->value.type->id == TypeTableEntryIdNumLitInt ||6954 if (prev_inst->value.type->id == TypeTableEntryIdNumLitInt ||
...@@ -7199,7 +7424,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction...@@ -7199,7 +7424,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction
7199 assert(wanted_type->id == TypeTableEntryIdErrorUnion);7424 assert(wanted_type->id == TypeTableEntryIdErrorUnion);
72007425
7201 if (instr_is_comptime(value)) {7426 if (instr_is_comptime(value)) {
7202 TypeTableEntry *payload_type = wanted_type->data.error.child_type;7427 TypeTableEntry *payload_type = wanted_type->data.error_union.payload_type;
7203 IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type);7428 IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type);
7204 if (type_is_invalid(casted_payload->value.type))7429 if (type_is_invalid(casted_payload->value.type))
7205 return ira->codegen->invalid_instruction;7430 return ira->codegen->invalid_instruction;
...@@ -7224,8 +7449,43 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction...@@ -7224,8 +7449,43 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction
7224 return result;7449 return result;
7225}7450}
72267451
7227static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, TypeTableEntry *wanted_type) {7452static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
7228 assert(wanted_type->id == TypeTableEntryIdErrorUnion);7453 TypeTableEntry *wanted_type)
7454{
7455 TypeTableEntry *contained_set = value->value.type;
7456 TypeTableEntry *container_set = wanted_type;
7457
7458 assert(contained_set->id == TypeTableEntryIdErrorSet);
7459 assert(container_set->id == TypeTableEntryIdErrorSet);
7460
7461 if (container_set->data.error_set.infer_fn == nullptr &&
7462 container_set != ira->codegen->builtin_types.entry_global_error_set)
7463 {
7464 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length);
7465 for (uint32_t i = 0; i < container_set->data.error_set.err_count; i += 1) {
7466 ErrorTableEntry *error_entry = container_set->data.error_set.errors[i];
7467 errors[error_entry->value] = error_entry;
7468 }
7469 ErrorMsg *err_msg = nullptr;
7470 for (uint32_t i = 0; i < contained_set->data.error_set.err_count; i += 1) {
7471 ErrorTableEntry *contained_error_entry = contained_set->data.error_set.errors[i];
7472 ErrorTableEntry *error_entry = errors[contained_error_entry->value];
7473 if (error_entry == nullptr) {
7474 if (err_msg == nullptr) {
7475 err_msg = ir_add_error(ira, source_instr,
7476 buf_sprintf("invalid cast of error set '%s' to error set '%s'",
7477 buf_ptr(&contained_set->name), buf_ptr(&container_set->name)));
7478 }
7479 add_error_note(ira->codegen, err_msg, contained_error_entry->decl_node,
7480 buf_sprintf("'%s.%s' not present in '%s'", buf_ptr(&contained_set->name),
7481 buf_ptr(&contained_error_entry->name), buf_ptr(&container_set->name)));
7482 }
7483 }
7484 free(errors);
7485 if (err_msg != nullptr) {
7486 return ira->codegen->invalid_instruction;
7487 }
7488 }
72297489
7230 if (instr_is_comptime(value)) {7490 if (instr_is_comptime(value)) {
7231 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);7491 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);
...@@ -7236,7 +7496,30 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so...@@ -7236,7 +7496,30 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so
7236 source_instr->scope, source_instr->source_node);7496 source_instr->scope, source_instr->source_node);
7237 const_instruction->base.value.type = wanted_type;7497 const_instruction->base.value.type = wanted_type;
7238 const_instruction->base.value.special = ConstValSpecialStatic;7498 const_instruction->base.value.special = ConstValSpecialStatic;
7239 const_instruction->base.value.data.x_err_union.err = val->data.x_pure_err;7499 const_instruction->base.value.data.x_err_set = val->data.x_err_set;
7500 return &const_instruction->base;
7501 }
7502
7503 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, CastOpNoop);
7504 result->value.type = wanted_type;
7505 return result;
7506}
7507
7508static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, TypeTableEntry *wanted_type) {
7509 assert(wanted_type->id == TypeTableEntryIdErrorUnion);
7510
7511 IrInstruction *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type);
7512
7513 if (instr_is_comptime(casted_value)) {
7514 ConstExprValue *val = ir_resolve_const(ira, casted_value, UndefBad);
7515 if (!val)
7516 return ira->codegen->invalid_instruction;
7517
7518 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb,
7519 source_instr->scope, source_instr->source_node);
7520 const_instruction->base.value.type = wanted_type;
7521 const_instruction->base.value.special = ConstValSpecialStatic;
7522 const_instruction->base.value.data.x_err_union.err = val->data.x_err_set;
7240 const_instruction->base.value.data.x_err_union.payload = nullptr;7523 const_instruction->base.value.data.x_err_union.payload = nullptr;
7241 return &const_instruction->base;7524 return &const_instruction->base;
7242 }7525 }
...@@ -7616,9 +7899,12 @@ static IrInstruction *ir_analyze_number_to_literal(IrAnalyze *ira, IrInstruction...@@ -7616,9 +7899,12 @@ static IrInstruction *ir_analyze_number_to_literal(IrAnalyze *ira, IrInstruction
7616 return result;7899 return result;
7617}7900}
76187901
7619static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target) {7902static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target,
7903 TypeTableEntry *wanted_type)
7904{
7620 assert(target->value.type->id == TypeTableEntryIdInt);7905 assert(target->value.type->id == TypeTableEntryIdInt);
7621 assert(!target->value.type->data.integral.is_signed);7906 assert(!target->value.type->data.integral.is_signed);
7907 assert(wanted_type->id == TypeTableEntryIdErrorSet);
76227908
7623 if (instr_is_comptime(target)) {7909 if (instr_is_comptime(target)) {
7624 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);7910 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);
...@@ -7626,10 +7912,10 @@ static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *sourc...@@ -7626,10 +7912,10 @@ static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *sourc
7626 return ira->codegen->invalid_instruction;7912 return ira->codegen->invalid_instruction;
76277913
7628 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,7914 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
7629 source_instr->source_node, ira->codegen->builtin_types.entry_pure_error);7915 source_instr->source_node, wanted_type);
76307916
7631 BigInt err_count;7917 BigInt err_count;
7632 bigint_init_unsigned(&err_count, ira->codegen->error_decls.length);7918 bigint_init_unsigned(&err_count, ira->codegen->errors_by_index.length);
7633 if (bigint_cmp_zero(&val->data.x_bigint) == CmpEQ || bigint_cmp(&val->data.x_bigint, &err_count) != CmpLT) {7919 if (bigint_cmp_zero(&val->data.x_bigint) == CmpEQ || bigint_cmp(&val->data.x_bigint, &err_count) != CmpLT) {
7634 Buf *val_buf = buf_alloc();7920 Buf *val_buf = buf_alloc();
7635 bigint_append_buf(val_buf, &val->data.x_bigint, 10);7921 bigint_append_buf(val_buf, &val->data.x_bigint, 10);
...@@ -7639,13 +7925,12 @@ static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *sourc...@@ -7639,13 +7925,12 @@ static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *sourc
7639 }7925 }
76407926
7641 size_t index = bigint_as_unsigned(&val->data.x_bigint);7927 size_t index = bigint_as_unsigned(&val->data.x_bigint);
7642 AstNode *error_decl_node = ira->codegen->error_decls.at(index);7928 result->value.data.x_err_set = ira->codegen->errors_by_index.at(index);
7643 result->value.data.x_pure_err = error_decl_node->data.error_value_decl.err;
7644 return result;7929 return result;
7645 }7930 }
76467931
7647 IrInstruction *result = ir_build_int_to_err(&ira->new_irb, source_instr->scope, source_instr->source_node, target);7932 IrInstruction *result = ir_build_int_to_err(&ira->new_irb, source_instr->scope, source_instr->source_node, target);
7648 result->value.type = ira->codegen->builtin_types.entry_pure_error;7933 result->value.type = wanted_type;
7649 return result;7934 return result;
7650}7935}
76517936
...@@ -7667,8 +7952,8 @@ static IrInstruction *ir_analyze_err_to_int(IrAnalyze *ira, IrInstruction *sourc...@@ -7667,8 +7952,8 @@ static IrInstruction *ir_analyze_err_to_int(IrAnalyze *ira, IrInstruction *sourc
7667 ErrorTableEntry *err;7952 ErrorTableEntry *err;
7668 if (err_type->id == TypeTableEntryIdErrorUnion) {7953 if (err_type->id == TypeTableEntryIdErrorUnion) {
7669 err = val->data.x_err_union.err;7954 err = val->data.x_err_union.err;
7670 } else if (err_type->id == TypeTableEntryIdPureError) {7955 } else if (err_type->id == TypeTableEntryIdErrorSet) {
7671 err = val->data.x_pure_err;7956 err = val->data.x_err_set;
7672 } else {7957 } else {
7673 zig_unreachable();7958 zig_unreachable();
7674 }7959 }
...@@ -7689,7 +7974,7 @@ static IrInstruction *ir_analyze_err_to_int(IrAnalyze *ira, IrInstruction *sourc...@@ -7689,7 +7974,7 @@ static IrInstruction *ir_analyze_err_to_int(IrAnalyze *ira, IrInstruction *sourc
7689 }7974 }
76907975
7691 BigInt bn;7976 BigInt bn;
7692 bigint_init_unsigned(&bn, ira->codegen->error_decls.length);7977 bigint_init_unsigned(&bn, ira->codegen->errors_by_index.length);
7693 if (!bigint_fits_in_bits(&bn, wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) {7978 if (!bigint_fits_in_bits(&bn, wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) {
7694 ir_add_error_node(ira, source_instr->source_node,7979 ir_add_error_node(ira, source_instr->source_node,
7695 buf_sprintf("too many error values to fit in '%s'", buf_ptr(&wanted_type->name)));7980 buf_sprintf("too many error values to fit in '%s'", buf_ptr(&wanted_type->name)));
...@@ -7734,6 +8019,13 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -7734,6 +8019,13 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
7734 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type);8019 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type);
7735 }8020 }
77368021
8022 // explicit error set cast
8023 if (wanted_type->id == TypeTableEntryIdErrorSet &&
8024 actual_type->id == TypeTableEntryIdErrorSet)
8025 {
8026 return ir_analyze_err_set_cast(ira, source_instr, value, wanted_type);
8027 }
8028
7737 // explicit cast from int to float8029 // explicit cast from int to float
7738 if (wanted_type->id == TypeTableEntryIdFloat &&8030 if (wanted_type->id == TypeTableEntryIdFloat &&
7739 actual_type->id == TypeTableEntryIdInt)8031 actual_type->id == TypeTableEntryIdInt)
...@@ -7894,12 +8186,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -7894,12 +8186,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
78948186
7895 // explicit cast from child type of error type to error type8187 // explicit cast from child type of error type to error type
7896 if (wanted_type->id == TypeTableEntryIdErrorUnion) {8188 if (wanted_type->id == TypeTableEntryIdErrorUnion) {
7897 if (types_match_const_cast_only(wanted_type->data.error.child_type, actual_type)) {8189 if (types_match_const_cast_only(wanted_type->data.error_union.payload_type, actual_type)) {
7898 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);8190 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);
7899 } else if (actual_type->id == TypeTableEntryIdNumLitInt ||8191 } else if (actual_type->id == TypeTableEntryIdNumLitInt ||
7900 actual_type->id == TypeTableEntryIdNumLitFloat)8192 actual_type->id == TypeTableEntryIdNumLitFloat)
7901 {8193 {
7902 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error.child_type, true)) {8194 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) {
7903 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);8195 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);
7904 } else {8196 } else {
7905 return ira->codegen->invalid_instruction;8197 return ira->codegen->invalid_instruction;
...@@ -7909,16 +8201,16 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -7909,16 +8201,16 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
79098201
7910 // explicit cast from [N]T to %[]const T8202 // explicit cast from [N]T to %[]const T
7911 if (wanted_type->id == TypeTableEntryIdErrorUnion &&8203 if (wanted_type->id == TypeTableEntryIdErrorUnion &&
7912 is_slice(wanted_type->data.error.child_type) &&8204 is_slice(wanted_type->data.error_union.payload_type) &&
7913 actual_type->id == TypeTableEntryIdArray)8205 actual_type->id == TypeTableEntryIdArray)
7914 {8206 {
7915 TypeTableEntry *ptr_type =8207 TypeTableEntry *ptr_type =
7916 wanted_type->data.error.child_type->data.structure.fields[slice_ptr_index].type_entry;8208 wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index].type_entry;
7917 assert(ptr_type->id == TypeTableEntryIdPointer);8209 assert(ptr_type->id == TypeTableEntryIdPointer);
7918 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&8210 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
7919 types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))8211 types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
7920 {8212 {
7921 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error.child_type, value);8213 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);
7922 if (type_is_invalid(cast1->value.type))8214 if (type_is_invalid(cast1->value.type))
7923 return ira->codegen->invalid_instruction;8215 return ira->codegen->invalid_instruction;
79248216
...@@ -7930,25 +8222,25 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -7930,25 +8222,25 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
7930 }8222 }
7931 }8223 }
79328224
7933 // explicit cast from pure error to error union type8225 // explicit cast from error set to error union type
7934 if (wanted_type->id == TypeTableEntryIdErrorUnion &&8226 if (wanted_type->id == TypeTableEntryIdErrorUnion &&
7935 actual_type->id == TypeTableEntryIdPureError)8227 actual_type->id == TypeTableEntryIdErrorSet)
7936 {8228 {
7937 return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type);8229 return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type);
7938 }8230 }
79398231
7940 // explicit cast from T to %?T8232 // explicit cast from T to %?T
7941 if (wanted_type->id == TypeTableEntryIdErrorUnion &&8233 if (wanted_type->id == TypeTableEntryIdErrorUnion &&
7942 wanted_type->data.error.child_type->id == TypeTableEntryIdMaybe &&8234 wanted_type->data.error_union.payload_type->id == TypeTableEntryIdMaybe &&
7943 actual_type->id != TypeTableEntryIdMaybe)8235 actual_type->id != TypeTableEntryIdMaybe)
7944 {8236 {
7945 TypeTableEntry *wanted_child_type = wanted_type->data.error.child_type->data.maybe.child_type;8237 TypeTableEntry *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type;
7946 if (types_match_const_cast_only(wanted_child_type, actual_type) ||8238 if (types_match_const_cast_only(wanted_child_type, actual_type) ||
7947 actual_type->id == TypeTableEntryIdNullLit ||8239 actual_type->id == TypeTableEntryIdNullLit ||
7948 actual_type->id == TypeTableEntryIdNumLitInt ||8240 actual_type->id == TypeTableEntryIdNumLitInt ||
7949 actual_type->id == TypeTableEntryIdNumLitFloat)8241 actual_type->id == TypeTableEntryIdNumLitFloat)
7950 {8242 {
7951 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error.child_type, value);8243 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);
7952 if (type_is_invalid(cast1->value.type))8244 if (type_is_invalid(cast1->value.type))
7953 return ira->codegen->invalid_instruction;8245 return ira->codegen->invalid_instruction;
79548246
...@@ -8017,21 +8309,19 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8017,21 +8309,19 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
8017 return ir_analyze_number_to_literal(ira, source_instr, value, wanted_type);8309 return ir_analyze_number_to_literal(ira, source_instr, value, wanted_type);
8018 }8310 }
80198311
8020 // explicit cast from %void to integer type which can fit it8312 // explicit cast from T!void to integer type which can fit it
8021 bool actual_type_is_void_err = actual_type->id == TypeTableEntryIdErrorUnion &&8313 bool actual_type_is_void_err = actual_type->id == TypeTableEntryIdErrorUnion &&
8022 !type_has_bits(actual_type->data.error.child_type);8314 !type_has_bits(actual_type->data.error_union.payload_type);
8023 bool actual_type_is_pure_err = actual_type->id == TypeTableEntryIdPureError;8315 bool actual_type_is_err_set = actual_type->id == TypeTableEntryIdErrorSet;
8024 if ((actual_type_is_void_err || actual_type_is_pure_err) &&8316 if ((actual_type_is_void_err || actual_type_is_err_set) && wanted_type->id == TypeTableEntryIdInt) {
8025 wanted_type->id == TypeTableEntryIdInt)
8026 {
8027 return ir_analyze_err_to_int(ira, source_instr, value, wanted_type);8317 return ir_analyze_err_to_int(ira, source_instr, value, wanted_type);
8028 }8318 }
80298319
8030 // explicit cast from integer to pure error8320 // explicit cast from integer to error set
8031 if (wanted_type->id == TypeTableEntryIdPureError && actual_type->id == TypeTableEntryIdInt &&8321 if (wanted_type->id == TypeTableEntryIdErrorSet && actual_type->id == TypeTableEntryIdInt &&
8032 !actual_type->data.integral.is_signed)8322 !actual_type->data.integral.is_signed)
8033 {8323 {
8034 return ir_analyze_int_to_err(ira, source_instr, value);8324 return ir_analyze_int_to_err(ira, source_instr, value, wanted_type);
8035 }8325 }
80368326
8037 // explicit cast from integer to enum type with no payload8327 // explicit cast from integer to enum type with no payload
...@@ -8524,7 +8814,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp...@@ -8524,7 +8814,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
8524 case TypeTableEntryIdMetaType:8814 case TypeTableEntryIdMetaType:
8525 case TypeTableEntryIdVoid:8815 case TypeTableEntryIdVoid:
8526 case TypeTableEntryIdPointer:8816 case TypeTableEntryIdPointer:
8527 case TypeTableEntryIdPureError:8817 case TypeTableEntryIdErrorSet:
8528 case TypeTableEntryIdFn:8818 case TypeTableEntryIdFn:
8529 case TypeTableEntryIdOpaque:8819 case TypeTableEntryIdOpaque:
8530 case TypeTableEntryIdNamespace:8820 case TypeTableEntryIdNamespace:
...@@ -9312,7 +9602,7 @@ static VarClassRequired get_var_class_required(TypeTableEntry *type_entry) {...@@ -9312,7 +9602,7 @@ static VarClassRequired get_var_class_required(TypeTableEntry *type_entry) {
9312 case TypeTableEntryIdInt:9602 case TypeTableEntryIdInt:
9313 case TypeTableEntryIdFloat:9603 case TypeTableEntryIdFloat:
9314 case TypeTableEntryIdVoid:9604 case TypeTableEntryIdVoid:
9315 case TypeTableEntryIdPureError:9605 case TypeTableEntryIdErrorSet:
9316 case TypeTableEntryIdFn:9606 case TypeTableEntryIdFn:
9317 return VarClassRequiredAny;9607 return VarClassRequiredAny;
9318 case TypeTableEntryIdNumLitFloat:9608 case TypeTableEntryIdNumLitFloat:
...@@ -9338,7 +9628,7 @@ static VarClassRequired get_var_class_required(TypeTableEntry *type_entry) {...@@ -9338,7 +9628,7 @@ static VarClassRequired get_var_class_required(TypeTableEntry *type_entry) {
9338 case TypeTableEntryIdMaybe:9628 case TypeTableEntryIdMaybe:
9339 return get_var_class_required(type_entry->data.maybe.child_type);9629 return get_var_class_required(type_entry->data.maybe.child_type);
9340 case TypeTableEntryIdErrorUnion:9630 case TypeTableEntryIdErrorUnion:
9341 return get_var_class_required(type_entry->data.error.child_type);9631 return get_var_class_required(type_entry->data.error_union.payload_type);
93429632
9343 case TypeTableEntryIdStruct:9633 case TypeTableEntryIdStruct:
9344 case TypeTableEntryIdEnum:9634 case TypeTableEntryIdEnum:
...@@ -9573,7 +9863,7 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi...@@ -9573,7 +9863,7 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi
9573 case TypeTableEntryIdNullLit:9863 case TypeTableEntryIdNullLit:
9574 case TypeTableEntryIdMaybe:9864 case TypeTableEntryIdMaybe:
9575 case TypeTableEntryIdErrorUnion:9865 case TypeTableEntryIdErrorUnion:
9576 case TypeTableEntryIdPureError:9866 case TypeTableEntryIdErrorSet:
9577 case TypeTableEntryIdNamespace:9867 case TypeTableEntryIdNamespace:
9578 case TypeTableEntryIdBlock:9868 case TypeTableEntryIdBlock:
9579 case TypeTableEntryIdBoundFn:9869 case TypeTableEntryIdBoundFn:
...@@ -9596,7 +9886,7 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi...@@ -9596,7 +9886,7 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi
9596 case TypeTableEntryIdNullLit:9886 case TypeTableEntryIdNullLit:
9597 case TypeTableEntryIdMaybe:9887 case TypeTableEntryIdMaybe:
9598 case TypeTableEntryIdErrorUnion:9888 case TypeTableEntryIdErrorUnion:
9599 case TypeTableEntryIdPureError:9889 case TypeTableEntryIdErrorSet:
9600 zig_panic("TODO export const value of type %s", buf_ptr(&target->value.type->name));9890 zig_panic("TODO export const value of type %s", buf_ptr(&target->value.type->name));
9601 case TypeTableEntryIdNamespace:9891 case TypeTableEntryIdNamespace:
9602 case TypeTableEntryIdBlock:9892 case TypeTableEntryIdBlock:
...@@ -9630,6 +9920,24 @@ static TypeTableEntry *ir_analyze_instruction_error_return_trace(IrAnalyze *ira,...@@ -9630,6 +9920,24 @@ static TypeTableEntry *ir_analyze_instruction_error_return_trace(IrAnalyze *ira,
9630 return nullable_type;9920 return nullable_type;
9631}9921}
96329922
9923static TypeTableEntry *ir_analyze_instruction_error_union(IrAnalyze *ira,
9924 IrInstructionErrorUnion *instruction)
9925{
9926 TypeTableEntry *err_set_type = ir_resolve_type(ira, instruction->err_set->other);
9927 if (type_is_invalid(err_set_type))
9928 return ira->codegen->builtin_types.entry_invalid;
9929
9930 TypeTableEntry *payload_type = ir_resolve_type(ira, instruction->payload->other);
9931 if (type_is_invalid(payload_type))
9932 return ira->codegen->builtin_types.entry_invalid;
9933
9934 TypeTableEntry *result_type = get_error_union_type(ira->codegen, err_set_type, payload_type);
9935
9936 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
9937 out_val->data.x_type = result_type;
9938 return ira->codegen->builtin_types.entry_type;
9939}
9940
9633static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node,9941static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node,
9634 IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i)9942 IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i)
9635{9943{
...@@ -10114,7 +10422,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -10114,7 +10422,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
10114 TypeTableEntry *return_type = impl_fn->type_entry->data.fn.fn_type_id.return_type;10422 TypeTableEntry *return_type = impl_fn->type_entry->data.fn.fn_type_id.return_type;
10115 ir_add_alloca(ira, new_call_instruction, return_type);10423 ir_add_alloca(ira, new_call_instruction, return_type);
1011610424
10117 if (return_type->id == TypeTableEntryIdPureError || return_type->id == TypeTableEntryIdErrorUnion) {10425 if (return_type->id == TypeTableEntryIdErrorSet || return_type->id == TypeTableEntryIdErrorUnion) {
10118 parent_fn_entry->calls_errorable_function = true;10426 parent_fn_entry->calls_errorable_function = true;
10119 }10427 }
1012010428
...@@ -10124,7 +10432,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -10124,7 +10432,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
10124 FnTableEntry *parent_fn_entry = exec_fn_entry(ira->new_irb.exec);10432 FnTableEntry *parent_fn_entry = exec_fn_entry(ira->new_irb.exec);
10125 assert(fn_type_id->return_type != nullptr);10433 assert(fn_type_id->return_type != nullptr);
10126 assert(parent_fn_entry != nullptr);10434 assert(parent_fn_entry != nullptr);
10127 if (fn_type_id->return_type->id == TypeTableEntryIdPureError || fn_type_id->return_type->id == TypeTableEntryIdErrorUnion) {10435 if (fn_type_id->return_type->id == TypeTableEntryIdErrorSet || fn_type_id->return_type->id == TypeTableEntryIdErrorUnion) {
10128 parent_fn_entry->calls_errorable_function = true;10436 parent_fn_entry->calls_errorable_function = true;
10129 }10437 }
1013010438
...@@ -10243,58 +10551,6 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction...@@ -10243,58 +10551,6 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction
10243 }10551 }
10244}10552}
1024510553
10246static TypeTableEntry *ir_analyze_unary_prefix_op_err(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) {
10247 assert(un_op_instruction->op_id == IrUnOpError);
10248 IrInstruction *value = un_op_instruction->value->other;
10249
10250 TypeTableEntry *meta_type = ir_resolve_type(ira, value);
10251 if (type_is_invalid(meta_type))
10252 return ira->codegen->builtin_types.entry_invalid;
10253
10254
10255 switch (meta_type->id) {
10256 case TypeTableEntryIdInvalid: // handled above
10257 zig_unreachable();
10258
10259 case TypeTableEntryIdVoid:
10260 case TypeTableEntryIdBool:
10261 case TypeTableEntryIdInt:
10262 case TypeTableEntryIdFloat:
10263 case TypeTableEntryIdPointer:
10264 case TypeTableEntryIdArray:
10265 case TypeTableEntryIdStruct:
10266 case TypeTableEntryIdMaybe:
10267 case TypeTableEntryIdErrorUnion:
10268 case TypeTableEntryIdPureError:
10269 case TypeTableEntryIdEnum:
10270 case TypeTableEntryIdUnion:
10271 case TypeTableEntryIdFn:
10272 case TypeTableEntryIdBoundFn:
10273 {
10274 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base);
10275 TypeTableEntry *result_type = get_error_type(ira->codegen, meta_type);
10276 out_val->data.x_type = result_type;
10277 return ira->codegen->builtin_types.entry_type;
10278 }
10279 case TypeTableEntryIdMetaType:
10280 case TypeTableEntryIdNumLitFloat:
10281 case TypeTableEntryIdNumLitInt:
10282 case TypeTableEntryIdUndefLit:
10283 case TypeTableEntryIdNullLit:
10284 case TypeTableEntryIdNamespace:
10285 case TypeTableEntryIdBlock:
10286 case TypeTableEntryIdUnreachable:
10287 case TypeTableEntryIdVar:
10288 case TypeTableEntryIdArgTuple:
10289 case TypeTableEntryIdOpaque:
10290 ir_add_error_node(ira, un_op_instruction->base.source_node,
10291 buf_sprintf("unable to wrap type '%s' in error type", buf_ptr(&meta_type->name)));
10292 return ira->codegen->builtin_types.entry_invalid;
10293 }
10294 zig_unreachable();
10295}
10296
10297
10298static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) {10554static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) {
10299 IrInstruction *value = un_op_instruction->value->other;10555 IrInstruction *value = un_op_instruction->value->other;
1030010556
...@@ -10350,7 +10606,7 @@ static TypeTableEntry *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op...@@ -10350,7 +10606,7 @@ static TypeTableEntry *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op
10350 case TypeTableEntryIdNullLit:10606 case TypeTableEntryIdNullLit:
10351 case TypeTableEntryIdMaybe:10607 case TypeTableEntryIdMaybe:
10352 case TypeTableEntryIdErrorUnion:10608 case TypeTableEntryIdErrorUnion:
10353 case TypeTableEntryIdPureError:10609 case TypeTableEntryIdErrorSet:
10354 case TypeTableEntryIdEnum:10610 case TypeTableEntryIdEnum:
10355 case TypeTableEntryIdUnion:10611 case TypeTableEntryIdUnion:
10356 case TypeTableEntryIdFn:10612 case TypeTableEntryIdFn:
...@@ -10460,8 +10716,6 @@ static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructio...@@ -10460,8 +10716,6 @@ static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructio
10460 return ir_analyze_dereference(ira, un_op_instruction);10716 return ir_analyze_dereference(ira, un_op_instruction);
10461 case IrUnOpMaybe:10717 case IrUnOpMaybe:
10462 return ir_analyze_maybe(ira, un_op_instruction);10718 return ir_analyze_maybe(ira, un_op_instruction);
10463 case IrUnOpError:
10464 return ir_analyze_unary_prefix_op_err(ira, un_op_instruction);
10465 }10719 }
10466 zig_unreachable();10720 zig_unreachable();
10467}10721}
...@@ -11083,6 +11337,17 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source...@@ -11083,6 +11337,17 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source
11083 zig_unreachable();11337 zig_unreachable();
11084}11338}
1108511339
11340static ErrorTableEntry *find_err_table_entry(TypeTableEntry *err_set_type, Buf *field_name) {
11341 assert(err_set_type->id == TypeTableEntryIdErrorSet);
11342 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) {
11343 ErrorTableEntry *err_table_entry = err_set_type->data.error_set.errors[i];
11344 if (buf_eql_buf(&err_table_entry->name, field_name)) {
11345 return err_table_entry;
11346 }
11347 }
11348 return nullptr;
11349}
11350
11086static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstructionFieldPtr *field_ptr_instruction) {11351static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstructionFieldPtr *field_ptr_instruction) {
11087 IrInstruction *container_ptr = field_ptr_instruction->container_ptr->other;11352 IrInstruction *container_ptr = field_ptr_instruction->container_ptr->other;
11088 if (type_is_invalid(container_ptr->value.type))11353 if (type_is_invalid(container_ptr->value.type))
...@@ -11224,23 +11489,49 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -11224,23 +11489,49 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
11224 buf_sprintf("container '%s' has no member called '%s'",11489 buf_sprintf("container '%s' has no member called '%s'",
11225 buf_ptr(&child_type->name), buf_ptr(field_name)));11490 buf_ptr(&child_type->name), buf_ptr(field_name)));
11226 return ira->codegen->builtin_types.entry_invalid;11491 return ira->codegen->builtin_types.entry_invalid;
11227 } else if (child_type->id == TypeTableEntryIdPureError) {11492 } else if (child_type->id == TypeTableEntryIdErrorSet) {
11228 auto err_table_entry = ira->codegen->error_table.maybe_get(field_name);11493 ErrorTableEntry *err_entry;
11229 if (err_table_entry) {11494 TypeTableEntry *err_set_type;
11230 ConstExprValue *const_val = create_const_vals(1);11495 if (child_type == ira->codegen->builtin_types.entry_global_error_set) {
11231 const_val->special = ConstValSpecialStatic;11496 auto existing_entry = ira->codegen->error_table.maybe_get(field_name);
11232 const_val->type = child_type;11497 if (existing_entry) {
11233 const_val->data.x_pure_err = err_table_entry->value;11498 err_entry = existing_entry->value;
1123411499 } else {
11235 bool ptr_is_const = true;11500 err_entry = allocate<ErrorTableEntry>(1);
11236 bool ptr_is_volatile = false;11501 err_entry->decl_node = field_ptr_instruction->base.source_node;
11237 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, const_val,11502 buf_init_from_buf(&err_entry->name, field_name);
11238 child_type, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile);11503 size_t error_value_count = ira->codegen->errors_by_index.length;
11504 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)ira->codegen->err_tag_type->data.integral.bit_count));
11505 err_entry->value = error_value_count;
11506 ira->codegen->errors_by_index.append(err_entry);
11507 ira->codegen->err_enumerators.append(ZigLLVMCreateDebugEnumerator(ira->codegen->dbuilder,
11508 buf_ptr(field_name), error_value_count));
11509 ira->codegen->error_table.put(field_name, err_entry);
11510 }
11511 if (err_entry->set_with_only_this_in_it == nullptr) {
11512 err_entry->set_with_only_this_in_it = make_err_set_with_one_item(ira->codegen,
11513 field_ptr_instruction->base.scope, field_ptr_instruction->base.source_node,
11514 err_entry);
11515 }
11516 err_set_type = err_entry->set_with_only_this_in_it;
11517 } else {
11518 ErrorTableEntry *err_entry = find_err_table_entry(child_type, field_name);
11519 if (err_entry == nullptr) {
11520 ir_add_error(ira, &field_ptr_instruction->base,
11521 buf_sprintf("no error named '%s' in '%s'", buf_ptr(field_name), buf_ptr(&child_type->name)));
11522 return ira->codegen->builtin_types.entry_invalid;
11523 }
11524 err_set_type = child_type;
11239 }11525 }
11526 ConstExprValue *const_val = create_const_vals(1);
11527 const_val->special = ConstValSpecialStatic;
11528 const_val->type = err_set_type;
11529 const_val->data.x_err_set = err_entry;
1124011530
11241 ir_add_error(ira, &field_ptr_instruction->base,11531 bool ptr_is_const = true;
11242 buf_sprintf("use of undeclared error value '%s'", buf_ptr(field_name)));11532 bool ptr_is_volatile = false;
11243 return ira->codegen->builtin_types.entry_invalid;11533 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, const_val,
11534 err_set_type, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile);
11244 } else if (child_type->id == TypeTableEntryIdInt) {11535 } else if (child_type->id == TypeTableEntryIdInt) {
11245 if (buf_eql_str(field_name, "bit_count")) {11536 if (buf_eql_str(field_name, "bit_count")) {
11246 bool ptr_is_const = true;11537 bool ptr_is_const = true;
...@@ -11323,11 +11614,18 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -11323,11 +11614,18 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
11323 return ira->codegen->builtin_types.entry_invalid;11614 return ira->codegen->builtin_types.entry_invalid;
11324 }11615 }
11325 } else if (child_type->id == TypeTableEntryIdErrorUnion) {11616 } else if (child_type->id == TypeTableEntryIdErrorUnion) {
11326 if (buf_eql_str(field_name, "Child")) {11617 if (buf_eql_str(field_name, "Payload")) {
11618 bool ptr_is_const = true;
11619 bool ptr_is_volatile = false;
11620 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base,
11621 create_const_type(ira->codegen, child_type->data.error_union.payload_type),
11622 ira->codegen->builtin_types.entry_type,
11623 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile);
11624 } else if (buf_eql_str(field_name, "ErrorSet")) {
11327 bool ptr_is_const = true;11625 bool ptr_is_const = true;
11328 bool ptr_is_volatile = false;11626 bool ptr_is_volatile = false;
11329 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base,11627 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base,
11330 create_const_type(ira->codegen, child_type->data.error.child_type),11628 create_const_type(ira->codegen, child_type->data.error_union.err_set_type),
11331 ira->codegen->builtin_types.entry_type,11629 ira->codegen->builtin_types.entry_type,
11332 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile);11630 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile);
11333 } else {11631 } else {
...@@ -11514,7 +11812,7 @@ static TypeTableEntry *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructi...@@ -11514,7 +11812,7 @@ static TypeTableEntry *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructi
11514 case TypeTableEntryIdStruct:11812 case TypeTableEntryIdStruct:
11515 case TypeTableEntryIdMaybe:11813 case TypeTableEntryIdMaybe:
11516 case TypeTableEntryIdErrorUnion:11814 case TypeTableEntryIdErrorUnion:
11517 case TypeTableEntryIdPureError:11815 case TypeTableEntryIdErrorSet:
11518 case TypeTableEntryIdEnum:11816 case TypeTableEntryIdEnum:
11519 case TypeTableEntryIdUnion:11817 case TypeTableEntryIdUnion:
11520 case TypeTableEntryIdFn:11818 case TypeTableEntryIdFn:
...@@ -11781,7 +12079,7 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,...@@ -11781,7 +12079,7 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,
11781 case TypeTableEntryIdNumLitInt:12079 case TypeTableEntryIdNumLitInt:
11782 case TypeTableEntryIdMaybe:12080 case TypeTableEntryIdMaybe:
11783 case TypeTableEntryIdErrorUnion:12081 case TypeTableEntryIdErrorUnion:
11784 case TypeTableEntryIdPureError:12082 case TypeTableEntryIdErrorSet:
11785 case TypeTableEntryIdEnum:12083 case TypeTableEntryIdEnum:
11786 case TypeTableEntryIdUnion:12084 case TypeTableEntryIdUnion:
11787 case TypeTableEntryIdFn:12085 case TypeTableEntryIdFn:
...@@ -11889,7 +12187,7 @@ static TypeTableEntry *ir_analyze_instruction_array_type(IrAnalyze *ira,...@@ -11889,7 +12187,7 @@ static TypeTableEntry *ir_analyze_instruction_array_type(IrAnalyze *ira,
11889 case TypeTableEntryIdNumLitInt:12187 case TypeTableEntryIdNumLitInt:
11890 case TypeTableEntryIdMaybe:12188 case TypeTableEntryIdMaybe:
11891 case TypeTableEntryIdErrorUnion:12189 case TypeTableEntryIdErrorUnion:
11892 case TypeTableEntryIdPureError:12190 case TypeTableEntryIdErrorSet:
11893 case TypeTableEntryIdEnum:12191 case TypeTableEntryIdEnum:
11894 case TypeTableEntryIdUnion:12192 case TypeTableEntryIdUnion:
11895 case TypeTableEntryIdFn:12193 case TypeTableEntryIdFn:
...@@ -11942,7 +12240,7 @@ static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira,...@@ -11942,7 +12240,7 @@ static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira,
11942 case TypeTableEntryIdStruct:12240 case TypeTableEntryIdStruct:
11943 case TypeTableEntryIdMaybe:12241 case TypeTableEntryIdMaybe:
11944 case TypeTableEntryIdErrorUnion:12242 case TypeTableEntryIdErrorUnion:
11945 case TypeTableEntryIdPureError:12243 case TypeTableEntryIdErrorSet:
11946 case TypeTableEntryIdEnum:12244 case TypeTableEntryIdEnum:
11947 case TypeTableEntryIdUnion:12245 case TypeTableEntryIdUnion:
11948 case TypeTableEntryIdFn:12246 case TypeTableEntryIdFn:
...@@ -12277,7 +12575,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,...@@ -12277,7 +12575,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,
12277 case TypeTableEntryIdPointer:12575 case TypeTableEntryIdPointer:
12278 case TypeTableEntryIdFn:12576 case TypeTableEntryIdFn:
12279 case TypeTableEntryIdNamespace:12577 case TypeTableEntryIdNamespace:
12280 case TypeTableEntryIdPureError:12578 case TypeTableEntryIdErrorSet:
12281 if (pointee_val) {12579 if (pointee_val) {
12282 ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base);12580 ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base);
12283 copy_const_val(out_val, pointee_val, true);12581 copy_const_val(out_val, pointee_val, true);
...@@ -12347,8 +12645,6 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,...@@ -12347,8 +12645,6 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,
12347 return target_type;12645 return target_type;
12348 }12646 }
12349 case TypeTableEntryIdErrorUnion:12647 case TypeTableEntryIdErrorUnion:
12350 // see https://github.com/andrewrk/zig/issues/632
12351 zig_panic("TODO switch on error union");
12352 case TypeTableEntryIdUnreachable:12648 case TypeTableEntryIdUnreachable:
12353 case TypeTableEntryIdArray:12649 case TypeTableEntryIdArray:
12354 case TypeTableEntryIdStruct:12650 case TypeTableEntryIdStruct:
...@@ -12873,7 +13169,7 @@ static TypeTableEntry *ir_analyze_min_max(IrAnalyze *ira, IrInstruction *source_...@@ -12873,7 +13169,7 @@ static TypeTableEntry *ir_analyze_min_max(IrAnalyze *ira, IrInstruction *source_
12873 case TypeTableEntryIdNullLit:13169 case TypeTableEntryIdNullLit:
12874 case TypeTableEntryIdMaybe:13170 case TypeTableEntryIdMaybe:
12875 case TypeTableEntryIdErrorUnion:13171 case TypeTableEntryIdErrorUnion:
12876 case TypeTableEntryIdPureError:13172 case TypeTableEntryIdErrorSet:
12877 case TypeTableEntryIdUnion:13173 case TypeTableEntryIdUnion:
12878 case TypeTableEntryIdFn:13174 case TypeTableEntryIdFn:
12879 case TypeTableEntryIdNamespace:13175 case TypeTableEntryIdNamespace:
...@@ -12961,7 +13257,7 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc...@@ -12961,7 +13257,7 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc
12961 TypeTableEntry *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);13257 TypeTableEntry *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);
12962 TypeTableEntry *str_type = get_slice_type(ira->codegen, u8_ptr_type);13258 TypeTableEntry *str_type = get_slice_type(ira->codegen, u8_ptr_type);
12963 if (casted_value->value.special == ConstValSpecialStatic) {13259 if (casted_value->value.special == ConstValSpecialStatic) {
12964 ErrorTableEntry *err = casted_value->value.data.x_pure_err;13260 ErrorTableEntry *err = casted_value->value.data.x_err_set;
12965 if (!err->cached_error_name_val) {13261 if (!err->cached_error_name_val) {
12966 ConstExprValue *array_val = create_const_str_lit(ira->codegen, &err->name);13262 ConstExprValue *array_val = create_const_str_lit(ira->codegen, &err->name);
12967 err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true);13263 err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true);
...@@ -14106,7 +14402,7 @@ static TypeTableEntry *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruc...@@ -14106,7 +14402,7 @@ static TypeTableEntry *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruc
14106 case TypeTableEntryIdStruct:14402 case TypeTableEntryIdStruct:
14107 case TypeTableEntryIdMaybe:14403 case TypeTableEntryIdMaybe:
14108 case TypeTableEntryIdErrorUnion:14404 case TypeTableEntryIdErrorUnion:
14109 case TypeTableEntryIdPureError:14405 case TypeTableEntryIdErrorSet:
14110 case TypeTableEntryIdEnum:14406 case TypeTableEntryIdEnum:
14111 case TypeTableEntryIdUnion:14407 case TypeTableEntryIdUnion:
14112 case TypeTableEntryIdFn:14408 case TypeTableEntryIdFn:
...@@ -14239,7 +14535,7 @@ static TypeTableEntry *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruc...@@ -14239,7 +14535,7 @@ static TypeTableEntry *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruc
1423914535
14240 ir_build_test_err_from(&ira->new_irb, &instruction->base, value);14536 ir_build_test_err_from(&ira->new_irb, &instruction->base, value);
14241 return ira->codegen->builtin_types.entry_bool;14537 return ira->codegen->builtin_types.entry_bool;
14242 } else if (type_entry->id == TypeTableEntryIdPureError) {14538 } else if (type_entry->id == TypeTableEntryIdErrorSet) {
14243 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);14539 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
14244 out_val->data.x_bool = true;14540 out_val->data.x_bool = true;
14245 return ira->codegen->builtin_types.entry_bool;14541 return ira->codegen->builtin_types.entry_bool;
...@@ -14275,13 +14571,13 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira,...@@ -14275,13 +14571,13 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira,
14275 assert(err);14571 assert(err);
1427614572
14277 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);14573 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
14278 out_val->data.x_pure_err = err;14574 out_val->data.x_err_set = err;
14279 return ira->codegen->builtin_types.entry_pure_error;14575 return type_entry->data.error_union.err_set_type;
14280 }14576 }
14281 }14577 }
1428214578
14283 ir_build_unwrap_err_code_from(&ira->new_irb, &instruction->base, value);14579 ir_build_unwrap_err_code_from(&ira->new_irb, &instruction->base, value);
14284 return ira->codegen->builtin_types.entry_pure_error;14580 return type_entry->data.error_union.err_set_type;
14285 } else {14581 } else {
14286 ir_add_error(ira, value,14582 ir_add_error(ira, value,
14287 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name)));14583 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name)));
...@@ -14305,10 +14601,10 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,...@@ -14305,10 +14601,10 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
14305 if (type_is_invalid(type_entry)) {14601 if (type_is_invalid(type_entry)) {
14306 return ira->codegen->builtin_types.entry_invalid;14602 return ira->codegen->builtin_types.entry_invalid;
14307 } else if (type_entry->id == TypeTableEntryIdErrorUnion) {14603 } else if (type_entry->id == TypeTableEntryIdErrorUnion) {
14308 TypeTableEntry *child_type = type_entry->data.error.child_type;14604 TypeTableEntry *payload_type = type_entry->data.error_union.payload_type;
14309 TypeTableEntry *result_type = get_pointer_to_type_extra(ira->codegen, child_type,14605 TypeTableEntry *result_type = get_pointer_to_type_extra(ira->codegen, payload_type,
14310 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,14606 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
14311 get_abi_alignment(ira->codegen, child_type), 0, 0);14607 get_abi_alignment(ira->codegen, payload_type), 0, 0);
14312 if (instr_is_comptime(value)) {14608 if (instr_is_comptime(value)) {
14313 ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad);14609 ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad);
14314 if (!ptr_val)14610 if (!ptr_val)
...@@ -14343,6 +14639,12 @@ static TypeTableEntry *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruc...@@ -14343,6 +14639,12 @@ static TypeTableEntry *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruc
14343 AstNode *proto_node = instruction->base.source_node;14639 AstNode *proto_node = instruction->base.source_node;
14344 assert(proto_node->type == NodeTypeFnProto);14640 assert(proto_node->type == NodeTypeFnProto);
1434514641
14642 if (proto_node->data.fn_proto.auto_err_set) {
14643 ir_add_error(ira, &instruction->base,
14644 buf_sprintf("inferring error set of return type valid only for function definitions"));
14645 return ira->codegen->builtin_types.entry_invalid;
14646 }
14647
14346 FnTypeId fn_type_id = {0};14648 FnTypeId fn_type_id = {0};
14347 init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length);14649 init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length);
1434814650
...@@ -14468,6 +14770,71 @@ static TypeTableEntry *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira...@@ -14468,6 +14770,71 @@ static TypeTableEntry *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira
14468 }14770 }
14469 }14771 }
14470 }14772 }
14773 } else if (switch_type->id == TypeTableEntryIdErrorSet) {
14774 FnTableEntry *infer_fn = switch_type->data.error_set.infer_fn;
14775 if (infer_fn != nullptr) {
14776 if (infer_fn->anal_state == FnAnalStateInvalid) {
14777 return ira->codegen->builtin_types.entry_invalid;
14778 } else if (infer_fn->anal_state == FnAnalStateReady) {
14779 analyze_fn_body(ira->codegen, infer_fn);
14780 if (switch_type->data.error_set.infer_fn != nullptr) {
14781 assert(ira->codegen->errors.length != 0);
14782 return ira->codegen->builtin_types.entry_invalid;
14783 }
14784 } else {
14785 ir_add_error(ira, &instruction->base,
14786 buf_sprintf("cannot switch on inferred error set '%s': function '%s' not fully analyzed yet",
14787 buf_ptr(&switch_type->name), buf_ptr(&switch_type->data.error_set.infer_fn->symbol_name)));
14788 return ira->codegen->builtin_types.entry_invalid;
14789 }
14790 }
14791
14792 AstNode **field_prev_uses = allocate<AstNode *>(ira->codegen->errors_by_index.length);
14793
14794 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) {
14795 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i];
14796
14797 IrInstruction *start_value = range->start->other;
14798 if (type_is_invalid(start_value->value.type))
14799 return ira->codegen->builtin_types.entry_invalid;
14800
14801 IrInstruction *end_value = range->end->other;
14802 if (type_is_invalid(end_value->value.type))
14803 return ira->codegen->builtin_types.entry_invalid;
14804
14805 assert(start_value->value.type->id == TypeTableEntryIdErrorSet);
14806 uint32_t start_index = start_value->value.data.x_err_set->value;
14807
14808 assert(end_value->value.type->id == TypeTableEntryIdErrorSet);
14809 uint32_t end_index = end_value->value.data.x_err_set->value;
14810
14811 if (start_index != end_index) {
14812 ir_add_error(ira, end_value, buf_sprintf("ranges not allowed when switching on errors"));
14813 return ira->codegen->builtin_types.entry_invalid;
14814 }
14815
14816 AstNode *prev_node = field_prev_uses[start_index];
14817 if (prev_node != nullptr) {
14818 Buf *err_name = &ira->codegen->errors_by_index.at(start_index)->name;
14819 ErrorMsg *msg = ir_add_error(ira, start_value,
14820 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), buf_ptr(err_name)));
14821 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here"));
14822 }
14823 field_prev_uses[start_index] = start_value->source_node;
14824 }
14825 if (!instruction->have_else_prong) {
14826 for (uint32_t i = 0; i < switch_type->data.error_set.err_count; i += 1) {
14827 ErrorTableEntry *err_entry = switch_type->data.error_set.errors[i];
14828
14829 AstNode *prev_node = field_prev_uses[err_entry->value];
14830 if (prev_node == nullptr) {
14831 ir_add_error(ira, &instruction->base,
14832 buf_sprintf("error.%s not handled in switch", buf_ptr(&err_entry->name)));
14833 }
14834 }
14835 }
14836
14837 free(field_prev_uses);
14471 } else if (switch_type->id == TypeTableEntryIdInt) {14838 } else if (switch_type->id == TypeTableEntryIdInt) {
14472 RangeSet rs = {0};14839 RangeSet rs = {0};
14473 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) {14840 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) {
...@@ -14760,7 +15127,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue...@@ -14760,7 +15127,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
14760 zig_panic("TODO buf_write_value_bytes maybe type");15127 zig_panic("TODO buf_write_value_bytes maybe type");
14761 case TypeTableEntryIdErrorUnion:15128 case TypeTableEntryIdErrorUnion:
14762 zig_panic("TODO buf_write_value_bytes error union");15129 zig_panic("TODO buf_write_value_bytes error union");
14763 case TypeTableEntryIdPureError:15130 case TypeTableEntryIdErrorSet:
14764 zig_panic("TODO buf_write_value_bytes pure error type");15131 zig_panic("TODO buf_write_value_bytes pure error type");
14765 case TypeTableEntryIdEnum:15132 case TypeTableEntryIdEnum:
14766 zig_panic("TODO buf_write_value_bytes enum type");15133 zig_panic("TODO buf_write_value_bytes enum type");
...@@ -14818,7 +15185,7 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue...@@ -14818,7 +15185,7 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
14818 zig_panic("TODO buf_read_value_bytes maybe type");15185 zig_panic("TODO buf_read_value_bytes maybe type");
14819 case TypeTableEntryIdErrorUnion:15186 case TypeTableEntryIdErrorUnion:
14820 zig_panic("TODO buf_read_value_bytes error union");15187 zig_panic("TODO buf_read_value_bytes error union");
14821 case TypeTableEntryIdPureError:15188 case TypeTableEntryIdErrorSet:
14822 zig_panic("TODO buf_read_value_bytes pure error type");15189 zig_panic("TODO buf_read_value_bytes pure error type");
14823 case TypeTableEntryIdEnum:15190 case TypeTableEntryIdEnum:
14824 zig_panic("TODO buf_read_value_bytes enum type");15191 zig_panic("TODO buf_read_value_bytes enum type");
...@@ -15429,6 +15796,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi...@@ -15429,6 +15796,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
15429 return ir_analyze_instruction_export(ira, (IrInstructionExport *)instruction);15796 return ir_analyze_instruction_export(ira, (IrInstructionExport *)instruction);
15430 case IrInstructionIdErrorReturnTrace:15797 case IrInstructionIdErrorReturnTrace:
15431 return ir_analyze_instruction_error_return_trace(ira, (IrInstructionErrorReturnTrace *)instruction);15798 return ir_analyze_instruction_error_return_trace(ira, (IrInstructionErrorReturnTrace *)instruction);
15799 case IrInstructionIdErrorUnion:
15800 return ir_analyze_instruction_error_union(ira, (IrInstructionErrorUnion *)instruction);
15432 }15801 }
15433 zig_unreachable();15802 zig_unreachable();
15434}15803}
...@@ -15614,6 +15983,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -15614,6 +15983,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
15614 case IrInstructionIdArgType:15983 case IrInstructionIdArgType:
15615 case IrInstructionIdTagType:15984 case IrInstructionIdTagType:
15616 case IrInstructionIdErrorReturnTrace:15985 case IrInstructionIdErrorReturnTrace:
15986 case IrInstructionIdErrorUnion:
15617 return false;15987 return false;
15618 case IrInstructionIdAsm:15988 case IrInstructionIdAsm:
15619 {15989 {
src/ir_print.cpp+8-2
...@@ -148,8 +148,6 @@ static const char *ir_un_op_id_str(IrUnOp op_id) {...@@ -148,8 +148,6 @@ static const char *ir_un_op_id_str(IrUnOp op_id) {
148 return "*";148 return "*";
149 case IrUnOpMaybe:149 case IrUnOpMaybe:
150 return "?";150 return "?";
151 case IrUnOpError:
152 return "%";
153 }151 }
154 zig_unreachable();152 zig_unreachable();
155}153}
...@@ -1004,6 +1002,11 @@ static void ir_print_error_return_trace(IrPrint *irp, IrInstructionErrorReturnTr...@@ -1004,6 +1002,11 @@ static void ir_print_error_return_trace(IrPrint *irp, IrInstructionErrorReturnTr
1004 fprintf(irp->f, "@errorReturnTrace()");1002 fprintf(irp->f, "@errorReturnTrace()");
1005}1003}
10061004
1005static void ir_print_error_union(IrPrint *irp, IrInstructionErrorUnion *instruction) {
1006 ir_print_other_instruction(irp, instruction->err_set);
1007 fprintf(irp->f, "!");
1008 ir_print_other_instruction(irp, instruction->payload);
1009}
10071010
1008static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {1011static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1009 ir_print_prefix(irp, instruction);1012 ir_print_prefix(irp, instruction);
...@@ -1322,6 +1325,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1322,6 +1325,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1322 case IrInstructionIdErrorReturnTrace:1325 case IrInstructionIdErrorReturnTrace:
1323 ir_print_error_return_trace(irp, (IrInstructionErrorReturnTrace *)instruction);1326 ir_print_error_return_trace(irp, (IrInstructionErrorReturnTrace *)instruction);
1324 break;1327 break;
1328 case IrInstructionIdErrorUnion:
1329 ir_print_error_union(irp, (IrInstructionErrorUnion *)instruction);
1330 break;
1325 }1331 }
1326 fprintf(irp->f, "\n");1332 fprintf(irp->f, "\n");
1327}1333}
src/parser.cpp+50-37
...@@ -221,6 +221,7 @@ static AstNode *ast_parse_grouped_expr(ParseContext *pc, size_t *token_index, bo...@@ -221,6 +221,7 @@ static AstNode *ast_parse_grouped_expr(ParseContext *pc, size_t *token_index, bo
221static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory);221static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory);
222static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory);222static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory);
223static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index);223static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index);
224static AstNode *ast_parse_symbol(ParseContext *pc, size_t *token_index);
224225
225static void ast_expect_token(ParseContext *pc, Token *token, TokenId token_id) {226static void ast_expect_token(ParseContext *pc, Token *token, TokenId token_id) {
226 if (token->id == token_id) {227 if (token->id == token_id) {
...@@ -651,8 +652,9 @@ static AstNode *ast_parse_comptime_expr(ParseContext *pc, size_t *token_index, b...@@ -651,8 +652,9 @@ static AstNode *ast_parse_comptime_expr(ParseContext *pc, size_t *token_index, b
651}652}
652653
653/*654/*
654PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." Symbol) | ContainerDecl | ("continue" option(":" Symbol))655PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ContainerDecl | ("continue" option(":" Symbol)) | ErrorSetDecl
655KeywordLiteral = "true" | "false" | "null" | "undefined" | "error" | "this" | "unreachable"656KeywordLiteral = "true" | "false" | "null" | "undefined" | "error" | "this" | "unreachable"
657ErrorSetDecl = "error" "{" list(Symbol, ",") "}"
656*/658*/
657static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory) {659static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
658 Token *token = &pc->tokens->at(*token_index);660 Token *token = &pc->tokens->at(*token_index);
...@@ -716,9 +718,31 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo...@@ -716,9 +718,31 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo
716 *token_index += 1;718 *token_index += 1;
717 return node;719 return node;
718 } else if (token->id == TokenIdKeywordError) {720 } else if (token->id == TokenIdKeywordError) {
719 AstNode *node = ast_create_node(pc, NodeTypeErrorType, token);721 Token *next_token = &pc->tokens->at(*token_index + 1);
720 *token_index += 1;722 if (next_token->id == TokenIdLBrace) {
721 return node;723 AstNode *node = ast_create_node(pc, NodeTypeErrorSetDecl, token);
724 *token_index += 2;
725 for (;;) {
726 Token *item_tok = &pc->tokens->at(*token_index);
727 if (item_tok->id == TokenIdRBrace) {
728 *token_index += 1;
729 return node;
730 } else if (item_tok->id == TokenIdSymbol) {
731 AstNode *symbol_node = ast_parse_symbol(pc, token_index);
732 node->data.err_set_decl.decls.append(symbol_node);
733 Token *opt_comma_tok = &pc->tokens->at(*token_index);
734 if (opt_comma_tok->id == TokenIdComma) {
735 *token_index += 1;
736 }
737 } else {
738 ast_invalid_token_error(pc, item_tok);
739 }
740 }
741 } else {
742 AstNode *node = ast_create_node(pc, NodeTypeErrorType, token);
743 *token_index += 1;
744 return node;
745 }
722 } else if (token->id == TokenIdAtSign) {746 } else if (token->id == TokenIdAtSign) {
723 *token_index += 1;747 *token_index += 1;
724 Token *name_tok = &pc->tokens->at(*token_index);748 Token *name_tok = &pc->tokens->at(*token_index);
...@@ -950,7 +974,6 @@ static PrefixOp tok_to_prefix_op(Token *token) {...@@ -950,7 +974,6 @@ static PrefixOp tok_to_prefix_op(Token *token) {
950 case TokenIdTilde: return PrefixOpBinNot;974 case TokenIdTilde: return PrefixOpBinNot;
951 case TokenIdStar: return PrefixOpDereference;975 case TokenIdStar: return PrefixOpDereference;
952 case TokenIdMaybe: return PrefixOpMaybe;976 case TokenIdMaybe: return PrefixOpMaybe;
953 case TokenIdPercent: return PrefixOpError;
954 case TokenIdDoubleQuestion: return PrefixOpUnwrapMaybe;977 case TokenIdDoubleQuestion: return PrefixOpUnwrapMaybe;
955 case TokenIdStarStar: return PrefixOpDereference;978 case TokenIdStarStar: return PrefixOpDereference;
956 default: return PrefixOpInvalid;979 default: return PrefixOpInvalid;
...@@ -998,7 +1021,7 @@ static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) {...@@ -998,7 +1021,7 @@ static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) {
9981021
999/*1022/*
1000PrefixOpExpression : PrefixOp PrefixOpExpression | SuffixOpExpression1023PrefixOpExpression : PrefixOp PrefixOpExpression | SuffixOpExpression
1001PrefixOp = "!" | "-" | "~" | "*" | ("&amp;" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%" | "try"1024PrefixOp = "!" | "-" | "~" | "*" | ("&" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "??" | "-%" | "try"
1002*/1025*/
1003static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {1026static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
1004 Token *token = &pc->tokens->at(*token_index);1027 Token *token = &pc->tokens->at(*token_index);
...@@ -1043,12 +1066,13 @@ static BinOpType tok_to_mult_op(Token *token) {...@@ -1043,12 +1066,13 @@ static BinOpType tok_to_mult_op(Token *token) {
1043 case TokenIdStarStar: return BinOpTypeArrayMult;1066 case TokenIdStarStar: return BinOpTypeArrayMult;
1044 case TokenIdSlash: return BinOpTypeDiv;1067 case TokenIdSlash: return BinOpTypeDiv;
1045 case TokenIdPercent: return BinOpTypeMod;1068 case TokenIdPercent: return BinOpTypeMod;
1069 case TokenIdBang: return BinOpTypeErrorUnion;
1046 default: return BinOpTypeInvalid;1070 default: return BinOpTypeInvalid;
1047 }1071 }
1048}1072}
10491073
1050/*1074/*
1051MultiplyOperator = "*" | "/" | "%" | "**" | "*%"1075MultiplyOperator = "!" | "*" | "/" | "%" | "**" | "*%"
1052*/1076*/
1053static BinOpType ast_parse_mult_op(ParseContext *pc, size_t *token_index, bool mandatory) {1077static BinOpType ast_parse_mult_op(ParseContext *pc, size_t *token_index, bool mandatory) {
1054 Token *token = &pc->tokens->at(*token_index);1078 Token *token = &pc->tokens->at(*token_index);
...@@ -2240,7 +2264,7 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand...@@ -2240,7 +2264,7 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand
2240}2264}
22412265
2242/*2266/*
2243FnProto = option("nakedcc" | "stdcallcc" | "extern") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") TypeExpr2267FnProto = option("nakedcc" | "stdcallcc" | "extern") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("!") TypeExpr
2244*/2268*/
2245static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {2269static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {
2246 Token *first_token = &pc->tokens->at(*token_index);2270 Token *first_token = &pc->tokens->at(*token_index);
...@@ -2315,6 +2339,21 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m...@@ -2315,6 +2339,21 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
2315 ast_eat_token(pc, token_index, TokenIdRParen);2339 ast_eat_token(pc, token_index, TokenIdRParen);
2316 next_token = &pc->tokens->at(*token_index);2340 next_token = &pc->tokens->at(*token_index);
2317 }2341 }
2342 if (next_token->id == TokenIdKeywordError) {
2343 Token *maybe_lbrace_tok = &pc->tokens->at(*token_index + 1);
2344 if (maybe_lbrace_tok->id == TokenIdLBrace) {
2345 *token_index += 1;
2346 node->data.fn_proto.return_type = ast_create_node(pc, NodeTypeErrorType, next_token);
2347 return node;
2348 }
2349
2350 return node;
2351 }
2352 if (next_token->id == TokenIdBang) {
2353 *token_index += 1;
2354 node->data.fn_proto.auto_err_set = true;
2355 next_token = &pc->tokens->at(*token_index);
2356 }
2318 node->data.fn_proto.return_type = ast_parse_type_expr(pc, token_index, true);2357 node->data.fn_proto.return_type = ast_parse_type_expr(pc, token_index, true);
23192358
2320 return node;2359 return node;
...@@ -2559,26 +2598,6 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,...@@ -2559,26 +2598,6 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
2559 return node;2598 return node;
2560}2599}
25612600
2562/*
2563ErrorValueDecl : "error" "Symbol" ";"
2564*/
2565static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index) {
2566 Token *first_token = &pc->tokens->at(*token_index);
2567
2568 if (first_token->id != TokenIdKeywordError) {
2569 return nullptr;
2570 }
2571 *token_index += 1;
2572
2573 Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol);
2574 ast_eat_token(pc, token_index, TokenIdSemicolon);
2575
2576 AstNode *node = ast_create_node(pc, NodeTypeErrorValueDecl, first_token);
2577 node->data.error_value_decl.name = token_buf(name_tok);
2578
2579 return node;
2580}
2581
2582/*2601/*
2583TestDecl = "test" String Block2602TestDecl = "test" String Block
2584*/2603*/
...@@ -2611,12 +2630,6 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig...@@ -2611,12 +2630,6 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig
2611 continue;2630 continue;
2612 }2631 }
26132632
2614 AstNode *error_value_node = ast_parse_error_value_decl(pc, token_index);
2615 if (error_value_node) {
2616 top_level_decls->append(error_value_node);
2617 continue;
2618 }
2619
2620 AstNode *test_decl_node = ast_parse_test_decl_node(pc, token_index);2633 AstNode *test_decl_node = ast_parse_test_decl_node(pc, token_index);
2621 if (test_decl_node) {2634 if (test_decl_node) {
2622 top_level_decls->append(test_decl_node);2635 top_level_decls->append(test_decl_node);
...@@ -2744,9 +2757,6 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont...@@ -2744,9 +2757,6 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
2744 visit_field(&node->data.variable_declaration.align_expr, visit, context);2757 visit_field(&node->data.variable_declaration.align_expr, visit, context);
2745 visit_field(&node->data.variable_declaration.section_expr, visit, context);2758 visit_field(&node->data.variable_declaration.section_expr, visit, context);
2746 break;2759 break;
2747 case NodeTypeErrorValueDecl:
2748 // none
2749 break;
2750 case NodeTypeTestDecl:2760 case NodeTypeTestDecl:
2751 visit_field(&node->data.test_decl.body, visit, context);2761 visit_field(&node->data.test_decl.body, visit, context);
2752 break;2762 break;
...@@ -2899,5 +2909,8 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont...@@ -2899,5 +2909,8 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
2899 visit_field(&node->data.addr_of_expr.align_expr, visit, context);2909 visit_field(&node->data.addr_of_expr.align_expr, visit, context);
2900 visit_field(&node->data.addr_of_expr.op_expr, visit, context);2910 visit_field(&node->data.addr_of_expr.op_expr, visit, context);
2901 break;2911 break;
2912 case NodeTypeErrorSetDecl:
2913 visit_node_list(&node->data.err_set_decl.decls, visit, context);
2914 break;
2902 }2915 }
2903}2916}
src/zig_llvm.cpp+4
...@@ -437,6 +437,10 @@ unsigned ZigLLVMTag_DW_structure_type(void) {...@@ -437,6 +437,10 @@ unsigned ZigLLVMTag_DW_structure_type(void) {
437 return dwarf::DW_TAG_structure_type;437 return dwarf::DW_TAG_structure_type;
438}438}
439439
440unsigned ZigLLVMTag_DW_enumeration_type(void) {
441 return dwarf::DW_TAG_enumeration_type;
442}
443
440unsigned ZigLLVMTag_DW_union_type(void) {444unsigned ZigLLVMTag_DW_union_type(void) {
441 return dwarf::DW_TAG_union_type;445 return dwarf::DW_TAG_union_type;
442}446}
src/zig_llvm.h+1
...@@ -133,6 +133,7 @@ ZIG_EXTERN_C unsigned ZigLLVMEncoding_DW_ATE_signed_char(void);...@@ -133,6 +133,7 @@ ZIG_EXTERN_C unsigned ZigLLVMEncoding_DW_ATE_signed_char(void);
133ZIG_EXTERN_C unsigned ZigLLVMLang_DW_LANG_C99(void);133ZIG_EXTERN_C unsigned ZigLLVMLang_DW_LANG_C99(void);
134ZIG_EXTERN_C unsigned ZigLLVMTag_DW_variable(void);134ZIG_EXTERN_C unsigned ZigLLVMTag_DW_variable(void);
135ZIG_EXTERN_C unsigned ZigLLVMTag_DW_structure_type(void);135ZIG_EXTERN_C unsigned ZigLLVMTag_DW_structure_type(void);
136ZIG_EXTERN_C unsigned ZigLLVMTag_DW_enumeration_type(void);
136ZIG_EXTERN_C unsigned ZigLLVMTag_DW_union_type(void);137ZIG_EXTERN_C unsigned ZigLLVMTag_DW_union_type(void);
137138
138ZIG_EXTERN_C struct ZigLLVMDIBuilder *ZigLLVMCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved);139ZIG_EXTERN_C struct ZigLLVMDIBuilder *ZigLLVMCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved);
std/debug/index.zig+34-46
...@@ -10,15 +10,6 @@ const builtin = @import("builtin");...@@ -10,15 +10,6 @@ const builtin = @import("builtin");
1010
11pub const FailingAllocator = @import("failing_allocator.zig").FailingAllocator;11pub const FailingAllocator = @import("failing_allocator.zig").FailingAllocator;
1212
13error MissingDebugInfo;
14error InvalidDebugInfo;
15error UnsupportedDebugInfo;
16error UnknownObjectFormat;
17error TodoSupportCoffDebugInfo;
18error TodoSupportMachoDebugInfo;
19error TodoSupportCOFFDebugInfo;
20
21
22/// Tries to write to stderr, unbuffered, and ignores any error returned.13/// Tries to write to stderr, unbuffered, and ignores any error returned.
23/// Does not append a newline.14/// Does not append a newline.
24/// TODO atomic/multithread support15/// TODO atomic/multithread support
...@@ -29,7 +20,7 @@ pub fn warn(comptime fmt: []const u8, args: ...) void {...@@ -29,7 +20,7 @@ pub fn warn(comptime fmt: []const u8, args: ...) void {
29 const stderr = getStderrStream() catch return;20 const stderr = getStderrStream() catch return;
30 stderr.print(fmt, args) catch return;21 stderr.print(fmt, args) catch return;
31}22}
32fn getStderrStream() %&io.OutStream {23fn getStderrStream() !&io.OutStream {
33 if (stderr_stream) |st| {24 if (stderr_stream) |st| {
34 return st;25 return st;
35 } else {26 } else {
...@@ -42,7 +33,7 @@ fn getStderrStream() %&io.OutStream {...@@ -42,7 +33,7 @@ fn getStderrStream() %&io.OutStream {
42}33}
4334
44var self_debug_info: ?&ElfStackTrace = null;35var self_debug_info: ?&ElfStackTrace = null;
45pub fn getSelfDebugInfo() %&ElfStackTrace {36pub fn getSelfDebugInfo() !&ElfStackTrace {
46 if (self_debug_info) |info| {37 if (self_debug_info) |info| {
47 return info;38 return info;
48 } else {39 } else {
...@@ -149,11 +140,8 @@ const WHITE = "\x1b[37;1m";...@@ -149,11 +140,8 @@ const WHITE = "\x1b[37;1m";
149const DIM = "\x1b[2m";140const DIM = "\x1b[2m";
150const RESET = "\x1b[0m";141const RESET = "\x1b[0m";
151142
152error PathNotFound;
153error InvalidDebugInfo;
154
155pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: &io.OutStream, allocator: &mem.Allocator,143pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: &io.OutStream, allocator: &mem.Allocator,
156 debug_info: &ElfStackTrace, tty_color: bool) %void144 debug_info: &ElfStackTrace, tty_color: bool) !void
157{145{
158 var frame_index: usize = undefined;146 var frame_index: usize = undefined;
159 var frames_left: usize = undefined;147 var frames_left: usize = undefined;
...@@ -175,7 +163,7 @@ pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: &io.O...@@ -175,7 +163,7 @@ pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: &io.O
175}163}
176164
177pub fn writeCurrentStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator,165pub fn writeCurrentStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator,
178 debug_info: &ElfStackTrace, tty_color: bool, ignore_frame_count: usize) %void166 debug_info: &ElfStackTrace, tty_color: bool, ignore_frame_count: usize) !void
179{167{
180 var ignored_count: usize = 0;168 var ignored_count: usize = 0;
181169
...@@ -191,7 +179,7 @@ pub fn writeCurrentStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocat...@@ -191,7 +179,7 @@ pub fn writeCurrentStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocat
191 }179 }
192}180}
193181
194fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: &io.OutStream, address: usize) %void {182fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: &io.OutStream, address: usize) !void {
195 if (builtin.os == builtin.Os.windows) {183 if (builtin.os == builtin.Os.windows) {
196 return error.UnsupportedDebugInfo;184 return error.UnsupportedDebugInfo;
197 }185 }
...@@ -232,7 +220,7 @@ fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: &io.OutStream, a...@@ -232,7 +220,7 @@ fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: &io.OutStream, a
232 }220 }
233}221}
234222
235pub fn openSelfDebugInfo(allocator: &mem.Allocator) %&ElfStackTrace {223pub fn openSelfDebugInfo(allocator: &mem.Allocator) !&ElfStackTrace {
236 switch (builtin.object_format) {224 switch (builtin.object_format) {
237 builtin.ObjectFormat.elf => {225 builtin.ObjectFormat.elf => {
238 const st = try allocator.create(ElfStackTrace);226 const st = try allocator.create(ElfStackTrace);
...@@ -276,7 +264,7 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) %&ElfStackTrace {...@@ -276,7 +264,7 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) %&ElfStackTrace {
276 }264 }
277}265}
278266
279fn printLineFromFile(allocator: &mem.Allocator, out_stream: &io.OutStream, line_info: &const LineInfo) %void {267fn printLineFromFile(allocator: &mem.Allocator, out_stream: &io.OutStream, line_info: &const LineInfo) !void {
280 var f = try io.File.openRead(line_info.file_name, allocator);268 var f = try io.File.openRead(line_info.file_name, allocator);
281 defer f.close();269 defer f.close();
282 // TODO fstat and make sure that the file has the correct size270 // TODO fstat and make sure that the file has the correct size
...@@ -324,7 +312,7 @@ pub const ElfStackTrace = struct {...@@ -324,7 +312,7 @@ pub const ElfStackTrace = struct {
324 return self.abbrev_table_list.allocator;312 return self.abbrev_table_list.allocator;
325 }313 }
326314
327 pub fn readString(self: &ElfStackTrace) %[]u8 {315 pub fn readString(self: &ElfStackTrace) ![]u8 {
328 var in_file_stream = io.FileInStream.init(&self.self_exe_file);316 var in_file_stream = io.FileInStream.init(&self.self_exe_file);
329 const in_stream = &in_file_stream.stream;317 const in_stream = &in_file_stream.stream;
330 return readStringRaw(self.allocator(), in_stream);318 return readStringRaw(self.allocator(), in_stream);
...@@ -387,7 +375,7 @@ const Constant = struct {...@@ -387,7 +375,7 @@ const Constant = struct {
387 payload: []u8,375 payload: []u8,
388 signed: bool,376 signed: bool,
389377
390 fn asUnsignedLe(self: &const Constant) %u64 {378 fn asUnsignedLe(self: &const Constant) !u64 {
391 if (self.payload.len > @sizeOf(u64))379 if (self.payload.len > @sizeOf(u64))
392 return error.InvalidDebugInfo;380 return error.InvalidDebugInfo;
393 if (self.signed)381 if (self.signed)
...@@ -414,7 +402,7 @@ const Die = struct {...@@ -414,7 +402,7 @@ const Die = struct {
414 return null;402 return null;
415 }403 }
416404
417 fn getAttrAddr(self: &const Die, id: u64) %u64 {405 fn getAttrAddr(self: &const Die, id: u64) !u64 {
418 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;406 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
419 return switch (*form_value) {407 return switch (*form_value) {
420 FormValue.Address => |value| value,408 FormValue.Address => |value| value,
...@@ -422,7 +410,7 @@ const Die = struct {...@@ -422,7 +410,7 @@ const Die = struct {
422 };410 };
423 }411 }
424412
425 fn getAttrSecOffset(self: &const Die, id: u64) %u64 {413 fn getAttrSecOffset(self: &const Die, id: u64) !u64 {
426 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;414 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
427 return switch (*form_value) {415 return switch (*form_value) {
428 FormValue.Const => |value| value.asUnsignedLe(),416 FormValue.Const => |value| value.asUnsignedLe(),
...@@ -431,7 +419,7 @@ const Die = struct {...@@ -431,7 +419,7 @@ const Die = struct {
431 };419 };
432 }420 }
433421
434 fn getAttrUnsignedLe(self: &const Die, id: u64) %u64 {422 fn getAttrUnsignedLe(self: &const Die, id: u64) !u64 {
435 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;423 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
436 return switch (*form_value) {424 return switch (*form_value) {
437 FormValue.Const => |value| value.asUnsignedLe(),425 FormValue.Const => |value| value.asUnsignedLe(),
...@@ -439,7 +427,7 @@ const Die = struct {...@@ -439,7 +427,7 @@ const Die = struct {
439 };427 };
440 }428 }
441429
442 fn getAttrString(self: &const Die, st: &ElfStackTrace, id: u64) %[]u8 {430 fn getAttrString(self: &const Die, st: &ElfStackTrace, id: u64) ![]u8 {
443 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;431 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
444 return switch (*form_value) {432 return switch (*form_value) {
445 FormValue.String => |value| value,433 FormValue.String => |value| value,
...@@ -512,7 +500,7 @@ const LineNumberProgram = struct {...@@ -512,7 +500,7 @@ const LineNumberProgram = struct {
512 };500 };
513 }501 }
514502
515 pub fn checkLineMatch(self: &LineNumberProgram) %?LineInfo {503 pub fn checkLineMatch(self: &LineNumberProgram) !?LineInfo {
516 if (self.target_address >= self.prev_address and self.target_address < self.address) {504 if (self.target_address >= self.prev_address and self.target_address < self.address) {
517 const file_entry = if (self.prev_file == 0) {505 const file_entry = if (self.prev_file == 0) {
518 return error.MissingDebugInfo;506 return error.MissingDebugInfo;
...@@ -544,7 +532,7 @@ const LineNumberProgram = struct {...@@ -544,7 +532,7 @@ const LineNumberProgram = struct {
544 }532 }
545};533};
546534
547fn readStringRaw(allocator: &mem.Allocator, in_stream: &io.InStream) %[]u8 {535fn readStringRaw(allocator: &mem.Allocator, in_stream: &io.InStream) ![]u8 {
548 var buf = ArrayList(u8).init(allocator);536 var buf = ArrayList(u8).init(allocator);
549 while (true) {537 while (true) {
550 const byte = try in_stream.readByte();538 const byte = try in_stream.readByte();
...@@ -555,58 +543,58 @@ fn readStringRaw(allocator: &mem.Allocator, in_stream: &io.InStream) %[]u8 {...@@ -555,58 +543,58 @@ fn readStringRaw(allocator: &mem.Allocator, in_stream: &io.InStream) %[]u8 {
555 return buf.toSlice();543 return buf.toSlice();
556}544}
557545
558fn getString(st: &ElfStackTrace, offset: u64) %[]u8 {546fn getString(st: &ElfStackTrace, offset: u64) ![]u8 {
559 const pos = st.debug_str.offset + offset;547 const pos = st.debug_str.offset + offset;
560 try st.self_exe_file.seekTo(pos);548 try st.self_exe_file.seekTo(pos);
561 return st.readString();549 return st.readString();
562}550}
563551
564fn readAllocBytes(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) %[]u8 {552fn readAllocBytes(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) ![]u8 {
565 const buf = try global_allocator.alloc(u8, size);553 const buf = try global_allocator.alloc(u8, size);
566 errdefer global_allocator.free(buf);554 errdefer global_allocator.free(buf);
567 if ((try in_stream.read(buf)) < size) return error.EndOfFile;555 if ((try in_stream.read(buf)) < size) return error.EndOfFile;
568 return buf;556 return buf;
569}557}
570558
571fn parseFormValueBlockLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) %FormValue {559fn parseFormValueBlockLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) !FormValue {
572 const buf = try readAllocBytes(allocator, in_stream, size);560 const buf = try readAllocBytes(allocator, in_stream, size);
573 return FormValue { .Block = buf };561 return FormValue { .Block = buf };
574}562}
575563
576fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) %FormValue {564fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) !FormValue {
577 const block_len = try in_stream.readVarInt(builtin.Endian.Little, usize, size);565 const block_len = try in_stream.readVarInt(builtin.Endian.Little, usize, size);
578 return parseFormValueBlockLen(allocator, in_stream, block_len);566 return parseFormValueBlockLen(allocator, in_stream, block_len);
579}567}
580568
581fn parseFormValueConstant(allocator: &mem.Allocator, in_stream: &io.InStream, signed: bool, size: usize) %FormValue {569fn parseFormValueConstant(allocator: &mem.Allocator, in_stream: &io.InStream, signed: bool, size: usize) !FormValue {
582 return FormValue { .Const = Constant {570 return FormValue { .Const = Constant {
583 .signed = signed,571 .signed = signed,
584 .payload = try readAllocBytes(allocator, in_stream, size),572 .payload = try readAllocBytes(allocator, in_stream, size),
585 }};573 }};
586}574}
587575
588fn parseFormValueDwarfOffsetSize(in_stream: &io.InStream, is_64: bool) %u64 {576fn parseFormValueDwarfOffsetSize(in_stream: &io.InStream, is_64: bool) !u64 {
589 return if (is_64) try in_stream.readIntLe(u64)577 return if (is_64) try in_stream.readIntLe(u64)
590 else u64(try in_stream.readIntLe(u32)) ;578 else u64(try in_stream.readIntLe(u32)) ;
591}579}
592580
593fn parseFormValueTargetAddrSize(in_stream: &io.InStream) %u64 {581fn parseFormValueTargetAddrSize(in_stream: &io.InStream) !u64 {
594 return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLe(u32))582 return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLe(u32))
595 else if (@sizeOf(usize) == 8) try in_stream.readIntLe(u64)583 else if (@sizeOf(usize) == 8) try in_stream.readIntLe(u64)
596 else unreachable;584 else unreachable;
597}585}
598586
599fn parseFormValueRefLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) %FormValue {587fn parseFormValueRefLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) !FormValue {
600 const buf = try readAllocBytes(allocator, in_stream, size);588 const buf = try readAllocBytes(allocator, in_stream, size);
601 return FormValue { .Ref = buf };589 return FormValue { .Ref = buf };
602}590}
603591
604fn parseFormValueRef(allocator: &mem.Allocator, in_stream: &io.InStream, comptime T: type) %FormValue {592fn parseFormValueRef(allocator: &mem.Allocator, in_stream: &io.InStream, comptime T: type) !FormValue {
605 const block_len = try in_stream.readIntLe(T);593 const block_len = try in_stream.readIntLe(T);
606 return parseFormValueRefLen(allocator, in_stream, block_len);594 return parseFormValueRefLen(allocator, in_stream, block_len);
607}595}
608596
609fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u64, is_64: bool) %FormValue {597fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u64, is_64: bool) !FormValue {
610 return switch (form_id) {598 return switch (form_id) {
611 DW.FORM_addr => FormValue { .Address = try parseFormValueTargetAddrSize(in_stream) },599 DW.FORM_addr => FormValue { .Address = try parseFormValueTargetAddrSize(in_stream) },
612 DW.FORM_block1 => parseFormValueBlock(allocator, in_stream, 1),600 DW.FORM_block1 => parseFormValueBlock(allocator, in_stream, 1),
...@@ -656,7 +644,7 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u...@@ -656,7 +644,7 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u
656 };644 };
657}645}
658646
659fn parseAbbrevTable(st: &ElfStackTrace) %AbbrevTable {647fn parseAbbrevTable(st: &ElfStackTrace) !AbbrevTable {
660 const in_file = &st.self_exe_file;648 const in_file = &st.self_exe_file;
661 var in_file_stream = io.FileInStream.init(in_file);649 var in_file_stream = io.FileInStream.init(in_file);
662 const in_stream = &in_file_stream.stream;650 const in_stream = &in_file_stream.stream;
...@@ -688,7 +676,7 @@ fn parseAbbrevTable(st: &ElfStackTrace) %AbbrevTable {...@@ -688,7 +676,7 @@ fn parseAbbrevTable(st: &ElfStackTrace) %AbbrevTable {
688676
689/// Gets an already existing AbbrevTable given the abbrev_offset, or if not found,677/// Gets an already existing AbbrevTable given the abbrev_offset, or if not found,
690/// seeks in the stream and parses it.678/// seeks in the stream and parses it.
691fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) %&const AbbrevTable {679fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) !&const AbbrevTable {
692 for (st.abbrev_table_list.toSlice()) |*header| {680 for (st.abbrev_table_list.toSlice()) |*header| {
693 if (header.offset == abbrev_offset) {681 if (header.offset == abbrev_offset) {
694 return &header.table;682 return &header.table;
...@@ -710,7 +698,7 @@ fn getAbbrevTableEntry(abbrev_table: &const AbbrevTable, abbrev_code: u64) ?&con...@@ -710,7 +698,7 @@ fn getAbbrevTableEntry(abbrev_table: &const AbbrevTable, abbrev_code: u64) ?&con
710 return null;698 return null;
711}699}
712700
713fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) %Die {701fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) !Die {
714 const in_file = &st.self_exe_file;702 const in_file = &st.self_exe_file;
715 var in_file_stream = io.FileInStream.init(in_file);703 var in_file_stream = io.FileInStream.init(in_file);
716 const in_stream = &in_file_stream.stream;704 const in_stream = &in_file_stream.stream;
...@@ -732,7 +720,7 @@ fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) %...@@ -732,7 +720,7 @@ fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) %
732 return result;720 return result;
733}721}
734722
735fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, target_address: usize) %LineInfo {723fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, target_address: usize) !LineInfo {
736 const compile_unit_cwd = try compile_unit.die.getAttrString(st, DW.AT_comp_dir);724 const compile_unit_cwd = try compile_unit.die.getAttrString(st, DW.AT_comp_dir);
737725
738 const in_file = &st.self_exe_file;726 const in_file = &st.self_exe_file;
...@@ -910,7 +898,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe...@@ -910,7 +898,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
910 return error.MissingDebugInfo;898 return error.MissingDebugInfo;
911}899}
912900
913fn scanAllCompileUnits(st: &ElfStackTrace) %void {901fn scanAllCompileUnits(st: &ElfStackTrace) !void {
914 const debug_info_end = st.debug_info.offset + st.debug_info.size;902 const debug_info_end = st.debug_info.offset + st.debug_info.size;
915 var this_unit_offset = st.debug_info.offset;903 var this_unit_offset = st.debug_info.offset;
916 var cu_index: usize = 0;904 var cu_index: usize = 0;
...@@ -986,7 +974,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) %void {...@@ -986,7 +974,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) %void {
986 }974 }
987}975}
988976
989fn findCompileUnit(st: &ElfStackTrace, target_address: u64) %&const CompileUnit {977fn findCompileUnit(st: &ElfStackTrace, target_address: u64) !&const CompileUnit {
990 var in_file_stream = io.FileInStream.init(&st.self_exe_file);978 var in_file_stream = io.FileInStream.init(&st.self_exe_file);
991 const in_stream = &in_file_stream.stream;979 const in_stream = &in_file_stream.stream;
992 for (st.compile_unit_list.toSlice()) |*compile_unit| {980 for (st.compile_unit_list.toSlice()) |*compile_unit| {
...@@ -1022,7 +1010,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) %&const CompileUnit...@@ -1022,7 +1010,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) %&const CompileUnit
1022 return error.MissingDebugInfo;1010 return error.MissingDebugInfo;
1023}1011}
10241012
1025fn readInitialLength(in_stream: &io.InStream, is_64: &bool) %u64 {1013fn readInitialLength(in_stream: &io.InStream, is_64: &bool) !u64 {
1026 const first_32_bits = try in_stream.readIntLe(u32);1014 const first_32_bits = try in_stream.readIntLe(u32);
1027 *is_64 = (first_32_bits == 0xffffffff);1015 *is_64 = (first_32_bits == 0xffffffff);
1028 if (*is_64) {1016 if (*is_64) {
...@@ -1033,7 +1021,7 @@ fn readInitialLength(in_stream: &io.InStream, is_64: &bool) %u64 {...@@ -1033,7 +1021,7 @@ fn readInitialLength(in_stream: &io.InStream, is_64: &bool) %u64 {
1033 }1021 }
1034}1022}
10351023
1036fn readULeb128(in_stream: &io.InStream) %u64 {1024fn readULeb128(in_stream: &io.InStream) !u64 {
1037 var result: u64 = 0;1025 var result: u64 = 0;
1038 var shift: usize = 0;1026 var shift: usize = 0;
10391027
...@@ -1054,7 +1042,7 @@ fn readULeb128(in_stream: &io.InStream) %u64 {...@@ -1054,7 +1042,7 @@ fn readULeb128(in_stream: &io.InStream) %u64 {
1054 }1042 }
1055}1043}
10561044
1057fn readILeb128(in_stream: &io.InStream) %i64 {1045fn readILeb128(in_stream: &io.InStream) !i64 {
1058 var result: i64 = 0;1046 var result: i64 = 0;
1059 var shift: usize = 0;1047 var shift: usize = 0;
10601048
std/os/index.zig+43-77
...@@ -57,25 +57,10 @@ const ArrayList = std.ArrayList;...@@ -57,25 +57,10 @@ const ArrayList = std.ArrayList;
57const Buffer = std.Buffer;57const Buffer = std.Buffer;
58const math = std.math;58const math = std.math;
5959
60error SystemResources;
61error AccessDenied;
62error InvalidExe;
63error FileSystem;
64error IsDir;
65error FileNotFound;
66error FileBusy;
67error PathAlreadyExists;
68error SymLinkLoop;
69error ReadOnlyFileSystem;
70error LinkQuotaExceeded;
71error RenameAcrossMountPoints;
72error DirNotEmpty;
73error WouldBlock;
74
75/// Fills `buf` with random bytes. If linking against libc, this calls the60/// Fills `buf` with random bytes. If linking against libc, this calls the
76/// appropriate OS-specific library call. Otherwise it uses the zig standard61/// appropriate OS-specific library call. Otherwise it uses the zig standard
77/// library implementation.62/// library implementation.
78pub fn getRandomBytes(buf: []u8) %void {63pub fn getRandomBytes(buf: []u8) !void {
79 switch (builtin.os) {64 switch (builtin.os) {
80 Os.linux => while (true) {65 Os.linux => while (true) {
81 // TODO check libc version and potentially call c.getrandom.66 // TODO check libc version and potentially call c.getrandom.
...@@ -182,7 +167,7 @@ pub fn close(handle: FileHandle) void {...@@ -182,7 +167,7 @@ pub fn close(handle: FileHandle) void {
182}167}
183168
184/// Calls POSIX read, and keeps trying if it gets interrupted.169/// Calls POSIX read, and keeps trying if it gets interrupted.
185pub fn posixRead(fd: i32, buf: []u8) %void {170pub fn posixRead(fd: i32, buf: []u8) !void {
186 var index: usize = 0;171 var index: usize = 0;
187 while (index < buf.len) {172 while (index < buf.len) {
188 const amt_written = posix.read(fd, &buf[index], buf.len - index);173 const amt_written = posix.read(fd, &buf[index], buf.len - index);
...@@ -203,17 +188,8 @@ pub fn posixRead(fd: i32, buf: []u8) %void {...@@ -203,17 +188,8 @@ pub fn posixRead(fd: i32, buf: []u8) %void {
203 }188 }
204}189}
205190
206error WouldBlock;
207error FileClosed;
208error DestinationAddressRequired;
209error DiskQuota;
210error FileTooBig;
211error InputOutput;
212error NoSpaceLeft;
213error BrokenPipe;
214
215/// Calls POSIX write, and keeps trying if it gets interrupted.191/// Calls POSIX write, and keeps trying if it gets interrupted.
216pub fn posixWrite(fd: i32, bytes: []const u8) %void {192pub fn posixWrite(fd: i32, bytes: []const u8) !void {
217 while (true) {193 while (true) {
218 const write_ret = posix.write(fd, bytes.ptr, bytes.len);194 const write_ret = posix.write(fd, bytes.ptr, bytes.len);
219 const write_err = posix.getErrno(write_ret);195 const write_err = posix.getErrno(write_ret);
...@@ -243,7 +219,7 @@ pub fn posixWrite(fd: i32, bytes: []const u8) %void {...@@ -243,7 +219,7 @@ pub fn posixWrite(fd: i32, bytes: []const u8) %void {
243/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.219/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
244/// Calls POSIX open, keeps trying if it gets interrupted, and translates220/// Calls POSIX open, keeps trying if it gets interrupted, and translates
245/// the return value into zig errors.221/// the return value into zig errors.
246pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Allocator) %i32 {222pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Allocator) !i32 {
247 var stack_buf: [max_noalloc_path_len]u8 = undefined;223 var stack_buf: [max_noalloc_path_len]u8 = undefined;
248 var path0: []u8 = undefined;224 var path0: []u8 = undefined;
249 var need_free = false;225 var need_free = false;
...@@ -292,7 +268,7 @@ pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Al...@@ -292,7 +268,7 @@ pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Al
292 }268 }
293}269}
294270
295pub fn posixDup2(old_fd: i32, new_fd: i32) %void {271pub fn posixDup2(old_fd: i32, new_fd: i32) !void {
296 while (true) {272 while (true) {
297 const err = posix.getErrno(posix.dup2(old_fd, new_fd));273 const err = posix.getErrno(posix.dup2(old_fd, new_fd));
298 if (err > 0) {274 if (err > 0) {
...@@ -307,7 +283,7 @@ pub fn posixDup2(old_fd: i32, new_fd: i32) %void {...@@ -307,7 +283,7 @@ pub fn posixDup2(old_fd: i32, new_fd: i32) %void {
307 }283 }
308}284}
309285
310pub fn createNullDelimitedEnvMap(allocator: &Allocator, env_map: &const BufMap) %[]?&u8 {286pub fn createNullDelimitedEnvMap(allocator: &Allocator, env_map: &const BufMap) ![]?&u8 {
311 const envp_count = env_map.count();287 const envp_count = env_map.count();
312 const envp_buf = try allocator.alloc(?&u8, envp_count + 1);288 const envp_buf = try allocator.alloc(?&u8, envp_count + 1);
313 mem.set(?&u8, envp_buf, null);289 mem.set(?&u8, envp_buf, null);
...@@ -344,7 +320,7 @@ pub fn freeNullDelimitedEnvMap(allocator: &Allocator, envp_buf: []?&u8) void {...@@ -344,7 +320,7 @@ pub fn freeNullDelimitedEnvMap(allocator: &Allocator, envp_buf: []?&u8) void {
344/// `argv[0]` is the executable path.320/// `argv[0]` is the executable path.
345/// This function also uses the PATH environment variable to get the full path to the executable.321/// This function also uses the PATH environment variable to get the full path to the executable.
346pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap,322pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap,
347 allocator: &Allocator) %void323 allocator: &Allocator) !void
348{324{
349 const argv_buf = try allocator.alloc(?&u8, argv.len + 1);325 const argv_buf = try allocator.alloc(?&u8, argv.len + 1);
350 mem.set(?&u8, argv_buf, null);326 mem.set(?&u8, argv_buf, null);
...@@ -419,7 +395,7 @@ fn posixExecveErrnoToErr(err: usize) error {...@@ -419,7 +395,7 @@ fn posixExecveErrnoToErr(err: usize) error {
419pub var posix_environ_raw: []&u8 = undefined;395pub var posix_environ_raw: []&u8 = undefined;
420396
421/// Caller must free result when done.397/// Caller must free result when done.
422pub fn getEnvMap(allocator: &Allocator) %BufMap {398pub fn getEnvMap(allocator: &Allocator) !BufMap {
423 var result = BufMap.init(allocator);399 var result = BufMap.init(allocator);
424 errdefer result.deinit();400 errdefer result.deinit();
425401
...@@ -480,10 +456,8 @@ pub fn getEnvPosix(key: []const u8) ?[]const u8 {...@@ -480,10 +456,8 @@ pub fn getEnvPosix(key: []const u8) ?[]const u8 {
480 return null;456 return null;
481}457}
482458
483error EnvironmentVariableNotFound;
484
485/// Caller must free returned memory.459/// Caller must free returned memory.
486pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) %[]u8 {460pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) ![]u8 {
487 if (is_windows) {461 if (is_windows) {
488 const key_with_null = try cstr.addNullByte(allocator, key);462 const key_with_null = try cstr.addNullByte(allocator, key);
489 defer allocator.free(key_with_null);463 defer allocator.free(key_with_null);
...@@ -517,7 +491,7 @@ pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) %[]u8 {...@@ -517,7 +491,7 @@ pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) %[]u8 {
517}491}
518492
519/// Caller must free the returned memory.493/// Caller must free the returned memory.
520pub fn getCwd(allocator: &Allocator) %[]u8 {494pub fn getCwd(allocator: &Allocator) ![]u8 {
521 switch (builtin.os) {495 switch (builtin.os) {
522 Os.windows => {496 Os.windows => {
523 var buf = try allocator.alloc(u8, 256);497 var buf = try allocator.alloc(u8, 256);
...@@ -564,7 +538,7 @@ test "os.getCwd" {...@@ -564,7 +538,7 @@ test "os.getCwd" {
564 _ = getCwd(debug.global_allocator);538 _ = getCwd(debug.global_allocator);
565}539}
566540
567pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) %void {541pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) !void {
568 if (is_windows) {542 if (is_windows) {
569 return symLinkWindows(allocator, existing_path, new_path);543 return symLinkWindows(allocator, existing_path, new_path);
570 } else {544 } else {
...@@ -572,7 +546,7 @@ pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []con...@@ -572,7 +546,7 @@ pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []con
572 }546 }
573}547}
574548
575pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) %void {549pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) !void {
576 const existing_with_null = try cstr.addNullByte(allocator, existing_path);550 const existing_with_null = try cstr.addNullByte(allocator, existing_path);
577 defer allocator.free(existing_with_null);551 defer allocator.free(existing_with_null);
578 const new_with_null = try cstr.addNullByte(allocator, new_path);552 const new_with_null = try cstr.addNullByte(allocator, new_path);
...@@ -586,7 +560,7 @@ pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path...@@ -586,7 +560,7 @@ pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path
586 }560 }
587}561}
588562
589pub fn symLinkPosix(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) %void {563pub fn symLinkPosix(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) !void {
590 const full_buf = try allocator.alloc(u8, existing_path.len + new_path.len + 2);564 const full_buf = try allocator.alloc(u8, existing_path.len + new_path.len + 2);
591 defer allocator.free(full_buf);565 defer allocator.free(full_buf);
592566
...@@ -623,7 +597,7 @@ const b64_fs_encoder = base64.Base64Encoder.init(...@@ -623,7 +597,7 @@ const b64_fs_encoder = base64.Base64Encoder.init(
623 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",597 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",
624 base64.standard_pad_char);598 base64.standard_pad_char);
625599
626pub fn atomicSymLink(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) %void {600pub fn atomicSymLink(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) !void {
627 if (symLink(allocator, existing_path, new_path)) {601 if (symLink(allocator, existing_path, new_path)) {
628 return;602 return;
629 } else |err| {603 } else |err| {
...@@ -652,7 +626,7 @@ pub fn atomicSymLink(allocator: &Allocator, existing_path: []const u8, new_path:...@@ -652,7 +626,7 @@ pub fn atomicSymLink(allocator: &Allocator, existing_path: []const u8, new_path:
652626
653}627}
654628
655pub fn deleteFile(allocator: &Allocator, file_path: []const u8) %void {629pub fn deleteFile(allocator: &Allocator, file_path: []const u8) !void {
656 if (builtin.os == Os.windows) {630 if (builtin.os == Os.windows) {
657 return deleteFileWindows(allocator, file_path);631 return deleteFileWindows(allocator, file_path);
658 } else {632 } else {
...@@ -660,10 +634,7 @@ pub fn deleteFile(allocator: &Allocator, file_path: []const u8) %void {...@@ -660,10 +634,7 @@ pub fn deleteFile(allocator: &Allocator, file_path: []const u8) %void {
660 }634 }
661}635}
662636
663error FileNotFound;637pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) !void {
664error AccessDenied;
665
666pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) %void {
667 const buf = try allocator.alloc(u8, file_path.len + 1);638 const buf = try allocator.alloc(u8, file_path.len + 1);
668 defer allocator.free(buf);639 defer allocator.free(buf);
669640
...@@ -681,7 +652,7 @@ pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) %void {...@@ -681,7 +652,7 @@ pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) %void {
681 }652 }
682}653}
683654
684pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) %void {655pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) !void {
685 const buf = try allocator.alloc(u8, file_path.len + 1);656 const buf = try allocator.alloc(u8, file_path.len + 1);
686 defer allocator.free(buf);657 defer allocator.free(buf);
687658
...@@ -708,13 +679,13 @@ pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) %void {...@@ -708,13 +679,13 @@ pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) %void {
708}679}
709680
710/// Calls ::copyFileMode with 0o666 for the mode.681/// Calls ::copyFileMode with 0o666 for the mode.
711pub fn copyFile(allocator: &Allocator, source_path: []const u8, dest_path: []const u8) %void {682pub fn copyFile(allocator: &Allocator, source_path: []const u8, dest_path: []const u8) !void {
712 return copyFileMode(allocator, source_path, dest_path, 0o666);683 return copyFileMode(allocator, source_path, dest_path, 0o666);
713}684}
714685
715// TODO instead of accepting a mode argument, use the mode from fstat'ing the source path once open686// TODO instead of accepting a mode argument, use the mode from fstat'ing the source path once open
716/// Guaranteed to be atomic.687/// Guaranteed to be atomic.
717pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: []const u8, mode: usize) %void {688pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: []const u8, mode: usize) !void {
718 var rand_buf: [12]u8 = undefined;689 var rand_buf: [12]u8 = undefined;
719 const tmp_path = try allocator.alloc(u8, dest_path.len + base64.Base64Encoder.calcSize(rand_buf.len));690 const tmp_path = try allocator.alloc(u8, dest_path.len + base64.Base64Encoder.calcSize(rand_buf.len));
720 defer allocator.free(tmp_path);691 defer allocator.free(tmp_path);
...@@ -738,7 +709,7 @@ pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: [...@@ -738,7 +709,7 @@ pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: [
738 }709 }
739}710}
740711
741pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8) %void {712pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8) !void {
742 const full_buf = try allocator.alloc(u8, old_path.len + new_path.len + 2);713 const full_buf = try allocator.alloc(u8, old_path.len + new_path.len + 2);
743 defer allocator.free(full_buf);714 defer allocator.free(full_buf);
744715
...@@ -783,7 +754,7 @@ pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8)...@@ -783,7 +754,7 @@ pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8)
783 }754 }
784}755}
785756
786pub fn makeDir(allocator: &Allocator, dir_path: []const u8) %void {757pub fn makeDir(allocator: &Allocator, dir_path: []const u8) !void {
787 if (is_windows) {758 if (is_windows) {
788 return makeDirWindows(allocator, dir_path);759 return makeDirWindows(allocator, dir_path);
789 } else {760 } else {
...@@ -791,7 +762,7 @@ pub fn makeDir(allocator: &Allocator, dir_path: []const u8) %void {...@@ -791,7 +762,7 @@ pub fn makeDir(allocator: &Allocator, dir_path: []const u8) %void {
791 }762 }
792}763}
793764
794pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) %void {765pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) !void {
795 const path_buf = try cstr.addNullByte(allocator, dir_path);766 const path_buf = try cstr.addNullByte(allocator, dir_path);
796 defer allocator.free(path_buf);767 defer allocator.free(path_buf);
797768
...@@ -805,7 +776,7 @@ pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) %void {...@@ -805,7 +776,7 @@ pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) %void {
805 }776 }
806}777}
807778
808pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) %void {779pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) !void {
809 const path_buf = try cstr.addNullByte(allocator, dir_path);780 const path_buf = try cstr.addNullByte(allocator, dir_path);
810 defer allocator.free(path_buf);781 defer allocator.free(path_buf);
811782
...@@ -831,7 +802,7 @@ pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) %void {...@@ -831,7 +802,7 @@ pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) %void {
831802
832/// Calls makeDir recursively to make an entire path. Returns success if the path803/// Calls makeDir recursively to make an entire path. Returns success if the path
833/// already exists and is a directory.804/// already exists and is a directory.
834pub fn makePath(allocator: &Allocator, full_path: []const u8) %void {805pub fn makePath(allocator: &Allocator, full_path: []const u8) !void {
835 const resolved_path = try path.resolve(allocator, full_path);806 const resolved_path = try path.resolve(allocator, full_path);
836 defer allocator.free(resolved_path);807 defer allocator.free(resolved_path);
837808
...@@ -869,7 +840,7 @@ pub fn makePath(allocator: &Allocator, full_path: []const u8) %void {...@@ -869,7 +840,7 @@ pub fn makePath(allocator: &Allocator, full_path: []const u8) %void {
869840
870/// Returns ::error.DirNotEmpty if the directory is not empty.841/// Returns ::error.DirNotEmpty if the directory is not empty.
871/// To delete a directory recursively, see ::deleteTree842/// To delete a directory recursively, see ::deleteTree
872pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) %void {843pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) !void {
873 const path_buf = try allocator.alloc(u8, dir_path.len + 1);844 const path_buf = try allocator.alloc(u8, dir_path.len + 1);
874 defer allocator.free(path_buf);845 defer allocator.free(path_buf);
875846
...@@ -898,7 +869,7 @@ pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) %void {...@@ -898,7 +869,7 @@ pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) %void {
898/// removes it. If it cannot be removed because it is a non-empty directory,869/// removes it. If it cannot be removed because it is a non-empty directory,
899/// this function recursively removes its entries and then tries again.870/// this function recursively removes its entries and then tries again.
900// TODO non-recursive implementation871// TODO non-recursive implementation
901pub fn deleteTree(allocator: &Allocator, full_path: []const u8) %void {872pub fn deleteTree(allocator: &Allocator, full_path: []const u8) !void {
902 start_over: while (true) {873 start_over: while (true) {
903 // First, try deleting the item as a file. This way we don't follow sym links.874 // First, try deleting the item as a file. This way we don't follow sym links.
904 if (deleteFile(allocator, full_path)) {875 if (deleteFile(allocator, full_path)) {
...@@ -967,7 +938,7 @@ pub const Dir = struct {...@@ -967,7 +938,7 @@ pub const Dir = struct {
967 };938 };
968 };939 };
969940
970 pub fn open(allocator: &Allocator, dir_path: []const u8) %Dir {941 pub fn open(allocator: &Allocator, dir_path: []const u8) !Dir {
971 const fd = try posixOpen(dir_path, posix.O_RDONLY|posix.O_DIRECTORY|posix.O_CLOEXEC, 0, allocator);942 const fd = try posixOpen(dir_path, posix.O_RDONLY|posix.O_DIRECTORY|posix.O_CLOEXEC, 0, allocator);
972 return Dir {943 return Dir {
973 .allocator = allocator,944 .allocator = allocator,
...@@ -985,7 +956,7 @@ pub const Dir = struct {...@@ -985,7 +956,7 @@ pub const Dir = struct {
985956
986 /// Memory such as file names referenced in this returned entry becomes invalid957 /// Memory such as file names referenced in this returned entry becomes invalid
987 /// with subsequent calls to next, as well as when this ::Dir is deinitialized.958 /// with subsequent calls to next, as well as when this ::Dir is deinitialized.
988 pub fn next(self: &Dir) %?Entry {959 pub fn next(self: &Dir) !?Entry {
989 start_over: while (true) {960 start_over: while (true) {
990 if (self.index >= self.end_index) {961 if (self.index >= self.end_index) {
991 if (self.buf.len == 0) {962 if (self.buf.len == 0) {
...@@ -1042,7 +1013,7 @@ pub const Dir = struct {...@@ -1042,7 +1013,7 @@ pub const Dir = struct {
1042 }1013 }
1043};1014};
10441015
1045pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) %void {1016pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) !void {
1046 const path_buf = try allocator.alloc(u8, dir_path.len + 1);1017 const path_buf = try allocator.alloc(u8, dir_path.len + 1);
1047 defer allocator.free(path_buf);1018 defer allocator.free(path_buf);
10481019
...@@ -1066,7 +1037,7 @@ pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) %void {...@@ -1066,7 +1037,7 @@ pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) %void {
1066}1037}
10671038
1068/// Read value of a symbolic link.1039/// Read value of a symbolic link.
1069pub fn readLink(allocator: &Allocator, pathname: []const u8) %[]u8 {1040pub fn readLink(allocator: &Allocator, pathname: []const u8) ![]u8 {
1070 const path_buf = try allocator.alloc(u8, pathname.len + 1);1041 const path_buf = try allocator.alloc(u8, pathname.len + 1);
1071 defer allocator.free(path_buf);1042 defer allocator.free(path_buf);
10721043
...@@ -1143,11 +1114,7 @@ test "os.sleep" {...@@ -1143,11 +1114,7 @@ test "os.sleep" {
1143 sleep(0, 1);1114 sleep(0, 1);
1144}1115}
11451116
1146error ResourceLimitReached;1117pub fn posix_setuid(uid: u32) !void {
1147error InvalidUserId;
1148error PermissionDenied;
1149
1150pub fn posix_setuid(uid: u32) %void {
1151 const err = posix.getErrno(posix.setuid(uid));1118 const err = posix.getErrno(posix.setuid(uid));
1152 if (err == 0) return;1119 if (err == 0) return;
1153 return switch (err) {1120 return switch (err) {
...@@ -1158,7 +1125,7 @@ pub fn posix_setuid(uid: u32) %void {...@@ -1158,7 +1125,7 @@ pub fn posix_setuid(uid: u32) %void {
1158 };1125 };
1159}1126}
11601127
1161pub fn posix_setreuid(ruid: u32, euid: u32) %void {1128pub fn posix_setreuid(ruid: u32, euid: u32) !void {
1162 const err = posix.getErrno(posix.setreuid(ruid, euid));1129 const err = posix.getErrno(posix.setreuid(ruid, euid));
1163 if (err == 0) return;1130 if (err == 0) return;
1164 return switch (err) {1131 return switch (err) {
...@@ -1169,7 +1136,7 @@ pub fn posix_setreuid(ruid: u32, euid: u32) %void {...@@ -1169,7 +1136,7 @@ pub fn posix_setreuid(ruid: u32, euid: u32) %void {
1169 };1136 };
1170}1137}
11711138
1172pub fn posix_setgid(gid: u32) %void {1139pub fn posix_setgid(gid: u32) !void {
1173 const err = posix.getErrno(posix.setgid(gid));1140 const err = posix.getErrno(posix.setgid(gid));
1174 if (err == 0) return;1141 if (err == 0) return;
1175 return switch (err) {1142 return switch (err) {
...@@ -1180,7 +1147,7 @@ pub fn posix_setgid(gid: u32) %void {...@@ -1180,7 +1147,7 @@ pub fn posix_setgid(gid: u32) %void {
1180 };1147 };
1181}1148}
11821149
1183pub fn posix_setregid(rgid: u32, egid: u32) %void {1150pub fn posix_setregid(rgid: u32, egid: u32) !void {
1184 const err = posix.getErrno(posix.setregid(rgid, egid));1151 const err = posix.getErrno(posix.setregid(rgid, egid));
1185 if (err == 0) return;1152 if (err == 0) return;
1186 return switch (err) {1153 return switch (err) {
...@@ -1191,8 +1158,7 @@ pub fn posix_setregid(rgid: u32, egid: u32) %void {...@@ -1191,8 +1158,7 @@ pub fn posix_setregid(rgid: u32, egid: u32) %void {
1191 };1158 };
1192}1159}
11931160
1194error NoStdHandles;1161pub fn windowsGetStdHandle(handle_id: windows.DWORD) !windows.HANDLE {
1195pub fn windowsGetStdHandle(handle_id: windows.DWORD) %windows.HANDLE {
1196 if (windows.GetStdHandle(handle_id)) |handle| {1162 if (windows.GetStdHandle(handle_id)) |handle| {
1197 if (handle == windows.INVALID_HANDLE_VALUE) {1163 if (handle == windows.INVALID_HANDLE_VALUE) {
1198 const err = windows.GetLastError();1164 const err = windows.GetLastError();
...@@ -1261,7 +1227,7 @@ pub const ArgIteratorWindows = struct {...@@ -1261,7 +1227,7 @@ pub const ArgIteratorWindows = struct {
1261 }1227 }
12621228
1263 /// You must free the returned memory when done.1229 /// You must free the returned memory when done.
1264 pub fn next(self: &ArgIteratorWindows, allocator: &Allocator) ?%[]u8 {1230 pub fn next(self: &ArgIteratorWindows, allocator: &Allocator) ?internalNext.errors![]u8 {
1265 // march forward over whitespace1231 // march forward over whitespace
1266 while (true) : (self.index += 1) {1232 while (true) : (self.index += 1) {
1267 const byte = self.cmd_line[self.index];1233 const byte = self.cmd_line[self.index];
...@@ -1314,7 +1280,7 @@ pub const ArgIteratorWindows = struct {...@@ -1314,7 +1280,7 @@ pub const ArgIteratorWindows = struct {
1314 }1280 }
1315 }1281 }
13161282
1317 fn internalNext(self: &ArgIteratorWindows, allocator: &Allocator) %[]u8 {1283 fn internalNext(self: &ArgIteratorWindows, allocator: &Allocator) ![]u8 {
1318 var buf = try Buffer.initSize(allocator, 0);1284 var buf = try Buffer.initSize(allocator, 0);
1319 defer buf.deinit();1285 defer buf.deinit();
13201286
...@@ -1358,7 +1324,7 @@ pub const ArgIteratorWindows = struct {...@@ -1358,7 +1324,7 @@ pub const ArgIteratorWindows = struct {
1358 }1324 }
1359 }1325 }
13601326
1361 fn emitBackslashes(self: &ArgIteratorWindows, buf: &Buffer, emit_count: usize) %void {1327 fn emitBackslashes(self: &ArgIteratorWindows, buf: &Buffer, emit_count: usize) !void {
1362 var i: usize = 0;1328 var i: usize = 0;
1363 while (i < emit_count) : (i += 1) {1329 while (i < emit_count) : (i += 1) {
1364 try buf.appendByte('\\');1330 try buf.appendByte('\\');
...@@ -1397,7 +1363,7 @@ pub const ArgIterator = struct {...@@ -1397,7 +1363,7 @@ pub const ArgIterator = struct {
1397 }1363 }
1398 1364
1399 /// You must free the returned memory when done.1365 /// You must free the returned memory when done.
1400 pub fn next(self: &ArgIterator, allocator: &Allocator) ?%[]u8 {1366 pub fn next(self: &ArgIterator, allocator: &Allocator) ?![]u8 {
1401 if (builtin.os == Os.windows) {1367 if (builtin.os == Os.windows) {
1402 return self.inner.next(allocator);1368 return self.inner.next(allocator);
1403 } else {1369 } else {
...@@ -1422,7 +1388,7 @@ pub fn args() ArgIterator {...@@ -1422,7 +1388,7 @@ pub fn args() ArgIterator {
1422}1388}
14231389
1424/// Caller must call freeArgs on result.1390/// Caller must call freeArgs on result.
1425pub fn argsAlloc(allocator: &mem.Allocator) %[]const []u8 {1391pub fn argsAlloc(allocator: &mem.Allocator) ![]const []u8 {
1426 // TODO refactor to only make 1 allocation.1392 // TODO refactor to only make 1 allocation.
1427 var it = args();1393 var it = args();
1428 var contents = try Buffer.initSize(allocator, 0);1394 var contents = try Buffer.initSize(allocator, 0);
...@@ -1529,7 +1495,7 @@ pub fn unexpectedErrorWindows(err: windows.DWORD) error {...@@ -1529,7 +1495,7 @@ pub fn unexpectedErrorWindows(err: windows.DWORD) error {
1529 return error.Unexpected;1495 return error.Unexpected;
1530}1496}
15311497
1532pub fn openSelfExe() %io.File {1498pub fn openSelfExe() !io.File {
1533 switch (builtin.os) {1499 switch (builtin.os) {
1534 Os.linux => {1500 Os.linux => {
1535 return io.File.openRead("/proc/self/exe", null);1501 return io.File.openRead("/proc/self/exe", null);
...@@ -1547,7 +1513,7 @@ pub fn openSelfExe() %io.File {...@@ -1547,7 +1513,7 @@ pub fn openSelfExe() %io.File {
1547/// This function may return an error if the current executable1513/// This function may return an error if the current executable
1548/// was deleted after spawning.1514/// was deleted after spawning.
1549/// Caller owns returned memory.1515/// Caller owns returned memory.
1550pub fn selfExePath(allocator: &mem.Allocator) %[]u8 {1516pub fn selfExePath(allocator: &mem.Allocator) ![]u8 {
1551 switch (builtin.os) {1517 switch (builtin.os) {
1552 Os.linux => {1518 Os.linux => {
1553 // If the currently executing binary has been deleted,1519 // If the currently executing binary has been deleted,
...@@ -1590,7 +1556,7 @@ pub fn selfExePath(allocator: &mem.Allocator) %[]u8 {...@@ -1590,7 +1556,7 @@ pub fn selfExePath(allocator: &mem.Allocator) %[]u8 {
15901556
1591/// Get the directory path that contains the current executable.1557/// Get the directory path that contains the current executable.
1592/// Caller owns returned memory.1558/// Caller owns returned memory.
1593pub fn selfExeDirPath(allocator: &mem.Allocator) %[]u8 {1559pub fn selfExeDirPath(allocator: &mem.Allocator) ![]u8 {
1594 switch (builtin.os) {1560 switch (builtin.os) {
1595 Os.linux => {1561 Os.linux => {
1596 // If the currently executing binary has been deleted,1562 // If the currently executing binary has been deleted,
std/special/test_runner.zig+1-1
...@@ -4,7 +4,7 @@ const builtin = @import("builtin");...@@ -4,7 +4,7 @@ const builtin = @import("builtin");
4const test_fn_list = builtin.__zig_test_fn_slice;4const test_fn_list = builtin.__zig_test_fn_slice;
5const warn = std.debug.warn;5const warn = std.debug.warn;
66
7pub fn main() %void {7pub fn main() !void {
8 for (test_fn_list) |test_fn, i| {8 for (test_fn_list) |test_fn, i| {
9 warn("Test {}/{} {}...", i + 1, test_fn_list.len, test_fn.name);9 warn("Test {}/{} {}...", i + 1, test_fn_list.len, test_fn.name);
1010