Commit db50cf7049

Andrew Kelley <andrew@ziglang.org>
2019-08-27 04:38:45
fix more compile error regressions
1 parent bad4b04
src/analyze.cpp
@@ -1603,14 +1603,17 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
     }
 
     if (!calling_convention_allows_zig_types(fn_type_id.cc) &&
-        fn_type_id.return_type->id != ZigTypeIdVoid &&
-        !type_allowed_in_extern(g, fn_type_id.return_type))
+        fn_type_id.return_type->id != ZigTypeIdVoid)
     {
-        add_node_error(g, fn_proto->return_type,
-                buf_sprintf("return type '%s' not allowed in function with calling convention '%s'",
-                    buf_ptr(&fn_type_id.return_type->name),
-                    calling_convention_name(fn_type_id.cc)));
-        return g->builtin_types.entry_invalid;
+        if ((err = type_resolve(g, fn_type_id.return_type, ResolveStatusSizeKnown)))
+            return g->builtin_types.entry_invalid;
+        if (!type_allowed_in_extern(g, fn_type_id.return_type)) {
+            add_node_error(g, fn_proto->return_type,
+                    buf_sprintf("return type '%s' not allowed in function with calling convention '%s'",
+                        buf_ptr(&fn_type_id.return_type->name),
+                        calling_convention_name(fn_type_id.cc)));
+            return g->builtin_types.entry_invalid;
+        }
     }
 
     switch (fn_type_id.return_type->id) {
@@ -2018,6 +2021,17 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {
     return ErrorNone;
 }
 
+ZigType *resolve_union_field_type(CodeGen *g, TypeUnionField *union_field) {
+    Error err;
+    if (union_field->type_entry == nullptr) {
+        if ((err = ir_resolve_lazy(g, union_field->decl_node, union_field->type_val))) {
+            return nullptr;
+        }
+        union_field->type_entry = union_field->type_val->data.x_type;
+    }
+    return union_field->type_entry;
+}
+
 static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
     assert(union_type->id == ZigTypeIdUnion);
 
@@ -2057,17 +2071,12 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
     union_type->data.unionation.resolve_loop_flag_other = true;
 
     for (uint32_t i = 0; i < field_count; i += 1) {
-        AstNode *field_source_node = decl_node->data.container_decl.fields.at(i);
         TypeUnionField *union_field = &union_type->data.unionation.fields[i];
-
-        if (union_field->type_entry == nullptr) {
-            if ((err = ir_resolve_lazy(g, field_source_node, union_field->type_val))) {
-                union_type->data.unionation.resolve_status = ResolveStatusInvalid;
-                return err;
-            }
-            union_field->type_entry = union_field->type_val->data.x_type;
+        ZigType *field_type = resolve_union_field_type(g, union_field);
+        if (field_type == nullptr) {
+            union_type->data.unionation.resolve_status = ResolveStatusInvalid;
+            return ErrorSemanticAnalyzeFail;
         }
-        ZigType *field_type = union_field->type_entry;
 
         if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) {
             union_type->data.unionation.resolve_status = ResolveStatusInvalid;
src/analyze.hpp
@@ -247,5 +247,6 @@ void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);
 bool fn_is_async(ZigFn *fn);
 
 Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t *abi_align);
+ZigType *resolve_union_field_type(CodeGen *g, TypeUnionField *union_field);
 
 #endif
src/ir.cpp
@@ -6830,7 +6830,7 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod
         const char modifier = *buf_ptr(asm_output->constraint);
         if (modifier != '=') {
             add_node_error(irb->codegen, node,
-                buf_sprintf("invalid modifier starting output constraint for '%s': '%c', only '=' is supported"
+                buf_sprintf("invalid modifier starting output constraint for '%s': '%c', only '=' is supported."
                     " Compiler TODO: see https://github.com/ziglang/zig/issues/215",
                     buf_ptr(asm_output->asm_symbolic_name), modifier));
             return irb->codegen->invalid_instruction;
@@ -8176,9 +8176,19 @@ bool ir_gen_fn(CodeGen *codegen, ZigFn *fn_entry) {
     return ir_gen(codegen, body_node, fn_entry->child_scope, ir_executable);
 }
 
+static void ir_add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, ErrorMsg *err_msg, int limit) {
+    if (!exec || !exec->source_node || limit < 0) return;
+    add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here"));
+
+    ir_add_call_stack_errors(codegen, exec->parent_exec, err_msg, limit - 1);
+}
+
 static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) {
     ErrorMsg *err_msg = add_node_error(codegen, source_node, msg);
     invalidate_exec(exec, err_msg);
+    if (exec->parent_exec) {
+        ir_add_call_stack_errors(codegen, exec, err_msg, 10);
+    }
     return err_msg;
 }
 
@@ -10783,8 +10793,7 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod
     ir_gen(codegen, node, scope, ir_executable);
 
     if (ir_executable->first_err_trace_msg != nullptr) {
-        codegen->trace_err = add_error_note(codegen, ir_executable->first_err_trace_msg,
-                source_node, buf_create_from_str("called from here"));
+        codegen->trace_err = ir_executable->first_err_trace_msg;
         return &codegen->invalid_instruction->value;
     }
 
@@ -11408,10 +11417,13 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so
             return ira->codegen->invalid_instruction;
         TypeUnionField *union_field = find_union_field_by_tag(wanted_type, &val->data.x_enum_tag);
         assert(union_field != nullptr);
-        if ((err = type_resolve(ira->codegen, union_field->type_entry, ResolveStatusZeroBitsKnown)))
+        ZigType *field_type = resolve_union_field_type(ira->codegen, union_field);
+        if (field_type == nullptr)
+            return ira->codegen->invalid_instruction;
+        if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown)))
             return ira->codegen->invalid_instruction;
 
