authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-04 00:58:45-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-04 00:58:45-07:00
log1f9734d1eefa98c4c51ee740717a6cc003a5a7ed
treee1f6a95b41a3300c2f9ec639017b6202e82850a3
parenta6d43352175ac49ee180592055d56101fe20b83a

allow defining errors with the same name

they get the same value, too.

5 files changed, 44 insertions(+), 26 deletions(-)

src/all_types.hpp+2-1
......@@ -271,6 +271,7 @@ struct AstNodeErrorValueDecl {
271271
272272 // populated by semantic analyzer
273273 TopLevelDecl top_level_decl;
274 ErrorTableEntry *err;
274275};
275276
276277enum BinOpType {
......@@ -1034,6 +1035,7 @@ struct CodeGen {
10341035 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> primitive_type_table;
10351036 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> unresolved_top_level_decls;
10361037 HashMap<FnTypeId, TypeTableEntry *, fn_type_id_hash, fn_type_id_eql> fn_type_table;
1038 HashMap<Buf *, ErrorTableEntry *, buf_hash, buf_eql_buf> error_table;
10371039
10381040 uint32_t next_unresolved_index;
10391041
......@@ -1111,7 +1113,6 @@ struct CodeGen {
11111113 LLVMValueRef trap_fn_val;
11121114 bool error_during_imports;
11131115 uint32_t next_node_index;
1114 uint32_t next_error_index;
11151116 uint32_t error_value_count;
11161117 TypeTableEntry *err_tag_type;
11171118 LLVMValueRef int_overflow_fns[2][3][4]; // [0-signed,1-unsigned][0-add,1-sub,2-mul][0-8,1-16,2-32,3-64]
src/analyze.cpp+30-19
......@@ -1290,36 +1290,39 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,
12901290 }
12911291}
12921292
1293static void resolve_error_value_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {
1293static void preview_error_value_decl(CodeGen *g, AstNode *node) {
12941294 assert(node->type == NodeTypeErrorValueDecl);
12951295
12961296 ErrorTableEntry *err = allocate<ErrorTableEntry>(1);
12971297
1298 err->value = g->next_error_index;
1299 g->next_error_index += 1;
1300
13011298 err->decl_node = node;
13021299 buf_init_from_buf(&err->name, &node->data.error_value_decl.name);
13031300
1304 auto existing_entry = import->block_context->error_table.maybe_get(&err->name);
1301 auto existing_entry = g->error_table.maybe_get(&err->name);
13051302 if (existing_entry) {
1306 add_node_error(g, node, buf_sprintf("redefinition of error '%s'", buf_ptr(&err->name)));
1303 // duplicate error definitions allowed and they get the same value
1304 err->value = existing_entry->value->value;
13071305 } else {
1308 import->block_context->error_table.put(&err->name, err);
1306 err->value = g->error_value_count;
1307 g->error_value_count += 1;
1308 g->error_table.put(&err->name, err);
13091309 }
13101310
1311 node->data.error_value_decl.err = err;
1312}
1313
1314static void resolve_error_value_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {
1315 assert(node->type == NodeTypeErrorValueDecl);
1316
1317 ErrorTableEntry *err = node->data.error_value_decl.err;
1318
1319 import->block_context->error_table.put(&err->name, err);
1320
13111321 bool is_pub = (node->data.error_value_decl.visib_mod != VisibModPrivate);
13121322 if (is_pub) {
13131323 for (int i = 0; i < import->importers.length; i += 1) {
13141324 ImporterInfo importer = import->importers.at(i);
1315 auto table_entry = importer.import->block_context->error_table.maybe_get(&err->name);
1316 if (table_entry) {
1317 add_node_error(g, importer.source_node,
1318 buf_sprintf("import of error '%s' overrides existing definition",
1319 buf_ptr(&err->name)));
1320 } else {
1321 importer.import->block_context->error_table.put(&err->name, err);
1322 }
1325 importer.import->block_context->error_table.put(&err->name, err);
13231326 }
13241327 }
13251328}
......@@ -2516,7 +2519,7 @@ static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *
25162519 add_node_error(g, node,
25172520 buf_sprintf("use of undeclared error value '%s'", buf_ptr(err_name)));
25182521
2519 return get_error_type(g, g->builtin_types.entry_void);
2522 return g->builtin_types.entry_invalid;
25202523}
25212524
25222525
......@@ -2759,6 +2762,16 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im
27592762 are_equal = true;
27602763 }
27612764 }
2765 if (bin_op_type == BinOpTypeCmpEq) {
2766 answer = are_equal;
2767 } else if (bin_op_type == BinOpTypeCmpNotEq) {
2768 answer = !are_equal;
2769 } else {
2770 zig_unreachable();
2771 }
2772 } else if (resolved_type->id == TypeTableEntryIdPureError) {
2773 bool are_equal = op1_val->data.x_err.err == op2_val->data.x_err.err;
2774
27622775 if (bin_op_type == BinOpTypeCmpEq) {
27632776 answer = are_equal;
27642777 } else if (bin_op_type == BinOpTypeCmpNotEq) {
......@@ -5402,7 +5415,7 @@ void semantic_analyze(CodeGen *g) {
54025415
54035416 target_import->importers.append({import, child});
54045417 } else if (child->type == NodeTypeErrorValueDecl) {
5405 g->error_value_count += 1;
5418 preview_error_value_decl(g, child);
54065419 }
54075420 }
54085421 }
......@@ -5428,8 +5441,6 @@ void semantic_analyze(CodeGen *g) {
54285441 }
54295442 }
54305443
5431 assert(g->error_value_count == g->next_error_index);
5432
54335444 {
54345445 auto it = g->import_table.entry_iterator();
54355446 for (;;) {
src/codegen.cpp+1-1
......@@ -28,10 +28,10 @@ CodeGen *codegen_create(Buf *root_source_dir) {
2828 g->primitive_type_table.init(32);
2929 g->unresolved_top_level_decls.init(32);
3030 g->fn_type_table.init(32);
31 g->error_table.init(16);
3132 g->is_release_build = false;
3233 g->is_test_build = false;
3334 g->root_source_dir = root_source_dir;
34 g->next_error_index = 1;
3535 g->error_value_count = 1;
3636
3737 g->libc_lib_dir = buf_create_from_str(ZIG_LIBC_LIB_DIR);
test/run_tests.cpp-5
......@@ -1789,11 +1789,6 @@ enum A {}
17891789enum A {}
17901790 )SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of 'A'");
17911791
1792 add_compile_fail_case("redefinition of error values", R"SOURCE(
1793error A;
1794error A;
1795 )SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of error 'A'");
1796
17971792 add_compile_fail_case("redefinition of global variables", R"SOURCE(
17981793var a : i32 = 1;
17991794var a : i32 = 2;
test/self_hosted.zig+11
......@@ -35,3 +35,14 @@ fn a_func() -> i32 { 13 }
3535fn call_struct_field(foo: Foo) -> i32 {
3636 return foo.ptr();
3737}
38
39
40
41error AnError;
42error AnError;
43error SecondError;
44
45#attribute("test")
46fn redefinition_of_error_values_allowed() {
47 if (error.AnError == error.SecondError) unreachable{}
48}