| ... | @@ -25277,7 +25277,7 @@ fn zirBuiltinExtern( | ... | @@ -25277,7 +25277,7 @@ fn zirBuiltinExtern( |
| 25277 | if (!ty.isPtrAtRuntime(mod)) { | 25277 | if (!ty.isPtrAtRuntime(mod)) { |
| 25278 | return sema.fail(block, ty_src, "expected (optional) pointer", .{}); | 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 | const msg = msg: { | 25281 | const msg = msg: { |
| 25282 | const msg = try sema.errMsg(block, ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(mod)}); | 25282 | const msg = try sema.errMsg(block, ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(mod)}); |
| 25283 | errdefer msg.destroy(sema.gpa); | 25283 | errdefer msg.destroy(sema.gpa); |
| ... | @@ -25618,7 +25618,12 @@ fn validateExternType( | ... | @@ -25618,7 +25618,12 @@ fn validateExternType( |
| 25618 | .Float, | 25618 | .Float, |
| 25619 | .AnyFrame, | 25619 | .AnyFrame, |
| 25620 | => return true, | 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 | .Int => switch (ty.intInfo(mod).bits) { | 25627 | .Int => switch (ty.intInfo(mod).bits) { |
| 25623 | 0, 8, 16, 32, 64, 128 => return true, | 25628 | 0, 8, 16, 32, 64, 128 => return true, |
| 25624 | else => return false, | 25629 | else => return false, |
| ... | @@ -25687,8 +25692,13 @@ fn explainWhyTypeIsNotExtern( | ... | @@ -25687,8 +25692,13 @@ fn explainWhyTypeIsNotExtern( |
| 25687 | try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{}); | 25692 | try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{}); |
| 25688 | } else { | 25693 | } else { |
| 25689 | const pointee_ty = ty.childType(mod); | 25694 | const pointee_ty = ty.childType(mod); |
| 25690 | try mod.errNoteNonLazy(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(sema.mod)}); | 25695 | if (!ty.isConstPtr(mod) and pointee_ty.zigTypeTag(mod) == .Fn) { |
| 25691 | try sema.explainWhyTypeIsComptime(msg, src_loc, pointee_ty); | 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 | .Void => try mod.errNoteNonLazy(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}), | 25704 | .Void => try mod.errNoteNonLazy(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}), |