Commit 226994cd7e

Veikka Tuominen <git@vexu.eu>
2022-07-01 20:09:07
Sema: misc error message fixes
1 parent c07c2d6
Changed files (36)
src
test
cases
compile_errors
src/Sema.zig
@@ -1718,9 +1718,17 @@ fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, opt
 }
 
 fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
-    return sema.fail(block, src, "type '{}' does not support array initialization syntax", .{
-        ty.fmt(sema.mod),
-    });
+    const msg = msg: {
+        const msg = try sema.errMsg(block, src, "type '{}' does not support array initialization syntax", .{
+            ty.fmt(sema.mod),
+        });
+        errdefer msg.destroy(sema.gpa);
+        if (ty.isSlice()) {
+            try sema.errNote(block, src, msg, "inferred array length is specified with an underscore: '[_]{}'", .{ty.elemType2().fmt(sema.mod)});
+        }
+        break :msg msg;
+    };
+    return sema.failWithOwnedErrorMsg(block, msg);
 }
 
 fn failWithStructInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
@@ -4817,14 +4825,16 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
             alignment,
         });
     }
-    const func = sema.owner_func orelse
+    const func = sema.func orelse
         return sema.fail(block, src, "@setAlignStack outside function body", .{});
 
     const fn_owner_decl = sema.mod.declPtr(func.owner_decl);
     switch (fn_owner_decl.ty.fnCallingConvention()) {
         .Naked => return sema.fail(block, src, "@setAlignStack in naked function", .{}),
         .Inline => return sema.fail(block, src, "@setAlignStack in inline function", .{}),
-        else => {},
+        else => if (block.inlining != null) {
+            return sema.fail(block, src, "@setAlignStack in inline call", .{});
+        },
     }
 
     const gop = try sema.mod.align_stack_fns.getOrPut(sema.mod.gpa, func);
@@ -7451,11 +7461,11 @@ fn analyzeAs(
     zir_operand: Zir.Inst.Ref,
 ) CompileError!Air.Inst.Ref {
     const dest_ty = try sema.resolveType(block, src, zir_dest_type);
+    const operand = try sema.resolveInst(zir_operand);
+    if (dest_ty.tag() == .var_args_param) return operand;
     if (dest_ty.zigTypeTag() == .NoReturn) {
         return sema.fail(block, src, "cannot cast to noreturn", .{});
     }
-    const operand = try sema.resolveInst(zir_operand);
-    if (dest_ty.tag() == .var_args_param) return operand;
     return sema.coerce(block, dest_ty, operand, src);
 }
 
