parent
a6d4335217
commit
1f9734d1ee
|
@ -271,6 +271,7 @@ struct AstNodeErrorValueDecl {
|
|||
|
||||
// populated by semantic analyzer
|
||||
TopLevelDecl top_level_decl;
|
||||
ErrorTableEntry *err;
|
||||
};
|
||||
|
||||
enum BinOpType {
|
||||
|
@ -1034,6 +1035,7 @@ struct CodeGen {
|
|||
HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> primitive_type_table;
|
||||
HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> unresolved_top_level_decls;
|
||||
HashMap<FnTypeId, TypeTableEntry *, fn_type_id_hash, fn_type_id_eql> fn_type_table;
|
||||
HashMap<Buf *, ErrorTableEntry *, buf_hash, buf_eql_buf> error_table;
|
||||
|
||||
uint32_t next_unresolved_index;
|
||||
|
||||
|
@ -1111,7 +1113,6 @@ struct CodeGen {
|
|||
LLVMValueRef trap_fn_val;
|
||||
bool error_during_imports;
|
||||
uint32_t next_node_index;
|
||||
uint32_t next_error_index;
|
||||
uint32_t error_value_count;
|
||||
TypeTableEntry *err_tag_type;
|
||||
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]
|
||||
|
|
|
@ -1290,36 +1290,39 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,
|
|||
}
|
||||
}
|
||||
|
||||
static void resolve_error_value_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {
|
||||
static void preview_error_value_decl(CodeGen *g, AstNode *node) {
|
||||
assert(node->type == NodeTypeErrorValueDecl);
|
||||
|
||||
ErrorTableEntry *err = allocate<ErrorTableEntry>(1);
|
||||
|
||||
err->value = g->next_error_index;
|
||||
g->next_error_index += 1;
|
||||
|
||||
err->decl_node = node;
|
||||
buf_init_from_buf(&err->name, &node->data.error_value_decl.name);
|
||||
|
||||
auto existing_entry = import->block_context->error_table.maybe_get(&err->name);
|
||||
auto existing_entry = g->error_table.maybe_get(&err->name);
|
||||
if (existing_entry) {
|
||||
add_node_error(g, node, buf_sprintf("redefinition of error '%s'", buf_ptr(&err->name)));
|
||||
// duplicate error definitions allowed and they get the same value
|
||||
err->value = existing_entry->value->value;
|
||||
} else {
|
||||
import->block_context->error_table.put(&err->name, err);
|
||||
err->value = g->error_value_count;
|
||||
g->error_value_count += 1;
|
||||
g->error_table.put(&err->name, err);
|
||||
}
|
||||
|
||||
node->data.error_value_decl.err = err;
|
||||
}
|
||||
|
||||
static void resolve_error_value_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {
|
||||
assert(node->type == NodeTypeErrorValueDecl);
|
||||
|
||||
ErrorTableEntry *err = node->data.error_value_decl.err;
|
||||
|
||||
import->block_context->error_table.put(&err->name, err);
|
||||
|
||||
bool is_pub = (node->data.error_value_decl.visib_mod != VisibModPrivate);
|
||||
if (is_pub) {
|
||||
for (int i = 0; i < import->importers.length; i += 1) {
|
||||
ImporterInfo importer = import->importers.at(i);
|
||||
auto table_entry = importer.import->block_context->error_table.maybe_get(&err->name);
|
||||
if (table_entry) {
|
||||
add_node_error(g, importer.source_node,
|
||||
buf_sprintf("import of error '%s' overrides existing definition",
|
||||
buf_ptr(&err->name)));
|
||||
} else {
|
||||
importer.import->block_context->error_table.put(&err->name, err);
|
||||
}
|
||||
importer.import->block_context->error_table.put(&err->name, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2516,7 +2519,7 @@ static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *
|
|||
add_node_error(g, node,
|
||||
buf_sprintf("use of undeclared error value '%s'", buf_ptr(err_name)));
|
||||
|
||||
return get_error_type(g, g->builtin_types.entry_void);
|
||||
return g->builtin_types.entry_invalid;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2759,6 +2762,16 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im
|
|||
are_equal = true;
|
||||
}
|
||||
}
|
||||
if (bin_op_type == BinOpTypeCmpEq) {
|
||||
answer = are_equal;
|
||||
} else if (bin_op_type == BinOpTypeCmpNotEq) {
|
||||
answer = !are_equal;
|
||||
} else {
|
||||
zig_unreachable();
|
||||
}
|
||||
} else if (resolved_type->id == TypeTableEntryIdPureError) {
|
||||
bool are_equal = op1_val->data.x_err.err == op2_val->data.x_err.err;
|
||||
|
||||
if (bin_op_type == BinOpTypeCmpEq) {
|
||||
answer = are_equal;
|
||||
} else if (bin_op_type == BinOpTypeCmpNotEq) {
|
||||
|
@ -5402,7 +5415,7 @@ void semantic_analyze(CodeGen *g) {
|
|||
|
||||
target_import->importers.append({import, child});
|
||||
} else if (child->type == NodeTypeErrorValueDecl) {
|
||||
g->error_value_count += 1;
|
||||
preview_error_value_decl(g, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5428,8 +5441,6 @@ void semantic_analyze(CodeGen *g) {
|
|||
}
|
||||
}
|
||||
|
||||
assert(g->error_value_count == g->next_error_index);
|
||||
|
||||
{
|
||||
auto it = g->import_table.entry_iterator();
|
||||
for (;;) {
|
||||
|
|
|
@ -28,10 +28,10 @@ CodeGen *codegen_create(Buf *root_source_dir) {
|
|||
g->primitive_type_table.init(32);
|
||||
g->unresolved_top_level_decls.init(32);
|
||||
g->fn_type_table.init(32);
|
||||
g->error_table.init(16);
|
||||
g->is_release_build = false;
|
||||
g->is_test_build = false;
|
||||
g->root_source_dir = root_source_dir;
|
||||
g->next_error_index = 1;
|
||||
g->error_value_count = 1;
|
||||
|
||||
g->libc_lib_dir = buf_create_from_str(ZIG_LIBC_LIB_DIR);
|
||||
|
|
|
@ -1789,11 +1789,6 @@ enum A {}
|
|||
enum A {}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of 'A'");
|
||||
|
||||
add_compile_fail_case("redefinition of error values", R"SOURCE(
|
||||
error A;
|
||||
error A;
|
||||
)SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of error 'A'");
|
||||
|
||||
add_compile_fail_case("redefinition of global variables", R"SOURCE(
|
||||
var a : i32 = 1;
|
||||
var a : i32 = 2;
|
||||
|
|
|
@ -35,3 +35,14 @@ fn a_func() -> i32 { 13 }
|
|||
fn call_struct_field(foo: Foo) -> i32 {
|
||||
return foo.ptr();
|
||||
}
|
||||
|
||||
|
||||
|
||||
error AnError;
|
||||
error AnError;
|
||||
error SecondError;
|
||||
|
||||
#attribute("test")
|
||||
fn redefinition_of_error_values_allowed() {
|
||||
if (error.AnError == error.SecondError) unreachable{}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue