@@ -25277,7 +25277,7 @@ fn zirBuiltinExtern(
25277
25277
if (!ty.isPtrAtRuntime(mod)) {
25278
25278
return sema.fail(block, ty_src, "expected (optional) pointer", .{});
25279
25279
}
25280
- if (!try sema.validateExternType(ty.childType(mod) , .other)) {
25280
+ if (!try sema.validateExternType(ty, .other)) {
25281
25281
const msg = msg: {
25282
25282
const msg = try sema.errMsg(block, ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(mod)});
25283
25283
errdefer msg.destroy(sema.gpa);
@@ -25618,7 +25618,12 @@ fn validateExternType(
25618
25618
.Float,
25619
25619
.AnyFrame,
25620
25620
=> return true,
25621
- .Pointer => return !(ty.isSlice(mod) or try sema.typeRequiresComptime(ty)),
25621
+ .Pointer => {
25622
+ if (ty.childType(mod).zigTypeTag(mod) == .Fn) {
25623
+ return ty.isConstPtr(mod) and try sema.validateExternType(ty.childType(mod), .other);
25624
+ }
25625
+ return !(ty.isSlice(mod) or try sema.typeRequiresComptime(ty));
25626
+ },
25622
25627
.Int => switch (ty.intInfo(mod).bits) {
25623
25628
0, 8, 16, 32, 64, 128 => return true,
25624
25629
else => return false,
@@ -25687,8 +25692,13 @@ fn explainWhyTypeIsNotExtern(
25687
25692
try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{});
25688
25693
} else {
25689
25694
const pointee_ty = ty.childType(mod);
25690
- try mod.errNoteNonLazy(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(sema.mod)});
25691
- try sema.explainWhyTypeIsComptime(msg, src_loc, pointee_ty);
25695
+ if (!ty.isConstPtr(mod) and pointee_ty.zigTypeTag(mod) == .Fn) {
25696
+ try mod.errNoteNonLazy(src_loc, msg, "pointer to extern function must be 'const'", .{});
25697
+ } else if (try sema.typeRequiresComptime(ty)) {
25698
+ try mod.errNoteNonLazy(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(sema.mod)});
25699
+ try sema.explainWhyTypeIsComptime(msg, src_loc, ty);
25700
+ }
25701
+ try sema.explainWhyTypeIsNotExtern(msg, src_loc, pointee_ty, position);
25692
25702
}
25693
25703
},
25694
25704
.Void => try mod.errNoteNonLazy(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}),
0 commit comments