aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorBogdan Romanyuk <65823030+wrongnull@users.noreply.github.com>2023-10-16 04:30:39 +0300
committerGitHub <noreply@github.com>2023-10-16 01:30:39 +0000
commitebde525ccee41a8eefbb868cf4df756f1a937dd2 (patch)
tree5cb5a1b6780edb493d23275d01ab958651c0a556 /src/Sema.zig
parentfd6b3db34252f2a548630c0e57fe80f32202aa12 (diff)
downloadzig-ebde525ccee41a8eefbb868cf4df756f1a937dd2.tar.gz
zig-ebde525ccee41a8eefbb868cf4df756f1a937dd2.zip
Sema: fix `@extern` error on function pointer
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index f25457a21d..ef1a953343 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -25277,7 +25277,7 @@ fn zirBuiltinExtern(
if (!ty.isPtrAtRuntime(mod)) {
return sema.fail(block, ty_src, "expected (optional) pointer", .{});
}
- if (!try sema.validateExternType(ty.childType(mod), .other)) {
+ if (!try sema.validateExternType(ty, .other)) {
const msg = msg: {
const msg = try sema.errMsg(block, ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(mod)});
errdefer msg.destroy(sema.gpa);
@@ -25618,7 +25618,12 @@ fn validateExternType(
.Float,
.AnyFrame,
=> return true,
- .Pointer => return !(ty.isSlice(mod) or try sema.typeRequiresComptime(ty)),
+ .Pointer => {
+ if (ty.childType(mod).zigTypeTag(mod) == .Fn) {
+ return ty.isConstPtr(mod) and try sema.validateExternType(ty.childType(mod), .other);
+ }
+ return !(ty.isSlice(mod) or try sema.typeRequiresComptime(ty));
+ },
.Int => switch (ty.intInfo(mod).bits) {
0, 8, 16, 32, 64, 128 => return true,
else => return false,
@@ -25687,8 +25692,13 @@ fn explainWhyTypeIsNotExtern(
try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{});
} else {
const pointee_ty = ty.childType(mod);
- try mod.errNoteNonLazy(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(sema.mod)});
- try sema.explainWhyTypeIsComptime(msg, src_loc, pointee_ty);
+ if (!ty.isConstPtr(mod) and pointee_ty.zigTypeTag(mod) == .Fn) {
+ try mod.errNoteNonLazy(src_loc, msg, "pointer to extern function must be 'const'", .{});
+ } else if (try sema.typeRequiresComptime(ty)) {
+ try mod.errNoteNonLazy(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(sema.mod)});
+ try sema.explainWhyTypeIsComptime(msg, src_loc, ty);
+ }
+ try sema.explainWhyTypeIsNotExtern(msg, src_loc, pointee_ty, position);
}
},
.Void => try mod.errNoteNonLazy(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}),