authorgravatar for wrongnull@gmail.comBogdan Romanyuk <wrongnull@gmail.com> 2023-05-01 08:18:05+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-05-15 04:52:02+03:00
log2516d8671faaaff7e8803a2025ba4891a6ae7c78
treefd45ae6b614d6dd7087d8a6b9a67a224cefcb998
parent2952fb97588fa2eb711bf84b479e959b60542192

correct error note and check type of extern variables


4 files changed, 28 insertions(+), 7 deletions(-)

src/Sema.zig+15-5
......@@ -22986,9 +22986,19 @@ fn validateVarType(
2298622986 var_ty: Type,
2298722987 is_extern: bool,
2298822988) CompileError!void {
22989 if (try sema.validateRunTimeType(var_ty, is_extern)) return;
22990
2299122989 const mod = sema.mod;
22990 if (is_extern and !try sema.validateExternType(var_ty, .other)) {
22991 const msg = msg: {
22992 const msg = try sema.errMsg(block, src, "extern variable cannot have type '{}'", .{var_ty.fmt(mod)});
22993 errdefer msg.destroy(sema.gpa);
22994 const src_decl = mod.declPtr(block.src_decl);
22995 try sema.explainWhyTypeIsNotExtern(msg, src.toSrcLoc(src_decl), var_ty, .other);
22996 break :msg msg;
22997 };
22998 return sema.failWithOwnedErrorMsg(msg);
22999 }
23000
23001 if (try sema.validateRunTimeType(var_ty, is_extern)) return;
2299223002
2299323003 const msg = msg: {
2299423004 const msg = try sema.errMsg(block, src, "variable of type '{}' must be const or comptime", .{var_ty.fmt(mod)});
......@@ -23295,10 +23305,10 @@ fn explainWhyTypeIsNotExtern(
2329523305 .Pointer => try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{}),
2329623306 .Void => try mod.errNoteNonLazy(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}),
2329723307 .NoReturn => try mod.errNoteNonLazy(src_loc, msg, "'noreturn' is only allowed as a return type", .{}),
23298 .Int => if (ty.intInfo(sema.mod.getTarget()).bits > 128) {
23299 try mod.errNoteNonLazy(src_loc, msg, "only integers with less than 128 bits are extern compatible", .{});
23300 } else {
23308 .Int => if (!std.math.isPowerOfTwo(ty.intInfo(sema.mod.getTarget()).bits)) {
2330123309 try mod.errNoteNonLazy(src_loc, msg, "only integers with power of two bits are extern compatible", .{});
23310 } else {
23311 try mod.errNoteNonLazy(src_loc, msg, "only integers with 8, 16, 32, 64 and 128 bits are extern compatible", .{});
2330223312 },
2330323313 .Fn => {
2330423314 if (position != .other) {
test/cases/compile_errors/exported_enum_without_explicit_integer_tag_type.zig+1-1
......@@ -14,5 +14,5 @@ comptime {
1414// :3:5: error: unable to export type 'type'
1515// :7:5: error: unable to export type 'tmp.E'
1616// :7:5: note: enum tag type 'u1' is not extern compatible
17// :7:5: note: only integers with power of two bits are extern compatible
17// :7:5: note: only integers with 8, 16, 32, 64 and 128 bits are extern compatible
1818// :1:11: note: enum declared here
test/cases/compile_errors/extern_variable_has_non_extern_type.zig created+11
......@@ -0,0 +1,11 @@
1extern var foo: u3;
2pub export fn entry() void {
3 _ = foo;
4}
5
6// error
7// backend=stage2
8// target=native
9//
10// :1:17: error: extern variable cannot have type 'u3'
11// :1:17: note: only integers with power of two bits are extern compatible
test/cases/compile_errors/function_with_non-extern_non-packed_enum_parameter.zig+1-1
......@@ -7,5 +7,5 @@ export fn entry(foo: Foo) void { _ = foo; }
77//
88// :2:17: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'C'
99// :2:17: note: enum tag type 'u2' is not extern compatible
10// :2:17: note: only integers with power of two bits are extern compatible
10// :2:17: note: only integers with 8, 16, 32, 64 and 128 bits are extern compatible
1111// :1:13: note: enum declared here