authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-24 01:34:48-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-24 01:34:57-07:00
log5c18826240fe983a30a9de6e04d3848643db7cf6
treed427af30c78ff59d768bf75cd194e008757ab7bf
parent37aae530098f10565ea3408891c901e086b8d5b8

introduce the error keyword and type

See #23

12 files changed, 223 insertions(+), 128 deletions(-)

doc/langref.md+4-4
...@@ -7,7 +7,7 @@ Root : many(TopLevelDecl) "EOF"...@@ -7,7 +7,7 @@ Root : many(TopLevelDecl) "EOF"
77
8TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Import | ContainerDecl | VariableDeclaration | ErrorValueDecl8TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Import | ContainerDecl | VariableDeclaration | ErrorValueDecl
99
10ErrorValueDecl : option(FnVisibleMod) "%." "Symbol"10ErrorValueDecl : option(FnVisibleMod) "error" "Symbol"
1111
12VariableDeclaration : option(FnVisibleMod) ("var" | "const") "Symbol" ("=" Expression | ":" PrefixOpExpression option("=" Expression))12VariableDeclaration : option(FnVisibleMod) ("var" | "const") "Symbol" ("=" Expression | ":" PrefixOpExpression option("=" Expression))
1313
...@@ -133,9 +133,9 @@ ContainerInitBody : list(StructLiteralField, ",") | list(Expression, ",")...@@ -133,9 +133,9 @@ ContainerInitBody : list(StructLiteralField, ",") | list(Expression, ",")
133133
134StructLiteralField : "." "Symbol" "=" Expression134StructLiteralField : "." "Symbol" "=" Expression
135135
136PrefixOp : "!" | "-" | "~" | "*" | ("&" option("const")) | "?"136PrefixOp : "!" | "-" | "~" | "*" | ("&" option("const")) | "?" | "%"
137137
138PrimaryExpression : "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | AsmExpression | ("%." "Symbol")138PrimaryExpression : "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | AsmExpression | ("error" "." "Symbol")
139139
140ArrayType : "[" option(Expression) "]" option("const") PrefixOpExpression140ArrayType : "[" option(Expression) "]" option("const") PrefixOpExpression
141141
...@@ -143,7 +143,7 @@ GotoExpression: "goto" "Symbol"...@@ -143,7 +143,7 @@ GotoExpression: "goto" "Symbol"
143143
144GroupedExpression : "(" Expression ")"144GroupedExpression : "(" Expression ")"
145145
146KeywordLiteral : "true" | "false" | "null" | "break" | "continue" | "undefined"146KeywordLiteral : "true" | "false" | "null" | "break" | "continue" | "undefined" | "error"
147```147```
148148
149## Operator Precedence149## Operator Precedence
doc/vim/syntax/zig.vim+1-1
...@@ -15,7 +15,7 @@ syn keyword zigRepeat while for...@@ -15,7 +15,7 @@ syn keyword zigRepeat while for
1515
16syn keyword zigConstant null undefined16syn keyword zigConstant null undefined
17syn keyword zigKeyword fn import17syn keyword zigKeyword fn import
18syn keyword zigType bool i8 u8 i16 u16 i32 u32 i64 u64 isize usize f32 f64 f128 void unreachable type18syn keyword zigType bool i8 u8 i16 u16 i32 u32 i64 u64 isize usize f32 f64 f128 void unreachable type error
1919
20syn keyword zigBoolean true false20syn keyword zigBoolean true false
2121
example/cat/main.zig+2-1
...@@ -10,6 +10,7 @@ import "std.zig";...@@ -10,6 +10,7 @@ import "std.zig";
10// * %% binary operator10// * %% binary operator
11// * %% prefix operator11// * %% prefix operator
12// * cast err type to string12// * cast err type to string
13// * string equality
1314
14pub fn main(args: [][]u8) %void => {15pub fn main(args: [][]u8) %void => {
15 const exe = args[0];16 const exe = args[0];
...@@ -39,7 +40,7 @@ pub fn main(args: [][]u8) %void => {...@@ -39,7 +40,7 @@ pub fn main(args: [][]u8) %void => {
3940
40fn usage(exe: []u8) %void => {41fn usage(exe: []u8) %void => {
41 %%stderr.print("Usage: {} [FILE]...\n", exe);42 %%stderr.print("Usage: {} [FILE]...\n", exe);
42 return %.Invalid;43 return error.Invalid;
43}44}
4445
45fn cat_stream(is: InputStream) %void => {46fn cat_stream(is: InputStream) %void => {
example/guess_number/main.zig+4-4
...@@ -3,8 +3,8 @@ export executable "guess_number";...@@ -3,8 +3,8 @@ export executable "guess_number";
3import "std.zig";3import "std.zig";
4import "rand.zig";4import "rand.zig";
55
6%.GetRandomFail;6error GetRandomFail;
7%.ReadInputFail;7error ReadInputFail;
88
9pub fn main(args: [][]u8) %void => {9pub fn main(args: [][]u8) %void => {
10 print_str("Welcome to the Guess Number Game in Zig.\n");10 print_str("Welcome to the Guess Number Game in Zig.\n");
...@@ -15,7 +15,7 @@ pub fn main(args: [][]u8) %void => {...@@ -15,7 +15,7 @@ pub fn main(args: [][]u8) %void => {
15 if (err != @sizeof(u32)) {15 if (err != @sizeof(u32)) {
16 // TODO full error message16 // TODO full error message
17 fprint_str(stderr_fileno, "unable to get random bytes\n");17 fprint_str(stderr_fileno, "unable to get random bytes\n");
18 return %.GetRandomFail;18 return error.GetRandomFail;
19 }19 }
2020
21 var rand : Rand;21 var rand : Rand;
...@@ -31,7 +31,7 @@ pub fn main(args: [][]u8) %void => {...@@ -31,7 +31,7 @@ pub fn main(args: [][]u8) %void => {
31 if (readline(line_buf, &line_len) || line_len == line_buf.len) {31 if (readline(line_buf, &line_len) || line_len == line_buf.len) {
32 // TODO full error message32 // TODO full error message
33 fprint_str(stderr_fileno, "unable to read input\n");33 fprint_str(stderr_fileno, "unable to read input\n");
34 return %.ReadInputFail;34 return error.ReadInputFail;
35 }35 }
3636
37 var guess : u64;37 var guess : u64;
src/all_types.hpp+11-10
...@@ -133,7 +133,6 @@ enum NodeType {...@@ -133,7 +133,6 @@ enum NodeType {
133 NodeTypeNumberLiteral,133 NodeTypeNumberLiteral,
134 NodeTypeStringLiteral,134 NodeTypeStringLiteral,
135 NodeTypeCharLiteral,135 NodeTypeCharLiteral,
136 NodeTypeErrorLiteral,
137 NodeTypeSymbol,136 NodeTypeSymbol,
138 NodeTypePrefixOpExpr,137 NodeTypePrefixOpExpr,
139 NodeTypeFnCallExpr,138 NodeTypeFnCallExpr,
...@@ -161,6 +160,7 @@ enum NodeType {...@@ -161,6 +160,7 @@ enum NodeType {
161 NodeTypeContainerInitExpr,160 NodeTypeContainerInitExpr,
162 NodeTypeStructValueField,161 NodeTypeStructValueField,
163 NodeTypeArrayType,162 NodeTypeArrayType,
163 NodeTypeErrorType,
164};164};
165165
166struct AstNodeRoot {166struct AstNodeRoot {
...@@ -315,6 +315,7 @@ enum CastOp {...@@ -315,6 +315,7 @@ enum CastOp {
315 CastOpToUnknownSizeArray,315 CastOpToUnknownSizeArray,
316 CastOpMaybeWrap,316 CastOpMaybeWrap,
317 CastOpErrorWrap,317 CastOpErrorWrap,
318 CastOpPureErrorWrap,
318 CastOpPointerReinterpret,319 CastOpPointerReinterpret,
319 CastOpErrToInt,320 CastOpErrToInt,
320};321};
...@@ -584,13 +585,6 @@ struct AstNodeNumberLiteral {...@@ -584,13 +585,6 @@ struct AstNodeNumberLiteral {
584 Expr resolved_expr;585 Expr resolved_expr;
585};586};
586587
587struct AstNodeErrorLiteral {
588 Buf symbol;
589
590 // populated by semantic analyzer
591 Expr resolved_expr;
592};
593
594struct AstNodeStructValueField {588struct AstNodeStructValueField {
595 Buf name;589 Buf name;
596 AstNode *expr;590 AstNode *expr;
...@@ -663,6 +657,11 @@ struct AstNodeArrayType {...@@ -663,6 +657,11 @@ struct AstNodeArrayType {
663 Expr resolved_expr;657 Expr resolved_expr;
664};658};
665659
660struct AstNodeErrorType {
661 // populated by semantic analyzer
662 Expr resolved_expr;
663};
664
666struct AstNode {665struct AstNode {
667 enum NodeType type;666 enum NodeType type;
668 int line;667 int line;
...@@ -705,7 +704,6 @@ struct AstNode {...@@ -705,7 +704,6 @@ struct AstNode {
705 AstNodeStringLiteral string_literal;704 AstNodeStringLiteral string_literal;
706 AstNodeCharLiteral char_literal;705 AstNodeCharLiteral char_literal;
707 AstNodeNumberLiteral number_literal;706 AstNodeNumberLiteral number_literal;
708 AstNodeErrorLiteral error_literal;
709 AstNodeContainerInitExpr container_init_expr;707 AstNodeContainerInitExpr container_init_expr;
710 AstNodeStructValueField struct_val_field;708 AstNodeStructValueField struct_val_field;
711 AstNodeNullLiteral null_literal;709 AstNodeNullLiteral null_literal;
...@@ -715,6 +713,7 @@ struct AstNode {...@@ -715,6 +713,7 @@ struct AstNode {
715 AstNodeBreakExpr break_expr;713 AstNodeBreakExpr break_expr;
716 AstNodeContinueExpr continue_expr;714 AstNodeContinueExpr continue_expr;
717 AstNodeArrayType array_type;715 AstNodeArrayType array_type;
716 AstNodeErrorType error_type;
718 } data;717 } data;
719};718};
720719
...@@ -820,7 +819,8 @@ enum TypeTableEntryId {...@@ -820,7 +819,8 @@ enum TypeTableEntryId {
820 TypeTableEntryIdNumLitInt,819 TypeTableEntryIdNumLitInt,
821 TypeTableEntryIdUndefLit,820 TypeTableEntryIdUndefLit,
822 TypeTableEntryIdMaybe,821 TypeTableEntryIdMaybe,
823 TypeTableEntryIdError,822 TypeTableEntryIdErrorUnion,
823 TypeTableEntryIdPureError,
824 TypeTableEntryIdEnum,824 TypeTableEntryIdEnum,
825 TypeTableEntryIdFn,825 TypeTableEntryIdFn,
826};826};
...@@ -961,6 +961,7 @@ struct CodeGen {...@@ -961,6 +961,7 @@ struct CodeGen {
961 TypeTableEntry *entry_num_lit_int;961 TypeTableEntry *entry_num_lit_int;
962 TypeTableEntry *entry_num_lit_float;962 TypeTableEntry *entry_num_lit_float;
963 TypeTableEntry *entry_undef;963 TypeTableEntry *entry_undef;
964 TypeTableEntry *entry_pure_error;
964 } builtin_types;965 } builtin_types;
965966
966 LLVMTargetDataRef target_data_ref;967 LLVMTargetDataRef target_data_ref;
src/analyze.cpp+111-50
...@@ -19,6 +19,8 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE...@@ -19,6 +19,8 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
19static TypeTableEntry *unwrapped_node_type(AstNode *node);19static TypeTableEntry *unwrapped_node_type(AstNode *node);
20static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,20static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
21 AstNode *node);21 AstNode *node);
22static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import,
23 BlockContext *context, AstNode *node, Buf *err_name);
2224
23static AstNode *first_executing_node(AstNode *node) {25static AstNode *first_executing_node(AstNode *node) {
24 switch (node->type) {26 switch (node->type) {
...@@ -47,7 +49,6 @@ static AstNode *first_executing_node(AstNode *node) {...@@ -47,7 +49,6 @@ static AstNode *first_executing_node(AstNode *node) {
47 case NodeTypeVariableDeclaration:49 case NodeTypeVariableDeclaration:
48 case NodeTypeErrorValueDecl:50 case NodeTypeErrorValueDecl:
49 case NodeTypeNumberLiteral:51 case NodeTypeNumberLiteral:
50 case NodeTypeErrorLiteral:
51 case NodeTypeStringLiteral:52 case NodeTypeStringLiteral:
52 case NodeTypeCharLiteral:53 case NodeTypeCharLiteral:
53 case NodeTypeSymbol:54 case NodeTypeSymbol:
...@@ -71,6 +72,7 @@ static AstNode *first_executing_node(AstNode *node) {...@@ -71,6 +72,7 @@ static AstNode *first_executing_node(AstNode *node) {
71 case NodeTypeSwitchExpr:72 case NodeTypeSwitchExpr:
72 case NodeTypeSwitchProng:73 case NodeTypeSwitchProng:
73 case NodeTypeArrayType:74 case NodeTypeArrayType:
75 case NodeTypeErrorType:
74 case NodeTypeContainerInitExpr:76 case NodeTypeContainerInitExpr:
75 return node;77 return node;
76 }78 }
...@@ -110,7 +112,8 @@ TypeTableEntry *new_type_table_entry(TypeTableEntryId id) {...@@ -110,7 +112,8 @@ TypeTableEntry *new_type_table_entry(TypeTableEntryId id) {
110 case TypeTableEntryIdNumLitInt:112 case TypeTableEntryIdNumLitInt:
111 case TypeTableEntryIdMaybe:113 case TypeTableEntryIdMaybe:
112 case TypeTableEntryIdFn:114 case TypeTableEntryIdFn:
113 case TypeTableEntryIdError:115 case TypeTableEntryIdErrorUnion:
116 case TypeTableEntryIdPureError:
114 case TypeTableEntryIdUndefLit:117 case TypeTableEntryIdUndefLit:
115 // nothing to init118 // nothing to init
116 break;119 break;
...@@ -200,7 +203,7 @@ static TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {...@@ -200,7 +203,7 @@ static TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {
200 "val", di_file, line, child_type->size_in_bits, child_type->align_in_bits, 0, 0,203 "val", di_file, line, child_type->size_in_bits, child_type->align_in_bits, 0, 0,
201 child_type->di_type),204 child_type->di_type),
202 LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type),205 LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type),
203 "maybe", di_file, line, 8, 8, 8, 0,206 "maybe", di_file, line, 8, 8, child_type->size_in_bits, 0,
204 child_type->di_type),207 child_type->di_type),
205 };208 };
206 LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder,209 LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder,
...@@ -223,7 +226,7 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {...@@ -223,7 +226,7 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
223 if (child_type->error_parent) {226 if (child_type->error_parent) {
224 return child_type->error_parent;227 return child_type->error_parent;
225 } else {228 } else {
226 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdError);229 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdErrorUnion);
227 assert(child_type->type_ref);230 assert(child_type->type_ref);
228 assert(child_type->di_type);231 assert(child_type->di_type);
229232
...@@ -239,7 +242,38 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {...@@ -239,7 +242,38 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
239 entry->di_type = g->err_tag_type->di_type;242 entry->di_type = g->err_tag_type->di_type;
240243
241 } else {244 } else {
242 zig_panic("TODO get_error_type non-void");245 LLVMTypeRef elem_types[] = {
246 g->err_tag_type->type_ref,
247 child_type->type_ref,
248 };
249 entry->type_ref = LLVMStructType(elem_types, 2, false);
250 entry->size_in_bits = g->err_tag_type->size_in_bits + child_type->size_in_bits;
251 entry->align_in_bits = g->err_tag_type->align_in_bits;
252
253 LLVMZigDIScope *compile_unit_scope = LLVMZigCompileUnitToScope(g->compile_unit);
254 LLVMZigDIFile *di_file = nullptr;
255 unsigned line = 0;
256 entry->di_type = LLVMZigCreateReplaceableCompositeType(g->dbuilder,
257 LLVMZigTag_DW_structure_type(), buf_ptr(&entry->name),
258 compile_unit_scope, di_file, line);
259
260 LLVMZigDIType *di_element_types[] = {
261 LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type),
262 "tag", di_file, line, g->err_tag_type->size_in_bits, g->err_tag_type->align_in_bits,
263 0, 0, child_type->di_type),
264 LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type),
265 "value", di_file, line, child_type->size_in_bits, child_type->align_in_bits,
266 g->err_tag_type->size_in_bits, 0, child_type->di_type),
267 };
268
269 LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder,
270 compile_unit_scope,
271 buf_ptr(&entry->name),
272 di_file, line, entry->size_in_bits, entry->align_in_bits, 0,
273 nullptr, di_element_types, 2, 0, nullptr, "");
274
275 LLVMZigReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type);
276 entry->di_type = replacement_di_type;
243 }277 }
244278
245 child_type->error_parent = entry;279 child_type->error_parent = entry;
...@@ -1012,7 +1046,6 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode...@@ -1012,7 +1046,6 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
1012 case NodeTypeArrayAccessExpr:1046 case NodeTypeArrayAccessExpr:
1013 case NodeTypeSliceExpr:1047 case NodeTypeSliceExpr:
1014 case NodeTypeNumberLiteral:1048 case NodeTypeNumberLiteral:
1015 case NodeTypeErrorLiteral:
1016 case NodeTypeStringLiteral:1049 case NodeTypeStringLiteral:
1017 case NodeTypeCharLiteral:1050 case NodeTypeCharLiteral:
1018 case NodeTypeBoolLiteral:1051 case NodeTypeBoolLiteral:
...@@ -1037,6 +1070,7 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode...@@ -1037,6 +1070,7 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
1037 case NodeTypeStructValueField:1070 case NodeTypeStructValueField:
1038 case NodeTypeContainerInitExpr:1071 case NodeTypeContainerInitExpr:
1039 case NodeTypeArrayType:1072 case NodeTypeArrayType:
1073 case NodeTypeErrorType:
1040 zig_unreachable();1074 zig_unreachable();
1041 }1075 }
1042}1076}
...@@ -1083,7 +1117,8 @@ static bool type_has_codegen_value(TypeTableEntryId id) {...@@ -1083,7 +1117,8 @@ static bool type_has_codegen_value(TypeTableEntryId id) {
1083 case TypeTableEntryIdArray:1117 case TypeTableEntryIdArray:
1084 case TypeTableEntryIdStruct:1118 case TypeTableEntryIdStruct:
1085 case TypeTableEntryIdMaybe:1119 case TypeTableEntryIdMaybe:
1086 case TypeTableEntryIdError:1120 case TypeTableEntryIdErrorUnion:
1121 case TypeTableEntryIdPureError:
1087 case TypeTableEntryIdEnum:1122 case TypeTableEntryIdEnum:
1088 case TypeTableEntryIdFn:1123 case TypeTableEntryIdFn:
1089 return true;1124 return true;
...@@ -1166,8 +1201,8 @@ static bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTable...@@ -1166,8 +1201,8 @@ static bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTable
1166 }1201 }
11671202
1168 // error1203 // error
1169 if (expected_type->id == TypeTableEntryIdError &&1204 if (expected_type->id == TypeTableEntryIdErrorUnion &&
1170 actual_type->id == TypeTableEntryIdError)1205 actual_type->id == TypeTableEntryIdErrorUnion)
1171 {1206 {
1172 return types_match_const_cast_only(1207 return types_match_const_cast_only(
1173 expected_type->data.error.child_type,1208 expected_type->data.error.child_type,
...@@ -1224,11 +1259,11 @@ static TypeTableEntry *determine_peer_type_compatibility(CodeGen *g, AstNode *pa...@@ -1224,11 +1259,11 @@ static TypeTableEntry *determine_peer_type_compatibility(CodeGen *g, AstNode *pa
1224 prev_type = cur_type;1259 prev_type = cur_type;
1225 prev_node = cur_node;1260 prev_node = cur_node;
1226 }1261 }
1227 } else if (prev_type->id == TypeTableEntryIdError &&1262 } else if (prev_type->id == TypeTableEntryIdErrorUnion &&
1228 types_match_const_cast_only(prev_type->data.error.child_type, cur_type))1263 types_match_const_cast_only(prev_type->data.error.child_type, cur_type))
1229 {1264 {
1230 continue;1265 continue;
1231 } else if (cur_type->id == TypeTableEntryIdError &&1266 } else if (cur_type->id == TypeTableEntryIdErrorUnion &&
1232 types_match_const_cast_only(cur_type->data.error.child_type, prev_type))1267 types_match_const_cast_only(cur_type->data.error.child_type, prev_type))
1233 {1268 {
1234 prev_type = cur_type;1269 prev_type = cur_type;
...@@ -1287,13 +1322,20 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_...@@ -1287,13 +1322,20 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_
1287 }1322 }
12881323
1289 // implicit conversion from error child type to error type1324 // implicit conversion from error child type to error type
1290 if (expected_type->id == TypeTableEntryIdError &&1325 if (expected_type->id == TypeTableEntryIdErrorUnion &&
1291 types_match_with_implicit_cast(g, expected_type->data.error.child_type, actual_type,1326 types_match_with_implicit_cast(g, expected_type->data.error.child_type, actual_type,
1292 literal_node, reported_err))1327 literal_node, reported_err))
1293 {1328 {
1294 return true;1329 return true;
1295 }1330 }
12961331
1332 // implicit conversion from pure error to error union type
1333 if (expected_type->id == TypeTableEntryIdErrorUnion &&
1334 actual_type->id == TypeTableEntryIdPureError)
1335 {
1336 return true;
1337 }
1338
1297 // implicit widening conversion1339 // implicit widening conversion
1298 if (expected_type->id == TypeTableEntryIdInt &&1340 if (expected_type->id == TypeTableEntryIdInt &&
1299 actual_type->id == TypeTableEntryIdInt &&1341 actual_type->id == TypeTableEntryIdInt &&
...@@ -1695,12 +1737,11 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i...@@ -1695,12 +1737,11 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
16951737
1696 AstNode *struct_expr_node = node->data.field_access_expr.struct_expr;1738 AstNode *struct_expr_node = node->data.field_access_expr.struct_expr;
1697 TypeTableEntry *struct_type = analyze_expression(g, import, context, nullptr, struct_expr_node);1739 TypeTableEntry *struct_type = analyze_expression(g, import, context, nullptr, struct_expr_node);
1740 Buf *field_name = &node->data.field_access_expr.field_name;
16981741
1699 if (struct_type->id == TypeTableEntryIdStruct || (struct_type->id == TypeTableEntryIdPointer &&1742 if (struct_type->id == TypeTableEntryIdStruct || (struct_type->id == TypeTableEntryIdPointer &&
1700 struct_type->data.pointer.child_type->id == TypeTableEntryIdStruct))1743 struct_type->data.pointer.child_type->id == TypeTableEntryIdStruct))
1701 {1744 {
1702 Buf *field_name = &node->data.field_access_expr.field_name;
1703
1704 TypeTableEntry *bare_struct_type = (struct_type->id == TypeTableEntryIdStruct) ?1745 TypeTableEntry *bare_struct_type = (struct_type->id == TypeTableEntryIdStruct) ?
1705 struct_type : struct_type->data.pointer.child_type;1746 struct_type : struct_type->data.pointer.child_type;
17061747
...@@ -1713,15 +1754,14 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i...@@ -1713,15 +1754,14 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
1713 return g->builtin_types.entry_invalid;1754 return g->builtin_types.entry_invalid;
1714 }1755 }
1715 } else if (struct_type->id == TypeTableEntryIdArray) {1756 } else if (struct_type->id == TypeTableEntryIdArray) {
1716 Buf *name = &node->data.field_access_expr.field_name;1757 if (buf_eql_str(field_name, "len")) {
1717 if (buf_eql_str(name, "len")) {
1718 return g->builtin_types.entry_isize;1758 return g->builtin_types.entry_isize;
1719 } else if (buf_eql_str(name, "ptr")) {1759 } else if (buf_eql_str(field_name, "ptr")) {
1720 // TODO determine whether the pointer should be const1760 // TODO determine whether the pointer should be const
1721 return get_pointer_to_type(g, struct_type->data.array.child_type, false);1761 return get_pointer_to_type(g, struct_type->data.array.child_type, false);
1722 } else {1762 } else {
1723 add_node_error(g, node,1763 add_node_error(g, node,
1724 buf_sprintf("no member named '%s' in '%s'", buf_ptr(name),1764 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name),
1725 buf_ptr(&struct_type->name)));1765 buf_ptr(&struct_type->name)));
1726 return g->builtin_types.entry_invalid;1766 return g->builtin_types.entry_invalid;
1727 }1767 }
...@@ -1731,8 +1771,9 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i...@@ -1731,8 +1771,9 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
1731 if (enum_type->id == TypeTableEntryIdInvalid) {1771 if (enum_type->id == TypeTableEntryIdInvalid) {
1732 return g->builtin_types.entry_invalid;1772 return g->builtin_types.entry_invalid;
1733 } else if (enum_type->id == TypeTableEntryIdEnum) {1773 } else if (enum_type->id == TypeTableEntryIdEnum) {
1734 Buf *field_name = &node->data.field_access_expr.field_name;
1735 return analyze_enum_value_expr(g, import, context, node, nullptr, enum_type, field_name);1774 return analyze_enum_value_expr(g, import, context, node, nullptr, enum_type, field_name);
1775 } else if (enum_type->id == TypeTableEntryIdPureError) {
1776 return analyze_error_literal_expr(g, import, context, node, field_name);
1736 } else {1777 } else {
1737 add_node_error(g, node,1778 add_node_error(g, node,
1738 buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name)));1779 buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name)));
...@@ -1846,7 +1887,7 @@ static TypeTableEntry *resolve_expr_const_val_as_err(CodeGen *g, AstNode *node,...@@ -1846,7 +1887,7 @@ static TypeTableEntry *resolve_expr_const_val_as_err(CodeGen *g, AstNode *node,
1846 Expr *expr = get_resolved_expr(node);1887 Expr *expr = get_resolved_expr(node);
1847 expr->const_val.ok = true;1888 expr->const_val.ok = true;
1848 expr->const_val.data.x_err.err = err;1889 expr->const_val.data.x_err.err = err;
1849 return get_error_type(g, g->builtin_types.entry_void);1890 return g->builtin_types.entry_pure_error;
1850}1891}
18511892
1852static TypeTableEntry *resolve_expr_const_val_as_bool(CodeGen *g, AstNode *node, bool value) {1893static TypeTableEntry *resolve_expr_const_val_as_bool(CodeGen *g, AstNode *node, bool value) {
...@@ -1959,6 +2000,21 @@ static TypeTableEntry *resolve_expr_const_val_as_bignum_op(CodeGen *g, AstNode *...@@ -1959,6 +2000,21 @@ static TypeTableEntry *resolve_expr_const_val_as_bignum_op(CodeGen *g, AstNode *
1959 return resolved_type;2000 return resolved_type;
1960}2001}
19612002
2003static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import,
2004 BlockContext *context, AstNode *node, Buf *err_name)
2005{
2006 auto err_table_entry = import->block_context->error_table.maybe_get(err_name);
2007
2008 if (err_table_entry) {
2009 return resolve_expr_const_val_as_err(g, node, err_table_entry->value);
2010 }
2011
2012 add_node_error(g, node,
2013 buf_sprintf("use of undeclared error value '%s'", buf_ptr(err_name)));
2014
2015 return get_error_type(g, g->builtin_types.entry_void);
2016}
2017
19622018
1963static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,2019static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
1964 TypeTableEntry *expected_type, AstNode *node)2020 TypeTableEntry *expected_type, AstNode *node)
...@@ -2564,23 +2620,6 @@ static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry...@@ -2564,23 +2620,6 @@ static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry
2564 }2620 }
2565}2621}
25662622
2567static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import,
2568 BlockContext *block_context, TypeTableEntry *expected_type, AstNode *node)
2569{
2570 Buf *err_name = &node->data.error_literal.symbol;
2571
2572 auto err_table_entry = import->block_context->error_table.maybe_get(err_name);
2573
2574 if (err_table_entry) {
2575 return resolve_expr_const_val_as_err(g, node, err_table_entry->value);
2576 }
2577
2578 add_node_error(g, node,
2579 buf_sprintf("use of undeclared error value '%s'", buf_ptr(err_name)));
2580
2581 return get_error_type(g, g->builtin_types.entry_void);
2582}
2583
2584static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import, BlockContext *context,2623static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import, BlockContext *context,
2585 TypeTableEntry *expected_type, AstNode *node)2624 TypeTableEntry *expected_type, AstNode *node)
2586{2625{
...@@ -2906,6 +2945,10 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex...@@ -2906,6 +2945,10 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex
2906 const_val->data.x_err.payload = other_val;2945 const_val->data.x_err.payload = other_val;
2907 const_val->ok = true;2946 const_val->ok = true;
2908 break;2947 break;
2948 case CastOpPureErrorWrap:
2949 const_val->data.x_err.err = other_val->data.x_err.err;
2950 const_val->ok = true;
2951 break;
2909 case CastOpErrToInt:2952 case CastOpErrToInt:
2910 {2953 {
2911 uint64_t value = other_val->data.x_err.err ? other_val->data.x_err.err->value : 0;2954 uint64_t value = other_val->data.x_err.err ? other_val->data.x_err.err->value : 0;
...@@ -3007,7 +3050,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B...@@ -3007,7 +3050,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
3007 }3050 }
30083051
3009 // explicit cast from child type of error type to error type3052 // explicit cast from child type of error type to error type
3010 if (wanted_type->id == TypeTableEntryIdError) {3053 if (wanted_type->id == TypeTableEntryIdErrorUnion) {
3011 if (types_match_const_cast_only(wanted_type->data.error.child_type, actual_type)) {3054 if (types_match_const_cast_only(wanted_type->data.error.child_type, actual_type)) {
3012 node->data.fn_call_expr.cast_op = CastOpErrorWrap;3055 node->data.fn_call_expr.cast_op = CastOpErrorWrap;
3013 eval_const_expr_implicit_cast(g, node, expr_node);3056 eval_const_expr_implicit_cast(g, node, expr_node);
...@@ -3025,6 +3068,15 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B...@@ -3025,6 +3068,15 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
3025 }3068 }
3026 }3069 }
30273070
3071 // explicit cast from pure error to error union type
3072 if (wanted_type->id == TypeTableEntryIdErrorUnion &&
3073 actual_type->id == TypeTableEntryIdPureError)
3074 {
3075 node->data.fn_call_expr.cast_op = CastOpPureErrorWrap;
3076 eval_const_expr_implicit_cast(g, node, expr_node);
3077 return wanted_type;
3078 }
3079
3028 // explicit cast from number literal to another type3080 // explicit cast from number literal to another type
3029 if (actual_type->id == TypeTableEntryIdNumLitFloat ||3081 if (actual_type->id == TypeTableEntryIdNumLitFloat ||
3030 actual_type->id == TypeTableEntryIdNumLitInt)3082 actual_type->id == TypeTableEntryIdNumLitInt)
...@@ -3039,8 +3091,10 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B...@@ -3039,8 +3091,10 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
3039 }3091 }
30403092
3041 // explicit cast from %void to integer type which can fit it3093 // explicit cast from %void to integer type which can fit it
3042 if (actual_type->id == TypeTableEntryIdError &&3094 bool actual_type_is_void_err = actual_type->id == TypeTableEntryIdErrorUnion &&
3043 actual_type->data.error.child_type->size_in_bits == 0 &&3095 actual_type->data.error.child_type->size_in_bits == 0;
3096 bool actual_type_is_pure_err = actual_type->id == TypeTableEntryIdPureError;
3097 if ((actual_type_is_void_err || actual_type_is_pure_err) &&
3044 wanted_type->id == TypeTableEntryIdInt)3098 wanted_type->id == TypeTableEntryIdInt)
3045 {3099 {
3046 BigNum bn;3100 BigNum bn;
...@@ -3754,9 +3808,6 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -3754,9 +3808,6 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import,
3754 case NodeTypeNumberLiteral:3808 case NodeTypeNumberLiteral:
3755 return_type = analyze_number_literal_expr(g, import, context, expected_type, node);3809 return_type = analyze_number_literal_expr(g, import, context, expected_type, node);
3756 break;3810 break;
3757 case NodeTypeErrorLiteral:
3758 return_type = analyze_error_literal_expr(g, import, context, expected_type, node);
3759 break;
3760 case NodeTypeStringLiteral:3811 case NodeTypeStringLiteral:
3761 return_type = analyze_string_literal_expr(g, import, context, expected_type, node);3812 return_type = analyze_string_literal_expr(g, import, context, expected_type, node);
3762 break;3813 break;
...@@ -3794,6 +3845,9 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -3794,6 +3845,9 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import,
3794 case NodeTypeArrayType:3845 case NodeTypeArrayType:
3795 return_type = analyze_array_type(g, import, context, expected_type, node);3846 return_type = analyze_array_type(g, import, context, expected_type, node);
3796 break;3847 break;
3848 case NodeTypeErrorType:
3849 return_type = resolve_expr_const_val_as_type(g, node, g->builtin_types.entry_pure_error);
3850 break;
3797 case NodeTypeSwitchExpr:3851 case NodeTypeSwitchExpr:
3798 return_type = analyze_switch_expr(g, import, context, expected_type, node);3852 return_type = analyze_switch_expr(g, import, context, expected_type, node);
3799 break;3853 break;
...@@ -3933,7 +3987,6 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode...@@ -3933,7 +3987,6 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
3933 case NodeTypeArrayAccessExpr:3987 case NodeTypeArrayAccessExpr:
3934 case NodeTypeSliceExpr:3988 case NodeTypeSliceExpr:
3935 case NodeTypeNumberLiteral:3989 case NodeTypeNumberLiteral:
3936 case NodeTypeErrorLiteral:
3937 case NodeTypeStringLiteral:3990 case NodeTypeStringLiteral:
3938 case NodeTypeCharLiteral:3991 case NodeTypeCharLiteral:
3939 case NodeTypeBoolLiteral:3992 case NodeTypeBoolLiteral:
...@@ -3958,6 +4011,7 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode...@@ -3958,6 +4011,7 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
3958 case NodeTypeStructValueField:4011 case NodeTypeStructValueField:
3959 case NodeTypeContainerInitExpr:4012 case NodeTypeContainerInitExpr:
3960 case NodeTypeArrayType:4013 case NodeTypeArrayType:
4014 case NodeTypeErrorType:
3961 zig_unreachable();4015 zig_unreachable();
3962 }4016 }
3963}4017}
...@@ -3967,7 +4021,6 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode...@@ -3967,7 +4021,6 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode
3967{4021{
3968 switch (node->type) {4022 switch (node->type) {
3969 case NodeTypeNumberLiteral:4023 case NodeTypeNumberLiteral:
3970 case NodeTypeErrorLiteral:
3971 case NodeTypeStringLiteral:4024 case NodeTypeStringLiteral:
3972 case NodeTypeCharLiteral:4025 case NodeTypeCharLiteral:
3973 case NodeTypeBoolLiteral:4026 case NodeTypeBoolLiteral:
...@@ -3977,6 +4030,7 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode...@@ -3977,6 +4030,7 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode
3977 case NodeTypeBreak:4030 case NodeTypeBreak:
3978 case NodeTypeContinue:4031 case NodeTypeContinue:
3979 case NodeTypeErrorValueDecl:4032 case NodeTypeErrorValueDecl:
4033 case NodeTypeErrorType:
3980 // no dependencies on other top level declarations4034 // no dependencies on other top level declarations
3981 break;4035 break;
3982 case NodeTypeSymbol:4036 case NodeTypeSymbol:
...@@ -4286,7 +4340,6 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast...@@ -4286,7 +4340,6 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
4286 case NodeTypeArrayAccessExpr:4340 case NodeTypeArrayAccessExpr:
4287 case NodeTypeSliceExpr:4341 case NodeTypeSliceExpr:
4288 case NodeTypeNumberLiteral:4342 case NodeTypeNumberLiteral:
4289 case NodeTypeErrorLiteral:
4290 case NodeTypeStringLiteral:4343 case NodeTypeStringLiteral:
4291 case NodeTypeCharLiteral:4344 case NodeTypeCharLiteral:
4292 case NodeTypeBoolLiteral:4345 case NodeTypeBoolLiteral:
...@@ -4311,6 +4364,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast...@@ -4311,6 +4364,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
4311 case NodeTypeContainerInitExpr:4364 case NodeTypeContainerInitExpr:
4312 case NodeTypeStructValueField:4365 case NodeTypeStructValueField:
4313 case NodeTypeArrayType:4366 case NodeTypeArrayType:
4367 case NodeTypeErrorType:
4314 zig_unreachable();4368 zig_unreachable();
4315 }4369 }
4316}4370}
...@@ -4419,7 +4473,14 @@ void semantic_analyze(CodeGen *g) {...@@ -4419,7 +4473,14 @@ void semantic_analyze(CodeGen *g) {
4419 }4473 }
4420 }4474 }
44214475
4422 g->err_tag_type = get_smallest_unsigned_int_type(g, g->error_value_count);4476 {
4477 g->err_tag_type = get_smallest_unsigned_int_type(g, g->error_value_count);
4478
4479 g->builtin_types.entry_pure_error->type_ref = g->err_tag_type->type_ref;
4480 g->builtin_types.entry_pure_error->size_in_bits = g->err_tag_type->size_in_bits;
4481 g->builtin_types.entry_pure_error->align_in_bits = g->err_tag_type->align_in_bits;
4482 g->builtin_types.entry_pure_error->di_type = g->err_tag_type->di_type;
4483 }
44234484
4424 {4485 {
4425 auto it = g->import_table.entry_iterator();4486 auto it = g->import_table.entry_iterator();
...@@ -4493,8 +4554,6 @@ Expr *get_resolved_expr(AstNode *node) {...@@ -4493,8 +4554,6 @@ Expr *get_resolved_expr(AstNode *node) {
4493 return &node->data.container_init_expr.resolved_expr;4554 return &node->data.container_init_expr.resolved_expr;
4494 case NodeTypeNumberLiteral:4555 case NodeTypeNumberLiteral:
4495 return &node->data.number_literal.resolved_expr;4556 return &node->data.number_literal.resolved_expr;
4496 case NodeTypeErrorLiteral:
4497 return &node->data.error_literal.resolved_expr;
4498 case NodeTypeStringLiteral:4557 case NodeTypeStringLiteral:
4499 return &node->data.string_literal.resolved_expr;4558 return &node->data.string_literal.resolved_expr;
4500 case NodeTypeBlock:4559 case NodeTypeBlock:
...@@ -4521,6 +4580,8 @@ Expr *get_resolved_expr(AstNode *node) {...@@ -4521,6 +4580,8 @@ Expr *get_resolved_expr(AstNode *node) {
4521 return &node->data.label.resolved_expr;4580 return &node->data.label.resolved_expr;
4522 case NodeTypeArrayType:4581 case NodeTypeArrayType:
4523 return &node->data.array_type.resolved_expr;4582 return &node->data.array_type.resolved_expr;
4583 case NodeTypeErrorType:
4584 return &node->data.error_type.resolved_expr;
4524 case NodeTypeSwitchExpr:4585 case NodeTypeSwitchExpr:
4525 return &node->data.switch_expr.resolved_expr;4586 return &node->data.switch_expr.resolved_expr;
4526 case NodeTypeSwitchProng:4587 case NodeTypeSwitchProng:
...@@ -4554,7 +4615,6 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) {...@@ -4554,7 +4615,6 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) {
4554 case NodeTypeErrorValueDecl:4615 case NodeTypeErrorValueDecl:
4555 return &node->data.error_value_decl.top_level_decl;4616 return &node->data.error_value_decl.top_level_decl;
4556 case NodeTypeNumberLiteral:4617 case NodeTypeNumberLiteral:
4557 case NodeTypeErrorLiteral:
4558 case NodeTypeReturnExpr:4618 case NodeTypeReturnExpr:
4559 case NodeTypeBinOpExpr:4619 case NodeTypeBinOpExpr:
4560 case NodeTypePrefixOpExpr:4620 case NodeTypePrefixOpExpr:
...@@ -4593,6 +4653,7 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) {...@@ -4593,6 +4653,7 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) {
4593 case NodeTypeStructField:4653 case NodeTypeStructField:
4594 case NodeTypeStructValueField:4654 case NodeTypeStructValueField:
4595 case NodeTypeArrayType:4655 case NodeTypeArrayType:
4656 case NodeTypeErrorType:
4596 zig_unreachable();4657 zig_unreachable();
4597 }4658 }
4598 zig_unreachable();4659 zig_unreachable();
src/codegen.cpp+39-7
...@@ -306,7 +306,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {...@@ -306,7 +306,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
306 case CastOpNoop:306 case CastOpNoop:
307 return expr_val;307 return expr_val;
308 case CastOpErrToInt:308 case CastOpErrToInt:
309 assert(actual_type->id == TypeTableEntryIdError);309 assert(actual_type->id == TypeTableEntryIdErrorUnion);
310 if (actual_type->data.error.child_type->size_in_bits == 0) {310 if (actual_type->data.error.child_type->size_in_bits == 0) {
311 return gen_widen_or_shorten(g, node, g->err_tag_type, wanted_type, expr_val);311 return gen_widen_or_shorten(g, node, g->err_tag_type, wanted_type, expr_val);
312 } else {312 } else {
...@@ -330,12 +330,19 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {...@@ -330,12 +330,19 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
330 return cast_expr->tmp_ptr;330 return cast_expr->tmp_ptr;
331 }331 }
332 case CastOpErrorWrap:332 case CastOpErrorWrap:
333 assert(wanted_type->id == TypeTableEntryIdError);333 assert(wanted_type->id == TypeTableEntryIdErrorUnion);
334 if (wanted_type->data.error.child_type->size_in_bits == 0) {334 if (wanted_type->data.error.child_type->size_in_bits == 0) {
335 return LLVMConstNull(g->err_tag_type->type_ref);335 return LLVMConstNull(g->err_tag_type->type_ref);
336 } else {336 } else {
337 zig_panic("TODO");337 zig_panic("TODO");
338 }338 }
339 case CastOpPureErrorWrap:
340 assert(wanted_type->id == TypeTableEntryIdErrorUnion);
341 if (wanted_type->data.error.child_type->size_in_bits == 0) {
342 return expr_val;
343 } else {
344 zig_panic("TODO");
345 }
339 case CastOpPtrToInt:346 case CastOpPtrToInt:
340 add_debug_source_node(g, node);347 add_debug_source_node(g, node);
341 return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, "");348 return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, "");
...@@ -1292,7 +1299,7 @@ static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMV...@@ -1292,7 +1299,7 @@ static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMV
1292 return nullptr;1299 return nullptr;
1293 }1300 }
12941301
1295 assert(!use_expr_value || then_type->id == TypeTableEntryIdError);1302 assert(!use_expr_value || then_type->id == TypeTableEntryIdErrorUnion);
12961303
1297 LLVMBasicBlockRef then_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "Then");1304 LLVMBasicBlockRef then_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "Then");
1298 LLVMBasicBlockRef endif_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "EndIf");1305 LLVMBasicBlockRef endif_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "EndIf");
...@@ -2011,7 +2018,6 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {...@@ -2011,7 +2018,6 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
2011 return gen_container_init_expr(g, node);2018 return gen_container_init_expr(g, node);
2012 case NodeTypeSwitchExpr:2019 case NodeTypeSwitchExpr:
2013 return gen_switch_expr(g, node);2020 return gen_switch_expr(g, node);
2014 case NodeTypeErrorLiteral:
2015 case NodeTypeNumberLiteral:2021 case NodeTypeNumberLiteral:
2016 case NodeTypeBoolLiteral:2022 case NodeTypeBoolLiteral:
2017 case NodeTypeStringLiteral:2023 case NodeTypeStringLiteral:
...@@ -2033,6 +2039,7 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {...@@ -2033,6 +2039,7 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
2033 case NodeTypeStructField:2039 case NodeTypeStructField:
2034 case NodeTypeStructValueField:2040 case NodeTypeStructValueField:
2035 case NodeTypeArrayType:2041 case NodeTypeArrayType:
2042 case NodeTypeErrorType:
2036 case NodeTypeSwitchProng:2043 case NodeTypeSwitchProng:
2037 case NodeTypeSwitchRange:2044 case NodeTypeSwitchRange:
2038 case NodeTypeErrorValueDecl:2045 case NodeTypeErrorValueDecl:
...@@ -2063,6 +2070,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE...@@ -2063,6 +2070,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
20632070
2064 if (type_entry->id == TypeTableEntryIdInt) {2071 if (type_entry->id == TypeTableEntryIdInt) {
2065 return LLVMConstInt(type_entry->type_ref, bignum_to_twos_complement(&const_val->data.x_bignum), false);2072 return LLVMConstInt(type_entry->type_ref, bignum_to_twos_complement(&const_val->data.x_bignum), false);
2073 } else if (type_entry->id == TypeTableEntryIdPureError) {
2074 assert(const_val->data.x_err.err);
2075 return LLVMConstInt(g->builtin_types.entry_pure_error->type_ref, const_val->data.x_err.err->value, false);
2066 } else if (type_entry->id == TypeTableEntryIdFloat) {2076 } else if (type_entry->id == TypeTableEntryIdFloat) {
2067 if (const_val->data.x_bignum.kind == BigNumKindFloat) {2077 if (const_val->data.x_bignum.kind == BigNumKindFloat) {
2068 return LLVMConstReal(type_entry->type_ref, const_val->data.x_bignum.data.x_float);2078 return LLVMConstReal(type_entry->type_ref, const_val->data.x_bignum.data.x_float);
...@@ -2148,12 +2158,26 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE...@@ -2148,12 +2158,26 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
2148 } else {2158 } else {
2149 return global_value;2159 return global_value;
2150 }2160 }
2151 } else if (type_entry->id == TypeTableEntryIdError) {2161 } else if (type_entry->id == TypeTableEntryIdErrorUnion) {
2152 if (type_entry->data.error.child_type->size_in_bits == 0) {2162 TypeTableEntry *child_type = type_entry->data.error.child_type;
2163 if (child_type->size_in_bits == 0) {
2153 uint64_t value = const_val->data.x_err.err ? const_val->data.x_err.err->value : 0;2164 uint64_t value = const_val->data.x_err.err ? const_val->data.x_err.err->value : 0;
2154 return LLVMConstInt(g->err_tag_type->type_ref, value, false);2165 return LLVMConstInt(g->err_tag_type->type_ref, value, false);
2155 } else {2166 } else {
2156 zig_panic("TODO");2167 LLVMValueRef err_tag_value;
2168 LLVMValueRef err_payload_value;
2169 if (const_val->data.x_err.err) {
2170 err_tag_value = LLVMConstInt(g->err_tag_type->type_ref, const_val->data.x_err.err->value, false);
2171 err_payload_value = LLVMConstNull(child_type->type_ref);
2172 } else {
2173 err_tag_value = LLVMConstNull(g->err_tag_type->type_ref);
2174 err_payload_value = gen_const_val(g, child_type, const_val->data.x_err.payload);
2175 }
2176 LLVMValueRef fields[] = {
2177 err_tag_value,
2178 err_payload_value,
2179 };
2180 return LLVMConstStruct(fields, 2, false);
2157 }2181 }
2158 } else {2182 } else {
2159 zig_unreachable();2183 zig_unreachable();
...@@ -2557,6 +2581,14 @@ static void define_builtin_types(CodeGen *g) {...@@ -2557,6 +2581,14 @@ static void define_builtin_types(CodeGen *g) {
2557 g->builtin_types.entry_type = entry;2581 g->builtin_types.entry_type = entry;
2558 g->primitive_type_table.put(&entry->name, entry);2582 g->primitive_type_table.put(&entry->name, entry);
2559 }2583 }
2584 {
2585 // partially complete the error type. we complete it later after we know
2586 // error_value_count.
2587 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPureError);
2588 buf_init_from_str(&entry->name, "error");
2589 g->builtin_types.entry_pure_error = entry;
2590 g->primitive_type_table.put(&entry->name, entry);
2591 }
25602592
2561 g->builtin_types.entry_u8 = get_int_type(g, false, 8);2593 g->builtin_types.entry_u8 = get_int_type(g, false, 8);
2562 g->builtin_types.entry_u16 = get_int_type(g, false, 16);2594 g->builtin_types.entry_u16 = get_int_type(g, false, 16);
src/parser.cpp+18-22
...@@ -113,8 +113,6 @@ const char *node_type_str(NodeType node_type) {...@@ -113,8 +113,6 @@ const char *node_type_str(NodeType node_type) {
113 return "ErrorValueDecl";113 return "ErrorValueDecl";
114 case NodeTypeNumberLiteral:114 case NodeTypeNumberLiteral:
115 return "NumberLiteral";115 return "NumberLiteral";
116 case NodeTypeErrorLiteral:
117 return "ErrorLiteral";
118 case NodeTypeStringLiteral:116 case NodeTypeStringLiteral:
119 return "StringLiteral";117 return "StringLiteral";
120 case NodeTypeCharLiteral:118 case NodeTypeCharLiteral:
...@@ -167,6 +165,8 @@ const char *node_type_str(NodeType node_type) {...@@ -167,6 +165,8 @@ const char *node_type_str(NodeType node_type) {
167 return "ContainerInitExpr";165 return "ContainerInitExpr";
168 case NodeTypeArrayType:166 case NodeTypeArrayType:
169 return "ArrayType";167 return "ArrayType";
168 case NodeTypeErrorType:
169 return "ErrorType";
170 }170 }
171 zig_unreachable();171 zig_unreachable();
172}172}
...@@ -313,11 +313,6 @@ void ast_print(AstNode *node, int indent) {...@@ -313,11 +313,6 @@ void ast_print(AstNode *node, int indent) {
313 }313 }
314 break;314 break;
315 }315 }
316 case NodeTypeErrorLiteral:
317 {
318 fprintf(stderr, "%s '%s'", node_type_str(node->type), buf_ptr(&node->data.error_literal.symbol));
319 break;
320 }
321 case NodeTypeStringLiteral:316 case NodeTypeStringLiteral:
322 {317 {
323 const char *c = node->data.string_literal.c ? "c" : "";318 const char *c = node->data.string_literal.c ? "c" : "";
...@@ -465,6 +460,9 @@ void ast_print(AstNode *node, int indent) {...@@ -465,6 +460,9 @@ void ast_print(AstNode *node, int indent) {
465 ast_print(node->data.array_type.child_type, indent + 2);460 ast_print(node->data.array_type.child_type, indent + 2);
466 break;461 break;
467 }462 }
463 case NodeTypeErrorType:
464 fprintf(stderr, "%s\n", node_type_str(node->type));
465 break;
468 }466 }
469}467}
470468
...@@ -1372,8 +1370,8 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, int *token_index, bool mand...@@ -1372,8 +1370,8 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, int *token_index, bool mand
1372}1370}
13731371
1374/*1372/*
1375PrimaryExpression : "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | AsmExpression | ("%." "Symbol")1373PrimaryExpression : "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | AsmExpression | ("error" "." "Symbol")
1376KeywordLiteral : "true" | "false" | "null" | "break" | "continue" | "undefined"1374KeywordLiteral : "true" | "false" | "null" | "break" | "continue" | "undefined" | "error"
1377*/1375*/
1378static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) {1376static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) {
1379 Token *token = &pc->tokens->at(*token_index);1377 Token *token = &pc->tokens->at(*token_index);
...@@ -1419,6 +1417,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool...@@ -1419,6 +1417,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
1419 AstNode *node = ast_create_node(pc, NodeTypeUndefinedLiteral, token);1417 AstNode *node = ast_create_node(pc, NodeTypeUndefinedLiteral, token);
1420 *token_index += 1;1418 *token_index += 1;
1421 return node;1419 return node;
1420 } else if (token->id == TokenIdKeywordError) {
1421 AstNode *node = ast_create_node(pc, NodeTypeErrorType, token);
1422 *token_index += 1;
1423 return node;
1422 } else if (token->id == TokenIdAtSign) {1424 } else if (token->id == TokenIdAtSign) {
1423 *token_index += 1;1425 *token_index += 1;
1424 Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol);1426 Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol);
...@@ -1448,12 +1450,6 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool...@@ -1448,12 +1450,6 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
14481450
1449 ast_buf_from_token(pc, dest_symbol, &node->data.goto_expr.name);1451 ast_buf_from_token(pc, dest_symbol, &node->data.goto_expr.name);
1450 return node;1452 return node;
1451 } else if (token->id == TokenIdPercentDot) {
1452 *token_index += 1;
1453 Token *symbol_tok = ast_eat_token(pc, token_index, TokenIdSymbol);
1454 AstNode *node = ast_create_node(pc, NodeTypeErrorLiteral, token);
1455 ast_buf_from_token(pc, symbol_tok, &node->data.error_literal.symbol);
1456 return node;
1457 }1453 }
14581454
1459 AstNode *grouped_expr_node = ast_parse_grouped_expr(pc, token_index, false);1455 AstNode *grouped_expr_node = ast_parse_grouped_expr(pc, token_index, false);
...@@ -2969,7 +2965,7 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) {...@@ -2969,7 +2965,7 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) {
2969}2965}
29702966
2971/*2967/*
2972ErrorValueDecl : option(FnVisibleMod) "%." "Symbol"2968ErrorValueDecl : option(FnVisibleMod) "error" "Symbol"
2973*/2969*/
2974static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, bool mandatory) {2970static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, bool mandatory) {
2975 Token *first_token = &pc->tokens->at(*token_index);2971 Token *first_token = &pc->tokens->at(*token_index);
...@@ -2978,7 +2974,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, b...@@ -2978,7 +2974,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, b
29782974
2979 if (first_token->id == TokenIdKeywordPub) {2975 if (first_token->id == TokenIdKeywordPub) {
2980 Token *next_token = &pc->tokens->at(*token_index + 1);2976 Token *next_token = &pc->tokens->at(*token_index + 1);
2981 if (next_token->id == TokenIdPercentDot) {2977 if (next_token->id == TokenIdKeywordError) {
2982 visib_mod = VisibModPub;2978 visib_mod = VisibModPub;
2983 *token_index += 2;2979 *token_index += 2;
2984 } else if (mandatory) {2980 } else if (mandatory) {
...@@ -2988,7 +2984,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, b...@@ -2988,7 +2984,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, b
2988 }2984 }
2989 } else if (first_token->id == TokenIdKeywordExport) {2985 } else if (first_token->id == TokenIdKeywordExport) {
2990 Token *next_token = &pc->tokens->at(*token_index + 1);2986 Token *next_token = &pc->tokens->at(*token_index + 1);
2991 if (next_token->id == TokenIdPercentDot) {2987 if (next_token->id == TokenIdKeywordError) {
2992 visib_mod = VisibModExport;2988 visib_mod = VisibModExport;
2993 *token_index += 2;2989 *token_index += 2;
2994 } else if (mandatory) {2990 } else if (mandatory) {
...@@ -2996,7 +2992,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, b...@@ -2996,7 +2992,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, b
2996 } else {2992 } else {
2997 return nullptr;2993 return nullptr;
2998 }2994 }
2999 } else if (first_token->id == TokenIdPercentDot) {2995 } else if (first_token->id == TokenIdKeywordError) {
3000 visib_mod = VisibModPrivate;2996 visib_mod = VisibModPrivate;
3001 *token_index += 1;2997 *token_index += 1;
3002 } else if (mandatory) {2998 } else if (mandatory) {
...@@ -3177,9 +3173,6 @@ void normalize_parent_ptrs(AstNode *node) {...@@ -3177,9 +3173,6 @@ void normalize_parent_ptrs(AstNode *node) {
3177 case NodeTypeCharLiteral:3173 case NodeTypeCharLiteral:
3178 // none3174 // none
3179 break;3175 break;
3180 case NodeTypeErrorLiteral:
3181 // none
3182 break;
3183 case NodeTypeSymbol:3176 case NodeTypeSymbol:
3184 // none3177 // none
3185 break;3178 break;
...@@ -3290,5 +3283,8 @@ void normalize_parent_ptrs(AstNode *node) {...@@ -3290,5 +3283,8 @@ void normalize_parent_ptrs(AstNode *node) {
3290 set_field(&node->data.array_type.size);3283 set_field(&node->data.array_type.size);
3291 set_field(&node->data.array_type.child_type);3284 set_field(&node->data.array_type.child_type);
3292 break;3285 break;
3286 case NodeTypeErrorType:
3287 // none
3288 break;
3293 }3289 }
3294}3290}
src/tokenizer.cpp+3
...@@ -247,6 +247,8 @@ static void end_token(Tokenize *t) {...@@ -247,6 +247,8 @@ static void end_token(Tokenize *t) {
247 t->cur_tok->id = TokenIdKeywordSwitch;247 t->cur_tok->id = TokenIdKeywordSwitch;
248 } else if (mem_eql_str(token_mem, token_len, "undefined")) {248 } else if (mem_eql_str(token_mem, token_len, "undefined")) {
249 t->cur_tok->id = TokenIdKeywordUndefined;249 t->cur_tok->id = TokenIdKeywordUndefined;
250 } else if (mem_eql_str(token_mem, token_len, "error")) {
251 t->cur_tok->id = TokenIdKeywordError;
250 }252 }
251253
252 t->cur_tok = nullptr;254 t->cur_tok = nullptr;
...@@ -1046,6 +1048,7 @@ const char * token_name(TokenId id) {...@@ -1046,6 +1048,7 @@ const char * token_name(TokenId id) {
1046 case TokenIdKeywordNoAlias: return "noalias";1048 case TokenIdKeywordNoAlias: return "noalias";
1047 case TokenIdKeywordSwitch: return "switch";1049 case TokenIdKeywordSwitch: return "switch";
1048 case TokenIdKeywordUndefined: return "undefined";1050 case TokenIdKeywordUndefined: return "undefined";
1051 case TokenIdKeywordError: return "error";
1049 case TokenIdLParen: return "(";1052 case TokenIdLParen: return "(";
1050 case TokenIdRParen: return ")";1053 case TokenIdRParen: return ")";
1051 case TokenIdComma: return ",";1054 case TokenIdComma: return ",";
src/tokenizer.hpp+1
...@@ -38,6 +38,7 @@ enum TokenId {...@@ -38,6 +38,7 @@ enum TokenId {
38 TokenIdKeywordNoAlias,38 TokenIdKeywordNoAlias,
39 TokenIdKeywordSwitch,39 TokenIdKeywordSwitch,
40 TokenIdKeywordUndefined,40 TokenIdKeywordUndefined,
41 TokenIdKeywordError,
41 TokenIdLParen,42 TokenIdLParen,
42 TokenIdRParen,43 TokenIdRParen,
43 TokenIdComma,44 TokenIdComma,
std/std.zig+23-23
...@@ -25,15 +25,15 @@ pub var stderr = OutStream {...@@ -25,15 +25,15 @@ pub var stderr = OutStream {
25};25};
26*/26*/
2727
28pub %.Unexpected;28pub error Unexpected;
29pub %.DiskQuota;29pub error DiskQuota;
30pub %.FileTooBig;30pub error FileTooBig;
31pub %.SigInterrupt;31pub error SigInterrupt;
32pub %.Io;32pub error Io;
33pub %.NoSpaceLeft;33pub error NoSpaceLeft;
34pub %.BadPerm;34pub error BadPerm;
35pub %.PipeFail;35pub error PipeFail;
36pub %.Invalid;36pub error Invalid;
3737
38const buffer_size = 4 * 1024;38const buffer_size = 4 * 1024;
39const max_u64_base10_digits = 20;39const max_u64_base10_digits = 20;
...@@ -100,14 +100,14 @@ pub struct OutStream {...@@ -100,14 +100,14 @@ pub struct OutStream {
100 os.index = 0;100 os.index = 0;
101 switch (write(os.fd, os.buffer.ptr, amt_to_write)) {101 switch (write(os.fd, os.buffer.ptr, amt_to_write)) {
102 EINVAL => unreachable{},102 EINVAL => unreachable{},
103 EDQUOT => %.DiskQuota,103 EDQUOT => error.DiskQuota,
104 EFBIG => %.FileTooBig,104 EFBIG => error.FileTooBig,
105 EINTR => %.SigInterrupt,105 EINTR => error.SigInterrupt,
106 EIO => %.Io,106 EIO => error.Io,
107 ENOSPC => %.NoSpaceLeft,107 ENOSPC => error.NoSpaceLeft,
108 EPERM => %.BadPerm,108 EPERM => error.BadPerm,
109 EPIPE => %.PipeFail,109 EPIPE => error.PipeFail,
110 else => %.Unexpected,110 else => error.Unexpected,
111 }111 }
112 }112 }
113}113}
...@@ -121,10 +121,10 @@ pub struct InStream {...@@ -121,10 +121,10 @@ pub struct InStream {
121 switch (-amt_read) {121 switch (-amt_read) {
122 EINVAL => unreachable{},122 EINVAL => unreachable{},
123 EFAULT => unreachable{},123 EFAULT => unreachable{},
124 EBADF => %.BadFd,124 EBADF => error.BadFd,
125 EINTR => %.SigInterrupt,125 EINTR => error.SigInterrupt,
126 EIO => %.Io,126 EIO => error.Io,
127 else => %.Unexpected,127 else => error.Unexpected,
128 }128 }
129 }129 }
130 return amt_read;130 return amt_read;
...@@ -136,8 +136,8 @@ pub fn os_get_random_bytes(buf: []u8) %void => {...@@ -136,8 +136,8 @@ pub fn os_get_random_bytes(buf: []u8) %void => {
136 switch (getrandom(buf.ptr, buf.len, 0)) {136 switch (getrandom(buf.ptr, buf.len, 0)) {
137 EINVAL => unreachable{},137 EINVAL => unreachable{},
138 EFAULT => unreachable{},138 EFAULT => unreachable{},
139 EINTR => %.SigInterrupt,139 EINTR => error.SigInterrupt,
140 else => %.Unexpected,140 else => error.Unexpected,
141 }141 }
142}142}
143*/143*/
test/run_tests.cpp+6-6
...@@ -1213,11 +1213,11 @@ pub fn main(args: [][]u8) %void => {...@@ -1213,11 +1213,11 @@ pub fn main(args: [][]u8) %void => {
12131213
1214 add_simple_case("error values", R"SOURCE(1214 add_simple_case("error values", R"SOURCE(
1215import "std.zig";1215import "std.zig";
1216%.err1;1216error err1;
1217%.err2;1217error err2;
1218pub fn main(args: [][]u8) %void => {1218pub fn main(args: [][]u8) %void => {
1219 const a = i32(%.err1);1219 const a = i32(error.err1);
1220 const b = i32(%.err2);1220 const b = i32(error.err2);
1221 if (a == b) {1221 if (a == b) {
1222 print_str("BAD\n");1222 print_str("BAD\n");
1223 }1223 }
...@@ -1467,8 +1467,8 @@ enum A {}...@@ -1467,8 +1467,8 @@ enum A {}
1467 )SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of 'A'");1467 )SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of 'A'");
14681468
1469 add_compile_fail_case("redefinition of error values", R"SOURCE(1469 add_compile_fail_case("redefinition of error values", R"SOURCE(
1470%.A;1470error A;
1471%.A;1471error A;
1472 )SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of error 'A'");1472 )SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of error 'A'");
14731473
1474 add_compile_fail_case("redefinition of global variables", R"SOURCE(1474 add_compile_fail_case("redefinition of global variables", R"SOURCE(