authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-08-02 18:32:44+03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-08-02 18:32:44+03:00
log4831c1c65f51ccfdb48c8d16bdf77435e0256070
tree62ed249f1b2ce780c511b7aa6304104c4cd5bc90
parent2375658da9f8e73d3e4b6d14d88c02cc765ae579
parente47706f34454c46dd00fe10fdf9252657117a00d
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #12277 from Vexu/stage2-compile-errors

Stage2: validate packed struct field types

22 files changed, 459 insertions(+), 233 deletions(-)

src/AstGen.zig+2-1
...@@ -7424,7 +7424,8 @@ fn builtinCall(...@@ -7424,7 +7424,8 @@ fn builtinCall(
7424 const token_starts = tree.tokens.items(.start);7424 const token_starts = tree.tokens.items(.start);
7425 const node_start = token_starts[tree.firstToken(node)];7425 const node_start = token_starts[tree.firstToken(node)];
7426 astgen.advanceSourceCursor(node_start);7426 astgen.advanceSourceCursor(node_start);
7427 const result = try gz.addExtendedPayload(.builtin_src, Zir.Inst.LineColumn{7427 const result = try gz.addExtendedPayload(.builtin_src, Zir.Inst.Src{
7428 .node = gz.nodeIndexToRelative(node),
7428 .line = astgen.source_line,7429 .line = astgen.source_line,
7429 .column = astgen.source_column,7430 .column = astgen.source_column,
7430 });7431 });
src/Module.zig+94-13
...@@ -2161,6 +2161,10 @@ pub const SrcLoc = struct {...@@ -2161,6 +2161,10 @@ pub const SrcLoc = struct {
2161 .local_var_decl => tree.localVarDecl(node),2161 .local_var_decl => tree.localVarDecl(node),
2162 .simple_var_decl => tree.simpleVarDecl(node),2162 .simple_var_decl => tree.simpleVarDecl(node),
2163 .aligned_var_decl => tree.alignedVarDecl(node),2163 .aligned_var_decl => tree.alignedVarDecl(node),
2164 .@"usingnamespace" => {
2165 const node_data = tree.nodes.items(.data);
2166 return nodeToSpan(tree, node_data[node].lhs);
2167 },
2164 else => unreachable,2168 else => unreachable,
2165 };2169 };
2166 if (full.ast.type_node != 0) {2170 if (full.ast.type_node != 0) {
...@@ -2171,6 +2175,58 @@ pub const SrcLoc = struct {...@@ -2171,6 +2175,58 @@ pub const SrcLoc = struct {
2171 const end = start + @intCast(u32, tree.tokenSlice(tok_index).len);2175 const end = start + @intCast(u32, tree.tokenSlice(tok_index).len);
2172 return Span{ .start = start, .end = end, .main = start };2176 return Span{ .start = start, .end = end, .main = start };
2173 },2177 },
2178 .node_offset_var_decl_align => |node_off| {
2179 const tree = try src_loc.file_scope.getTree(gpa);
2180 const node = src_loc.declRelativeToNodeIndex(node_off);
2181 const node_tags = tree.nodes.items(.tag);
2182 const full: Ast.full.VarDecl = switch (node_tags[node]) {
2183 .global_var_decl => tree.globalVarDecl(node),
2184 .local_var_decl => tree.localVarDecl(node),
2185 .simple_var_decl => tree.simpleVarDecl(node),
2186 .aligned_var_decl => tree.alignedVarDecl(node),
2187 else => unreachable,
2188 };
2189 return nodeToSpan(tree, full.ast.align_node);
2190 },
2191 .node_offset_var_decl_section => |node_off| {
2192 const tree = try src_loc.file_scope.getTree(gpa);
2193 const node = src_loc.declRelativeToNodeIndex(node_off);
2194 const node_tags = tree.nodes.items(.tag);
2195 const full: Ast.full.VarDecl = switch (node_tags[node]) {
2196 .global_var_decl => tree.globalVarDecl(node),
2197 .local_var_decl => tree.localVarDecl(node),
2198 .simple_var_decl => tree.simpleVarDecl(node),
2199 .aligned_var_decl => tree.alignedVarDecl(node),
2200 else => unreachable,
2201 };
2202 return nodeToSpan(tree, full.ast.section_node);
2203 },
2204 .node_offset_var_decl_addrspace => |node_off| {
2205 const tree = try src_loc.file_scope.getTree(gpa);
2206 const node = src_loc.declRelativeToNodeIndex(node_off);
2207 const node_tags = tree.nodes.items(.tag);
2208 const full: Ast.full.VarDecl = switch (node_tags[node]) {
2209 .global_var_decl => tree.globalVarDecl(node),
2210 .local_var_decl => tree.localVarDecl(node),
2211 .simple_var_decl => tree.simpleVarDecl(node),
2212 .aligned_var_decl => tree.alignedVarDecl(node),
2213 else => unreachable,
2214 };
2215 return nodeToSpan(tree, full.ast.addrspace_node);
2216 },
2217 .node_offset_var_decl_init => |node_off| {
2218 const tree = try src_loc.file_scope.getTree(gpa);
2219 const node = src_loc.declRelativeToNodeIndex(node_off);
2220 const node_tags = tree.nodes.items(.tag);
2221 const full: Ast.full.VarDecl = switch (node_tags[node]) {
2222 .global_var_decl => tree.globalVarDecl(node),
2223 .local_var_decl => tree.localVarDecl(node),
2224 .simple_var_decl => tree.simpleVarDecl(node),
2225 .aligned_var_decl => tree.alignedVarDecl(node),
2226 else => unreachable,
2227 };
2228 return nodeToSpan(tree, full.ast.init_node);
2229 },
2174 .node_offset_builtin_call_arg0 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 0),2230 .node_offset_builtin_call_arg0 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 0),
2175 .node_offset_builtin_call_arg1 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 1),2231 .node_offset_builtin_call_arg1 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 1),
2176 .node_offset_builtin_call_arg2 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 2),2232 .node_offset_builtin_call_arg2 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 2),
...@@ -2857,6 +2913,18 @@ pub const LazySrcLoc = union(enum) {...@@ -2857,6 +2913,18 @@ pub const LazySrcLoc = union(enum) {
2857 /// to the type expression.2913 /// to the type expression.
2858 /// The Decl is determined contextually.2914 /// The Decl is determined contextually.
2859 node_offset_var_decl_ty: i32,2915 node_offset_var_decl_ty: i32,
2916 /// The source location points to the alignment expression of a var decl.
2917 /// The Decl is determined contextually.
2918 node_offset_var_decl_align: i32,
2919 /// The source location points to the linksection expression of a var decl.
2920 /// The Decl is determined contextually.
2921 node_offset_var_decl_section: i32,
2922 /// The source location points to the addrspace expression of a var decl.
2923 /// The Decl is determined contextually.
2924 node_offset_var_decl_addrspace: i32,
2925 /// The source location points to the initializer of a var decl.
2926 /// The Decl is determined contextually.
2927 node_offset_var_decl_init: i32,
2860 /// The source location points to a for loop condition expression,2928 /// The source location points to a for loop condition expression,
2861 /// found by taking this AST node index offset from the containing2929 /// found by taking this AST node index offset from the containing
2862 /// Decl AST node, which points to a for loop AST node. Next, navigate2930 /// Decl AST node, which points to a for loop AST node. Next, navigate
...@@ -3098,6 +3166,10 @@ pub const LazySrcLoc = union(enum) {...@@ -3098,6 +3166,10 @@ pub const LazySrcLoc = union(enum) {
3098 .node_offset,3166 .node_offset,
3099 .node_offset_initializer,3167 .node_offset_initializer,
3100 .node_offset_var_decl_ty,3168 .node_offset_var_decl_ty,
3169 .node_offset_var_decl_align,
3170 .node_offset_var_decl_section,
3171 .node_offset_var_decl_addrspace,
3172 .node_offset_var_decl_init,
3101 .node_offset_for_cond,3173 .node_offset_for_cond,
3102 .node_offset_builtin_call_arg0,3174 .node_offset_builtin_call_arg0,
3103 .node_offset_builtin_call_arg1,3175 .node_offset_builtin_call_arg1,
...@@ -4414,17 +4486,26 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4414,17 +4486,26 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4414 const body = zir.extra[extra.end..][0..extra.data.body_len];4486 const body = zir.extra[extra.end..][0..extra.data.body_len];
4415 const result_ref = (try sema.analyzeBodyBreak(&block_scope, body)).?.operand;4487 const result_ref = (try sema.analyzeBodyBreak(&block_scope, body)).?.operand;
4416 try wip_captures.finalize();4488 try wip_captures.finalize();
4417 const src = LazySrcLoc.nodeOffset(0);4489 const align_src: LazySrcLoc = .{ .node_offset_var_decl_align = 0 };
4418 const decl_tv = try sema.resolveInstValue(&block_scope, .unneeded, result_ref, undefined);4490 const section_src: LazySrcLoc = .{ .node_offset_var_decl_section = 0 };
4491 const address_space_src: LazySrcLoc = .{ .node_offset_var_decl_addrspace = 0 };
4492 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = 0 };
4493 const init_src: LazySrcLoc = .{ .node_offset_var_decl_init = 0 };
4494 const decl_tv = try sema.resolveInstValue(&block_scope, init_src, result_ref, undefined);
4419 const decl_align: u32 = blk: {4495 const decl_align: u32 = blk: {
4420 const align_ref = decl.zirAlignRef();4496 const align_ref = decl.zirAlignRef();
4421 if (align_ref == .none) break :blk 0;4497 if (align_ref == .none) break :blk 0;
4422 break :blk try sema.resolveAlign(&block_scope, src, align_ref);4498 break :blk try sema.resolveAlign(&block_scope, align_src, align_ref);
4423 };4499 };
4424 const decl_linksection: ?[*:0]const u8 = blk: {4500 const decl_linksection: ?[*:0]const u8 = blk: {
4425 const linksection_ref = decl.zirLinksectionRef();4501 const linksection_ref = decl.zirLinksectionRef();
4426 if (linksection_ref == .none) break :blk null;4502 if (linksection_ref == .none) break :blk null;
4427 const bytes = try sema.resolveConstString(&block_scope, src, linksection_ref, "linksection must be comptime known");4503 const bytes = try sema.resolveConstString(&block_scope, section_src, linksection_ref, "linksection must be comptime known");
4504 if (mem.indexOfScalar(u8, bytes, 0) != null) {
4505 return sema.fail(&block_scope, section_src, "linksection cannot contain null bytes", .{});
4506 } else if (bytes.len == 0) {
4507 return sema.fail(&block_scope, section_src, "linksection cannot be empty", .{});
4508 }
4428 break :blk (try decl_arena_allocator.dupeZ(u8, bytes)).ptr;4509 break :blk (try decl_arena_allocator.dupeZ(u8, bytes)).ptr;
4429 };4510 };
4430 const target = sema.mod.getTarget();4511 const target = sema.mod.getTarget();
...@@ -4442,27 +4523,27 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4442,27 +4523,27 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4442 .constant => target_util.defaultAddressSpace(target, .global_constant),4523 .constant => target_util.defaultAddressSpace(target, .global_constant),
4443 else => unreachable,4524 else => unreachable,
4444 },4525 },
4445 else => |addrspace_ref| try sema.analyzeAddrspace(&block_scope, src, addrspace_ref, addrspace_ctx),4526 else => |addrspace_ref| try sema.analyzeAddrspace(&block_scope, address_space_src, addrspace_ref, addrspace_ctx),
4446 };4527 };
4447 };4528 };
44484529
4449 // Note this resolves the type of the Decl, not the value; if this Decl4530 // Note this resolves the type of the Decl, not the value; if this Decl
4450 // is a struct, for example, this resolves `type` (which needs no resolution),4531 // is a struct, for example, this resolves `type` (which needs no resolution),
4451 // not the struct itself.4532 // not the struct itself.
4452 try sema.resolveTypeLayout(&block_scope, src, decl_tv.ty);4533 try sema.resolveTypeLayout(&block_scope, ty_src, decl_tv.ty);
44534534
4454 const decl_arena_state = try decl_arena_allocator.create(std.heap.ArenaAllocator.State);4535 const decl_arena_state = try decl_arena_allocator.create(std.heap.ArenaAllocator.State);
44554536
4456 if (decl.is_usingnamespace) {4537 if (decl.is_usingnamespace) {
4457 if (!decl_tv.ty.eql(Type.type, mod)) {4538 if (!decl_tv.ty.eql(Type.type, mod)) {
4458 return sema.fail(&block_scope, src, "expected type, found {}", .{4539 return sema.fail(&block_scope, ty_src, "expected type, found {}", .{
4459 decl_tv.ty.fmt(mod),4540 decl_tv.ty.fmt(mod),
4460 });4541 });
4461 }4542 }
4462 var buffer: Value.ToTypeBuffer = undefined;4543 var buffer: Value.ToTypeBuffer = undefined;
4463 const ty = try decl_tv.val.toType(&buffer).copy(decl_arena_allocator);4544 const ty = try decl_tv.val.toType(&buffer).copy(decl_arena_allocator);
4464 if (ty.getNamespace() == null) {4545 if (ty.getNamespace() == null) {
4465 return sema.fail(&block_scope, src, "type {} has no namespace", .{ty.fmt(mod)});4546 return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(mod)});
4466 }4547 }
44674548
4468 decl.ty = Type.type;4549 decl.ty = Type.type;
...@@ -4508,7 +4589,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4508,7 +4589,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4508 decl.analysis = .complete;4589 decl.analysis = .complete;
4509 decl.generation = mod.generation;4590 decl.generation = mod.generation;
45104591
4511 const has_runtime_bits = try sema.fnHasRuntimeBits(&block_scope, src, decl.ty);4592 const has_runtime_bits = try sema.fnHasRuntimeBits(&block_scope, ty_src, decl.ty);
45124593
4513 if (has_runtime_bits) {4594 if (has_runtime_bits) {
4514 // We don't fully codegen the decl until later, but we do need to reserve a global4595 // We don't fully codegen the decl until later, but we do need to reserve a global
...@@ -4525,7 +4606,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4525,7 +4606,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
45254606
4526 const is_inline = decl.ty.fnCallingConvention() == .Inline;4607 const is_inline = decl.ty.fnCallingConvention() == .Inline;
4527 if (decl.is_exported) {4608 if (decl.is_exported) {
4528 const export_src = src; // TODO make this point at `export` token4609 const export_src: LazySrcLoc = .{ .token_offset = @boolToInt(decl.is_pub) };
4529 if (is_inline) {4610 if (is_inline) {
4530 return sema.fail(&block_scope, export_src, "export of inline function", .{});4611 return sema.fail(&block_scope, export_src, "export of inline function", .{});
4531 }4612 }
...@@ -4588,14 +4669,14 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4588,14 +4669,14 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4588 decl.generation = mod.generation;4669 decl.generation = mod.generation;
45894670
4590 const has_runtime_bits = is_extern or4671 const has_runtime_bits = is_extern or
4591 (queue_linker_work and try sema.typeHasRuntimeBits(&block_scope, src, decl.ty));4672 (queue_linker_work and try sema.typeHasRuntimeBits(&block_scope, ty_src, decl.ty));
45924673
4593 if (has_runtime_bits) {4674 if (has_runtime_bits) {
4594 log.debug("queue linker work for {*} ({s})", .{ decl, decl.name });4675 log.debug("queue linker work for {*} ({s})", .{ decl, decl.name });
45954676
4596 // Needed for codegen_decl which will call updateDecl and then the4677 // Needed for codegen_decl which will call updateDecl and then the
4597 // codegen backend wants full access to the Decl Type.4678 // codegen backend wants full access to the Decl Type.
4598 try sema.resolveTypeFully(&block_scope, src, decl.ty);4679 try sema.resolveTypeFully(&block_scope, ty_src, decl.ty);
45994680
4600 try mod.comp.bin_file.allocateDeclIndexes(decl_index);4681 try mod.comp.bin_file.allocateDeclIndexes(decl_index);
4601 try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });4682 try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
...@@ -4606,7 +4687,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4606,7 +4687,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4606 }4687 }
46074688
4608 if (decl.is_exported) {4689 if (decl.is_exported) {
4609 const export_src = src; // TODO point to the export token4690 const export_src: LazySrcLoc = .{ .token_offset = @boolToInt(decl.is_pub) };
4610 // The scope needs to have the decl in it.4691 // The scope needs to have the decl in it.
4611 const options: std.builtin.ExportOptions = .{ .name = mem.sliceTo(decl.name, 0) };4692 const options: std.builtin.ExportOptions = .{ .name = mem.sliceTo(decl.name, 0) };
4612 try sema.analyzeExport(&block_scope, export_src, options, decl_index);4693 try sema.analyzeExport(&block_scope, export_src, options, decl_index);
src/Sema.zig+215-49
...@@ -2971,7 +2971,7 @@ fn zirAllocExtended(...@@ -2971,7 +2971,7 @@ fn zirAllocExtended(
2971 const extra = sema.code.extraData(Zir.Inst.AllocExtended, extended.operand);2971 const extra = sema.code.extraData(Zir.Inst.AllocExtended, extended.operand);
2972 const src = LazySrcLoc.nodeOffset(extra.data.src_node);2972 const src = LazySrcLoc.nodeOffset(extra.data.src_node);
2973 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = extra.data.src_node };2973 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = extra.data.src_node };
2974 const align_src = src; // TODO better source location2974 const align_src: LazySrcLoc = .{ .node_offset_var_decl_align = extra.data.src_node };
2975 const small = @bitCast(Zir.Inst.AllocExtended.Small, extended.small);2975 const small = @bitCast(Zir.Inst.AllocExtended.Small, extended.small);
29762976
2977 var extra_index: usize = extra.end;2977 var extra_index: usize = extra.end;
...@@ -5049,13 +5049,13 @@ pub fn analyzeExport(...@@ -5049,13 +5049,13 @@ pub fn analyzeExport(
5049 try mod.ensureDeclAnalyzed(exported_decl_index);5049 try mod.ensureDeclAnalyzed(exported_decl_index);
5050 const exported_decl = mod.declPtr(exported_decl_index);5050 const exported_decl = mod.declPtr(exported_decl_index);
50515051
5052 if (!(try sema.validateExternType(exported_decl.ty, .other))) {5052 if (!sema.validateExternType(exported_decl.ty, .other)) {
5053 const msg = msg: {5053 const msg = msg: {
5054 const msg = try sema.errMsg(block, src, "unable to export type '{}'", .{exported_decl.ty.fmt(sema.mod)});5054 const msg = try sema.errMsg(block, src, "unable to export type '{}'", .{exported_decl.ty.fmt(sema.mod)});
5055 errdefer msg.destroy(sema.gpa);5055 errdefer msg.destroy(sema.gpa);
50565056
5057 const src_decl = sema.mod.declPtr(block.src_decl);5057 const src_decl = sema.mod.declPtr(block.src_decl);
5058 try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), exported_decl.ty, .other);5058 try sema.explainWhyTypeIsNotExtern(msg, src.toSrcLoc(src_decl), exported_decl.ty, .other);
50595059
5060 try sema.addDeclaredHereNote(msg, exported_decl.ty);5060 try sema.addDeclaredHereNote(msg, exported_decl.ty);
5061 break :msg msg;5061 break :msg msg;
...@@ -7634,7 +7634,7 @@ fn funcCommon(...@@ -7634,7 +7634,7 @@ fn funcCommon(
7634 };7634 };
7635 return sema.failWithOwnedErrorMsg(block, msg);7635 return sema.failWithOwnedErrorMsg(block, msg);
7636 }7636 }
7637 if (!Type.fnCallingConventionAllowsZigTypes(cc_workaround) and !(try sema.validateExternType(return_type, .ret_ty))) {7637 if (!Type.fnCallingConventionAllowsZigTypes(cc_workaround) and !sema.validateExternType(return_type, .ret_ty)) {
7638 const msg = msg: {7638 const msg = msg: {
7639 const msg = try sema.errMsg(block, ret_ty_src, "return type '{}' not allowed in function with calling convention '{s}'", .{7639 const msg = try sema.errMsg(block, ret_ty_src, "return type '{}' not allowed in function with calling convention '{s}'", .{
7640 return_type.fmt(sema.mod), @tagName(cc_workaround),7640 return_type.fmt(sema.mod), @tagName(cc_workaround),
...@@ -7642,7 +7642,7 @@ fn funcCommon(...@@ -7642,7 +7642,7 @@ fn funcCommon(
7642 errdefer msg.destroy(sema.gpa);7642 errdefer msg.destroy(sema.gpa);
76437643
7644 const src_decl = sema.mod.declPtr(block.src_decl);7644 const src_decl = sema.mod.declPtr(block.src_decl);
7645 try sema.explainWhyTypeIsNotExtern(block, ret_ty_src, msg, ret_ty_src.toSrcLoc(src_decl), return_type, .ret_ty);7645 try sema.explainWhyTypeIsNotExtern(msg, ret_ty_src.toSrcLoc(src_decl), return_type, .ret_ty);
76467646
7647 try sema.addDeclaredHereNote(msg, return_type);7647 try sema.addDeclaredHereNote(msg, return_type);
7648 break :msg msg;7648 break :msg msg;
...@@ -7830,7 +7830,7 @@ fn analyzeParameter(...@@ -7830,7 +7830,7 @@ fn analyzeParameter(
7830 };7830 };
7831 return sema.failWithOwnedErrorMsg(block, msg);7831 return sema.failWithOwnedErrorMsg(block, msg);
7832 }7832 }
7833 if (!Type.fnCallingConventionAllowsZigTypes(cc) and !(try sema.validateExternType(param.ty, .param_ty))) {7833 if (!Type.fnCallingConventionAllowsZigTypes(cc) and !sema.validateExternType(param.ty, .param_ty)) {
7834 const msg = msg: {7834 const msg = msg: {
7835 const msg = try sema.errMsg(block, param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{7835 const msg = try sema.errMsg(block, param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{
7836 param.ty.fmt(sema.mod), @tagName(cc),7836 param.ty.fmt(sema.mod), @tagName(cc),
...@@ -7838,7 +7838,7 @@ fn analyzeParameter(...@@ -7838,7 +7838,7 @@ fn analyzeParameter(
7838 errdefer msg.destroy(sema.gpa);7838 errdefer msg.destroy(sema.gpa);
78397839
7840 const src_decl = sema.mod.declPtr(block.src_decl);7840 const src_decl = sema.mod.declPtr(block.src_decl);
7841 try sema.explainWhyTypeIsNotExtern(block, param_src, msg, param_src.toSrcLoc(src_decl), param.ty, .param_ty);7841 try sema.explainWhyTypeIsNotExtern(msg, param_src.toSrcLoc(src_decl), param.ty, .param_ty);
78427842
7843 try sema.addDeclaredHereNote(msg, param.ty);7843 try sema.addDeclaredHereNote(msg, param.ty);
7844 break :msg msg;7844 break :msg msg;
...@@ -8046,7 +8046,7 @@ fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -8046,7 +8046,7 @@ fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
8046 if (try sema.resolveMaybeUndefValIntable(block, ptr_src, ptr)) |ptr_val| {8046 if (try sema.resolveMaybeUndefValIntable(block, ptr_src, ptr)) |ptr_val| {
8047 return sema.addConstant(Type.usize, ptr_val);8047 return sema.addConstant(Type.usize, ptr_val);
8048 }8048 }
8049 try sema.requireRuntimeBlock(block, ptr_src, ptr_src);8049 try sema.requireRuntimeBlock(block, inst_data.src(), ptr_src);
8050 return block.addUnOp(.ptrtoint, ptr);8050 return block.addUnOp(.ptrtoint, ptr);
8051}8051}
80528052
...@@ -8288,6 +8288,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -8288,6 +8288,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
82888288
8289 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);8289 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
8290 const operand = try sema.resolveInst(extra.rhs);8290 const operand = try sema.resolveInst(extra.rhs);
8291 const operand_ty = sema.typeOf(operand);
8291 switch (dest_ty.zigTypeTag()) {8292 switch (dest_ty.zigTypeTag()) {
8292 .AnyFrame,8293 .AnyFrame,
8293 .ComptimeFloat,8294 .ComptimeFloat,
...@@ -8310,8 +8311,8 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -8310,8 +8311,8 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
8310 const msg = msg: {8311 const msg = msg: {
8311 const msg = try sema.errMsg(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(sema.mod)});8312 const msg = try sema.errMsg(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(sema.mod)});
8312 errdefer msg.destroy(sema.gpa);8313 errdefer msg.destroy(sema.gpa);
8313 switch (sema.typeOf(operand).zigTypeTag()) {8314 switch (operand_ty.zigTypeTag()) {
8314 .Int, .ComptimeInt => try sema.errNote(block, dest_ty_src, msg, "use @intToEnum for type coercion", .{}),8315 .Int, .ComptimeInt => try sema.errNote(block, dest_ty_src, msg, "use @intToEnum to cast from '{}'", .{operand_ty.fmt(sema.mod)}),
8315 else => {},8316 else => {},
8316 }8317 }
83178318
...@@ -8320,9 +8321,20 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -8320,9 +8321,20 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
8320 return sema.failWithOwnedErrorMsg(block, msg);8321 return sema.failWithOwnedErrorMsg(block, msg);
8321 },8322 },
83228323
8323 .Pointer => return sema.fail(block, dest_ty_src, "cannot @bitCast to '{}', use @ptrCast to cast to a pointer", .{8324 .Pointer => {
8324 dest_ty.fmt(sema.mod),8325 const msg = msg: {
8325 }),8326 const msg = try sema.errMsg(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(sema.mod)});
8327 errdefer msg.destroy(sema.gpa);
8328 switch (operand_ty.zigTypeTag()) {
8329 .Int, .ComptimeInt => try sema.errNote(block, dest_ty_src, msg, "use @intToPtr to cast from '{}'", .{operand_ty.fmt(sema.mod)}),
8330 .Pointer => try sema.errNote(block, dest_ty_src, msg, "use @ptrCast to cast from '{}'", .{operand_ty.fmt(sema.mod)}),
8331 else => {},
8332 }
8333
8334 break :msg msg;
8335 };
8336 return sema.failWithOwnedErrorMsg(block, msg);
8337 },
8326 .Struct, .Union => if (dest_ty.containerLayout() == .Auto) {8338 .Struct, .Union => if (dest_ty.containerLayout() == .Auto) {
8327 const container = switch (dest_ty.zigTypeTag()) {8339 const container = switch (dest_ty.zigTypeTag()) {
8328 .Struct => "struct",8340 .Struct => "struct",
...@@ -8342,6 +8354,70 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -8342,6 +8354,70 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
8342 .Vector,8354 .Vector,
8343 => {},8355 => {},
8344 }8356 }
8357 switch (operand_ty.zigTypeTag()) {
8358 .AnyFrame,
8359 .ComptimeFloat,
8360 .ComptimeInt,
8361 .EnumLiteral,
8362 .ErrorSet,
8363 .ErrorUnion,
8364 .Fn,
8365 .Frame,
8366 .NoReturn,
8367 .Null,
8368 .Opaque,
8369 .Optional,
8370 .Type,
8371 .Undefined,
8372 .Void,
8373 => return sema.fail(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(sema.mod)}),
8374
8375 .Enum => {
8376 const msg = msg: {
8377 const msg = try sema.errMsg(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(sema.mod)});
8378 errdefer msg.destroy(sema.gpa);
8379 switch (dest_ty.zigTypeTag()) {
8380 .Int, .ComptimeInt => try sema.errNote(block, operand_src, msg, "use @enumToInt to cast to '{}'", .{dest_ty.fmt(sema.mod)}),
8381 else => {},
8382 }
8383
8384 break :msg msg;
8385 };
8386 return sema.failWithOwnedErrorMsg(block, msg);
8387 },
8388 .Pointer => {
8389 const msg = msg: {
8390 const msg = try sema.errMsg(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(sema.mod)});
8391 errdefer msg.destroy(sema.gpa);
8392 switch (dest_ty.zigTypeTag()) {
8393 .Int, .ComptimeInt => try sema.errNote(block, operand_src, msg, "use @ptrToInt to cast to '{}'", .{dest_ty.fmt(sema.mod)}),
8394 .Pointer => try sema.errNote(block, operand_src, msg, "use @ptrCast to cast to '{}'", .{dest_ty.fmt(sema.mod)}),
8395 else => {},
8396 }
8397
8398 break :msg msg;
8399 };
8400 return sema.failWithOwnedErrorMsg(block, msg);
8401 },
8402 .Struct, .Union => if (operand_ty.containerLayout() == .Auto) {
8403 const container = switch (operand_ty.zigTypeTag()) {
8404 .Struct => "struct",
8405 .Union => "union",
8406 else => unreachable,
8407 };
8408 return sema.fail(block, operand_src, "cannot @bitCast from '{}', {s} does not have a guaranteed in-memory layout", .{
8409 operand_ty.fmt(sema.mod), container,
8410 });
8411 },
8412 .BoundFn => @panic("TODO remove this type from the language and compiler"),
8413
8414 .Array,
8415 .Bool,
8416 .Float,
8417 .Int,
8418 .Vector,
8419 => {},
8420 }
8345 return sema.bitCast(block, dest_ty, operand, operand_src);8421 return sema.bitCast(block, dest_ty, operand, operand_src);
8346}8422}
83478423
...@@ -13098,8 +13174,8 @@ fn zirBuiltinSrc(...@@ -13098,8 +13174,8 @@ fn zirBuiltinSrc(
13098 const tracy = trace(@src());13174 const tracy = trace(@src());
13099 defer tracy.end();13175 defer tracy.end();
1310013176
13101 const src = sema.src; // TODO better source location13177 const extra = sema.code.extraData(Zir.Inst.Src, extended.operand).data;
13102 const extra = sema.code.extraData(Zir.Inst.LineColumn, extended.operand).data;13178 const src = LazySrcLoc.nodeOffset(extra.node);
13103 const func = sema.func orelse return sema.fail(block, src, "@src outside function", .{});13179 const func = sema.func orelse return sema.fail(block, src, "@src outside function", .{});
13104 const fn_owner_decl = sema.mod.declPtr(func.owner_decl);13180 const fn_owner_decl = sema.mod.declPtr(func.owner_decl);
1310513181
...@@ -14790,13 +14866,13 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -14790,13 +14866,13 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
14790 } else if (inst_data.size == .Many and elem_ty.zigTypeTag() == .Opaque) {14866 } else if (inst_data.size == .Many and elem_ty.zigTypeTag() == .Opaque) {
14791 return sema.fail(block, elem_ty_src, "unknown-length pointer to opaque not allowed", .{});14867 return sema.fail(block, elem_ty_src, "unknown-length pointer to opaque not allowed", .{});
14792 } else if (inst_data.size == .C) {14868 } else if (inst_data.size == .C) {
14793 if (!(try sema.validateExternType(elem_ty, .other))) {14869 if (!sema.validateExternType(elem_ty, .other)) {
14794 const msg = msg: {14870 const msg = msg: {
14795 const msg = try sema.errMsg(block, elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)});14871 const msg = try sema.errMsg(block, elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)});
14796 errdefer msg.destroy(sema.gpa);14872 errdefer msg.destroy(sema.gpa);
1479714873
14798 const src_decl = sema.mod.declPtr(block.src_decl);14874 const src_decl = sema.mod.declPtr(block.src_decl);
14799 try sema.explainWhyTypeIsNotExtern(block, elem_ty_src, msg, elem_ty_src.toSrcLoc(src_decl), elem_ty, .other);14875 try sema.explainWhyTypeIsNotExtern(msg, elem_ty_src.toSrcLoc(src_decl), elem_ty, .other);
1480014876
14801 try sema.addDeclaredHereNote(msg, elem_ty);14877 try sema.addDeclaredHereNote(msg, elem_ty);
14802 break :msg msg;14878 break :msg msg;
...@@ -15874,13 +15950,13 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -15874,13 +15950,13 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
15874 } else if (ptr_size == .Many and elem_ty.zigTypeTag() == .Opaque) {15950 } else if (ptr_size == .Many and elem_ty.zigTypeTag() == .Opaque) {
15875 return sema.fail(block, src, "unknown-length pointer to opaque not allowed", .{});15951 return sema.fail(block, src, "unknown-length pointer to opaque not allowed", .{});
15876 } else if (ptr_size == .C) {15952 } else if (ptr_size == .C) {
15877 if (!(try sema.validateExternType(elem_ty, .other))) {15953 if (!sema.validateExternType(elem_ty, .other)) {
15878 const msg = msg: {15954 const msg = msg: {
15879 const msg = try sema.errMsg(block, src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)});15955 const msg = try sema.errMsg(block, src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)});
15880 errdefer msg.destroy(sema.gpa);15956 errdefer msg.destroy(sema.gpa);
1588115957
15882 const src_decl = sema.mod.declPtr(block.src_decl);15958 const src_decl = sema.mod.declPtr(block.src_decl);
15883 try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), elem_ty, .other);15959 try sema.explainWhyTypeIsNotExtern(msg, src.toSrcLoc(src_decl), elem_ty, .other);
1588415960
15885 try sema.addDeclaredHereNote(msg, elem_ty);15961 try sema.addDeclaredHereNote(msg, elem_ty);
15886 break :msg msg;15962 break :msg msg;
...@@ -18883,10 +18959,8 @@ fn zirVarExtended(...@@ -18883,10 +18959,8 @@ fn zirVarExtended(
18883 extended: Zir.Inst.Extended.InstData,18959 extended: Zir.Inst.Extended.InstData,
18884) CompileError!Air.Inst.Ref {18960) CompileError!Air.Inst.Ref {
18885 const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand);18961 const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand);
18886 const src = sema.src;18962 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = 0 };
18887 const ty_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at type18963 const init_src: LazySrcLoc = .{ .node_offset_var_decl_init = 0 };
18888 const name_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at the name token
18889 const init_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at init expr
18890 const small = @bitCast(Zir.Inst.ExtendedVar.Small, extended.small);18964 const small = @bitCast(Zir.Inst.ExtendedVar.Small, extended.small);
1889118965
18892 var extra_index: usize = extra.end;18966 var extra_index: usize = extra.end;
...@@ -18900,12 +18974,6 @@ fn zirVarExtended(...@@ -18900,12 +18974,6 @@ fn zirVarExtended(
18900 // ZIR supports encoding this information but it is not used; the information18974 // ZIR supports encoding this information but it is not used; the information
18901 // is encoded via the Decl entry.18975 // is encoded via the Decl entry.
18902 assert(!small.has_align);18976 assert(!small.has_align);
18903 //const align_val: Value = if (small.has_align) blk: {
18904 // const align_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
18905 // extra_index += 1;
18906 // const align_tv = try sema.resolveInstConst(block, align_src, align_ref);
18907 // break :blk align_tv.val;
18908 //} else Value.@"null";
1890918977
18910 const uncasted_init: Air.Inst.Ref = if (small.has_init) blk: {18978 const uncasted_init: Air.Inst.Ref = if (small.has_init) blk: {
18911 const init_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);18979 const init_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
...@@ -18929,7 +18997,7 @@ fn zirVarExtended(...@@ -18929,7 +18997,7 @@ fn zirVarExtended(
18929 return sema.failWithNeededComptime(block, init_src, "container level variable initializers must be comptime known");18997 return sema.failWithNeededComptime(block, init_src, "container level variable initializers must be comptime known");
18930 } else Value.initTag(.unreachable_value);18998 } else Value.initTag(.unreachable_value);
1893118999
18932 try sema.validateVarType(block, name_src, var_ty, small.is_extern);19000 try sema.validateVarType(block, ty_src, var_ty, small.is_extern);
1893319001
18934 const new_var = try sema.gpa.create(Module.Var);19002 const new_var = try sema.gpa.create(Module.Var);
18935 errdefer sema.gpa.destroy(new_var);19003 errdefer sema.gpa.destroy(new_var);
...@@ -19668,7 +19736,7 @@ const ExternPosition = enum {...@@ -19668,7 +19736,7 @@ const ExternPosition = enum {
1966819736
19669/// Returns true if `ty` is allowed in extern types.19737/// Returns true if `ty` is allowed in extern types.
19670/// Does *NOT* require `ty` to be resolved in any way.19738/// Does *NOT* require `ty` to be resolved in any way.
19671fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileError!bool {19739fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) bool {
19672 switch (ty.zigTypeTag()) {19740 switch (ty.zigTypeTag()) {
19673 .Type,19741 .Type,
19674 .ComptimeFloat,19742 .ComptimeFloat,
...@@ -19713,8 +19781,6 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr...@@ -19713,8 +19781,6 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr
1971319781
19714fn explainWhyTypeIsNotExtern(19782fn explainWhyTypeIsNotExtern(
19715 sema: *Sema,19783 sema: *Sema,
19716 block: *Block,
19717 src: LazySrcLoc,
19718 msg: *Module.ErrorMsg,19784 msg: *Module.ErrorMsg,
19719 src_loc: Module.SrcLoc,19785 src_loc: Module.SrcLoc,
19720 ty: Type,19786 ty: Type,
...@@ -19758,7 +19824,7 @@ fn explainWhyTypeIsNotExtern(...@@ -19758,7 +19824,7 @@ fn explainWhyTypeIsNotExtern(
19758 var buf: Type.Payload.Bits = undefined;19824 var buf: Type.Payload.Bits = undefined;
19759 const tag_ty = ty.intTagType(&buf);19825 const tag_ty = ty.intTagType(&buf);
19760 try mod.errNoteNonLazy(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(sema.mod)});19826 try mod.errNoteNonLazy(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(sema.mod)});
19761 try sema.explainWhyTypeIsNotExtern(block, src, msg, src_loc, tag_ty, position);19827 try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position);
19762 },19828 },
19763 .Struct => try mod.errNoteNonLazy(src_loc, msg, "only structs with packed or extern layout are extern compatible", .{}),19829 .Struct => try mod.errNoteNonLazy(src_loc, msg, "only structs with packed or extern layout are extern compatible", .{}),
19764 .Union => try mod.errNoteNonLazy(src_loc, msg, "only unions with packed or extern layout are extern compatible", .{}),19830 .Union => try mod.errNoteNonLazy(src_loc, msg, "only unions with packed or extern layout are extern compatible", .{}),
...@@ -19768,13 +19834,87 @@ fn explainWhyTypeIsNotExtern(...@@ -19768,13 +19834,87 @@ fn explainWhyTypeIsNotExtern(
19768 } else if (position == .param_ty) {19834 } else if (position == .param_ty) {
19769 return mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a parameter type", .{});19835 return mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a parameter type", .{});
19770 }19836 }
19771 try sema.explainWhyTypeIsNotExtern(block, src, msg, src_loc, ty.elemType2(), position);19837 try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(), position);
19772 },19838 },
19773 .Vector => try sema.explainWhyTypeIsNotExtern(block, src, msg, src_loc, ty.elemType2(), position),19839 .Vector => try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(), position),
19774 .Optional => try mod.errNoteNonLazy(src_loc, msg, "only pointer like optionals are extern compatible", .{}),19840 .Optional => try mod.errNoteNonLazy(src_loc, msg, "only pointer like optionals are extern compatible", .{}),
19775 }19841 }
19776}19842}
1977719843
19844/// Returns true if `ty` is allowed in packed types.
19845/// Does *NOT* require `ty` to be resolved in any way.
19846fn validatePackedType(ty: Type) bool {
19847 switch (ty.zigTypeTag()) {
19848 .Type,
19849 .ComptimeFloat,
19850 .ComptimeInt,
19851 .EnumLiteral,
19852 .Undefined,
19853 .Null,
19854 .ErrorUnion,
19855 .ErrorSet,
19856 .BoundFn,
19857 .Frame,
19858 .NoReturn,
19859 .Opaque,
19860 .AnyFrame,
19861 .Fn,
19862 .Array,
19863 .Optional,
19864 => return false,
19865 .Void,
19866 .Bool,
19867 .Float,
19868 .Pointer,
19869 .Int,
19870 .Vector,
19871 .Enum,
19872 => return true,
19873 .Struct, .Union => return ty.containerLayout() == .Packed,
19874 }
19875}
19876
19877fn explainWhyTypeIsNotPacked(
19878 sema: *Sema,
19879 msg: *Module.ErrorMsg,
19880 src_loc: Module.SrcLoc,
19881 ty: Type,
19882) CompileError!void {
19883 const mod = sema.mod;
19884 switch (ty.zigTypeTag()) {
19885 .Void,
19886 .Bool,
19887 .Float,
19888 .Pointer,
19889 .Int,
19890 .Vector,
19891 .Enum,
19892 => return,
19893 .Type,
19894 .ComptimeFloat,
19895 .ComptimeInt,
19896 .EnumLiteral,
19897 .Undefined,
19898 .Null,
19899 .BoundFn,
19900 .Frame,
19901 .NoReturn,
19902 .Opaque,
19903 .ErrorUnion,
19904 .ErrorSet,
19905 .AnyFrame,
19906 .Optional,
19907 .Array,
19908 => try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{}),
19909 .Fn => {
19910 try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{});
19911 try mod.errNoteNonLazy(src_loc, msg, "use '*const ' to make a function pointer type", .{});
19912 },
19913 .Struct => try mod.errNoteNonLazy(src_loc, msg, "only packed structs layout are allowed in packed types", .{}),
19914 .Union => try mod.errNoteNonLazy(src_loc, msg, "only packed unions layout are allowed in packed types", .{}),
19915 }
19916}
19917
19778pub const PanicId = enum {19918pub const PanicId = enum {
19779 unreach,19919 unreach,
19780 unwrap_null,19920 unwrap_null,
...@@ -26851,28 +26991,41 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void...@@ -26851,28 +26991,41 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
26851 const field = &struct_obj.fields.values()[i];26991 const field = &struct_obj.fields.values()[i];
26852 field.ty = try field_ty.copy(decl_arena_allocator);26992 field.ty = try field_ty.copy(decl_arena_allocator);
2685326993
26854 if (struct_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .other))) {26994 if (field_ty.zigTypeTag() == .Opaque) {
26995 const msg = msg: {
26996 const tree = try sema.getAstTree(&block_scope);
26997 const field_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, i);
26998 const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
26999 errdefer msg.destroy(sema.gpa);
27000
27001 try sema.addDeclaredHereNote(msg, field_ty);
27002 break :msg msg;
27003 };
27004 return sema.failWithOwnedErrorMsg(&block_scope, msg);
27005 }
27006 if (struct_obj.layout == .Extern and !sema.validateExternType(field.ty, .other)) {
26855 const msg = msg: {27007 const msg = msg: {
26856 const tree = try sema.getAstTree(&block_scope);27008 const tree = try sema.getAstTree(&block_scope);
26857 const fields_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, i);27009 const fields_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, i);
26858 const msg = try sema.errMsg(&block_scope, fields_src, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)});27010 const msg = try sema.errMsg(&block_scope, fields_src, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)});
26859 errdefer msg.destroy(sema.gpa);27011 errdefer msg.destroy(sema.gpa);
2686027012
26861 try sema.explainWhyTypeIsNotExtern(&block_scope, fields_src, msg, fields_src.toSrcLoc(decl), field.ty, .other);27013 try sema.explainWhyTypeIsNotExtern(msg, fields_src.toSrcLoc(decl), field.ty, .other);
2686227014
26863 try sema.addDeclaredHereNote(msg, field.ty);27015 try sema.addDeclaredHereNote(msg, field.ty);
26864 break :msg msg;27016 break :msg msg;
26865 };27017 };
26866 return sema.failWithOwnedErrorMsg(&block_scope, msg);27018 return sema.failWithOwnedErrorMsg(&block_scope, msg);
26867 }27019 } else if (struct_obj.layout == .Packed and !(validatePackedType(field.ty))) {
26868 if (field_ty.zigTypeTag() == .Opaque) {
26869 const msg = msg: {27020 const msg = msg: {
26870 const tree = try sema.getAstTree(&block_scope);27021 const tree = try sema.getAstTree(&block_scope);
26871 const field_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, i);27022 const fields_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, i);
26872 const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});27023 const msg = try sema.errMsg(&block_scope, fields_src, "packed structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)});
26873 errdefer msg.destroy(sema.gpa);27024 errdefer msg.destroy(sema.gpa);
2687427025
26875 try sema.addDeclaredHereNote(msg, field_ty);27026 try sema.explainWhyTypeIsNotPacked(msg, fields_src.toSrcLoc(decl), field.ty);
27027
27028 try sema.addDeclaredHereNote(msg, field.ty);
26876 break :msg msg;27029 break :msg msg;
26877 };27030 };
26878 return sema.failWithOwnedErrorMsg(&block_scope, msg);27031 return sema.failWithOwnedErrorMsg(&block_scope, msg);
...@@ -27175,27 +27328,40 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -27175,27 +27328,40 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
27175 }27328 }
27176 }27329 }
2717727330
27178 if (union_obj.layout == .Extern and !(try sema.validateExternType(field_ty, .union_field))) {27331 if (field_ty.zigTypeTag() == .Opaque) {
27179 const msg = msg: {27332 const msg = msg: {
27180 const tree = try sema.getAstTree(&block_scope);27333 const tree = try sema.getAstTree(&block_scope);
27181 const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i);27334 const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i);
27182 const msg = try sema.errMsg(&block_scope, field_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});27335 const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{});
27183 errdefer msg.destroy(sema.gpa);27336 errdefer msg.destroy(sema.gpa);
2718427337
27185 try sema.explainWhyTypeIsNotExtern(&block_scope, field_src, msg, field_src.toSrcLoc(decl), field_ty, .union_field);
27186
27187 try sema.addDeclaredHereNote(msg, field_ty);27338 try sema.addDeclaredHereNote(msg, field_ty);
27188 break :msg msg;27339 break :msg msg;
27189 };27340 };
27190 return sema.failWithOwnedErrorMsg(&block_scope, msg);27341 return sema.failWithOwnedErrorMsg(&block_scope, msg);
27191 }27342 }
27192 if (field_ty.zigTypeTag() == .Opaque) {27343 if (union_obj.layout == .Extern and !sema.validateExternType(field_ty, .union_field)) {
27193 const msg = msg: {27344 const msg = msg: {
27194 const tree = try sema.getAstTree(&block_scope);27345 const tree = try sema.getAstTree(&block_scope);
27195 const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i);27346 const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i);
27196 const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{});27347 const msg = try sema.errMsg(&block_scope, field_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});
27197 errdefer msg.destroy(sema.gpa);27348 errdefer msg.destroy(sema.gpa);
2719827349
27350 try sema.explainWhyTypeIsNotExtern(msg, field_src.toSrcLoc(decl), field_ty, .union_field);
27351
27352 try sema.addDeclaredHereNote(msg, field_ty);
27353 break :msg msg;
27354 };
27355 return sema.failWithOwnedErrorMsg(&block_scope, msg);
27356 } else if (union_obj.layout == .Packed and !(validatePackedType(field_ty))) {
27357 const msg = msg: {
27358 const tree = try sema.getAstTree(&block_scope);
27359 const fields_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i);
27360 const msg = try sema.errMsg(&block_scope, fields_src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});
27361 errdefer msg.destroy(sema.gpa);
27362
27363 try sema.explainWhyTypeIsNotPacked(msg, fields_src.toSrcLoc(decl), field_ty);
27364
27199 try sema.addDeclaredHereNote(msg, field_ty);27365 try sema.addDeclaredHereNote(msg, field_ty);
27200 break :msg msg;27366 break :msg msg;
27201 };27367 };
src/Zir.zig+6
...@@ -3548,6 +3548,12 @@ pub const Inst = struct {...@@ -3548,6 +3548,12 @@ pub const Inst = struct {
3548 ty: Ref,3548 ty: Ref,
3549 init_count: u32,3549 init_count: u32,
3550 };3550 };
3551
3552 pub const Src = struct {
3553 node: i32,
3554 line: u32,
3555 column: u32,
3556 };
3551};3557};
35523558
3553pub const SpecialProng = enum { none, @"else", under };3559pub const SpecialProng = enum { none, @"else", under };
test/behavior/bitcast.zig-16
...@@ -90,22 +90,6 @@ test "nested bitcast" {...@@ -90,22 +90,6 @@ test "nested bitcast" {
90 comptime try S.foo(42);90 comptime try S.foo(42);
91}91}
9292
93test "@bitCast enum to its integer type" {
94 const SOCK = enum(c_int) {
95 A,
96 B,
97
98 fn testBitCastExternEnum() !void {
99 var SOCK_DGRAM = @This().B;
100 var sock_dgram = @bitCast(c_int, SOCK_DGRAM);
101 try expect(sock_dgram == 1);
102 }
103 };
104
105 try SOCK.testBitCastExternEnum();
106 comptime try SOCK.testBitCastExternEnum();
107}
108
109// issue #3010: compiler segfault93// issue #3010: compiler segfault
110test "bitcast literal [4]u8 param to u32" {94test "bitcast literal [4]u8 param to u32" {
111 const ip = @bitCast(u32, [_]u8{ 255, 255, 255, 255 });95 const ip = @bitCast(u32, [_]u8{ 255, 255, 255, 255 });
test/behavior/packed-struct.zig+2-26
...@@ -6,6 +6,8 @@ const expectEqual = std.testing.expectEqual;...@@ -6,6 +6,8 @@ const expectEqual = std.testing.expectEqual;
6const native_endian = builtin.cpu.arch.endian();6const native_endian = builtin.cpu.arch.endian();
77
8test "correct size of packed structs" {8test "correct size of packed structs" {
9 // Stage2 has different packed struct semantics.
10 if (builtin.zig_backend != .stage1) return error.SkipZigTest;
9 const T1 = packed struct { one: u8, three: [3]u8 };11 const T1 = packed struct { one: u8, three: [3]u8 };
1012
11 try expectEqual(4, @sizeOf(T1));13 try expectEqual(4, @sizeOf(T1));
...@@ -118,18 +120,6 @@ test "flags in packed structs" {...@@ -118,18 +120,6 @@ test "flags in packed structs" {
118 try expectEqual(32, @bitSizeOf(Flags3));120 try expectEqual(32, @bitSizeOf(Flags3));
119}121}
120122
121test "arrays in packed structs" {
122 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
123
124 const T1 = packed struct { array: [3][3]u8 };
125 const T2 = packed struct { array: [9]u8 };
126
127 try expectEqual(@sizeOf(u72), @sizeOf(T1));
128 try expectEqual(72, @bitSizeOf(T1));
129 try expectEqual(@sizeOf(u72), @sizeOf(T2));
130 try expectEqual(72, @bitSizeOf(T2));
131}
132
133test "consistent size of packed structs" {123test "consistent size of packed structs" {
134 if (builtin.zig_backend == .stage1) return error.SkipZigTest;124 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
135125
...@@ -145,23 +135,15 @@ test "consistent size of packed structs" {...@@ -145,23 +135,15 @@ test "consistent size of packed structs" {
145 try expectEqual(register_size_bits, @bitSizeOf(TxData2));135 try expectEqual(register_size_bits, @bitSizeOf(TxData2));
146 try expectEqual(register_size_bytes, @sizeOf(TxData2));136 try expectEqual(register_size_bytes, @sizeOf(TxData2));
147137
148 const TxData3 = packed struct { a: u32, b: [3]u8 };
149 const TxData4 = packed struct { a: u32, b: u24 };138 const TxData4 = packed struct { a: u32, b: u24 };
150 const TxData5 = packed struct { a: [3]u8, b: u32 };
151 const TxData6 = packed struct { a: u24, b: u32 };139 const TxData6 = packed struct { a: u24, b: u32 };
152140
153 const expectedBitSize = 56;141 const expectedBitSize = 56;
154 const expectedByteSize = @sizeOf(u56);142 const expectedByteSize = @sizeOf(u56);
155143
156 try expectEqual(expectedBitSize, @bitSizeOf(TxData3));
157 try expectEqual(expectedByteSize, @sizeOf(TxData3));
158
159 try expectEqual(expectedBitSize, @bitSizeOf(TxData4));144 try expectEqual(expectedBitSize, @bitSizeOf(TxData4));
160 try expectEqual(expectedByteSize, @sizeOf(TxData4));145 try expectEqual(expectedByteSize, @sizeOf(TxData4));
161146
162 try expectEqual(expectedBitSize, @bitSizeOf(TxData5));
163 try expectEqual(expectedByteSize, @sizeOf(TxData5));
164
165 try expectEqual(expectedBitSize, @bitSizeOf(TxData6));147 try expectEqual(expectedBitSize, @bitSizeOf(TxData6));
166 try expectEqual(expectedByteSize, @sizeOf(TxData6));148 try expectEqual(expectedByteSize, @sizeOf(TxData6));
167}149}
...@@ -234,12 +216,6 @@ test "correct sizeOf and offsets in packed structs" {...@@ -234,12 +216,6 @@ test "correct sizeOf and offsets in packed structs" {
234 try expectEqual(@as(u7, 0b1111010), s2.y);216 try expectEqual(@as(u7, 0b1111010), s2.y);
235 try expectEqual(@as(u24, 0xd5c71f), s2.z);217 try expectEqual(@as(u24, 0xd5c71f), s2.z);
236 }218 }
237
238 const S = packed struct { a: u32, pad: [3]u32, b: u32 };
239
240 try expectEqual(16, @offsetOf(S, "b"));
241 try expectEqual(128, @bitOffsetOf(S, "b"));
242 try expectEqual(@sizeOf(u160), @sizeOf(S));
243}219}
244220
245test "nested packed structs" {221test "nested packed structs" {
test/behavior/sizeof_and_typeof.zig+2
...@@ -105,6 +105,8 @@ test "@offsetOf" {...@@ -105,6 +105,8 @@ test "@offsetOf" {
105}105}
106106
107test "@offsetOf packed struct, array length not power of 2 or multiple of native pointer width in bytes" {107test "@offsetOf packed struct, array length not power of 2 or multiple of native pointer width in bytes" {
108 // Stage2 has different packed struct semantics.
109 if (builtin.zig_backend != .stage1) return error.SkipZigTest;
108 const p3a_len = 3;110 const p3a_len = 3;
109 const P3 = packed struct {111 const P3 = packed struct {
110 a: [p3a_len]u8,112 a: [p3a_len]u8,
test/behavior/struct.zig+2-4
...@@ -704,10 +704,8 @@ const FooArray24Bits = packed struct {...@@ -704,10 +704,8 @@ const FooArray24Bits = packed struct {
704};704};
705705
706test "aligned array of packed struct" {706test "aligned array of packed struct" {
707 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO707 // Stage2 has different packed struct semantics.
708 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO708 if (builtin.zig_backend != .stage1) return error.SkipZigTest;
709 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
710 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
711709
712 comptime {710 comptime {
713 try expect(@sizeOf(FooStructAligned) == 2);711 try expect(@sizeOf(FooStructAligned) == 2);
test/cases/compile_errors/bitCast_to_enum_type.zig+1-1
...@@ -9,4 +9,4 @@ export fn entry() void {...@@ -9,4 +9,4 @@ export fn entry() void {
9// target=native9// target=native
10//10//
11// :3:24: error: cannot @bitCast to 'tmp.entry.E'11// :3:24: error: cannot @bitCast to 'tmp.entry.E'
12// :3:24: note: use @intToEnum for type coercion12// :3:24: note: use @intToEnum to cast from 'u32'
test/cases/compile_errors/global_variable_alignment_non_power_of_2.zig created+8
...@@ -0,0 +1,8 @@
1const some_data: [100]u8 align(3) = undefined;
2export fn entry() usize { return @sizeOf(@TypeOf(some_data)); }
3
4// error
5// backend=stage2
6// target=native
7//
8// :1:32: error: alignment value '3' is not a power of two
test/cases/compile_errors/intToPtr_with_misaligned_address.zig created+10
...@@ -0,0 +1,10 @@
1pub export fn entry() void {
2 var y = @intToPtr([*]align(4) u8, 5);
3 _ = y;
4}
5
6// error
7// backend=stage2
8// target=native
9//
10// :2:39: error: pointer type '[*]align(4) u8' requires aligned address
test/cases/compile_errors/issue_3818_bitcast_from_parray-slice_to_u16.zig created+19
...@@ -0,0 +1,19 @@
1export fn foo1() void {
2 var bytes = [_]u8{1, 2};
3 const word: u16 = @bitCast(u16, bytes[0..]);
4 _ = word;
5}
6export fn foo2() void {
7 var bytes: []const u8 = &[_]u8{1, 2};
8 const word: u16 = @bitCast(u16, bytes);
9 _ = word;
10}
11
12// error
13// backend=stage2
14// target=native
15//
16// :3:42: error: cannot @bitCast from '*[2]u8'
17// :3:42: note: use @ptrToInt to cast to 'u16'
18// :8:37: error: cannot @bitCast from '[]const u8'
19// :8:37: note: use @ptrToInt to cast to 'u16'
test/cases/compile_errors/packed_struct_with_fields_of_not_allowed_types.zig created+84
...@@ -0,0 +1,84 @@
1export fn entry1() void {
2 _ = @sizeOf(packed struct {
3 x: anyerror,
4 });
5}
6export fn entry2() void {
7 _ = @sizeOf(packed struct {
8 x: [2]u24,
9 });
10}
11export fn entry3() void {
12 _ = @sizeOf(packed struct {
13 x: anyerror!u32,
14 });
15}
16export fn entry4() void {
17 _ = @sizeOf(packed struct {
18 x: S,
19 });
20}
21export fn entry5() void {
22 _ = @sizeOf(packed struct {
23 x: U,
24 });
25}
26export fn entry6() void {
27 _ = @sizeOf(packed struct {
28 x: ?anyerror,
29 });
30}
31export fn entry7() void {
32 _ = @sizeOf(packed struct {
33 x: enum { A, B },
34 });
35}
36export fn entry8() void {
37 _ = @sizeOf(packed struct {
38 x: fn () void,
39 });
40}
41export fn entry9() void {
42 _ = @sizeOf(packed struct {
43 x: *const fn () void,
44 });
45}
46export fn entry10() void {
47 _ = @sizeOf(packed struct {
48 x: packed struct { x: i32 },
49 });
50}
51export fn entry11() void {
52 _ = @sizeOf(packed struct {
53 x: packed union { A: i32, B: u32 },
54 });
55}
56const S = struct {
57 x: i32,
58};
59const U = extern union {
60 A: i32,
61 B: u32,
62};
63
64// error
65// backend=llvm
66// target=native
67//
68// :3:9: error: packed structs cannot contain fields of type 'anyerror'
69// :3:9: note: type has no guaranteed in-memory representation
70// :8:9: error: packed structs cannot contain fields of type '[2]u24'
71// :8:9: note: type has no guaranteed in-memory representation
72// :13:9: error: packed structs cannot contain fields of type 'anyerror!u32'
73// :13:9: note: type has no guaranteed in-memory representation
74// :18:9: error: packed structs cannot contain fields of type 'tmp.S'
75// :18:9: note: only packed structs layout are allowed in packed types
76// :56:11: note: struct declared here
77// :23:9: error: packed structs cannot contain fields of type 'tmp.U'
78// :23:9: note: only packed unions layout are allowed in packed types
79// :59:18: note: union declared here
80// :28:9: error: packed structs cannot contain fields of type '?anyerror'
81// :28:9: note: type has no guaranteed in-memory representation
82// :38:9: error: packed structs cannot contain fields of type 'fn() void'
83// :38:9: note: type has no guaranteed in-memory representation
84// :38:9: note: use '*const ' to make a function pointer type
test/cases/compile_errors/src_outside_function.zig created+9
...@@ -0,0 +1,9 @@
1comptime {
2 @src();
3}
4
5// error
6// backend=stage2
7// target=native
8//
9// :2:5: error: @src outside function
test/cases/compile_errors/stage1/obj/global_variable_alignment_non_power_of_2.zig deleted-8
...@@ -1,8 +0,0 @@
1const some_data: [100]u8 align(3) = undefined;
2export fn entry() usize { return @sizeOf(@TypeOf(some_data)); }
3
4// error
5// backend=stage1
6// target=native
7//
8// tmp.zig:1:32: error: alignment value 3 is not a power of 2
test/cases/compile_errors/stage1/obj/intToPtr_with_misaligned_address.zig deleted-10
...@@ -1,10 +0,0 @@
1pub fn main() void {
2 var y = @intToPtr([*]align(4) u8, 5);
3 _ = y;
4}
5
6// error
7// backend=stage1
8// target=native
9//
10// tmp.zig:2:13: error: pointer type '[*]align(4) u8' requires aligned address
test/cases/compile_errors/stage1/obj/issue_3818_bitcast_from_parray-slice_to_u16.zig deleted-17
...@@ -1,17 +0,0 @@
1export fn foo1() void {
2 var bytes = [_]u8{1, 2};
3 const word: u16 = @bitCast(u16, bytes[0..]);
4 _ = word;
5}
6export fn foo2() void {
7 var bytes: []const u8 = &[_]u8{1, 2};
8 const word: u16 = @bitCast(u16, bytes);
9 _ = word;
10}
11
12// error
13// backend=stage1
14// target=native
15//
16// tmp.zig:3:42: error: unable to @bitCast from pointer type '*[2]u8'
17// tmp.zig:8:32: error: destination type 'u16' has size 2 but source type '[]const u8' has size 16
test/cases/compile_errors/stage1/obj/src_outside_function.zig deleted-9
...@@ -1,9 +0,0 @@
1comptime {
2 @src();
3}
4
5// error
6// backend=stage1
7// target=native
8//
9// tmp.zig:2:5: error: @src outside function
test/cases/compile_errors/stage1/test/packed_struct_with_fields_of_not_allowed_types.zig deleted-74
...@@ -1,74 +0,0 @@
1const A = packed struct {
2 x: anyerror,
3};
4const B = packed struct {
5 x: [2]u24,
6};
7const C = packed struct {
8 x: [1]anyerror,
9};
10const D = packed struct {
11 x: [1]S,
12};
13const E = packed struct {
14 x: [1]U,
15};
16const F = packed struct {
17 x: ?anyerror,
18};
19const G = packed struct {
20 x: Enum,
21};
22export fn entry1() void {
23 var a: A = undefined;
24 _ = a;
25}
26export fn entry2() void {
27 var b: B = undefined;
28 _ = b;
29}
30export fn entry3() void {
31 var r: C = undefined;
32 _ = r;
33}
34export fn entry4() void {
35 var d: D = undefined;
36 _ = d;
37}
38export fn entry5() void {
39 var e: E = undefined;
40 _ = e;
41}
42export fn entry6() void {
43 var f: F = undefined;
44 _ = f;
45}
46export fn entry7() void {
47 var g: G = undefined;
48 _ = g;
49}
50const S = struct {
51 x: i32,
52};
53const U = struct {
54 A: i32,
55 B: u32,
56};
57const Enum = enum {
58 A,
59 B,
60};
61
62// error
63// backend=stage1
64// target=native
65// is_test=1
66//
67// tmp.zig:2:5: error: type 'anyerror' not allowed in packed struct; no guaranteed in-memory representation
68// tmp.zig:5:5: error: array of 'u24' not allowed in packed struct due to padding bits (must be padded from 48 to 64 bits)
69// tmp.zig:8:5: error: type 'anyerror' not allowed in packed struct; no guaranteed in-memory representation
70// tmp.zig:11:5: error: non-packed, non-extern struct 'S' not allowed in packed struct; no guaranteed in-memory representation
71// tmp.zig:14:5: error: non-packed, non-extern struct 'U' not allowed in packed struct; no guaranteed in-memory representation
72// tmp.zig:17:5: error: type '?anyerror' not allowed in packed struct; no guaranteed in-memory representation
73// tmp.zig:20:5: error: type 'Enum' not allowed in packed struct; no guaranteed in-memory representation
74// tmp.zig:57:14: note: enum declaration does not specify an integer tag type
test/cases/compile_errors/type_variables_must_be_constant.zig+2-2
...@@ -7,5 +7,5 @@ export fn entry() foo {...@@ -7,5 +7,5 @@ export fn entry() foo {
7// backend=stage27// backend=stage2
8// target=native8// target=native
9//9//
10// :1:1: error: variable of type 'type' must be const or comptime10// :1:5: error: variable of type 'type' must be const or comptime
11// :1:1: note: types are not available at runtime11// :1:5: note: types are not available at runtime
test/cases/compile_errors/use_invalid_number_literal_as_array_index.zig+2-2
...@@ -8,5 +8,5 @@ export fn entry() void {...@@ -8,5 +8,5 @@ export fn entry() void {
8// backend=stage28// backend=stage2
9// target=native9// target=native
10//10//
11// :1:1: error: variable of type 'comptime_int' must be const or comptime11// :1:5: error: variable of type 'comptime_int' must be const or comptime
12// :1:1: note: to modify this variable at runtime, it must be given an explicit fixed-size number type12// :1:5: note: to modify this variable at runtime, it must be given an explicit fixed-size number type
test/cases/compile_errors/usingnamespace_with_wrong_type.zig+1-1
...@@ -4,4 +4,4 @@ usingnamespace void;...@@ -4,4 +4,4 @@ usingnamespace void;
4// backend=stage24// backend=stage2
5// target=native5// target=native
6//6//
7// :1:1: error: type void has no namespace7// :1:16: error: type void has no namespace