-        switch (type_has_one_possible_value(ira->codegen, union_field->type_entry)) {
+        switch (type_has_one_possible_value(ira->codegen, field_type)) {
             case OnePossibleValueInvalid:
                 return ira->codegen->invalid_instruction;
             case OnePossibleValueNo: {
@@ -11420,7 +11432,7 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so
                 ErrorMsg *msg = ir_add_error(ira, source_instr,
                         buf_sprintf("cast to union '%s' must initialize '%s' field '%s'",
                             buf_ptr(&wanted_type->name),
-                            buf_ptr(&union_field->type_entry->name),
+                            buf_ptr(&field_type->name),
                             buf_ptr(union_field->name)));
                 add_error_note(ira->codegen, msg, field_node,
                         buf_sprintf("field '%s' declared here", buf_ptr(union_field->name)));
@@ -11436,7 +11448,7 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so
         bigint_init_bigint(&result->value.data.x_union.tag, &val->data.x_enum_tag);
         result->value.data.x_union.payload = create_const_vals(1);
         result->value.data.x_union.payload->special = ConstValSpecialStatic;
-        result->value.data.x_union.payload->type = union_field->type_entry;
+        result->value.data.x_union.payload->type = field_type;
         return result;
     }
 
@@ -11453,12 +11465,17 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so
                 buf_ptr(&wanted_type->name)));
     for (uint32_t i = 0; i < wanted_type->data.unionation.src_field_count; i += 1) {
         TypeUnionField *union_field = &wanted_type->data.unionation.fields[i];
-        if (type_has_bits(union_field->type_entry)) {
+        ZigType *field_type = resolve_union_field_type(ira->codegen, union_field);
+        if (field_type == nullptr)
+            return ira->codegen->invalid_instruction;
+        if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown)))
+            return ira->codegen->invalid_instruction;
+        if (type_has_bits(field_type)) {
             AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(i);
             add_error_note(ira->codegen, msg, field_node,
                     buf_sprintf("field '%s' has type '%s'",
                         buf_ptr(union_field->name),
-                        buf_ptr(&union_field->type_entry->name)));
+                        buf_ptr(&field_type->name)));
         }
     }
     return ira->codegen->invalid_instruction;
test/compile_errors.zig
@@ -470,7 +470,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
     );
 
     cases.add(
-        "Generic function where return type is self-referenced",
+        "generic function where return type is self-referenced",
         \\fn Foo(comptime T: type) Foo(T) {
         \\    return struct{ x: T };
         \\}
@@ -481,7 +481,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
         \\}
     ,
         "tmp.zig:1:29: error: evaluation exceeded 1000 backwards branches",
-        "tmp.zig:1:29: note: referenced here",
         "tmp.zig:5:18: note: referenced here",
     );
 
@@ -3597,7 +3596,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
     );
 
     cases.add(
-        "non constant expression in array size outside function",
+        "non constant expression in array size",
         \\const Foo = struct {
         \\    y: [get()]u8,
         \\};
@@ -3608,7 +3607,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
     ,
         "tmp.zig:5:25: error: unable to evaluate constant expression",
         "tmp.zig:2:12: note: referenced here",
-        "tmp.zig:2:8: note: referenced here",
     );
 
     cases.add(
@@ -4620,7 +4618,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
         \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
     ,
         "tmp.zig:2:26: error: index 1 outside argument list of size 1",
-        "tmp.zig:6:15: note: referenced here",
+        "tmp.zig:6:15: note: called from here",
     );
 
     cases.add(
@@ -5941,7 +5939,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
         \\    var x: MultipleChoice = undefined;
         \\}
     ,
-        "tmp.zig:2:14: error: non-enum union field assignment",
+        "tmp.zig:2:14: error: untagged union field assignment",
         "tmp.zig:1:24: note: consider 'union(enum)' here",
     );