| ... | @@ -1290,36 +1290,39 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import, | ... | @@ -1290,36 +1290,39 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import, |
| 1290 | } | 1290 | } |
| 1291 | } | 1291 | } |
| 1292 | | 1292 | |
| 1293 | static void resolve_error_value_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) { | 1293 | static void preview_error_value_decl(CodeGen *g, AstNode *node) { |
| 1294 | assert(node->type == NodeTypeErrorValueDecl); | 1294 | assert(node->type == NodeTypeErrorValueDecl); |
| 1295 | | 1295 | |
| 1296 | ErrorTableEntry *err = allocate<ErrorTableEntry>(1); | 1296 | ErrorTableEntry *err = allocate<ErrorTableEntry>(1); |
| 1297 | | 1297 | |
| 1298 | err->value = g->next_error_index; | | |
| 1299 | g->next_error_index += 1; | | |
| 1300 | | | |
| 1301 | err->decl_node = node; | 1298 | err->decl_node = node; |
| 1302 | buf_init_from_buf(&err->name, &node->data.error_value_decl.name); | 1299 | buf_init_from_buf(&err->name, &node->data.error_value_decl.name); |
| 1303 | | 1300 | |
| 1304 | auto existing_entry = import->block_context->error_table.maybe_get(&err->name); | 1301 | auto existing_entry = g->error_table.maybe_get(&err->name); |
| 1305 | if (existing_entry) { | 1302 | 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; |
| 1307 | } else { | 1305 | } 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); |
| 1309 | } | 1309 | } |
| 1310 | | 1310 | |
| | 1311 | node->data.error_value_decl.err = err; |
| | 1312 | } |
| | 1313 | |
| | 1314 | static 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 | |
| 1311 | bool is_pub = (node->data.error_value_decl.visib_mod != VisibModPrivate); | 1321 | bool is_pub = (node->data.error_value_decl.visib_mod != VisibModPrivate); |
| 1312 | if (is_pub) { | 1322 | if (is_pub) { |
| 1313 | for (int i = 0; i < import->importers.length; i += 1) { | 1323 | for (int i = 0; i < import->importers.length; i += 1) { |
| 1314 | ImporterInfo importer = import->importers.at(i); | 1324 | ImporterInfo importer = import->importers.at(i); |
| 1315 | auto table_entry = importer.import->block_context->error_table.maybe_get(&err->name); | 1325 | importer.import->block_context->error_table.put(&err->name, err); |
| 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 | } | | |
| 1323 | } | 1326 | } |
| 1324 | } | 1327 | } |
| 1325 | } | 1328 | } |
| ... | @@ -2516,7 +2519,7 @@ static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry * | ... | @@ -2516,7 +2519,7 @@ static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry * |
| 2516 | add_node_error(g, node, | 2519 | add_node_error(g, node, |
| 2517 | buf_sprintf("use of undeclared error value '%s'", buf_ptr(err_name))); | 2520 | buf_sprintf("use of undeclared error value '%s'", buf_ptr(err_name))); |
| 2518 | | 2521 | |
| 2519 | return get_error_type(g, g->builtin_types.entry_void); | 2522 | return g->builtin_types.entry_invalid; |
| 2520 | } | 2523 | } |
| 2521 | | 2524 | |
| 2522 | | 2525 | |
| ... | @@ -2759,6 +2762,16 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im | ... | @@ -2759,6 +2762,16 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im |
| 2759 | are_equal = true; | 2762 | are_equal = true; |
| 2760 | } | 2763 | } |
| 2761 | } | 2764 | } |
| | 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 | |
| 2762 | if (bin_op_type == BinOpTypeCmpEq) { | 2775 | if (bin_op_type == BinOpTypeCmpEq) { |
| 2763 | answer = are_equal; | 2776 | answer = are_equal; |
| 2764 | } else if (bin_op_type == BinOpTypeCmpNotEq) { | 2777 | } else if (bin_op_type == BinOpTypeCmpNotEq) { |
| ... | @@ -5402,7 +5415,7 @@ void semantic_analyze(CodeGen *g) { | ... | @@ -5402,7 +5415,7 @@ void semantic_analyze(CodeGen *g) { |
| 5402 | | 5415 | |
| 5403 | target_import->importers.append({import, child}); | 5416 | target_import->importers.append({import, child}); |
| 5404 | } else if (child->type == NodeTypeErrorValueDecl) { | 5417 | } else if (child->type == NodeTypeErrorValueDecl) { |
| 5405 | g->error_value_count += 1; | 5418 | preview_error_value_decl(g, child); |
| 5406 | } | 5419 | } |
| 5407 | } | 5420 | } |
| 5408 | } | 5421 | } |
| ... | @@ -5428,8 +5441,6 @@ void semantic_analyze(CodeGen *g) { | ... | @@ -5428,8 +5441,6 @@ void semantic_analyze(CodeGen *g) { |
| 5428 | } | 5441 | } |
| 5429 | } | 5442 | } |
| 5430 | | 5443 | |
| 5431 | assert(g->error_value_count == g->next_error_index); | | |
| 5432 | | | |
| 5433 | { | 5444 | { |
| 5434 | auto it = g->import_table.entry_iterator(); | 5445 | auto it = g->import_table.entry_iterator(); |
| 5435 | for (;;) { | 5446 | for (;;) { |