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 {
308308 prefix ++ "the function returns a comptime-only type '{}'",
309309 .{rt.return_ty.fmt(sema.mod)},
310310 );
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);
312312 },
313313 }
314314 }
......@@ -4804,7 +4804,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
48044804 errdefer msg.destroy(sema.gpa);
48054805
48064806 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);
48084808 break :msg msg;
48094809 };
48104810 return sema.failWithOwnedErrorMsg(msg);
......@@ -5578,7 +5578,7 @@ fn analyzeBlockBody(
55785578 try sema.errNote(child_block, runtime_src, msg, "runtime control flow here", .{});
55795579
55805580 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
55835583 break :msg msg;
55845584 };
......@@ -9026,7 +9026,7 @@ fn funcCommon(
90269026 "function with comptime-only return type '{}' requires all parameters to be comptime",
90279027 .{return_type.fmt(sema.mod)},
90289028 );
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
90319031 const tags = sema.code.instructions.items(.tag);
90329032 const data = sema.code.instructions.items(.data);
......@@ -9248,7 +9248,7 @@ fn analyzeParameter(
92489248 errdefer msg.destroy(sema.gpa);
92499249
92509250 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
92539253 try sema.addDeclaredHereNote(msg, param.ty);
92549254 break :msg msg;
......@@ -22905,6 +22905,17 @@ fn zirBuiltinExtern(
2290522905 if (!ty.isPtrAtRuntime()) {
2290622906 return sema.fail(block, ty_src, "expected (optional) pointer", .{});
2290722907 }
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
2290922920 const options = sema.resolveExternOptions(block, .unneeded, extra.rhs) catch |err| switch (err) {
2291022921 error.NeededSourceLocation => {
......@@ -23055,7 +23066,7 @@ fn validateVarType(
2305523066 errdefer msg.destroy(sema.gpa);
2305623067
2305723068 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);
2305923070 if (var_ty.zigTypeTag() == .ComptimeInt or var_ty.zigTypeTag() == .ComptimeFloat) {
2306023071 try sema.errNote(block, src, msg, "to modify this variable at runtime, it must be given an explicit fixed-size number type", .{});
2306123072 }
......@@ -23124,8 +23135,6 @@ const TypeSet = std.HashMapUnmanaged(Type, void, Type.HashContext64, std.hash_ma
2312423135
2312523136fn explainWhyTypeIsComptime(
2312623137 sema: *Sema,
23127 block: *Block,
23128 src: LazySrcLoc,
2312923138 msg: *Module.ErrorMsg,
2313023139 src_loc: Module.SrcLoc,
2313123140 ty: Type,
......@@ -23134,13 +23143,11 @@ fn explainWhyTypeIsComptime(
2313423143 defer type_set.deinit(sema.gpa);
2313523144
2313623145 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);
2313823147}
2313923148
2314023149fn explainWhyTypeIsComptimeInner(
2314123150 sema: *Sema,
23142 block: *Block,
23143 src: LazySrcLoc,
2314423151 msg: *Module.ErrorMsg,
2314523152 src_loc: Module.SrcLoc,
2314623153 ty: Type,
......@@ -23181,7 +23188,7 @@ fn explainWhyTypeIsComptimeInner(
2318123188 },
2318223189
2318323190 .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);
2318523192 },
2318623193 .Pointer => {
2318723194 const elem_ty = ty.elemType2();
......@@ -23199,15 +23206,15 @@ fn explainWhyTypeIsComptimeInner(
2319923206 }
2320023207 return;
2320123208 }
23202 try sema.explainWhyTypeIsComptimeInner(block, src, msg, src_loc, ty.elemType(), type_set);
23209 try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.elemType(), type_set);
2320323210 },
2320423211
2320523212 .Optional => {
2320623213 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);
2320823215 },
2320923216 .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);
2321123218 },
2321223219
2321323220 .Struct => {
......@@ -23223,7 +23230,7 @@ fn explainWhyTypeIsComptimeInner(
2322323230
2322423231 if (try sema.typeRequiresComptime(field.ty)) {
2322523232 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);
2322723234 }
2322823235 }
2322923236 }
......@@ -23243,7 +23250,7 @@ fn explainWhyTypeIsComptimeInner(
2324323250
2324423251 if (try sema.typeRequiresComptime(field.ty)) {
2324523252 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);
2324723254 }
2324823255 }
2324923256 }
......@@ -23286,7 +23293,7 @@ fn validateExternType(
2328623293 .Float,
2328723294 .AnyFrame,
2328823295 => return true,
23289 .Pointer => return !ty.isSlice(),
23296 .Pointer => return !(ty.isSlice() or try sema.typeRequiresComptime(ty)),
2329023297 .Int => switch (ty.intInfo(sema.mod.getTarget()).bits) {
2329123298 8, 16, 32, 64, 128 => return true,
2329223299 else => return false,
......@@ -23352,7 +23359,15 @@ fn explainWhyTypeIsNotExtern(
2335223359 .Frame,
2335323360 => 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 },
2335623371 .Void => try mod.errNoteNonLazy(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}),
2335723372 .NoReturn => try mod.errNoteNonLazy(src_loc, msg, "'noreturn' is only allowed as a return type", .{}),
2335823373 .Int => if (!std.math.isPowerOfTwo(ty.intInfo(sema.mod.getTarget()).bits)) {
......@@ -25041,7 +25056,7 @@ fn validateRuntimeElemAccess(
2504125056 errdefer msg.destroy(sema.gpa);
2504225057
2504325058 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
2504625061 break :msg msg;
2504725062 };
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'