@@ -8123,9 +8133,11 @@ fn zirSwitchCond(
             const union_ty = try sema.resolveTypeFields(block, operand_src, operand_ty);
             const enum_ty = union_ty.unionTagType() orelse {
                 const msg = msg: {
-                    const msg = try sema.errMsg(block, src, "switch on untagged union", .{});
+                    const msg = try sema.errMsg(block, src, "switch on union with no attached enum", .{});
                     errdefer msg.destroy(sema.gpa);
-                    try sema.addDeclaredHereNote(msg, union_ty);
+                    if (union_ty.declSrcLocOrNull(sema.mod)) |union_src| {
+                        try sema.mod.errNoteNonLazy(union_src, msg, "consider 'union(enum)' here", .{});
+                    }
                     break :msg msg;
                 };
                 return sema.failWithOwnedErrorMsg(block, msg);
@@ -8616,7 +8628,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
                     if (true_count + false_count == 2) {
                         return sema.fail(
                             block,
-                            src,
+                            special_prong_src,
                             "unreachable else prong; all cases already handled",
                             .{},
                         );
@@ -11965,7 +11977,6 @@ fn runtimeBoolCmp(
 
 fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
     const inst_data = sema.code.instructions.items(.data)[inst].un_node;
-    const src = inst_data.src();
     const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
     const ty = try sema.resolveType(block, operand_src, inst_data.operand);
     switch (ty.zigTypeTag()) {
@@ -11975,7 +11986,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
         .Null,
         .BoundFn,
         .Opaque,
-        => return sema.fail(block, src, "no size available for type '{}'", .{ty.fmt(sema.mod)}),
+        => return sema.fail(block, operand_src, "no size available for type '{}'", .{ty.fmt(sema.mod)}),
 
         .Type,
         .EnumLiteral,
@@ -12101,7 +12112,7 @@ fn zirBuiltinSrc(
     const tracy = trace(@src());
     defer tracy.end();
 
-    const src = LazySrcLoc.nodeOffset(@bitCast(i32, extended.operand));
+    const src = sema.src; // TODO better source location
     const extra = sema.code.extraData(Zir.Inst.LineColumn, extended.operand).data;
     const func = sema.func orelse return sema.fail(block, src, "@src outside function", .{});
     const fn_owner_decl = sema.mod.declPtr(func.owner_decl);
@@ -14606,14 +14617,12 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
         },
         .Enum => operand_ty,
         .Union => operand_ty.unionTagType() orelse {
-            const decl_index = operand_ty.getOwnerDecl();
-            const decl = mod.declPtr(decl_index);
             const msg = msg: {
-                const msg = try sema.errMsg(block, src, "union '{s}' is untagged", .{
-                    decl.name,
+                const msg = try sema.errMsg(block, src, "union '{}' is untagged", .{
+                    operand_ty.fmt(sema.mod),
                 });
                 errdefer msg.destroy(sema.gpa);
-                try mod.errNoteNonLazy(decl.srcLoc(), msg, "declared here", .{});
+                try sema.addDeclaredHereNote(msg, operand_ty);
                 break :msg msg;
             };
             return sema.failWithOwnedErrorMsg(block, msg);
test/cases/compile_errors/stage1/obj/non_constant_expression_in_array_size.zig
@@ -1,14 +0,0 @@
-const Foo = struct {
-    y: [get()]u8,
-};
-var global_var: usize = 1;
-fn get() usize { return global_var; }
-
-export fn entry() usize { return @sizeOf(@TypeOf(Foo)); }
-
-// error
-// backend=stage1
-// target=native
-//
-// tmp.zig:5:25: error: cannot store runtime value in compile time variable
-// tmp.zig:2:12: note: called from here
test/cases/compile_errors/stage1/obj/setAlignStack_in_inline_function.zig
@@ -1,12 +0,0 @@
-export fn entry() void {
-    foo();
-}
-fn foo() callconv(.Inline) void {
-    @setAlignStack(16);
-}
-
-// error
-// backend=stage1
-// target=native
-//
-// tmp.zig:5:5: error: @setAlignStack in inline function
test/cases/compile_errors/stage1/obj/signed_integer_remainder_division.zig
@@ -1,9 +0,0 @@
-export fn foo(a: i32, b: i32) i32 {
-    return a % b;
-}
-
-// error
-// backend=stage1
-// target=native
-//
-// tmp.zig:2:14: error: remainder division with 'i32' and 'i32': signed integers and floats must use @rem or @mod
test/cases/compile_errors/stage1/obj/slice_passed_as_array_init_type.zig
@@ -1,10 +0,0 @@
-export fn entry() void {
-    const x = []u8{};
-    _ = x;
-}
-
-// error
-// backend=stage1
-// target=native
-//
-// tmp.zig:2:15: error: array literal requires address-of operator (&) to coerce to slice type '[]u8'
test/cases/compile_errors/stage1/obj/slice_passed_as_array_init_type_with_elems.zig
@@ -1,10 +0,0 @@
-export fn entry() void {
-    const x = []u8{1, 2};
-    _ = x;
-}
-
-// error
-// backend=stage1
-// target=native
-//
-// tmp.zig:2:15: error: array literal requires address-of operator (&) to coerce to slice type '[]u8'
test/cases/compile_errors/stage1/obj/sub_overflow_in_function_evaluation.zig
@@ -1,12 +0,0 @@
-const y = sub(10, 20);
-fn sub(a: u16, b: u16) u16 {
-    return a - b;
-}
-
-export fn entry() usize { return @sizeOf(@TypeOf(y)); }
-
-// error
-// backend=stage1
-// target=native
-//
-// tmp.zig:3:14: error: operation caused overflow
test/cases/compile_errors/stage1/obj/switch_expression-switch_on_pointer_type_with_no_else.zig
@@ -1,13 +0,0 @@
-fn foo(x: *u8) void {
-    switch (x) {
-        &y => {},
-    }
-}
-const y: u8 = 100;
-export fn entry() usize { return @sizeOf(@TypeOf(foo)); }
-
-// error
-// backend=stage1
-// target=native
-//
-// tmp.zig:2:5: error: else prong required when switching on type '*u8'
test/cases/compile_errors/stage1/obj/switch_expression-unreachable_else_prong_bool.zig
@@ -1,14 +0,0 @@
-fn foo(x: bool) void {
-    switch (x) {
-        true => {},
-        false => {},
-        else => {},
-    }
-}
-export fn entry() usize { return @sizeOf(@TypeOf(foo)); }
-
-// error
-// backend=stage1
-// target=native
-//
-// tmp.zig:5:9: error: unreachable else prong, all cases already handled
test/cases/compile_errors/stage1/obj/type_variables_must_be_constant.zig
@@ -1,10 +0,0 @@
-var foo = u8;
-export fn entry() foo {
-    return 1;
-}
-
-// error
-// backend=stage1
-// target=native
-//
-// :1:1: error: variable of type 'type' must be constant
test/cases/compile_errors/stage1/obj/wasmMemoryGrow_is_a_compile_error_in_non-Wasm_targets.zig
@@ -1,10 +0,0 @@
-export fn foo() void {
-    _ = @wasmMemoryGrow(0, 1);
-    return;
-}
-
-// error
-// backend=stage1
-// target=native
-//
-// tmp.zig:2:9: error: @wasmMemoryGrow is a wasm32 feature only
test/cases/compile_errors/stage1/obj/wasmMemorySize_is_a_compile_error_in_non-Wasm_targets.zig
@@ -1,10 +0,0 @@
-export fn foo() void {
-    _ = @wasmMemorySize(0);
-    return;
-}
-
-// error
-// backend=stage1
-// target=native
-//
-// tmp.zig:2:9: error: @wasmMemorySize is a wasm32 feature only
test/cases/compile_errors/stage1/obj/wrong_type_for_reify_type.zig
@@ -1,9 +0,0 @@
-export fn entry() void {
-    _ = @Type(0);
-}
-
-// error
-// backend=stage1
-// target=native
-//
-// tmp.zig:2:15: error: expected type 'std.builtin.Type', found 'comptime_int'
test/cases/compile_errors/stage1/obj/switch_with_invalid_expression_parameter.zig → test/cases/compile_errors/stage1/switch_with_invalid_expression_parameter.zig
File renamed without changes
test/cases/compile_errors/stage1/obj/use_of_comptime-known_undefined_function_value.zig → test/cases/compile_errors/stage1/use_of_comptime-known_undefined_function_value.zig
File renamed without changes
test/cases/compile_errors/stage1/obj/array_access_of_type.zig → test/cases/compile_errors/array_access_of_type.zig
@@ -4,7 +4,7 @@ export fn foo() void {
 }
 
 // error
-// backend=stage1
+// backend=stage2
 // target=native
 //
-// tmp.zig:2:14: error: array access of non-array type 'type'
+// :2:14: error: element access of non-indexable type 'type'
test/cases/compile_errors/non_constant_expression_in_array_size.zig
@@ -0,0 +1,14 @@
+const Foo = struct {
+    y: [get()]u8,
+};
+var global_var: usize = 1;
+fn get() usize { return global_var; }
+
+export fn entry() usize { return @offsetOf(Foo, "y"); }
+
+// error
+// backend=stage2
+// target=native
+//
+// :5:25: error: unable to resolve comptime value
+// :2:15: note: called from here
test/cases/compile_errors/runtime_index_into_comptime_type_slice.zig
@@ -15,6 +15,5 @@ export fn entry() void {
 // target=native
 //
 // :9:51: error: values of type '[]const builtin.Type.StructField' must be comptime known, but index value is runtime known
-// :287:21: note: struct requires comptime because of this field
-// :287:21: note: types are not available at runtime
-// :290:20: note: struct requires comptime because of this field
+// :?:21: note: struct requires comptime because of this field
+// :?:21: note: types are not available at runtime
test/cases/compile_errors/setAlignStack_in_inline_function.zig
@@ -0,0 +1,23 @@
+export fn entry() void {
+    foo();
+}
+fn foo() callconv(.Inline) void {
+    @setAlignStack(16);
+}
+
+export fn entry1() void {
+    comptime bar();
+}
+fn bar() void {
+    @setAlignStack(16);
+}
+
+
+// error
+// backend=stage2
+// target=native
+//
+// :5:5: error: @setAlignStack in inline function
+// :2:8: note: called from here
+// :12:5: error: @setAlignStack in inline call
+// :9:17: note: called from here
test/cases/compile_errors/signed_integer_remainder_division.zig
@@ -0,0 +1,9 @@
+export fn foo(a: i32, b: i32) i32 {
+    return a % b;
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :2:12: error: remainder division with 'i32' and 'i32': signed integers and floats must use @rem or @mod
test/cases/compile_errors/stage1/obj/sizeOf_bad_type.zig → test/cases/compile_errors/sizeOf_bad_type.zig
@@ -3,7 +3,7 @@ export fn entry() usize {
 }
 
 // error
-// backend=stage1
+// backend=stage2
 // target=native
 //
-// tmp.zig:2:20: error: no size available for type '@Type(.Null)'
+// :2:20: error: no size available for type '@TypeOf(null)'
test/cases/compile_errors/stage1/obj/slice_cannot_have_its_bytes_reinterpreted.zig → test/cases/compile_errors/slice_cannot_have_its_bytes_reinterpreted.zig
@@ -5,7 +5,7 @@ export fn foo() void {
 }
 
 // error
-// backend=stage1
+// backend=stage2
 // target=native
 //
-// :3:52: error: slice '[]const u8' cannot have its bytes reinterpreted
+// :3:52: error: comptime dereference requires '[]const u8' to have a well-defined layout, but it does not.
test/cases/compile_errors/slice_passed_as_array_init_type.zig
@@ -0,0 +1,11 @@
+export fn entry() void {
+    const x = []u8{};
+    _ = x;
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :2:19: error: type '[]u8' does not support array initialization syntax
+// :2:19: note: inferred array length is specified with an underscore: '[_]u8'
test/cases/compile_errors/slice_passed_as_array_init_type_with_elems.zig
@@ -0,0 +1,11 @@
+export fn entry() void {
+    const x = []u8{1, 2};
+    _ = x;
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :2:19: error: type '[]u8' does not support array initialization syntax
+// :2:19: note: inferred array length is specified with an underscore: '[_]u8'
test/cases/compile_errors/sub_overflow_in_function_evaluation.zig
@@ -0,0 +1,13 @@
+const y = sub(10, 20);
+fn sub(a: u16, b: u16) u16 {
+    return a - b;
+}
+
+export fn entry() usize { return @sizeOf(@TypeOf(&y)); }
+
+// error
+// backend=stage2
+// target=native
+//
+// :3:14: error: overflow of integer type 'u16' with value '-10'
+// :1:14: note: called from here
test/cases/compile_errors/stage1/obj/switch_expression-duplicate_or_overlapping_integer_value.zig → test/cases/compile_errors/switch_expression-duplicate_or_overlapping_integer_value.zig
@@ -6,11 +6,11 @@ fn foo(x: u8) u8 {
         206 ... 255 => 3,
     };
 }
-export fn entry() usize { return @sizeOf(@TypeOf(foo)); }
+export fn entry() usize { return @sizeOf(@TypeOf(&foo)); }
 
 // error
-// backend=stage1
+// backend=stage2
 // target=native
 //
-// tmp.zig:6:9: error: duplicate switch value
-// tmp.zig:5:14: note: previous value here
+// :6:13: error: duplicate switch value
+// :5:18: note: previous value here
test/cases/compile_errors/switch_expression-switch_on_pointer_type_with_no_else.zig
@@ -0,0 +1,13 @@
+fn foo(x: *u8) void {
+    switch (x) {
+        &y => {},
+    }
+}
+var y: u8 = 100;
+export fn entry() usize { return @sizeOf(@TypeOf(&foo)); }
+
+// error
+// backend=stage2
+// target=native
+//
+// :2:5: error: else prong required when switching on type '*u8'
test/cases/compile_errors/switch_expression-unreachable_else_prong_bool.zig
@@ -0,0 +1,14 @@
+fn foo(x: bool) void {
+    switch (x) {
+        true => {},
+        false => {},
+        else => {},
+    }
+}
+export fn entry() usize { return @sizeOf(@TypeOf(&foo)); }
+
+// error
+// backend=stage2
+// target=native
+//
+// :5:14: error: unreachable else prong; all cases already handled
test/cases/compile_errors/stage1/obj/switch_on_union_with_no_attached_enum.zig → test/cases/compile_errors/switch_on_union_with_no_attached_enum.zig
@@ -5,7 +5,7 @@ const Payload = union {
 };
 export fn entry() void {
     const a = Payload { .A = 1234 };
-    foo(a);
+    foo(&a);
 }
 fn foo(a: *const Payload) void {
     switch (a.*) {
@@ -15,8 +15,8 @@ fn foo(a: *const Payload) void {
 }
 
 // error
-// backend=stage1
+// backend=stage2
 // target=native
 //
-// tmp.zig:11:14: error: switch on union which has no attached enum
-// tmp.zig:1:17: note: consider 'union(enum)' here
+// :11:14: error: switch on union with no attached enum
+// :1:17: note: consider 'union(enum)' here
test/cases/compile_errors/stage1/obj/switch_with_overlapping_case_ranges.zig → test/cases/compile_errors/switch_with_overlapping_case_ranges.zig
@@ -7,7 +7,8 @@ export fn entry() void {
 }
 
 // error
-// backend=stage1
+// backend=stage2
 // target=native
 //
-// tmp.zig:5:9: error: duplicate switch value
+// :5:10: error: duplicate switch value
+// :4:10: note: previous value here
test/cases/compile_errors/stage1/obj/tagName_used_on_union_with_no_associated_enum_tag.zig → test/cases/compile_errors/tagName_used_on_union_with_no_associated_enum_tag.zig
@@ -9,8 +9,8 @@ export fn entry() void {
 }
 
 // error
-// backend=stage1
+// backend=stage2
 // target=native
 //
-// tmp.zig:7:19: error: union has no associated enum
-// tmp.zig:1:18: note: declared here
+// :7:19: error: union 'tmp.FloatInt' is untagged
+// :1:25: note: union declared here
test/cases/compile_errors/type_variables_must_be_constant.zig
@@ -0,0 +1,11 @@
+var foo = u8;
+export fn entry() foo {
+    return 1;
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :1:1: error: variable of type 'type' must be const or comptime
+// :1:1: note: types are not available at runtime
test/cases/compile_errors/stage1/obj/unreachable_executed_at_comptime.zig → test/cases/compile_errors/unreachable_executed_at_comptime.zig
@@ -5,12 +5,12 @@ fn foo(comptime x: i32) i32 {
     }
 }
 export fn entry() void {
-    _ = foo(-42);
+    _ = comptime foo(-42);
 }
 
 // error
-// backend=stage1
+// backend=stage2
 // target=native
 //
-// tmp.zig:4:9: error: reached unreachable code
-// tmp.zig:8:12: note: called from here
+// :4:9: error: reached unreachable code
+// :8:21: note: called from here
test/cases/compile_errors/wasmMemoryGrow_is_a_compile_error_in_non-Wasm_targets.zig
@@ -0,0 +1,10 @@
+export fn foo() void {
+    _ = @wasmMemoryGrow(0, 1);
+    return;
+}
+
+// error
+// backend=stage2
+// target=x86_64-native
+//
+// :2:9: error: builtin @wasmMemoryGrow is available when targeting WebAssembly; targeted CPU architecture is x86_64
test/cases/compile_errors/wasmMemorySize_is_a_compile_error_in_non-Wasm_targets.zig
@@ -0,0 +1,10 @@
+export fn foo() void {
+    _ = @wasmMemorySize(0);
+    return;
+}
+
+// error
+// backend=stage2
+// target=x86_64-native
+//
+// :2:9: error: builtin @wasmMemorySize is available when targeting WebAssembly; targeted CPU architecture is x86_64
test/cases/compile_errors/wrong_type_for_reify_type.zig
@@ -0,0 +1,9 @@
+export fn entry() void {
+    _ = @Type(0);
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :2:15: error: expected type 'builtin.Type', found 'comptime_int'