authorgravatar for wrongnull@gmail.comBogdan Romanyuk <wrongnull@gmail.com> 2023-05-31 07:38:32+03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-05-31 04:38:32+00:00
log32e719e070067333efa9d4888927b425d118fc97
tree597eaab0377b3f3e2923e41ad97a4d2ab372103b
parent76aa1fffb7a06f0be0d803cb3379f3102c0b2590
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

sema: add compile error for incorrect extern type


2 files changed, 46 insertions(+), 20 deletions(-)

src/Sema.zig+35-20
...@@ -308,7 +308,7 @@ pub const Block = struct {...@@ -308,7 +308,7 @@ pub const Block = struct {
308 prefix ++ "the function returns a comptime-only type '{}'",308 prefix ++ "the function returns a comptime-only type '{}'",
309 .{rt.return_ty.fmt(sema.mod)},309 .{rt.return_ty.fmt(sema.mod)},
310 );310 );
311 try sema.explainWhyTypeIsComptime(rt.block, rt.func_src, parent, src_loc, rt.return_ty);311 try sema.explainWhyTypeIsComptime(parent, src_loc, rt.return_ty);
312 },312 },
313 }313 }
314 }314 }
...@@ -4804,7 +4804,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -4804,7 +4804,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
4804 errdefer msg.destroy(sema.gpa);4804 errdefer msg.destroy(sema.gpa);
48054805
4806 const src_decl = sema.mod.declPtr(block.src_decl);4806 const src_decl = sema.mod.declPtr(block.src_decl);
4807 try sema.explainWhyTypeIsComptime(block, src, msg, src.toSrcLoc(src_decl), elem_ty);4807 try sema.explainWhyTypeIsComptime(msg, src.toSrcLoc(src_decl), elem_ty);
4808 break :msg msg;4808 break :msg msg;
4809 };4809 };
4810 return sema.failWithOwnedErrorMsg(msg);4810 return sema.failWithOwnedErrorMsg(msg);
...@@ -5578,7 +5578,7 @@ fn analyzeBlockBody(...@@ -5578,7 +5578,7 @@ fn analyzeBlockBody(
5578 try sema.errNote(child_block, runtime_src, msg, "runtime control flow here", .{});5578 try sema.errNote(child_block, runtime_src, msg, "runtime control flow here", .{});
55795579
5580 const child_src_decl = mod.declPtr(child_block.src_decl);5580 const child_src_decl = mod.declPtr(child_block.src_decl);
5581 try sema.explainWhyTypeIsComptime(child_block, type_src, msg, type_src.toSrcLoc(child_src_decl), resolved_ty);5581 try sema.explainWhyTypeIsComptime(msg, type_src.toSrcLoc(child_src_decl), resolved_ty);
55825582
5583 break :msg msg;5583 break :msg msg;
5584 };5584 };
...@@ -9026,7 +9026,7 @@ fn funcCommon(...@@ -9026,7 +9026,7 @@ fn funcCommon(
9026 "function with comptime-only return type '{}' requires all parameters to be comptime",9026 "function with comptime-only return type '{}' requires all parameters to be comptime",
9027 .{return_type.fmt(sema.mod)},9027 .{return_type.fmt(sema.mod)},
9028 );9028 );
9029 try sema.explainWhyTypeIsComptime(block, ret_ty_src, msg, ret_ty_src.toSrcLoc(sema.owner_decl), return_type);9029 try sema.explainWhyTypeIsComptime(msg, ret_ty_src.toSrcLoc(sema.owner_decl), return_type);
90309030
9031 const tags = sema.code.instructions.items(.tag);9031 const tags = sema.code.instructions.items(.tag);
9032 const data = sema.code.instructions.items(.data);9032 const data = sema.code.instructions.items(.data);
...@@ -9248,7 +9248,7 @@ fn analyzeParameter(...@@ -9248,7 +9248,7 @@ fn analyzeParameter(
9248 errdefer msg.destroy(sema.gpa);9248 errdefer msg.destroy(sema.gpa);
92499249
9250 const src_decl = sema.mod.declPtr(block.src_decl);9250 const src_decl = sema.mod.declPtr(block.src_decl);
9251 try sema.explainWhyTypeIsComptime(block, param_src, msg, param_src.toSrcLoc(src_decl), param.ty);9251 try sema.explainWhyTypeIsComptime(msg, param_src.toSrcLoc(src_decl), param.ty);
92529252
9253 try sema.addDeclaredHereNote(msg, param.ty);9253 try sema.addDeclaredHereNote(msg, param.ty);
9254 break :msg msg;9254 break :msg msg;
...@@ -22905,6 +22905,17 @@ fn zirBuiltinExtern(...@@ -22905,6 +22905,17 @@ fn zirBuiltinExtern(
22905 if (!ty.isPtrAtRuntime()) {22905 if (!ty.isPtrAtRuntime()) {
22906 return sema.fail(block, ty_src, "expected (optional) pointer", .{});22906 return sema.fail(block, ty_src, "expected (optional) pointer", .{});
22907 }22907 }
22908 if (!try sema.validateExternType(ty.childType(), .other)) {
22909 const msg = msg: {
22910 const mod = sema.mod;
22911 const msg = try sema.errMsg(block, ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(mod)});
22912 errdefer msg.destroy(sema.gpa);
22913 const src_decl = sema.mod.declPtr(block.src_decl);
22914 try sema.explainWhyTypeIsNotExtern(msg, ty_src.toSrcLoc(src_decl), ty, .other);
22915 break :msg msg;
22916 };
22917 return sema.failWithOwnedErrorMsg(msg);
22918 }
2290822919
22909 const options = sema.resolveExternOptions(block, .unneeded, extra.rhs) catch |err| switch (err) {22920 const options = sema.resolveExternOptions(block, .unneeded, extra.rhs) catch |err| switch (err) {
22910 error.NeededSourceLocation => {22921 error.NeededSourceLocation => {
...@@ -23055,7 +23066,7 @@ fn validateVarType(...@@ -23055,7 +23066,7 @@ fn validateVarType(
23055 errdefer msg.destroy(sema.gpa);23066 errdefer msg.destroy(sema.gpa);
2305623067
23057 const src_decl = mod.declPtr(block.src_decl);23068 const src_decl = mod.declPtr(block.src_decl);
23058 try sema.explainWhyTypeIsComptime(block, src, msg, src.toSrcLoc(src_decl), var_ty);23069 try sema.explainWhyTypeIsComptime(msg, src.toSrcLoc(src_decl), var_ty);
23059 if (var_ty.zigTypeTag() == .ComptimeInt or var_ty.zigTypeTag() == .ComptimeFloat) {23070 if (var_ty.zigTypeTag() == .ComptimeInt or var_ty.zigTypeTag() == .ComptimeFloat) {
23060 try sema.errNote(block, src, msg, "to modify this variable at runtime, it must be given an explicit fixed-size number type", .{});23071 try sema.errNote(block, src, msg, "to modify this variable at runtime, it must be given an explicit fixed-size number type", .{});
23061 }23072 }
...@@ -23124,8 +23135,6 @@ const TypeSet = std.HashMapUnmanaged(Type, void, Type.HashContext64, std.hash_ma...@@ -23124,8 +23135,6 @@ const TypeSet = std.HashMapUnmanaged(Type, void, Type.HashContext64, std.hash_ma
2312423135
23125fn explainWhyTypeIsComptime(23136fn explainWhyTypeIsComptime(
23126 sema: *Sema,23137 sema: *Sema,
23127 block: *Block,
23128 src: LazySrcLoc,
23129 msg: *Module.ErrorMsg,23138 msg: *Module.ErrorMsg,
23130 src_loc: Module.SrcLoc,23139 src_loc: Module.SrcLoc,
23131 ty: Type,23140 ty: Type,
...@@ -23134,13 +23143,11 @@ fn explainWhyTypeIsComptime(...@@ -23134,13 +23143,11 @@ fn explainWhyTypeIsComptime(
23134 defer type_set.deinit(sema.gpa);23143 defer type_set.deinit(sema.gpa);
2313523144
23136 try sema.resolveTypeFully(ty);23145 try sema.resolveTypeFully(ty);
23137 return sema.explainWhyTypeIsComptimeInner(block, src, msg, src_loc, ty, &type_set);23146 return sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty, &type_set);
23138}23147}
2313923148
23140fn explainWhyTypeIsComptimeInner(23149fn explainWhyTypeIsComptimeInner(
23141 sema: *Sema,23150 sema: *Sema,
23142 block: *Block,
23143 src: LazySrcLoc,
23144 msg: *Module.ErrorMsg,23151 msg: *Module.ErrorMsg,
23145 src_loc: Module.SrcLoc,23152 src_loc: Module.SrcLoc,
23146 ty: Type,23153 ty: Type,
...@@ -23181,7 +23188,7 @@ fn explainWhyTypeIsComptimeInner(...@@ -23181,7 +23188,7 @@ fn explainWhyTypeIsComptimeInner(
23181 },23188 },
2318223189
23183 .Array, .Vector => {23190 .Array, .Vector => {
23184 try sema.explainWhyTypeIsComptimeInner(block, src, msg, src_loc, ty.elemType(), type_set);23191 try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.elemType(), type_set);
23185 },23192 },
23186 .Pointer => {23193 .Pointer => {
23187 const elem_ty = ty.elemType2();23194 const elem_ty = ty.elemType2();
...@@ -23199,15 +23206,15 @@ fn explainWhyTypeIsComptimeInner(...@@ -23199,15 +23206,15 @@ fn explainWhyTypeIsComptimeInner(
23199 }23206 }
23200 return;23207 return;
23201 }23208 }
23202 try sema.explainWhyTypeIsComptimeInner(block, src, msg, src_loc, ty.elemType(), type_set);23209 try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.elemType(), type_set);
23203 },23210 },
2320423211
23205 .Optional => {23212 .Optional => {
23206 var buf: Type.Payload.ElemType = undefined;23213 var buf: Type.Payload.ElemType = undefined;
23207 try sema.explainWhyTypeIsComptimeInner(block, src, msg, src_loc, ty.optionalChild(&buf), type_set);23214 try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.optionalChild(&buf), type_set);
23208 },23215 },
23209 .ErrorUnion => {23216 .ErrorUnion => {
23210 try sema.explainWhyTypeIsComptimeInner(block, src, msg, src_loc, ty.errorUnionPayload(), type_set);23217 try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.errorUnionPayload(), type_set);
23211 },23218 },
2321223219
23213 .Struct => {23220 .Struct => {
...@@ -23223,7 +23230,7 @@ fn explainWhyTypeIsComptimeInner(...@@ -23223,7 +23230,7 @@ fn explainWhyTypeIsComptimeInner(
2322323230
23224 if (try sema.typeRequiresComptime(field.ty)) {23231 if (try sema.typeRequiresComptime(field.ty)) {
23225 try mod.errNoteNonLazy(field_src_loc, msg, "struct requires comptime because of this field", .{});23232 try mod.errNoteNonLazy(field_src_loc, msg, "struct requires comptime because of this field", .{});
23226 try sema.explainWhyTypeIsComptimeInner(block, src, msg, field_src_loc, field.ty, type_set);23233 try sema.explainWhyTypeIsComptimeInner(msg, field_src_loc, field.ty, type_set);
23227 }23234 }
23228 }23235 }
23229 }23236 }
...@@ -23243,7 +23250,7 @@ fn explainWhyTypeIsComptimeInner(...@@ -23243,7 +23250,7 @@ fn explainWhyTypeIsComptimeInner(
2324323250
23244 if (try sema.typeRequiresComptime(field.ty)) {23251 if (try sema.typeRequiresComptime(field.ty)) {
23245 try mod.errNoteNonLazy(field_src_loc, msg, "union requires comptime because of this field", .{});23252 try mod.errNoteNonLazy(field_src_loc, msg, "union requires comptime because of this field", .{});
23246 try sema.explainWhyTypeIsComptimeInner(block, src, msg, field_src_loc, field.ty, type_set);23253 try sema.explainWhyTypeIsComptimeInner(msg, field_src_loc, field.ty, type_set);
23247 }23254 }
23248 }23255 }
23249 }23256 }
...@@ -23286,7 +23293,7 @@ fn validateExternType(...@@ -23286,7 +23293,7 @@ fn validateExternType(
23286 .Float,23293 .Float,
23287 .AnyFrame,23294 .AnyFrame,
23288 => return true,23295 => return true,
23289 .Pointer => return !ty.isSlice(),23296 .Pointer => return !(ty.isSlice() or try sema.typeRequiresComptime(ty)),
23290 .Int => switch (ty.intInfo(sema.mod.getTarget()).bits) {23297 .Int => switch (ty.intInfo(sema.mod.getTarget()).bits) {
23291 8, 16, 32, 64, 128 => return true,23298 8, 16, 32, 64, 128 => return true,
23292 else => return false,23299 else => return false,
...@@ -23352,7 +23359,15 @@ fn explainWhyTypeIsNotExtern(...@@ -23352,7 +23359,15 @@ fn explainWhyTypeIsNotExtern(
23352 .Frame,23359 .Frame,
23353 => return,23360 => return,
2335423361
23355 .Pointer => try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{}),23362 .Pointer => {
23363 if (ty.isSlice()) {
23364 try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{});
23365 } else {
23366 const pointee_ty = ty.childType();
23367 try mod.errNoteNonLazy(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(sema.mod)});
23368 try sema.explainWhyTypeIsComptime(msg, src_loc, pointee_ty);
23369 }
23370 },
23356 .Void => try mod.errNoteNonLazy(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}),23371 .Void => try mod.errNoteNonLazy(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}),
23357 .NoReturn => try mod.errNoteNonLazy(src_loc, msg, "'noreturn' is only allowed as a return type", .{}),23372 .NoReturn => try mod.errNoteNonLazy(src_loc, msg, "'noreturn' is only allowed as a return type", .{}),
23358 .Int => if (!std.math.isPowerOfTwo(ty.intInfo(sema.mod.getTarget()).bits)) {23373 .Int => if (!std.math.isPowerOfTwo(ty.intInfo(sema.mod.getTarget()).bits)) {
...@@ -25041,7 +25056,7 @@ fn validateRuntimeElemAccess(...@@ -25041,7 +25056,7 @@ fn validateRuntimeElemAccess(
25041 errdefer msg.destroy(sema.gpa);25056 errdefer msg.destroy(sema.gpa);
2504225057
25043 const src_decl = sema.mod.declPtr(block.src_decl);25058 const src_decl = sema.mod.declPtr(block.src_decl);
25044 try sema.explainWhyTypeIsComptime(block, elem_index_src, msg, parent_src.toSrcLoc(src_decl), parent_ty);25059 try sema.explainWhyTypeIsComptime(msg, parent_src.toSrcLoc(src_decl), parent_ty);
2504525060
25046 break :msg msg;25061 break :msg msg;
25047 };25062 };
test/cases/compile_errors/invalid_type_in_builtin_extern.zig created+11
...@@ -0,0 +1,11 @@
1const x = @extern(*comptime_int, .{.name="foo"});
2pub export fn entry() void {
3 _ = x;
4}
5
6// error
7// backend=stage2
8// target=native
9//
10// :1:19: error: extern symbol cannot have type '*comptime_int'
11// :1:19: note: pointer to comptime-only type 'comptime_int'