authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-22 13:07:32+03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-07-22 13:07:32+03:00
log8e75ba653b03477229cf72211e8a8bfe7b071254
tree4689ba96ff2ba3090d83c8b8c27f3f61ae34df92
parent460211431f407c9f707e3ac3bbff61610a487926
parentb749487f48cad2dd779d7fa6d0afcafc975ba26c
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

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

Stage2: explain why value must be comptime known

126 files changed, 2189 insertions(+), 1364 deletions(-)

build.zig+3
...@@ -11,6 +11,7 @@ const InstallDirectoryOptions = std.build.InstallDirectoryOptions;...@@ -11,6 +11,7 @@ const InstallDirectoryOptions = std.build.InstallDirectoryOptions;
11const assert = std.debug.assert;11const assert = std.debug.assert;
1212
13const zig_version = std.builtin.Version{ .major = 0, .minor = 10, .patch = 0 };13const zig_version = std.builtin.Version{ .major = 0, .minor = 10, .patch = 0 };
14const stack_size = 32 * 1024 * 1024;
1415
15pub fn build(b: *Builder) !void {16pub fn build(b: *Builder) !void {
16 b.setPreferredReleaseMode(.ReleaseFast);17 b.setPreferredReleaseMode(.ReleaseFast);
...@@ -41,6 +42,7 @@ pub fn build(b: *Builder) !void {...@@ -41,6 +42,7 @@ pub fn build(b: *Builder) !void {
41 const toolchain_step = b.step("test-toolchain", "Run the tests for the toolchain");42 const toolchain_step = b.step("test-toolchain", "Run the tests for the toolchain");
4243
43 var test_cases = b.addTest("src/test.zig");44 var test_cases = b.addTest("src/test.zig");
45 test_cases.stack_size = stack_size;
44 test_cases.setBuildMode(mode);46 test_cases.setBuildMode(mode);
45 test_cases.addPackagePath("test_cases", "test/cases.zig");47 test_cases.addPackagePath("test_cases", "test/cases.zig");
46 test_cases.single_threaded = single_threaded;48 test_cases.single_threaded = single_threaded;
...@@ -141,6 +143,7 @@ pub fn build(b: *Builder) !void {...@@ -141,6 +143,7 @@ pub fn build(b: *Builder) !void {
141 };143 };
142144
143 const exe = b.addExecutable("zig", main_file);145 const exe = b.addExecutable("zig", main_file);
146 exe.stack_size = stack_size;
144 exe.strip = strip;147 exe.strip = strip;
145 exe.build_id = b.option(bool, "build-id", "Include a build id note") orelse false;148 exe.build_id = b.option(bool, "build-id", "Include a build id note") orelse false;
146 exe.install();149 exe.install();
src/AstGen.zig+26-47
...@@ -1347,7 +1347,7 @@ fn arrayInitExpr(...@@ -1347,7 +1347,7 @@ fn arrayInitExpr(
1347 }1347 }
1348 }1348 }
1349 const array_type_inst = try typeExpr(gz, scope, array_init.ast.type_expr);1349 const array_type_inst = try typeExpr(gz, scope, array_init.ast.type_expr);
1350 _ = try gz.addUnNode(.validate_array_init_ty, array_type_inst, node);1350 _ = try gz.addUnNode(.validate_array_init_ty, array_type_inst, array_init.ast.type_expr);
1351 break :inst .{1351 break :inst .{
1352 .array = array_type_inst,1352 .array = array_type_inst,
1353 .elem = .none,1353 .elem = .none,
...@@ -2332,7 +2332,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner...@@ -2332,7 +2332,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
2332 .err_union_code,2332 .err_union_code,
2333 .err_union_code_ptr,2333 .err_union_code_ptr,
2334 .ptr_type,2334 .ptr_type,
2335 .ptr_type_simple,2335 .overflow_arithmetic_ptr,
2336 .enum_literal,2336 .enum_literal,
2337 .merge_error_sets,2337 .merge_error_sets,
2338 .error_union_type,2338 .error_union_type,
...@@ -3110,24 +3110,6 @@ fn ptrType(...@@ -3110,24 +3110,6 @@ fn ptrType(
31103110
3111 const elem_type = try typeExpr(gz, scope, ptr_info.ast.child_type);3111 const elem_type = try typeExpr(gz, scope, ptr_info.ast.child_type);
31123112
3113 const simple = ptr_info.ast.align_node == 0 and
3114 ptr_info.ast.addrspace_node == 0 and
3115 ptr_info.ast.sentinel == 0 and
3116 ptr_info.ast.bit_range_start == 0;
3117
3118 if (simple) {
3119 const result = try gz.add(.{ .tag = .ptr_type_simple, .data = .{
3120 .ptr_type_simple = .{
3121 .is_allowzero = ptr_info.allowzero_token != null,
3122 .is_mutable = ptr_info.const_token == null,
3123 .is_volatile = ptr_info.volatile_token != null,
3124 .size = ptr_info.size,
3125 .elem_type = elem_type,
3126 },
3127 } });
3128 return rvalue(gz, rl, result, node);
3129 }
3130
3131 var sentinel_ref: Zir.Inst.Ref = .none;3113 var sentinel_ref: Zir.Inst.Ref = .none;
3132 var align_ref: Zir.Inst.Ref = .none;3114 var align_ref: Zir.Inst.Ref = .none;
3133 var addrspace_ref: Zir.Inst.Ref = .none;3115 var addrspace_ref: Zir.Inst.Ref = .none;
...@@ -3160,7 +3142,10 @@ fn ptrType(...@@ -3160,7 +3142,10 @@ fn ptrType(
3160 try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.PtrType).Struct.fields.len +3142 try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.PtrType).Struct.fields.len +
3161 trailing_count);3143 trailing_count);
31623144
3163 const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.PtrType{ .elem_type = elem_type });3145 const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.PtrType{
3146 .elem_type = elem_type,
3147 .src_node = gz.nodeIndexToRelative(node),
3148 });
3164 if (sentinel_ref != .none) {3149 if (sentinel_ref != .none) {
3165 gz.astgen.extra.appendAssumeCapacity(@enumToInt(sentinel_ref));3150 gz.astgen.extra.appendAssumeCapacity(@enumToInt(sentinel_ref));
3166 }3151 }
...@@ -4314,7 +4299,7 @@ fn unionDeclInner(...@@ -4314,7 +4299,7 @@ fn unionDeclInner(
4314 members: []const Ast.Node.Index,4299 members: []const Ast.Node.Index,
4315 layout: std.builtin.Type.ContainerLayout,4300 layout: std.builtin.Type.ContainerLayout,
4316 arg_node: Ast.Node.Index,4301 arg_node: Ast.Node.Index,
4317 have_auto_enum: bool,4302 auto_enum_tok: ?Ast.TokenIndex,
4318) InnerError!Zir.Inst.Ref {4303) InnerError!Zir.Inst.Ref {
4319 const decl_inst = try gz.reserveInstructionIndex();4304 const decl_inst = try gz.reserveInstructionIndex();
43204305
...@@ -4348,6 +4333,15 @@ fn unionDeclInner(...@@ -4348,6 +4333,15 @@ fn unionDeclInner(
4348 const decl_count = try astgen.scanDecls(&namespace, members);4333 const decl_count = try astgen.scanDecls(&namespace, members);
4349 const field_count = @intCast(u32, members.len - decl_count);4334 const field_count = @intCast(u32, members.len - decl_count);
43504335
4336 if (layout != .Auto and (auto_enum_tok != null or arg_node != 0)) {
4337 const layout_str = if (layout == .Extern) "extern" else "packed";
4338 if (arg_node != 0) {
4339 return astgen.failNode(arg_node, "{s} union does not support enum tag type", .{layout_str});
4340 } else {
4341 return astgen.failTok(auto_enum_tok.?, "{s} union does not support enum tag type", .{layout_str});
4342 }
4343 }
4344
4351 const arg_inst: Zir.Inst.Ref = if (arg_node != 0)4345 const arg_inst: Zir.Inst.Ref = if (arg_node != 0)
4352 try typeExpr(&block_scope, &namespace.base, arg_node)4346 try typeExpr(&block_scope, &namespace.base, arg_node)
4353 else4347 else
...@@ -4382,7 +4376,7 @@ fn unionDeclInner(...@@ -4382,7 +4376,7 @@ fn unionDeclInner(
4382 if (have_type) {4376 if (have_type) {
4383 const field_type = try typeExpr(&block_scope, &namespace.base, member.ast.type_expr);4377 const field_type = try typeExpr(&block_scope, &namespace.base, member.ast.type_expr);
4384 wip_members.appendToField(@enumToInt(field_type));4378 wip_members.appendToField(@enumToInt(field_type));
4385 } else if (arg_inst == .none and !have_auto_enum) {4379 } else if (arg_inst == .none and auto_enum_tok == null) {
4386 return astgen.failNode(member_node, "union field missing type", .{});4380 return astgen.failNode(member_node, "union field missing type", .{});
4387 }4381 }
4388 if (have_align) {4382 if (have_align) {
...@@ -4404,7 +4398,7 @@ fn unionDeclInner(...@@ -4404,7 +4398,7 @@ fn unionDeclInner(
4404 },4398 },
4405 );4399 );
4406 }4400 }
4407 if (!have_auto_enum) {4401 if (auto_enum_tok == null) {
4408 return astgen.failNodeNotes(4402 return astgen.failNodeNotes(
4409 node,4403 node,
4410 "explicitly valued tagged union requires inferred enum tag type",4404 "explicitly valued tagged union requires inferred enum tag type",
...@@ -4440,7 +4434,7 @@ fn unionDeclInner(...@@ -4440,7 +4434,7 @@ fn unionDeclInner(
4440 .body_len = body_len,4434 .body_len = body_len,
4441 .fields_len = field_count,4435 .fields_len = field_count,
4442 .decls_len = decl_count,4436 .decls_len = decl_count,
4443 .auto_enum_tag = have_auto_enum,4437 .auto_enum_tag = auto_enum_tok != null,
4444 });4438 });
44454439
4446 wip_members.finishBits(bits_per_field);4440 wip_members.finishBits(bits_per_field);
...@@ -4496,9 +4490,7 @@ fn containerDecl(...@@ -4496,9 +4490,7 @@ fn containerDecl(
4496 else => unreachable,4490 else => unreachable,
4497 } else std.builtin.Type.ContainerLayout.Auto;4491 } else std.builtin.Type.ContainerLayout.Auto;
44984492
4499 const have_auto_enum = container_decl.ast.enum_token != null;4493 const result = try unionDeclInner(gz, scope, node, container_decl.ast.members, layout, container_decl.ast.arg, container_decl.ast.enum_token);
4500
4501 const result = try unionDeclInner(gz, scope, node, container_decl.ast.members, layout, container_decl.ast.arg, have_auto_enum);
4502 return rvalue(gz, rl, result, node);4494 return rvalue(gz, rl, result, node);
4503 },4495 },
4504 .keyword_enum => {4496 .keyword_enum => {
...@@ -4732,7 +4724,10 @@ fn containerDecl(...@@ -4732,7 +4724,10 @@ fn containerDecl(
4732 defer wip_members.deinit();4724 defer wip_members.deinit();
47334725
4734 for (container_decl.ast.members) |member_node| {4726 for (container_decl.ast.members) |member_node| {
4735 _ = try containerMember(gz, &namespace.base, &wip_members, member_node);4727 const res = try containerMember(gz, &namespace.base, &wip_members, member_node);
4728 if (res == .field) {
4729 return astgen.failNode(member_node, "opaque types cannot have fields", .{});
4730 }
4736 }4731 }
47374732
4738 try gz.setOpaque(decl_inst, .{4733 try gz.setOpaque(decl_inst, .{
...@@ -7588,15 +7583,7 @@ fn builtinCall(...@@ -7588,15 +7583,7 @@ fn builtinCall(
7588 .shl_with_overflow => {7583 .shl_with_overflow => {
7589 const int_type = try typeExpr(gz, scope, params[0]);7584 const int_type = try typeExpr(gz, scope, params[0]);
7590 const log2_int_type = try gz.addUnNode(.log2_int_type, int_type, params[0]);7585 const log2_int_type = try gz.addUnNode(.log2_int_type, int_type, params[0]);
7591 const ptr_type = try gz.add(.{ .tag = .ptr_type_simple, .data = .{7586 const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]);
7592 .ptr_type_simple = .{
7593 .is_allowzero = false,
7594 .is_mutable = true,
7595 .is_volatile = false,
7596 .size = .One,
7597 .elem_type = int_type,
7598 },
7599 } });
7600 const lhs = try expr(gz, scope, .{ .ty = int_type }, params[1]);7587 const lhs = try expr(gz, scope, .{ .ty = int_type }, params[1]);
7601 const rhs = try expr(gz, scope, .{ .ty = log2_int_type }, params[2]);7588 const rhs = try expr(gz, scope, .{ .ty = log2_int_type }, params[2]);
7602 const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[3]);7589 const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[3]);
...@@ -7987,15 +7974,7 @@ fn overflowArithmetic(...@@ -7987,15 +7974,7 @@ fn overflowArithmetic(
7987 tag: Zir.Inst.Extended,7974 tag: Zir.Inst.Extended,
7988) InnerError!Zir.Inst.Ref {7975) InnerError!Zir.Inst.Ref {
7989 const int_type = try typeExpr(gz, scope, params[0]);7976 const int_type = try typeExpr(gz, scope, params[0]);
7990 const ptr_type = try gz.add(.{ .tag = .ptr_type_simple, .data = .{7977 const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]);
7991 .ptr_type_simple = .{
7992 .is_allowzero = false,
7993 .is_mutable = true,
7994 .is_volatile = false,
7995 .size = .One,
7996 .elem_type = int_type,
7997 },
7998 } });
7999 const lhs = try expr(gz, scope, .{ .ty = int_type }, params[1]);7978 const lhs = try expr(gz, scope, .{ .ty = int_type }, params[1]);
8000 const rhs = try expr(gz, scope, .{ .ty = int_type }, params[2]);7979 const rhs = try expr(gz, scope, .{ .ty = int_type }, params[2]);
8001 const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[3]);7980 const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[3]);
src/Module.zig+375-17
...@@ -2348,7 +2348,92 @@ pub const SrcLoc = struct {...@@ -2348,7 +2348,92 @@ pub const SrcLoc = struct {
2348 }2348 }
2349 } else unreachable;2349 } else unreachable;
2350 },2350 },
23512351 .node_offset_switch_prong_capture => |node_off| {
2352 const tree = try src_loc.file_scope.getTree(gpa);
2353 const case_node = src_loc.declRelativeToNodeIndex(node_off);
2354 const node_tags = tree.nodes.items(.tag);
2355 const case = switch (node_tags[case_node]) {
2356 .switch_case_one => tree.switchCaseOne(case_node),
2357 .switch_case => tree.switchCase(case_node),
2358 else => unreachable,
2359 };
2360 const start_tok = case.payload_token.?;
2361 const token_tags = tree.tokens.items(.tag);
2362 const end_tok = switch (token_tags[start_tok]) {
2363 .asterisk => start_tok + 1,
2364 else => start_tok,
2365 };
2366 const start = tree.tokens.items(.start)[start_tok];
2367 const end_start = tree.tokens.items(.start)[end_tok];
2368 const end = end_start + @intCast(u32, tree.tokenSlice(end_tok).len);
2369 return Span{ .start = start, .end = end, .main = start };
2370 },
2371 .node_offset_fn_type_align => |node_off| {
2372 const tree = try src_loc.file_scope.getTree(gpa);
2373 const node_datas = tree.nodes.items(.data);
2374 const node_tags = tree.nodes.items(.tag);
2375 const node = src_loc.declRelativeToNodeIndex(node_off);
2376 var params: [1]Ast.Node.Index = undefined;
2377 const full = switch (node_tags[node]) {
2378 .fn_proto_simple => tree.fnProtoSimple(&params, node),
2379 .fn_proto_multi => tree.fnProtoMulti(node),
2380 .fn_proto_one => tree.fnProtoOne(&params, node),
2381 .fn_proto => tree.fnProto(node),
2382 .fn_decl => switch (node_tags[node_datas[node].lhs]) {
2383 .fn_proto_simple => tree.fnProtoSimple(&params, node_datas[node].lhs),
2384 .fn_proto_multi => tree.fnProtoMulti(node_datas[node].lhs),
2385 .fn_proto_one => tree.fnProtoOne(&params, node_datas[node].lhs),
2386 .fn_proto => tree.fnProto(node_datas[node].lhs),
2387 else => unreachable,
2388 },
2389 else => unreachable,
2390 };
2391 return nodeToSpan(tree, full.ast.align_expr);
2392 },
2393 .node_offset_fn_type_addrspace => |node_off| {
2394 const tree = try src_loc.file_scope.getTree(gpa);
2395 const node_datas = tree.nodes.items(.data);
2396 const node_tags = tree.nodes.items(.tag);
2397 const node = src_loc.declRelativeToNodeIndex(node_off);
2398 var params: [1]Ast.Node.Index = undefined;
2399 const full = switch (node_tags[node]) {
2400 .fn_proto_simple => tree.fnProtoSimple(&params, node),
2401 .fn_proto_multi => tree.fnProtoMulti(node),
2402 .fn_proto_one => tree.fnProtoOne(&params, node),
2403 .fn_proto => tree.fnProto(node),
2404 .fn_decl => switch (node_tags[node_datas[node].lhs]) {
2405 .fn_proto_simple => tree.fnProtoSimple(&params, node_datas[node].lhs),
2406 .fn_proto_multi => tree.fnProtoMulti(node_datas[node].lhs),
2407 .fn_proto_one => tree.fnProtoOne(&params, node_datas[node].lhs),
2408 .fn_proto => tree.fnProto(node_datas[node].lhs),
2409 else => unreachable,
2410 },
2411 else => unreachable,
2412 };
2413 return nodeToSpan(tree, full.ast.addrspace_expr);
2414 },
2415 .node_offset_fn_type_section => |node_off| {
2416 const tree = try src_loc.file_scope.getTree(gpa);
2417 const node_datas = tree.nodes.items(.data);
2418 const node_tags = tree.nodes.items(.tag);
2419 const node = src_loc.declRelativeToNodeIndex(node_off);
2420 var params: [1]Ast.Node.Index = undefined;
2421 const full = switch (node_tags[node]) {
2422 .fn_proto_simple => tree.fnProtoSimple(&params, node),
2423 .fn_proto_multi => tree.fnProtoMulti(node),
2424 .fn_proto_one => tree.fnProtoOne(&params, node),
2425 .fn_proto => tree.fnProto(node),
2426 .fn_decl => switch (node_tags[node_datas[node].lhs]) {
2427 .fn_proto_simple => tree.fnProtoSimple(&params, node_datas[node].lhs),
2428 .fn_proto_multi => tree.fnProtoMulti(node_datas[node].lhs),
2429 .fn_proto_one => tree.fnProtoOne(&params, node_datas[node].lhs),
2430 .fn_proto => tree.fnProto(node_datas[node].lhs),
2431 else => unreachable,
2432 },
2433 else => unreachable,
2434 };
2435 return nodeToSpan(tree, full.ast.section_expr);
2436 },
2352 .node_offset_fn_type_cc => |node_off| {2437 .node_offset_fn_type_cc => |node_off| {
2353 const tree = try src_loc.file_scope.getTree(gpa);2438 const tree = try src_loc.file_scope.getTree(gpa);
2354 const node_datas = tree.nodes.items(.data);2439 const node_datas = tree.nodes.items(.data);
...@@ -2374,6 +2459,7 @@ pub const SrcLoc = struct {...@@ -2374,6 +2459,7 @@ pub const SrcLoc = struct {
23742459
2375 .node_offset_fn_type_ret_ty => |node_off| {2460 .node_offset_fn_type_ret_ty => |node_off| {
2376 const tree = try src_loc.file_scope.getTree(gpa);2461 const tree = try src_loc.file_scope.getTree(gpa);
2462 const node_datas = tree.nodes.items(.data);
2377 const node_tags = tree.nodes.items(.tag);2463 const node_tags = tree.nodes.items(.tag);
2378 const node = src_loc.declRelativeToNodeIndex(node_off);2464 const node = src_loc.declRelativeToNodeIndex(node_off);
2379 var params: [1]Ast.Node.Index = undefined;2465 var params: [1]Ast.Node.Index = undefined;
...@@ -2382,10 +2468,55 @@ pub const SrcLoc = struct {...@@ -2382,10 +2468,55 @@ pub const SrcLoc = struct {
2382 .fn_proto_multi => tree.fnProtoMulti(node),2468 .fn_proto_multi => tree.fnProtoMulti(node),
2383 .fn_proto_one => tree.fnProtoOne(&params, node),2469 .fn_proto_one => tree.fnProtoOne(&params, node),
2384 .fn_proto => tree.fnProto(node),2470 .fn_proto => tree.fnProto(node),
2471 .fn_decl => blk: {
2472 const fn_proto = node_datas[node].lhs;
2473 break :blk switch (node_tags[fn_proto]) {
2474 .fn_proto_simple => tree.fnProtoSimple(&params, fn_proto),
2475 .fn_proto_multi => tree.fnProtoMulti(fn_proto),
2476 .fn_proto_one => tree.fnProtoOne(&params, fn_proto),
2477 .fn_proto => tree.fnProto(fn_proto),
2478 else => unreachable,
2479 };
2480 },
2385 else => unreachable,2481 else => unreachable,
2386 };2482 };
2387 return nodeToSpan(tree, full.ast.return_type);2483 return nodeToSpan(tree, full.ast.return_type);
2388 },2484 },
2485 .node_offset_param => |node_off| {
2486 const tree = try src_loc.file_scope.getTree(gpa);
2487 const token_tags = tree.tokens.items(.tag);
2488 const node = src_loc.declRelativeToNodeIndex(node_off);
2489
2490 var first_tok = tree.firstToken(node);
2491 while (true) switch (token_tags[first_tok - 1]) {
2492 .colon, .identifier, .keyword_comptime, .keyword_noalias => first_tok -= 1,
2493 else => break,
2494 };
2495 return tokensToSpan(
2496 tree,
2497 first_tok,
2498 tree.lastToken(node),
2499 first_tok,
2500 );
2501 },
2502 .token_offset_param => |token_off| {
2503 const tree = try src_loc.file_scope.getTree(gpa);
2504 const token_tags = tree.tokens.items(.tag);
2505 const main_token = tree.nodes.items(.main_token)[src_loc.parent_decl_node];
2506 const tok_index = @bitCast(Ast.TokenIndex, token_off + @bitCast(i32, main_token));
2507
2508 var first_tok = tok_index;
2509 while (true) switch (token_tags[first_tok - 1]) {
2510 .colon, .identifier, .keyword_comptime, .keyword_noalias => first_tok -= 1,
2511 else => break,
2512 };
2513 return tokensToSpan(
2514 tree,
2515 first_tok,
2516 tok_index,
2517 first_tok,
2518 );
2519 },
23892520
2390 .node_offset_anyframe_type => |node_off| {2521 .node_offset_anyframe_type => |node_off| {
2391 const tree = try src_loc.file_scope.getTree(gpa);2522 const tree = try src_loc.file_scope.getTree(gpa);
...@@ -2466,6 +2597,113 @@ pub const SrcLoc = struct {...@@ -2466,6 +2597,113 @@ pub const SrcLoc = struct {
24662597
2467 return nodeToSpan(tree, node_datas[node].lhs);2598 return nodeToSpan(tree, node_datas[node].lhs);
2468 },2599 },
2600 .node_offset_ptr_elem => |node_off| {
2601 const tree = try src_loc.file_scope.getTree(gpa);
2602 const node_tags = tree.nodes.items(.tag);
2603 const parent_node = src_loc.declRelativeToNodeIndex(node_off);
2604
2605 const full: Ast.full.PtrType = switch (node_tags[parent_node]) {
2606 .ptr_type_aligned => tree.ptrTypeAligned(parent_node),
2607 .ptr_type_sentinel => tree.ptrTypeSentinel(parent_node),
2608 .ptr_type => tree.ptrType(parent_node),
2609 .ptr_type_bit_range => tree.ptrTypeBitRange(parent_node),
2610 else => unreachable,
2611 };
2612 return nodeToSpan(tree, full.ast.child_type);
2613 },
2614 .node_offset_ptr_sentinel => |node_off| {
2615 const tree = try src_loc.file_scope.getTree(gpa);
2616 const node_tags = tree.nodes.items(.tag);
2617 const parent_node = src_loc.declRelativeToNodeIndex(node_off);
2618
2619 const full: Ast.full.PtrType = switch (node_tags[parent_node]) {
2620 .ptr_type_aligned => tree.ptrTypeAligned(parent_node),
2621 .ptr_type_sentinel => tree.ptrTypeSentinel(parent_node),
2622 .ptr_type => tree.ptrType(parent_node),
2623 .ptr_type_bit_range => tree.ptrTypeBitRange(parent_node),
2624 else => unreachable,
2625 };
2626 return nodeToSpan(tree, full.ast.sentinel);
2627 },
2628 .node_offset_ptr_align => |node_off| {
2629 const tree = try src_loc.file_scope.getTree(gpa);
2630 const node_tags = tree.nodes.items(.tag);
2631 const parent_node = src_loc.declRelativeToNodeIndex(node_off);
2632
2633 const full: Ast.full.PtrType = switch (node_tags[parent_node]) {
2634 .ptr_type_aligned => tree.ptrTypeAligned(parent_node),
2635 .ptr_type_sentinel => tree.ptrTypeSentinel(parent_node),
2636 .ptr_type => tree.ptrType(parent_node),
2637 .ptr_type_bit_range => tree.ptrTypeBitRange(parent_node),
2638 else => unreachable,
2639 };
2640 return nodeToSpan(tree, full.ast.align_node);
2641 },
2642 .node_offset_ptr_addrspace => |node_off| {
2643 const tree = try src_loc.file_scope.getTree(gpa);
2644 const node_tags = tree.nodes.items(.tag);
2645 const parent_node = src_loc.declRelativeToNodeIndex(node_off);
2646
2647 const full: Ast.full.PtrType = switch (node_tags[parent_node]) {
2648 .ptr_type_aligned => tree.ptrTypeAligned(parent_node),
2649 .ptr_type_sentinel => tree.ptrTypeSentinel(parent_node),
2650 .ptr_type => tree.ptrType(parent_node),
2651 .ptr_type_bit_range => tree.ptrTypeBitRange(parent_node),
2652 else => unreachable,
2653 };
2654 return nodeToSpan(tree, full.ast.addrspace_node);
2655 },
2656 .node_offset_ptr_bitoffset => |node_off| {
2657 const tree = try src_loc.file_scope.getTree(gpa);
2658 const node_tags = tree.nodes.items(.tag);
2659 const parent_node = src_loc.declRelativeToNodeIndex(node_off);
2660
2661 const full: Ast.full.PtrType = switch (node_tags[parent_node]) {
2662 .ptr_type_aligned => tree.ptrTypeAligned(parent_node),
2663 .ptr_type_sentinel => tree.ptrTypeSentinel(parent_node),
2664 .ptr_type => tree.ptrType(parent_node),
2665 .ptr_type_bit_range => tree.ptrTypeBitRange(parent_node),
2666 else => unreachable,
2667 };
2668 return nodeToSpan(tree, full.ast.bit_range_start);
2669 },
2670 .node_offset_ptr_hostsize => |node_off| {
2671 const tree = try src_loc.file_scope.getTree(gpa);
2672 const node_tags = tree.nodes.items(.tag);
2673 const parent_node = src_loc.declRelativeToNodeIndex(node_off);
2674
2675 const full: Ast.full.PtrType = switch (node_tags[parent_node]) {
2676 .ptr_type_aligned => tree.ptrTypeAligned(parent_node),
2677 .ptr_type_sentinel => tree.ptrTypeSentinel(parent_node),
2678 .ptr_type => tree.ptrType(parent_node),
2679 .ptr_type_bit_range => tree.ptrTypeBitRange(parent_node),
2680 else => unreachable,
2681 };
2682 return nodeToSpan(tree, full.ast.bit_range_end);
2683 },
2684 .node_offset_container_tag => |node_off| {
2685 const tree = try src_loc.file_scope.getTree(gpa);
2686 const node_tags = tree.nodes.items(.tag);
2687 const parent_node = src_loc.declRelativeToNodeIndex(node_off);
2688
2689 switch (node_tags[parent_node]) {
2690 .container_decl_arg, .container_decl_arg_trailing => {
2691 const full = tree.containerDeclArg(parent_node);
2692 return nodeToSpan(tree, full.ast.arg);
2693 },
2694 .tagged_union_enum_tag, .tagged_union_enum_tag_trailing => {
2695 const full = tree.taggedUnionEnumTag(parent_node);
2696
2697 return tokensToSpan(
2698 tree,
2699 tree.firstToken(full.ast.arg) - 2,
2700 tree.lastToken(full.ast.arg) + 1,
2701 tree.nodes.items(.main_token)[full.ast.arg],
2702 );
2703 },
2704 else => unreachable,
2705 }
2706 },
2469 }2707 }
2470 }2708 }
24712709
...@@ -2694,6 +2932,27 @@ pub const LazySrcLoc = union(enum) {...@@ -2694,6 +2932,27 @@ pub const LazySrcLoc = union(enum) {
2694 /// range nodes. The error applies to all of them.2932 /// range nodes. The error applies to all of them.
2695 /// The Decl is determined contextually.2933 /// The Decl is determined contextually.
2696 node_offset_switch_range: i32,2934 node_offset_switch_range: i32,
2935 /// The source location points to the capture of a switch_prong.
2936 /// The Decl is determined contextually.
2937 node_offset_switch_prong_capture: i32,
2938 /// The source location points to the align expr of a function type
2939 /// expression, found by taking this AST node index offset from the containing
2940 /// Decl AST node, which points to a function type AST node. Next, navigate to
2941 /// the calling convention node.
2942 /// The Decl is determined contextually.
2943 node_offset_fn_type_align: i32,
2944 /// The source location points to the addrspace expr of a function type
2945 /// expression, found by taking this AST node index offset from the containing
2946 /// Decl AST node, which points to a function type AST node. Next, navigate to
2947 /// the calling convention node.
2948 /// The Decl is determined contextually.
2949 node_offset_fn_type_addrspace: i32,
2950 /// The source location points to the linksection expr of a function type
2951 /// expression, found by taking this AST node index offset from the containing
2952 /// Decl AST node, which points to a function type AST node. Next, navigate to
2953 /// the calling convention node.
2954 /// The Decl is determined contextually.
2955 node_offset_fn_type_section: i32,
2697 /// The source location points to the calling convention of a function type2956 /// The source location points to the calling convention of a function type
2698 /// expression, found by taking this AST node index offset from the containing2957 /// expression, found by taking this AST node index offset from the containing
2699 /// Decl AST node, which points to a function type AST node. Next, navigate to2958 /// Decl AST node, which points to a function type AST node. Next, navigate to
...@@ -2706,6 +2965,8 @@ pub const LazySrcLoc = union(enum) {...@@ -2706,6 +2965,8 @@ pub const LazySrcLoc = union(enum) {
2706 /// the return type node.2965 /// the return type node.
2707 /// The Decl is determined contextually.2966 /// The Decl is determined contextually.
2708 node_offset_fn_type_ret_ty: i32,2967 node_offset_fn_type_ret_ty: i32,
2968 node_offset_param: i32,
2969 token_offset_param: i32,
2709 /// The source location points to the type expression of an `anyframe->T`2970 /// The source location points to the type expression of an `anyframe->T`
2710 /// expression, found by taking this AST node index offset from the containing2971 /// expression, found by taking this AST node index offset from the containing
2711 /// Decl AST node, which points to a `anyframe->T` expression AST node. Next, navigate2972 /// Decl AST node, which points to a `anyframe->T` expression AST node. Next, navigate
...@@ -2739,6 +3000,27 @@ pub const LazySrcLoc = union(enum) {...@@ -2739,6 +3000,27 @@ pub const LazySrcLoc = union(enum) {
2739 /// The source location points to the operand of an unary expression.3000 /// The source location points to the operand of an unary expression.
2740 /// The Decl is determined contextually.3001 /// The Decl is determined contextually.
2741 node_offset_un_op: i32,3002 node_offset_un_op: i32,
3003 /// The source location points to the elem type of a pointer.
3004 /// The Decl is determined contextually.
3005 node_offset_ptr_elem: i32,
3006 /// The source location points to the sentinel of a pointer.
3007 /// The Decl is determined contextually.
3008 node_offset_ptr_sentinel: i32,
3009 /// The source location points to the align expr of a pointer.
3010 /// The Decl is determined contextually.
3011 node_offset_ptr_align: i32,
3012 /// The source location points to the addrspace expr of a pointer.
3013 /// The Decl is determined contextually.
3014 node_offset_ptr_addrspace: i32,
3015 /// The source location points to the bit-offset of a pointer.
3016 /// The Decl is determined contextually.
3017 node_offset_ptr_bitoffset: i32,
3018 /// The source location points to the host size of a pointer.
3019 /// The Decl is determined contextually.
3020 node_offset_ptr_hostsize: i32,
3021 /// The source location points to the tag type of an union or an enum.
3022 /// The Decl is determined contextually.
3023 node_offset_container_tag: i32,
27423024
2743 pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease;3025 pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease;
27443026
...@@ -2795,14 +3077,27 @@ pub const LazySrcLoc = union(enum) {...@@ -2795,14 +3077,27 @@ pub const LazySrcLoc = union(enum) {
2795 .node_offset_switch_operand,3077 .node_offset_switch_operand,
2796 .node_offset_switch_special_prong,3078 .node_offset_switch_special_prong,
2797 .node_offset_switch_range,3079 .node_offset_switch_range,
3080 .node_offset_switch_prong_capture,
3081 .node_offset_fn_type_align,
3082 .node_offset_fn_type_addrspace,
3083 .node_offset_fn_type_section,
2798 .node_offset_fn_type_cc,3084 .node_offset_fn_type_cc,
2799 .node_offset_fn_type_ret_ty,3085 .node_offset_fn_type_ret_ty,
3086 .node_offset_param,
3087 .token_offset_param,
2800 .node_offset_anyframe_type,3088 .node_offset_anyframe_type,
2801 .node_offset_lib_name,3089 .node_offset_lib_name,
2802 .node_offset_array_type_len,3090 .node_offset_array_type_len,
2803 .node_offset_array_type_sentinel,3091 .node_offset_array_type_sentinel,
2804 .node_offset_array_type_elem,3092 .node_offset_array_type_elem,
2805 .node_offset_un_op,3093 .node_offset_un_op,
3094 .node_offset_ptr_elem,
3095 .node_offset_ptr_sentinel,
3096 .node_offset_ptr_align,
3097 .node_offset_ptr_addrspace,
3098 .node_offset_ptr_bitoffset,
3099 .node_offset_ptr_hostsize,
3100 .node_offset_container_tag,
2806 => .{3101 => .{
2807 .file_scope = decl.getFileScope(),3102 .file_scope = decl.getFileScope(),
2808 .parent_decl_node = decl.src_node,3103 .parent_decl_node = decl.src_node,
...@@ -3957,18 +4252,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -3957,18 +4252,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
3957 var wip_captures = try WipCaptureScope.init(gpa, new_decl_arena_allocator, null);4252 var wip_captures = try WipCaptureScope.init(gpa, new_decl_arena_allocator, null);
3958 defer wip_captures.deinit();4253 defer wip_captures.deinit();
39594254
3960 var block_scope: Sema.Block = .{
3961 .parent = null,
3962 .sema = &sema,
3963 .src_decl = new_decl_index,
3964 .namespace = &struct_obj.namespace,
3965 .wip_capture_scope = wip_captures.scope,
3966 .instructions = .{},
3967 .inlining = null,
3968 .is_comptime = true,
3969 };
3970 defer block_scope.instructions.deinit(gpa);
3971
3972 if (sema.analyzeStructDecl(new_decl, main_struct_inst, struct_obj)) |_| {4255 if (sema.analyzeStructDecl(new_decl, main_struct_inst, struct_obj)) |_| {
3973 try wip_captures.finalize();4256 try wip_captures.finalize();
3974 new_decl.analysis = .complete;4257 new_decl.analysis = .complete;
...@@ -4077,7 +4360,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4077,7 +4360,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4077 const result_ref = (try sema.analyzeBodyBreak(&block_scope, body)).?.operand;4360 const result_ref = (try sema.analyzeBodyBreak(&block_scope, body)).?.operand;
4078 try wip_captures.finalize();4361 try wip_captures.finalize();
4079 const src = LazySrcLoc.nodeOffset(0);4362 const src = LazySrcLoc.nodeOffset(0);
4080 const decl_tv = try sema.resolveInstValue(&block_scope, src, result_ref);4363 const decl_tv = try sema.resolveInstValue(&block_scope, .unneeded, result_ref, undefined);
4081 const decl_align: u32 = blk: {4364 const decl_align: u32 = blk: {
4082 const align_ref = decl.zirAlignRef();4365 const align_ref = decl.zirAlignRef();
4083 if (align_ref == .none) break :blk 0;4366 if (align_ref == .none) break :blk 0;
...@@ -4086,7 +4369,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4086,7 +4369,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4086 const decl_linksection: ?[*:0]const u8 = blk: {4369 const decl_linksection: ?[*:0]const u8 = blk: {
4087 const linksection_ref = decl.zirLinksectionRef();4370 const linksection_ref = decl.zirLinksectionRef();
4088 if (linksection_ref == .none) break :blk null;4371 if (linksection_ref == .none) break :blk null;
4089 const bytes = try sema.resolveConstString(&block_scope, src, linksection_ref);4372 const bytes = try sema.resolveConstString(&block_scope, src, linksection_ref, "linksection must be comptime known");
4090 break :blk (try decl_arena_allocator.dupeZ(u8, bytes)).ptr;4373 break :blk (try decl_arena_allocator.dupeZ(u8, bytes)).ptr;
4091 };4374 };
4092 const target = sema.mod.getTarget();4375 const target = sema.mod.getTarget();
...@@ -4518,7 +4801,7 @@ pub fn scanNamespace(...@@ -4518,7 +4801,7 @@ pub fn scanNamespace(
4518 extra_start: usize,4801 extra_start: usize,
4519 decls_len: u32,4802 decls_len: u32,
4520 parent_decl: *Decl,4803 parent_decl: *Decl,
4521) SemaError!usize {4804) Allocator.Error!usize {
4522 const tracy = trace(@src());4805 const tracy = trace(@src());
4523 defer tracy.end();4806 defer tracy.end();
45244807
...@@ -4565,7 +4848,7 @@ const ScanDeclIter = struct {...@@ -4565,7 +4848,7 @@ const ScanDeclIter = struct {
4565 unnamed_test_index: usize = 0,4848 unnamed_test_index: usize = 0,
4566};4849};
45674850
4568fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!void {4851fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Error!void {
4569 const tracy = trace(@src());4852 const tracy = trace(@src());
4570 defer tracy.end();4853 defer tracy.end();
45714854
...@@ -5382,6 +5665,7 @@ pub const SwitchProngSrc = union(enum) {...@@ -5382,6 +5665,7 @@ pub const SwitchProngSrc = union(enum) {
5382 scalar: u32,5665 scalar: u32,
5383 multi: Multi,5666 multi: Multi,
5384 range: Multi,5667 range: Multi,
5668 multi_capture: u32,
53855669
5386 pub const Multi = struct {5670 pub const Multi = struct {
5387 prong: u32,5671 prong: u32,
...@@ -5437,6 +5721,9 @@ pub const SwitchProngSrc = union(enum) {...@@ -5437,6 +5721,9 @@ pub const SwitchProngSrc = union(enum) {
5437 .scalar => |i| if (!is_multi and i == scalar_i) return LazySrcLoc.nodeOffset(5721 .scalar => |i| if (!is_multi and i == scalar_i) return LazySrcLoc.nodeOffset(
5438 decl.nodeIndexToRelative(case.ast.values[0]),5722 decl.nodeIndexToRelative(case.ast.values[0]),
5439 ),5723 ),
5724 .multi_capture => |i| if (is_multi and i == multi_i) {
5725 return LazySrcLoc{ .node_offset_switch_prong_capture = decl.nodeIndexToRelative(case_node) };
5726 },
5440 .multi => |s| if (is_multi and s.prong == multi_i) {5727 .multi => |s| if (is_multi and s.prong == multi_i) {
5441 var item_i: u32 = 0;5728 var item_i: u32 = 0;
5442 for (case.ast.values) |item_node| {5729 for (case.ast.values) |item_node| {
...@@ -5578,6 +5865,77 @@ fn queryFieldSrc(...@@ -5578,6 +5865,77 @@ fn queryFieldSrc(
5578 unreachable;5865 unreachable;
5579}5866}
55805867
5868pub fn paramSrc(
5869 func_node_offset: i32,
5870 gpa: Allocator,
5871 decl: *Decl,
5872 param_i: usize,
5873) LazySrcLoc {
5874 @setCold(true);
5875 const tree = decl.getFileScope().getTree(gpa) catch |err| {
5876 // In this case we emit a warning + a less precise source location.
5877 log.warn("unable to load {s}: {s}", .{
5878 decl.getFileScope().sub_file_path, @errorName(err),
5879 });
5880 return LazySrcLoc.nodeOffset(0);
5881 };
5882 const node_datas = tree.nodes.items(.data);
5883 const node_tags = tree.nodes.items(.tag);
5884 const node = decl.relativeToNodeIndex(func_node_offset);
5885 var params: [1]Ast.Node.Index = undefined;
5886 const full = switch (node_tags[node]) {
5887 .fn_proto_simple => tree.fnProtoSimple(&params, node),
5888 .fn_proto_multi => tree.fnProtoMulti(node),
5889 .fn_proto_one => tree.fnProtoOne(&params, node),
5890 .fn_proto => tree.fnProto(node),
5891 .fn_decl => switch (node_tags[node_datas[node].lhs]) {
5892 .fn_proto_simple => tree.fnProtoSimple(&params, node_datas[node].lhs),
5893 .fn_proto_multi => tree.fnProtoMulti(node_datas[node].lhs),
5894 .fn_proto_one => tree.fnProtoOne(&params, node_datas[node].lhs),
5895 .fn_proto => tree.fnProto(node_datas[node].lhs),
5896 else => unreachable,
5897 },
5898 else => unreachable,
5899 };
5900 var it = full.iterate(tree);
5901 while (true) {
5902 if (it.param_i == param_i) {
5903 const param = it.next().?;
5904 if (param.anytype_ellipsis3) |some| {
5905 const main_token = tree.nodes.items(.main_token)[decl.src_node];
5906 return .{ .token_offset_param = @bitCast(i32, some) - @bitCast(i32, main_token) };
5907 }
5908 return .{ .node_offset_param = decl.nodeIndexToRelative(param.type_expr) };
5909 }
5910 _ = it.next();
5911 }
5912}
5913
5914pub fn argSrc(
5915 call_node_offset: i32,
5916 gpa: Allocator,
5917 decl: *Decl,
5918 arg_i: usize,
5919) LazySrcLoc {
5920 @setCold(true);
5921 const tree = decl.getFileScope().getTree(gpa) catch |err| {
5922 // In this case we emit a warning + a less precise source location.
5923 log.warn("unable to load {s}: {s}", .{
5924 decl.getFileScope().sub_file_path, @errorName(err),
5925 });
5926 return LazySrcLoc.nodeOffset(0);
5927 };
5928 const node_tags = tree.nodes.items(.tag);
5929 const node = decl.relativeToNodeIndex(call_node_offset);
5930 var args: [1]Ast.Node.Index = undefined;
5931 const full = switch (node_tags[node]) {
5932 .call_one, .call_one_comma, .async_call_one, .async_call_one_comma => tree.callOne(&args, node),
5933 .call, .call_comma, .async_call, .async_call_comma => tree.callFull(node),
5934 else => unreachable,
5935 };
5936 return LazySrcLoc.nodeOffset(decl.nodeIndexToRelative(full.ast.params[arg_i]));
5937}
5938
5581/// Called from `performAllTheWork`, after all AstGen workers have finished,5939/// Called from `performAllTheWork`, after all AstGen workers have finished,
5582/// and before the main semantic analysis loop begins.5940/// and before the main semantic analysis loop begins.
5583pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {5941pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {
src/Sema.zig+974-591
...@@ -768,7 +768,7 @@ fn analyzeBodyInner(...@@ -768,7 +768,7 @@ fn analyzeBodyInner(
768 .optional_type => try sema.zirOptionalType(block, inst),768 .optional_type => try sema.zirOptionalType(block, inst),
769 .param_type => try sema.zirParamType(block, inst),769 .param_type => try sema.zirParamType(block, inst),
770 .ptr_type => try sema.zirPtrType(block, inst),770 .ptr_type => try sema.zirPtrType(block, inst),
771 .ptr_type_simple => try sema.zirPtrTypeSimple(block, inst),771 .overflow_arithmetic_ptr => try sema.zirOverflowArithmeticPtr(block, inst),
772 .ref => try sema.zirRef(block, inst),772 .ref => try sema.zirRef(block, inst),
773 .ret_err_value_code => try sema.zirRetErrValueCode(inst),773 .ret_err_value_code => try sema.zirRetErrValueCode(inst),
774 .shr => try sema.zirShr(block, inst, .shr),774 .shr => try sema.zirShr(block, inst, .shr),
...@@ -892,7 +892,7 @@ fn analyzeBodyInner(...@@ -892,7 +892,7 @@ fn analyzeBodyInner(
892 .shl_sat => try sema.zirShl(block, inst, .shl_sat),892 .shl_sat => try sema.zirShl(block, inst, .shl_sat),
893893
894 .ret_ptr => try sema.zirRetPtr(block, inst),894 .ret_ptr => try sema.zirRetPtr(block, inst),
895 .ret_type => try sema.zirRetType(block, inst),895 .ret_type => try sema.addType(sema.fn_ret_ty),
896896
897 // Instructions that we know to *always* be noreturn based solely on their tag.897 // Instructions that we know to *always* be noreturn based solely on their tag.
898 // These functions match the return type of analyzeBody so that we can898 // These functions match the return type of analyzeBody so that we can
...@@ -1173,7 +1173,7 @@ fn analyzeBodyInner(...@@ -1173,7 +1173,7 @@ fn analyzeBodyInner(
1173 } else {1173 } else {
1174 const src_node = sema.code.instructions.items(.data)[inst].node;1174 const src_node = sema.code.instructions.items(.data)[inst].node;
1175 const src = LazySrcLoc.nodeOffset(src_node);1175 const src = LazySrcLoc.nodeOffset(src_node);
1176 try sema.requireRuntimeBlock(block, src);1176 try sema.requireFunctionBlock(block, src);
1177 break always_noreturn;1177 break always_noreturn;
1178 }1178 }
1179 },1179 },
...@@ -1303,7 +1303,7 @@ fn analyzeBodyInner(...@@ -1303,7 +1303,7 @@ fn analyzeBodyInner(
1303 const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);1303 const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);
1304 const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len];1304 const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len];
1305 const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];1305 const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
1306 const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition);1306 const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition, "condition in comptime branch must be comptime known");
1307 const inline_body = if (cond.val.toBool()) then_body else else_body;1307 const inline_body = if (cond.val.toBool()) then_body else else_body;
1308 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse1308 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse
1309 break always_noreturn;1309 break always_noreturn;
...@@ -1319,7 +1319,7 @@ fn analyzeBodyInner(...@@ -1319,7 +1319,7 @@ fn analyzeBodyInner(
1319 const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);1319 const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);
1320 const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len];1320 const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len];
1321 const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];1321 const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
1322 const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition);1322 const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition, "condition in comptime branch must be comptime known");
1323 const inline_body = if (cond.val.toBool()) then_body else else_body;1323 const inline_body = if (cond.val.toBool()) then_body else else_body;
1324 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse1324 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse
1325 break always_noreturn;1325 break always_noreturn;
...@@ -1339,7 +1339,7 @@ fn analyzeBodyInner(...@@ -1339,7 +1339,7 @@ fn analyzeBodyInner(
1339 const err_union = try sema.resolveInst(extra.data.operand);1339 const err_union = try sema.resolveInst(extra.data.operand);
1340 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union);1340 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union);
1341 assert(is_non_err != .none);1341 assert(is_non_err != .none);
1342 const is_non_err_tv = try sema.resolveInstConst(block, operand_src, is_non_err);1342 const is_non_err_tv = try sema.resolveInstConst(block, operand_src, is_non_err, "try operand inside comptime block must be comptime known");
1343 if (is_non_err_tv.val.toBool()) {1343 if (is_non_err_tv.val.toBool()) {
1344 const err_union_ty = sema.typeOf(err_union);1344 const err_union_ty = sema.typeOf(err_union);
1345 break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, err_union, operand_src, false);1345 break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, err_union, operand_src, false);
...@@ -1395,7 +1395,7 @@ fn analyzeBodyInner(...@@ -1395,7 +1395,7 @@ fn analyzeBodyInner(
1395 const err_union = try sema.analyzeLoad(block, src, operand, operand_src);1395 const err_union = try sema.analyzeLoad(block, src, operand, operand_src);
1396 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union);1396 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union);
1397 assert(is_non_err != .none);1397 assert(is_non_err != .none);
1398 const is_non_err_tv = try sema.resolveInstConst(block, operand_src, is_non_err);1398 const is_non_err_tv = try sema.resolveInstConst(block, operand_src, is_non_err, "try operand inside comptime block must be comptime known");
1399 if (is_non_err_tv.val.toBool()) {1399 if (is_non_err_tv.val.toBool()) {
1400 break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false);1400 break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false);
1401 }1401 }
...@@ -1478,11 +1478,12 @@ fn resolveConstBool(...@@ -1478,11 +1478,12 @@ fn resolveConstBool(
1478 block: *Block,1478 block: *Block,
1479 src: LazySrcLoc,1479 src: LazySrcLoc,
1480 zir_ref: Zir.Inst.Ref,1480 zir_ref: Zir.Inst.Ref,
1481 reason: []const u8,
1481) !bool {1482) !bool {
1482 const air_inst = try sema.resolveInst(zir_ref);1483 const air_inst = try sema.resolveInst(zir_ref);
1483 const wanted_type = Type.bool;1484 const wanted_type = Type.bool;
1484 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);1485 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
1485 const val = try sema.resolveConstValue(block, src, coerced_inst);1486 const val = try sema.resolveConstValue(block, src, coerced_inst, reason);
1486 return val.toBool();1487 return val.toBool();
1487}1488}
14881489
...@@ -1491,11 +1492,12 @@ pub fn resolveConstString(...@@ -1491,11 +1492,12 @@ pub fn resolveConstString(
1491 block: *Block,1492 block: *Block,
1492 src: LazySrcLoc,1493 src: LazySrcLoc,
1493 zir_ref: Zir.Inst.Ref,1494 zir_ref: Zir.Inst.Ref,
1495 reason: []const u8,
1494) ![]u8 {1496) ![]u8 {
1495 const air_inst = try sema.resolveInst(zir_ref);1497 const air_inst = try sema.resolveInst(zir_ref);
1496 const wanted_type = Type.initTag(.const_slice_u8);1498 const wanted_type = Type.initTag(.const_slice_u8);
1497 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);1499 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
1498 const val = try sema.resolveConstValue(block, src, coerced_inst);1500 const val = try sema.resolveConstValue(block, src, coerced_inst, reason);
1499 return val.toAllocatedBytes(wanted_type, sema.arena, sema.mod);1501 return val.toAllocatedBytes(wanted_type, sema.arena, sema.mod);
1500}1502}
15011503
...@@ -1514,7 +1516,7 @@ fn analyzeAsType(...@@ -1514,7 +1516,7 @@ fn analyzeAsType(
1514) !Type {1516) !Type {
1515 const wanted_type = Type.initTag(.@"type");1517 const wanted_type = Type.initTag(.@"type");
1516 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);1518 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
1517 const val = try sema.resolveConstValue(block, src, coerced_inst);1519 const val = try sema.resolveConstValue(block, src, coerced_inst, "types must be comptime known");
1518 var buffer: Value.ToTypeBuffer = undefined;1520 var buffer: Value.ToTypeBuffer = undefined;
1519 const ty = val.toType(&buffer);1521 const ty = val.toType(&buffer);
1520 return ty.copy(sema.arena);1522 return ty.copy(sema.arena);
...@@ -1567,12 +1569,13 @@ fn resolveValue(...@@ -1567,12 +1569,13 @@ fn resolveValue(
1567 block: *Block,1569 block: *Block,
1568 src: LazySrcLoc,1570 src: LazySrcLoc,
1569 air_ref: Air.Inst.Ref,1571 air_ref: Air.Inst.Ref,
1572 reason: []const u8,
1570) CompileError!Value {1573) CompileError!Value {
1571 if (try sema.resolveMaybeUndefValAllowVariables(block, src, air_ref)) |val| {1574 if (try sema.resolveMaybeUndefValAllowVariables(block, src, air_ref)) |val| {
1572 if (val.tag() == .generic_poison) return error.GenericPoison;1575 if (val.tag() == .generic_poison) return error.GenericPoison;
1573 return val;1576 return val;
1574 }1577 }
1575 return sema.failWithNeededComptime(block, src);1578 return sema.failWithNeededComptime(block, src, reason);
1576}1579}
15771580
1578/// Value Tag `variable` will cause a compile error.1581/// Value Tag `variable` will cause a compile error.
...@@ -1582,15 +1585,16 @@ fn resolveConstMaybeUndefVal(...@@ -1582,15 +1585,16 @@ fn resolveConstMaybeUndefVal(
1582 block: *Block,1585 block: *Block,
1583 src: LazySrcLoc,1586 src: LazySrcLoc,
1584 inst: Air.Inst.Ref,1587 inst: Air.Inst.Ref,
1588 reason: []const u8,
1585) CompileError!Value {1589) CompileError!Value {
1586 if (try sema.resolveMaybeUndefValAllowVariables(block, src, inst)) |val| {1590 if (try sema.resolveMaybeUndefValAllowVariables(block, src, inst)) |val| {
1587 switch (val.tag()) {1591 switch (val.tag()) {
1588 .variable => return sema.failWithNeededComptime(block, src),1592 .variable => return sema.failWithNeededComptime(block, src, reason),
1589 .generic_poison => return error.GenericPoison,1593 .generic_poison => return error.GenericPoison,
1590 else => return val,1594 else => return val,
1591 }1595 }
1592 }1596 }
1593 return sema.failWithNeededComptime(block, src);1597 return sema.failWithNeededComptime(block, src, reason);
1594}1598}
15951599
1596/// Will not return Value Tags: `variable`, `undef`. Instead they will emit compile errors.1600/// Will not return Value Tags: `variable`, `undef`. Instead they will emit compile errors.
...@@ -1600,16 +1604,17 @@ fn resolveConstValue(...@@ -1600,16 +1604,17 @@ fn resolveConstValue(
1600 block: *Block,1604 block: *Block,
1601 src: LazySrcLoc,1605 src: LazySrcLoc,
1602 air_ref: Air.Inst.Ref,1606 air_ref: Air.Inst.Ref,
1607 reason: []const u8,
1603) CompileError!Value {1608) CompileError!Value {
1604 if (try sema.resolveMaybeUndefValAllowVariables(block, src, air_ref)) |val| {1609 if (try sema.resolveMaybeUndefValAllowVariables(block, src, air_ref)) |val| {
1605 switch (val.tag()) {1610 switch (val.tag()) {
1606 .undef => return sema.failWithUseOfUndef(block, src),1611 .undef => return sema.failWithUseOfUndef(block, src),
1607 .variable => return sema.failWithNeededComptime(block, src),1612 .variable => return sema.failWithNeededComptime(block, src, reason),
1608 .generic_poison => return error.GenericPoison,1613 .generic_poison => return error.GenericPoison,
1609 else => return val,1614 else => return val,
1610 }1615 }
1611 }1616 }
1612 return sema.failWithNeededComptime(block, src);1617 return sema.failWithNeededComptime(block, src, reason);
1613}1618}
16141619
1615/// Value Tag `variable` causes this function to return `null`.1620/// Value Tag `variable` causes this function to return `null`.
...@@ -1697,8 +1702,15 @@ fn resolveMaybeUndefValAllowVariables(...@@ -1697,8 +1702,15 @@ fn resolveMaybeUndefValAllowVariables(
1697 }1702 }
1698}1703}
16991704
1700fn failWithNeededComptime(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError {1705fn failWithNeededComptime(sema: *Sema, block: *Block, src: LazySrcLoc, reason: []const u8) CompileError {
1701 return sema.fail(block, src, "unable to resolve comptime value", .{});1706 const msg = msg: {
1707 const msg = try sema.errMsg(block, src, "unable to resolve comptime value", .{});
1708 errdefer msg.destroy(sema.gpa);
1709
1710 try sema.errNote(block, src, msg, "{s}", .{reason});
1711 break :msg msg;
1712 };
1713 return sema.failWithOwnedErrorMsg(block, msg);
1702}1714}
17031715
1704fn failWithUseOfUndef(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError {1716fn failWithUseOfUndef(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError {
...@@ -1870,15 +1882,24 @@ fn analyzeAsAlign(...@@ -1870,15 +1882,24 @@ fn analyzeAsAlign(
1870 src: LazySrcLoc,1882 src: LazySrcLoc,
1871 air_ref: Air.Inst.Ref,1883 air_ref: Air.Inst.Ref,
1872) !u32 {1884) !u32 {
1873 const alignment_big = try sema.analyzeAsInt(block, src, air_ref, align_ty);1885 const alignment_big = try sema.analyzeAsInt(block, src, air_ref, align_ty, "alignment must be comptime known");
1874 const alignment = @intCast(u32, alignment_big); // We coerce to u16 in the prev line.1886 const alignment = @intCast(u32, alignment_big); // We coerce to u16 in the prev line.
1887 try sema.validateAlign(block, src, alignment);
1888 return alignment;
1889}
1890
1891fn validateAlign(
1892 sema: *Sema,
1893 block: *Block,
1894 src: LazySrcLoc,
1895 alignment: u32,
1896) !void {
1875 if (alignment == 0) return sema.fail(block, src, "alignment must be >= 1", .{});1897 if (alignment == 0) return sema.fail(block, src, "alignment must be >= 1", .{});
1876 if (!std.math.isPowerOfTwo(alignment)) {1898 if (!std.math.isPowerOfTwo(alignment)) {
1877 return sema.fail(block, src, "alignment value '{d}' is not a power of two", .{1899 return sema.fail(block, src, "alignment value '{d}' is not a power of two", .{
1878 alignment,1900 alignment,
1879 });1901 });
1880 }1902 }
1881 return alignment;
1882}1903}
18831904
1884pub fn resolveAlign(1905pub fn resolveAlign(
...@@ -1897,9 +1918,10 @@ fn resolveInt(...@@ -1897,9 +1918,10 @@ fn resolveInt(
1897 src: LazySrcLoc,1918 src: LazySrcLoc,
1898 zir_ref: Zir.Inst.Ref,1919 zir_ref: Zir.Inst.Ref,
1899 dest_ty: Type,1920 dest_ty: Type,
1921 reason: []const u8,
1900) !u64 {1922) !u64 {
1901 const air_ref = try sema.resolveInst(zir_ref);1923 const air_ref = try sema.resolveInst(zir_ref);
1902 return analyzeAsInt(sema, block, src, air_ref, dest_ty);1924 return analyzeAsInt(sema, block, src, air_ref, dest_ty, reason);
1903}1925}
19041926
1905fn analyzeAsInt(1927fn analyzeAsInt(
...@@ -1908,9 +1930,10 @@ fn analyzeAsInt(...@@ -1908,9 +1930,10 @@ fn analyzeAsInt(
1908 src: LazySrcLoc,1930 src: LazySrcLoc,
1909 air_ref: Air.Inst.Ref,1931 air_ref: Air.Inst.Ref,
1910 dest_ty: Type,1932 dest_ty: Type,
1933 reason: []const u8,
1911) !u64 {1934) !u64 {
1912 const coerced = try sema.coerce(block, dest_ty, air_ref, src);1935 const coerced = try sema.coerce(block, dest_ty, air_ref, src);
1913 const val = try sema.resolveConstValue(block, src, coerced);1936 const val = try sema.resolveConstValue(block, src, coerced, reason);
1914 const target = sema.mod.getTarget();1937 const target = sema.mod.getTarget();
1915 return (try val.getUnsignedIntAdvanced(target, sema.kit(block, src))).?;1938 return (try val.getUnsignedIntAdvanced(target, sema.kit(block, src))).?;
1916}1939}
...@@ -1922,9 +1945,10 @@ pub fn resolveInstConst(...@@ -1922,9 +1945,10 @@ pub fn resolveInstConst(
1922 block: *Block,1945 block: *Block,
1923 src: LazySrcLoc,1946 src: LazySrcLoc,
1924 zir_ref: Zir.Inst.Ref,1947 zir_ref: Zir.Inst.Ref,
1948 reason: []const u8,
1925) CompileError!TypedValue {1949) CompileError!TypedValue {
1926 const air_ref = try sema.resolveInst(zir_ref);1950 const air_ref = try sema.resolveInst(zir_ref);
1927 const val = try sema.resolveConstValue(block, src, air_ref);1951 const val = try sema.resolveConstValue(block, src, air_ref, reason);
1928 return TypedValue{1952 return TypedValue{
1929 .ty = sema.typeOf(air_ref),1953 .ty = sema.typeOf(air_ref),
1930 .val = val,1954 .val = val,
...@@ -1938,9 +1962,10 @@ pub fn resolveInstValue(...@@ -1938,9 +1962,10 @@ pub fn resolveInstValue(
1938 block: *Block,1962 block: *Block,
1939 src: LazySrcLoc,1963 src: LazySrcLoc,
1940 zir_ref: Zir.Inst.Ref,1964 zir_ref: Zir.Inst.Ref,
1965 reason: []const u8,
1941) CompileError!TypedValue {1966) CompileError!TypedValue {
1942 const air_ref = try sema.resolveInst(zir_ref);1967 const air_ref = try sema.resolveInst(zir_ref);
1943 const val = try sema.resolveValue(block, src, air_ref);1968 const val = try sema.resolveValue(block, src, air_ref, reason);
1944 return TypedValue{1969 return TypedValue{
1945 .ty = sema.typeOf(air_ref),1970 .ty = sema.typeOf(air_ref),
1946 .val = val,1971 .val = val,
...@@ -1974,7 +1999,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -1974,7 +1999,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
1974 defer trash_block.instructions.deinit(sema.gpa);1999 defer trash_block.instructions.deinit(sema.gpa);
1975 const operand = try trash_block.addBitCast(pointee_ty, .void_value);2000 const operand = try trash_block.addBitCast(pointee_ty, .void_value);
19762001
1977 try sema.requireRuntimeBlock(block, src);2002 try sema.requireFunctionBlock(block, src);
1978 const ptr_ty = try Type.ptr(sema.arena, sema.mod, .{2003 const ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
1979 .pointee_type = pointee_ty,2004 .pointee_type = pointee_ty,
1980 .@"align" = inferred_alloc.alignment,2005 .@"align" = inferred_alloc.alignment,
...@@ -2259,7 +2284,7 @@ fn createAnonymousDeclTypeNamed(...@@ -2259,7 +2284,7 @@ fn createAnonymousDeclTypeNamed(
2259 const arg = sema.inst_map.get(zir_inst).?;2284 const arg = sema.inst_map.get(zir_inst).?;
2260 // The comptime call code in analyzeCall already did this, so we're2285 // The comptime call code in analyzeCall already did this, so we're
2261 // just repeating it here and it's guaranteed to work.2286 // just repeating it here and it's guaranteed to work.
2262 const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg) catch unreachable;2287 const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg, undefined) catch unreachable;
22632288
2264 if (arg_i != 0) try buf.appendSlice(",");2289 if (arg_i != 0) try buf.appendSlice(",");
2265 try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg), sema.mod)});2290 try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg), sema.mod)});
...@@ -2319,6 +2344,7 @@ fn zirEnumDecl(...@@ -2319,6 +2344,7 @@ fn zirEnumDecl(
2319 extra_index += 1;2344 extra_index += 1;
2320 break :blk LazySrcLoc.nodeOffset(node_offset);2345 break :blk LazySrcLoc.nodeOffset(node_offset);
2321 } else sema.src;2346 } else sema.src;
2347 const tag_ty_src: LazySrcLoc = .{ .node_offset_container_tag = src.node_offset.x };
23222348
2323 const tag_type_ref = if (small.has_tag_type) blk: {2349 const tag_type_ref = if (small.has_tag_type) blk: {
2324 const tag_type_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);2350 const tag_type_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
...@@ -2344,8 +2370,10 @@ fn zirEnumDecl(...@@ -2344,8 +2370,10 @@ fn zirEnumDecl(
2344 break :blk decls_len;2370 break :blk decls_len;
2345 } else 0;2371 } else 0;
23462372
2373 var done = false;
2374
2347 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);2375 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
2348 errdefer new_decl_arena.deinit();2376 errdefer if (!done) new_decl_arena.deinit();
2349 const new_decl_arena_allocator = new_decl_arena.allocator();2377 const new_decl_arena_allocator = new_decl_arena.allocator();
23502378
2351 const enum_obj = try new_decl_arena_allocator.create(Module.EnumFull);2379 const enum_obj = try new_decl_arena_allocator.create(Module.EnumFull);
...@@ -2362,7 +2390,7 @@ fn zirEnumDecl(...@@ -2362,7 +2390,7 @@ fn zirEnumDecl(
2362 }, small.name_strategy, "enum", inst);2390 }, small.name_strategy, "enum", inst);
2363 const new_decl = mod.declPtr(new_decl_index);2391 const new_decl = mod.declPtr(new_decl_index);
2364 new_decl.owns_tv = true;2392 new_decl.owns_tv = true;
2365 errdefer mod.abortAnonDecl(new_decl_index);2393 errdefer if (!done) mod.abortAnonDecl(new_decl_index);
23662394
2367 enum_obj.* = .{2395 enum_obj.* = .{
2368 .owner_decl = new_decl_index,2396 .owner_decl = new_decl_index,
...@@ -2381,19 +2409,28 @@ fn zirEnumDecl(...@@ -2381,19 +2409,28 @@ fn zirEnumDecl(
2381 &enum_obj.namespace, new_decl, new_decl.name,2409 &enum_obj.namespace, new_decl, new_decl.name,
2382 });2410 });
23832411
2412 try new_decl.finalizeNewArena(&new_decl_arena);
2413 const decl_val = try sema.analyzeDeclVal(block, src, new_decl_index);
2414 done = true;
2415
2416 var decl_arena = new_decl.value_arena.?.promote(gpa);
2417 defer new_decl.value_arena.?.* = decl_arena.state;
2418 const decl_arena_allocator = decl_arena.allocator();
2419
2384 extra_index = try mod.scanNamespace(&enum_obj.namespace, extra_index, decls_len, new_decl);2420 extra_index = try mod.scanNamespace(&enum_obj.namespace, extra_index, decls_len, new_decl);
23852421
2386 const body = sema.code.extra[extra_index..][0..body_len];2422 const body = sema.code.extra[extra_index..][0..body_len];
2387 if (fields_len == 0) {2423 if (fields_len == 0) {
2388 assert(body.len == 0);2424 assert(body.len == 0);
2389 if (tag_type_ref != .none) {2425 if (tag_type_ref != .none) {
2390 // TODO better source location2426 const ty = try sema.resolveType(block, tag_ty_src, tag_type_ref);
2391 const ty = try sema.resolveType(block, src, tag_type_ref);2427 if (ty.zigTypeTag() != .Int and ty.zigTypeTag() != .ComptimeInt) {
2428 return sema.fail(block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(sema.mod)});
2429 }
2392 enum_obj.tag_ty = try ty.copy(new_decl_arena_allocator);2430 enum_obj.tag_ty = try ty.copy(new_decl_arena_allocator);
2393 enum_obj.tag_ty_inferred = false;2431 enum_obj.tag_ty_inferred = false;
2394 }2432 }
2395 try new_decl.finalizeNewArena(&new_decl_arena);2433 return decl_val;
2396 return sema.analyzeDeclVal(block, src, new_decl_index);
2397 }2434 }
2398 extra_index += body.len;2435 extra_index += body.len;
23992436
...@@ -2446,13 +2483,15 @@ fn zirEnumDecl(...@@ -2446,13 +2483,15 @@ fn zirEnumDecl(
2446 try wip_captures.finalize();2483 try wip_captures.finalize();
24472484
2448 if (tag_type_ref != .none) {2485 if (tag_type_ref != .none) {
2449 // TODO better source location2486 const ty = try sema.resolveType(block, tag_ty_src, tag_type_ref);
2450 const ty = try sema.resolveType(block, src, tag_type_ref);2487 if (ty.zigTypeTag() != .Int and ty.zigTypeTag() != .ComptimeInt) {
2451 enum_obj.tag_ty = try ty.copy(new_decl_arena_allocator);2488 return sema.fail(block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(sema.mod)});
2489 }
2490 enum_obj.tag_ty = try ty.copy(decl_arena_allocator);
2452 enum_obj.tag_ty_inferred = false;2491 enum_obj.tag_ty_inferred = false;
2453 } else {2492 } else {
2454 const bits = std.math.log2_int_ceil(usize, fields_len);2493 const bits = std.math.log2_int_ceil(usize, fields_len);
2455 enum_obj.tag_ty = try Type.Tag.int_unsigned.create(new_decl_arena_allocator, bits);2494 enum_obj.tag_ty = try Type.Tag.int_unsigned.create(decl_arena_allocator, bits);
2456 enum_obj.tag_ty_inferred = true;2495 enum_obj.tag_ty_inferred = true;
2457 }2496 }
2458 }2497 }
...@@ -2463,12 +2502,12 @@ fn zirEnumDecl(...@@ -2463,12 +2502,12 @@ fn zirEnumDecl(
2463 }2502 }
2464 }2503 }
24652504
2466 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);2505 try enum_obj.fields.ensureTotalCapacity(decl_arena_allocator, fields_len);
2467 const any_values = for (sema.code.extra[body_end..][0..bit_bags_count]) |bag| {2506 const any_values = for (sema.code.extra[body_end..][0..bit_bags_count]) |bag| {
2468 if (bag != 0) break true;2507 if (bag != 0) break true;
2469 } else false;2508 } else false;
2470 if (any_values) {2509 if (any_values) {
2471 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{2510 try enum_obj.values.ensureTotalCapacityContext(decl_arena_allocator, fields_len, .{
2472 .ty = enum_obj.tag_ty,2511 .ty = enum_obj.tag_ty,
2473 .mod = mod,2512 .mod = mod,
2474 });2513 });
...@@ -2493,7 +2532,7 @@ fn zirEnumDecl(...@@ -2493,7 +2532,7 @@ fn zirEnumDecl(
2493 extra_index += 1;2532 extra_index += 1;
24942533
2495 // This string needs to outlive the ZIR code.2534 // This string needs to outlive the ZIR code.
2496 const field_name = try new_decl_arena_allocator.dupe(u8, field_name_zir);2535 const field_name = try decl_arena_allocator.dupe(u8, field_name_zir);
24972536
2498 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);2537 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);
2499 if (gop.found_existing) {2538 if (gop.found_existing) {
...@@ -2515,9 +2554,9 @@ fn zirEnumDecl(...@@ -2515,9 +2554,9 @@ fn zirEnumDecl(
2515 // TODO: if we need to report an error here, use a source location2554 // TODO: if we need to report an error here, use a source location
2516 // that points to this default value expression rather than the struct.2555 // that points to this default value expression rather than the struct.
2517 // But only resolve the source location if we need to emit a compile error.2556 // But only resolve the source location if we need to emit a compile error.
2518 const tag_val = (try sema.resolveInstConst(block, src, tag_val_ref)).val;2557 const tag_val = (try sema.resolveInstConst(block, src, tag_val_ref, "enum tag value must be comptime known")).val;
2519 last_tag_val = tag_val;2558 last_tag_val = tag_val;
2520 const copied_tag_val = try tag_val.copy(new_decl_arena_allocator);2559 const copied_tag_val = try tag_val.copy(decl_arena_allocator);
2521 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{2560 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{
2522 .ty = enum_obj.tag_ty,2561 .ty = enum_obj.tag_ty,
2523 .mod = mod,2562 .mod = mod,
...@@ -2528,16 +2567,14 @@ fn zirEnumDecl(...@@ -2528,16 +2567,14 @@ fn zirEnumDecl(
2528 else2567 else
2529 Value.zero;2568 Value.zero;
2530 last_tag_val = tag_val;2569 last_tag_val = tag_val;
2531 const copied_tag_val = try tag_val.copy(new_decl_arena_allocator);2570 const copied_tag_val = try tag_val.copy(decl_arena_allocator);
2532 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{2571 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{
2533 .ty = enum_obj.tag_ty,2572 .ty = enum_obj.tag_ty,
2534 .mod = mod,2573 .mod = mod,
2535 });2574 });
2536 }2575 }
2537 }2576 }
25382577 return decl_val;
2539 try new_decl.finalizeNewArena(&new_decl_arena);
2540 return sema.analyzeDeclVal(block, src, new_decl_index);
2541}2578}
25422579
2543fn zirUnionDecl(2580fn zirUnionDecl(
...@@ -2738,7 +2775,6 @@ fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -2738,7 +2775,6 @@ fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
27382775
2739 const inst_data = sema.code.instructions.items(.data)[inst].node;2776 const inst_data = sema.code.instructions.items(.data)[inst].node;
2740 const src = LazySrcLoc.nodeOffset(inst_data);2777 const src = LazySrcLoc.nodeOffset(inst_data);
2741 try sema.requireFunctionBlock(block, src);
27422778
2743 if (block.is_comptime or try sema.typeRequiresComptime(block, src, sema.fn_ret_ty)) {2779 if (block.is_comptime or try sema.typeRequiresComptime(block, src, sema.fn_ret_ty)) {
2744 const fn_ret_ty = try sema.resolveTypeFields(block, src, sema.fn_ret_ty);2780 const fn_ret_ty = try sema.resolveTypeFields(block, src, sema.fn_ret_ty);
...@@ -2770,16 +2806,6 @@ fn zirRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -2770,16 +2806,6 @@ fn zirRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
2770 return sema.analyzeRef(block, inst_data.src(), operand);2806 return sema.analyzeRef(block, inst_data.src(), operand);
2771}2807}
27722808
2773fn zirRetType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
2774 const tracy = trace(@src());
2775 defer tracy.end();
2776
2777 const inst_data = sema.code.instructions.items(.data)[inst].node;
2778 const src = LazySrcLoc.nodeOffset(inst_data);
2779 try sema.requireFunctionBlock(block, src);
2780 return sema.addType(sema.fn_ret_ty);
2781}
2782
2783fn zirEnsureResultUsed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {2809fn zirEnsureResultUsed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
2784 const tracy = trace(@src());2810 const tracy = trace(@src());
2785 defer tracy.end();2811 defer tracy.end();
...@@ -2925,7 +2951,7 @@ fn zirAllocExtended(...@@ -2925,7 +2951,7 @@ fn zirAllocExtended(
2925 try sema.validateVarType(block, ty_src, var_ty, false);2951 try sema.validateVarType(block, ty_src, var_ty, false);
2926 }2952 }
2927 const target = sema.mod.getTarget();2953 const target = sema.mod.getTarget();
2928 try sema.requireRuntimeBlock(block, src);2954 try sema.requireFunctionBlock(block, src);
2929 try sema.resolveTypeLayout(block, src, var_ty);2955 try sema.resolveTypeLayout(block, src, var_ty);
2930 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{2956 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
2931 .pointee_type = var_ty,2957 .pointee_type = var_ty,
...@@ -3024,7 +3050,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3024,7 +3050,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
3024 return sema.addConstant(const_ptr_ty, val);3050 return sema.addConstant(const_ptr_ty, val);
3025 }3051 }
30263052
3027 try sema.requireRuntimeBlock(block, src);3053 try sema.requireFunctionBlock(block, src);
3028 return block.addBitCast(const_ptr_ty, alloc);3054 return block.addBitCast(const_ptr_ty, alloc);
3029}3055}
30303056
...@@ -3061,7 +3087,7 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -3061,7 +3087,7 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
3061 .pointee_type = var_ty,3087 .pointee_type = var_ty,
3062 .@"addrspace" = target_util.defaultAddressSpace(target, .local),3088 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
3063 });3089 });
3064 try sema.requireRuntimeBlock(block, var_decl_src);3090 try sema.requireFunctionBlock(block, var_decl_src);
3065 try sema.queueFullTypeResolution(var_ty);3091 try sema.queueFullTypeResolution(var_ty);
3066 return block.addTy(.alloc, ptr_type);3092 return block.addTy(.alloc, ptr_type);
3067}3093}
...@@ -3083,7 +3109,7 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -3083,7 +3109,7 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
3083 .pointee_type = var_ty,3109 .pointee_type = var_ty,
3084 .@"addrspace" = target_util.defaultAddressSpace(target, .local),3110 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
3085 });3111 });
3086 try sema.requireRuntimeBlock(block, var_decl_src);3112 try sema.requireFunctionBlock(block, var_decl_src);
3087 try sema.queueFullTypeResolution(var_ty);3113 try sema.queueFullTypeResolution(var_ty);
3088 return block.addTy(.alloc, ptr_type);3114 return block.addTy(.alloc, ptr_type);
3089}3115}
...@@ -3272,7 +3298,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -3272,7 +3298,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
3272 return;3298 return;
3273 }3299 }
32743300
3275 try sema.requireRuntimeBlock(block, src);3301 try sema.requireFunctionBlock(block, src);
3276 try sema.queueFullTypeResolution(final_elem_ty);3302 try sema.queueFullTypeResolution(final_elem_ty);
32773303
3278 // Change it to a normal alloc.3304 // Change it to a normal alloc.
...@@ -3593,7 +3619,7 @@ fn validateUnionInit(...@@ -3593,7 +3619,7 @@ fn validateUnionInit(
3593 return;3619 return;
3594 }3620 }
35953621
3596 try sema.requireRuntimeBlock(block, init_src);3622 try sema.requireFunctionBlock(block, init_src);
3597 const new_tag = try sema.addConstant(union_obj.tag_ty, tag_val);3623 const new_tag = try sema.addConstant(union_obj.tag_ty, tag_val);
3598 _ = try block.addBinOp(.set_union_tag, union_ptr, new_tag);3624 _ = try block.addBinOp(.set_union_tag, union_ptr, new_tag);
3599}3625}
...@@ -3859,7 +3885,7 @@ fn zirValidateArrayInit(...@@ -3859,7 +3885,7 @@ fn zirValidateArrayInit(
3859 // any ZIR instructions at comptime; we need to do that here.3885 // any ZIR instructions at comptime; we need to do that here.
3860 if (array_ty.sentinel()) |sentinel_val| {3886 if (array_ty.sentinel()) |sentinel_val| {
3861 const array_len_ref = try sema.addIntUnsigned(Type.usize, array_len);3887 const array_len_ref = try sema.addIntUnsigned(Type.usize, array_len);
3862 const sentinel_ptr = try sema.elemPtrArray(block, init_src, array_ptr, init_src, array_len_ref, true);3888 const sentinel_ptr = try sema.elemPtrArray(block, init_src, init_src, array_ptr, init_src, array_len_ref, true);
3863 const sentinel = try sema.addConstant(array_ty.childType(), sentinel_val);3889 const sentinel = try sema.addConstant(array_ty.childType(), sentinel_val);
3864 try sema.storePtr2(block, init_src, sentinel_ptr, init_src, sentinel, init_src, .store);3890 try sema.storePtr2(block, init_src, sentinel_ptr, init_src, sentinel, init_src, .store);
3865 }3891 }
...@@ -4207,10 +4233,8 @@ fn storeToInferredAllocComptime(...@@ -4207,10 +4233,8 @@ fn storeToInferredAllocComptime(
4207 const operand_ty = sema.typeOf(operand);4233 const operand_ty = sema.typeOf(operand);
4208 // There will be only one store_to_inferred_ptr because we are running at comptime.4234 // There will be only one store_to_inferred_ptr because we are running at comptime.
4209 // The alloc will turn into a Decl.4235 // The alloc will turn into a Decl.
4210 if (try sema.resolveMaybeUndefValAllowVariables(block, src, operand)) |operand_val| {4236 if (try sema.resolveMaybeUndefValAllowVariables(block, src, operand)) |operand_val| store: {
4211 if (operand_val.tag() == .variable) {4237 if (operand_val.tag() == .variable) break :store;
4212 return sema.failWithNeededComptime(block, src);
4213 }
4214 var anon_decl = try block.startAnonDecl(src);4238 var anon_decl = try block.startAnonDecl(src);
4215 defer anon_decl.deinit();4239 defer anon_decl.deinit();
4216 iac.data.decl_index = try anon_decl.finish(4240 iac.data.decl_index = try anon_decl.finish(
...@@ -4219,15 +4243,15 @@ fn storeToInferredAllocComptime(...@@ -4219,15 +4243,15 @@ fn storeToInferredAllocComptime(
4219 iac.data.alignment,4243 iac.data.alignment,
4220 );4244 );
4221 return;4245 return;
4222 } else {
4223 return sema.failWithNeededComptime(block, src);
4224 }4246 }
4247
4248 return sema.failWithNeededComptime(block, src, "value being stored to a comptime variable must be comptime known");
4225}4249}
42264250
4227fn zirSetEvalBranchQuota(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {4251fn zirSetEvalBranchQuota(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
4228 const inst_data = sema.code.instructions.items(.data)[inst].un_node;4252 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
4229 const src = inst_data.src();4253 const src = inst_data.src();
4230 const quota = @intCast(u32, try sema.resolveInt(block, src, inst_data.operand, Type.u32));4254 const quota = @intCast(u32, try sema.resolveInt(block, src, inst_data.operand, Type.u32, "eval branch quota must be comptime known"));
4231 sema.branch_quota = @maximum(sema.branch_quota, quota);4255 sema.branch_quota = @maximum(sema.branch_quota, quota);
4232}4256}
42334257
...@@ -4282,7 +4306,7 @@ fn zirParamType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -4282,7 +4306,7 @@ fn zirParamType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
4282 var param_index = inst_data.param_index;4306 var param_index = inst_data.param_index;
42834307
4284 const fn_ty = if (callee_ty.tag() == .bound_fn) fn_ty: {4308 const fn_ty = if (callee_ty.tag() == .bound_fn) fn_ty: {
4285 const bound_fn_val = try sema.resolveConstValue(block, callee_src, callee);4309 const bound_fn_val = try sema.resolveConstValue(block, .unneeded, callee, undefined);
4286 const bound_fn = bound_fn_val.castTag(.bound_fn).?.data;4310 const bound_fn = bound_fn_val.castTag(.bound_fn).?.data;
4287 const fn_ty = sema.typeOf(bound_fn.func_inst);4311 const fn_ty = sema.typeOf(bound_fn.func_inst);
4288 param_index += 1;4312 param_index += 1;
...@@ -4417,7 +4441,7 @@ fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -4417,7 +4441,7 @@ fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
4417 const inst_data = sema.code.instructions.items(.data)[inst].un_node;4441 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
4418 const src = inst_data.src();4442 const src = inst_data.src();
4419 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };4443 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
4420 const msg = try sema.resolveConstString(block, operand_src, inst_data.operand);4444 const msg = try sema.resolveConstString(block, operand_src, inst_data.operand, "compile error string must be comptime known");
4421 return sema.fail(block, src, "{s}", .{msg});4445 return sema.fail(block, src, "{s}", .{msg});
4422}4446}
44234447
...@@ -4466,7 +4490,7 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index, force_comptime: bo...@@ -4466,7 +4490,7 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index, force_comptime: bo
4466 if (block.is_comptime or force_comptime) {4490 if (block.is_comptime or force_comptime) {
4467 return sema.fail(block, src, "encountered @panic at comptime", .{});4491 return sema.fail(block, src, "encountered @panic at comptime", .{});
4468 }4492 }
4469 try sema.requireRuntimeBlock(block, src);4493 try sema.requireFunctionBlock(block, src);
4470 return sema.panicWithMsg(block, src, msg_inst);4494 return sema.panicWithMsg(block, src, msg_inst);
4471}4495}
44724496
...@@ -4854,7 +4878,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -4854,7 +4878,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
4854 const src = inst_data.src();4878 const src = inst_data.src();
4855 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };4879 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
4856 const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };4880 const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
4857 const operand = try sema.resolveInstConst(block, operand_src, extra.operand);4881 const operand = try sema.resolveInstConst(block, operand_src, extra.operand, "export target must be comptime known");
4858 const options = try sema.resolveExportOptions(block, options_src, extra.options);4882 const options = try sema.resolveExportOptions(block, options_src, extra.options);
4859 const decl_index = switch (operand.val.tag()) {4883 const decl_index = switch (operand.val.tag()) {
4860 .function => operand.val.castTag(.function).?.data.owner_decl,4884 .function => operand.val.castTag(.function).?.data.owner_decl,
...@@ -4989,7 +5013,7 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -4989,7 +5013,7 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
4989fn zirSetCold(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {5013fn zirSetCold(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
4990 const inst_data = sema.code.instructions.items(.data)[inst].un_node;5014 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
4991 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };5015 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
4992 const is_cold = try sema.resolveConstBool(block, operand_src, inst_data.operand);5016 const is_cold = try sema.resolveConstBool(block, operand_src, inst_data.operand, "operand to @setCold must be comptime known");
4993 const func = sema.func orelse return; // does nothing outside a function5017 const func = sema.func orelse return; // does nothing outside a function
4994 func.is_cold = is_cold;5018 func.is_cold = is_cold;
4995}5019}
...@@ -4997,7 +5021,7 @@ fn zirSetCold(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi...@@ -4997,7 +5021,7 @@ fn zirSetCold(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
4997fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {5021fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
4998 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;5022 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
4999 const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };5023 const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
5000 const float_mode = try sema.resolveBuiltinEnum(block, src, extra.operand, "FloatMode");5024 const float_mode = try sema.resolveBuiltinEnum(block, src, extra.operand, "FloatMode", "operand to @setFloatMode must be comptime known");
5001 switch (float_mode) {5025 switch (float_mode) {
5002 .Strict => return,5026 .Strict => return,
5003 .Optimized => {5027 .Optimized => {
...@@ -5009,7 +5033,7 @@ fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -5009,7 +5033,7 @@ fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
5009fn zirSetRuntimeSafety(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {5033fn zirSetRuntimeSafety(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
5010 const inst_data = sema.code.instructions.items(.data)[inst].un_node;5034 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
5011 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };5035 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
5012 block.want_safety = try sema.resolveConstBool(block, operand_src, inst_data.operand);5036 block.want_safety = try sema.resolveConstBool(block, operand_src, inst_data.operand, "operand to @setRuntimeSafety must be comptime known");
5013}5037}
50145038
5015fn zirFence(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {5039fn zirFence(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
...@@ -5017,7 +5041,7 @@ fn zirFence(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) Co...@@ -5017,7 +5041,7 @@ fn zirFence(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) Co
50175041
5018 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;5042 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
5019 const order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };5043 const order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
5020 const order = try sema.resolveAtomicOrder(block, order_src, extra.operand);5044 const order = try sema.resolveAtomicOrder(block, order_src, extra.operand, "atomic order of @fence must be comptime known");
50215045
5022 if (@enumToInt(order) < @enumToInt(std.builtin.AtomicOrder.Acquire)) {5046 if (@enumToInt(order) < @enumToInt(std.builtin.AtomicOrder.Acquire)) {
5023 return sema.fail(block, order_src, "atomic ordering must be Acquire or stricter", .{});5047 return sema.fail(block, order_src, "atomic ordering must be Acquire or stricter", .{});
...@@ -5292,7 +5316,7 @@ fn zirCall(...@@ -5292,7 +5316,7 @@ fn zirCall(
52925316
5293 // Desugar bound functions here5317 // Desugar bound functions here
5294 if (func_type.tag() == .bound_fn) {5318 if (func_type.tag() == .bound_fn) {
5295 const bound_func = try sema.resolveValue(block, func_src, func);5319 const bound_func = try sema.resolveValue(block, .unneeded, func, undefined);
5296 const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data;5320 const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data;
5297 func = bound_data.func_inst;5321 func = bound_data.func_inst;
5298 resolved_args = try sema.arena.alloc(Air.Inst.Ref, args.len + 1);5322 resolved_args = try sema.arena.alloc(Air.Inst.Ref, args.len + 1);
...@@ -5489,7 +5513,8 @@ fn analyzeCall(...@@ -5489,7 +5513,8 @@ fn analyzeCall(
5489 }5513 }
54905514
5491 const result: Air.Inst.Ref = if (is_inline_call) res: {5515 const result: Air.Inst.Ref = if (is_inline_call) res: {
5492 const func_val = try sema.resolveConstValue(block, func_src, func);5516 // TODO explain why function is being called at comptime
5517 const func_val = try sema.resolveConstValue(block, func_src, func, "function being called at comptime must be comptime known");
5493 const module_fn = switch (func_val.tag()) {5518 const module_fn = switch (func_val.tag()) {
5494 .decl_ref => mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data,5519 .decl_ref => mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data,
5495 .function => func_val.castTag(.function).?.data,5520 .function => func_val.castTag(.function).?.data,
...@@ -5588,82 +5613,39 @@ fn analyzeCall(...@@ -5588,82 +5613,39 @@ fn analyzeCall(
5588 // which means its parameter type expressions must be resolved in order and used5613 // which means its parameter type expressions must be resolved in order and used
5589 // to successively coerce the arguments.5614 // to successively coerce the arguments.
5590 const fn_info = sema.code.getFnInfo(module_fn.zir_body_inst);5615 const fn_info = sema.code.getFnInfo(module_fn.zir_body_inst);
5591 const zir_tags = sema.code.instructions.items(.tag);
5592 var arg_i: usize = 0;5616 var arg_i: usize = 0;
5593 for (fn_info.param_body) |inst| switch (zir_tags[inst]) {5617 for (fn_info.param_body) |inst| {
5594 .param, .param_comptime => {5618 sema.analyzeInlineCallArg(
5595 // Evaluate the parameter type expression now that previous ones have5619 &child_block,
5596 // been mapped, and coerce the corresponding argument to it.5620 .unneeded,
5597 const pl_tok = sema.code.instructions.items(.data)[inst].pl_tok;5621 inst,
5598 const param_src = pl_tok.src();5622 new_fn_info,
5599 const extra = sema.code.extraData(Zir.Inst.Param, pl_tok.payload_index);5623 &arg_i,
5600 const param_body = sema.code.extra[extra.end..][0..extra.data.body_len];5624 uncasted_args,
5601 const param_ty_inst = try sema.resolveBody(&child_block, param_body, inst);5625 is_comptime_call,
5602 const param_ty = try sema.analyzeAsType(&child_block, param_src, param_ty_inst);5626 &should_memoize,
5603 new_fn_info.param_types[arg_i] = param_ty;5627 memoized_call_key,
5604 const arg_src = call_src; // TODO: better source location5628 ) catch |err| switch (err) {
5605 const casted_arg = try sema.coerce(&child_block, param_ty, uncasted_args[arg_i], arg_src);5629 error.NeededSourceLocation => {
5606 try sema.inst_map.putNoClobber(gpa, inst, casted_arg);5630 const decl = sema.mod.declPtr(block.src_decl);
56075631 try sema.analyzeInlineCallArg(
5608 if (is_comptime_call) {5632 // Intentionally use the wrong block here since we know it's
5609 const arg_val = try sema.resolveConstMaybeUndefVal(&child_block, arg_src, casted_arg);5633 // going to fail and `argSrc` is relative to `block.src_decl`.
5610 switch (arg_val.tag()) {5634 block,
5611 .generic_poison, .generic_poison_type => {5635 Module.argSrc(call_src.node_offset.x, sema.gpa, decl, arg_i),
5612 // This function is currently evaluated as part of an as-of-yet unresolvable5636 inst,
5613 // parameter or return type.5637 new_fn_info,
5614 return error.GenericPoison;5638 &arg_i,
5615 },5639 uncasted_args,
5616 else => {5640 is_comptime_call,
5617 // Needed so that lazy values do not trigger5641 &should_memoize,
5618 // assertion due to type not being resolved5642 memoized_call_key,
5619 // when the hash function is called.5643 );
5620 try sema.resolveLazyValue(&child_block, arg_src, arg_val);5644 return error.AnalysisFail;
5621 },5645 },
5622 }5646 else => |e| return e,
5623 should_memoize = should_memoize and !arg_val.canMutateComptimeVarState();5647 };
5624 memoized_call_key.args[arg_i] = .{5648 }
5625 .ty = param_ty,
5626 .val = arg_val,
5627 };
5628 }
5629
5630 arg_i += 1;
5631 continue;
5632 },
5633 .param_anytype, .param_anytype_comptime => {
5634 // No coercion needed.
5635 const uncasted_arg = uncasted_args[arg_i];
5636 new_fn_info.param_types[arg_i] = sema.typeOf(uncasted_arg);
5637 try sema.inst_map.putNoClobber(gpa, inst, uncasted_arg);
5638
5639 if (is_comptime_call) {
5640 const arg_src = call_src; // TODO: better source location
5641 const arg_val = try sema.resolveConstMaybeUndefVal(&child_block, arg_src, uncasted_arg);
5642 switch (arg_val.tag()) {
5643 .generic_poison, .generic_poison_type => {
5644 // This function is currently evaluated as part of an as-of-yet unresolvable
5645 // parameter or return type.
5646 return error.GenericPoison;
5647 },
5648 else => {
5649 // Needed so that lazy values do not trigger
5650 // assertion due to type not being resolved
5651 // when the hash function is called.
5652 try sema.resolveLazyValue(&child_block, arg_src, arg_val);
5653 },
5654 }
5655 should_memoize = should_memoize and !arg_val.canMutateComptimeVarState();
5656 memoized_call_key.args[arg_i] = .{
5657 .ty = sema.typeOf(uncasted_arg),
5658 .val = arg_val,
5659 };
5660 }
5661
5662 arg_i += 1;
5663 continue;
5664 },
5665 else => continue,
5666 };
56675649
5668 // In case it is a generic function with an expression for the return type that depends5650 // In case it is a generic function with an expression for the return type that depends
5669 // on parameters, we must now do the same for the return type as we just did with5651 // on parameters, we must now do the same for the return type as we just did with
...@@ -5719,6 +5701,7 @@ fn analyzeCall(...@@ -5719,6 +5701,7 @@ fn analyzeCall(
5719 if (!is_comptime_call) {5701 if (!is_comptime_call) {
5720 try sema.emitDbgInline(block, parent_func.?, module_fn, new_func_resolved_ty, .dbg_inline_begin);5702 try sema.emitDbgInline(block, parent_func.?, module_fn, new_func_resolved_ty, .dbg_inline_begin);
57215703
5704 const zir_tags = sema.code.instructions.items(.tag);
5722 for (fn_info.param_body) |param| switch (zir_tags[param]) {5705 for (fn_info.param_body) |param| switch (zir_tags[param]) {
5723 .param, .param_comptime => {5706 .param, .param_comptime => {
5724 const inst_data = sema.code.instructions.items(.data)[param].pl_tok;5707 const inst_data = sema.code.instructions.items(.data)[param].pl_tok;
...@@ -5764,7 +5747,7 @@ fn analyzeCall(...@@ -5764,7 +5747,7 @@ fn analyzeCall(
5764 }5747 }
57655748
5766 if (should_memoize and is_comptime_call) {5749 if (should_memoize and is_comptime_call) {
5767 const result_val = try sema.resolveConstMaybeUndefVal(block, call_src, result);5750 const result_val = try sema.resolveConstMaybeUndefVal(block, .unneeded, result, undefined);
57685751
5769 // TODO: check whether any external comptime memory was mutated by the5752 // TODO: check whether any external comptime memory was mutated by the
5770 // comptime function call. If so, then do not memoize the call here.5753 // comptime function call. If so, then do not memoize the call here.
...@@ -5795,15 +5778,30 @@ fn analyzeCall(...@@ -5795,15 +5778,30 @@ fn analyzeCall(
5795 break :res res2;5778 break :res res2;
5796 } else res: {5779 } else res: {
5797 assert(!func_ty_info.is_generic);5780 assert(!func_ty_info.is_generic);
5798 try sema.requireRuntimeBlock(block, call_src);5781 try sema.requireFunctionBlock(block, call_src);
57995782
5800 const args = try sema.arena.alloc(Air.Inst.Ref, uncasted_args.len);5783 const args = try sema.arena.alloc(Air.Inst.Ref, uncasted_args.len);
5801 for (uncasted_args) |uncasted_arg, i| {5784 for (uncasted_args) |uncasted_arg, i| {
5802 const arg_src = call_src; // TODO: better source location
5803 if (i < fn_params_len) {5785 if (i < fn_params_len) {
5804 const param_ty = func_ty.fnParamType(i);5786 const param_ty = func_ty.fnParamType(i);
5805 try sema.resolveTypeFully(block, arg_src, param_ty);5787 args[i] = sema.analyzeCallArg(
5806 args[i] = try sema.coerce(block, param_ty, uncasted_arg, arg_src);5788 block,
5789 .unneeded,
5790 param_ty,
5791 uncasted_arg,
5792 ) catch |err| switch (err) {
5793 error.NeededSourceLocation => {
5794 const decl = sema.mod.declPtr(block.src_decl);
5795 _ = try sema.analyzeCallArg(
5796 block,
5797 Module.argSrc(call_src.node_offset.x, sema.gpa, decl, i),
5798 param_ty,
5799 uncasted_arg,
5800 );
5801 return error.AnalysisFail;
5802 },
5803 else => |e| return e,
5804 };
5807 } else {5805 } else {
5808 args[i] = uncasted_arg;5806 args[i] = uncasted_arg;
5809 }5807 }
...@@ -5835,6 +5833,136 @@ fn analyzeCall(...@@ -5835,6 +5833,136 @@ fn analyzeCall(
5835 return result;5833 return result;
5836}5834}
58375835
5836fn analyzeInlineCallArg(
5837 sema: *Sema,
5838 block: *Block,
5839 arg_src: LazySrcLoc,
5840 inst: Zir.Inst.Index,
5841 new_fn_info: Type.Payload.Function.Data,
5842 arg_i: *usize,
5843 uncasted_args: []const Air.Inst.Ref,
5844 is_comptime_call: bool,
5845 should_memoize: *bool,
5846 memoized_call_key: Module.MemoizedCall.Key,
5847) !void {
5848 const zir_tags = sema.code.instructions.items(.tag);
5849 switch (zir_tags[inst]) {
5850 .param, .param_comptime => {
5851 // Evaluate the parameter type expression now that previous ones have
5852 // been mapped, and coerce the corresponding argument to it.
5853 const pl_tok = sema.code.instructions.items(.data)[inst].pl_tok;
5854 const param_src = pl_tok.src();
5855 const extra = sema.code.extraData(Zir.Inst.Param, pl_tok.payload_index);
5856 const param_body = sema.code.extra[extra.end..][0..extra.data.body_len];
5857 const param_ty_inst = try sema.resolveBody(block, param_body, inst);
5858 const param_ty = try sema.analyzeAsType(block, param_src, param_ty_inst);
5859 new_fn_info.param_types[arg_i.*] = param_ty;
5860 const uncasted_arg = uncasted_args[arg_i.*];
5861 if (try sema.typeRequiresComptime(block, arg_src, param_ty)) {
5862 _ = try sema.resolveConstMaybeUndefVal(block, arg_src, uncasted_arg, "argument to parameter with comptime only type must be comptime known");
5863 }
5864 const casted_arg = try sema.coerce(block, param_ty, uncasted_arg, arg_src);
5865 try sema.inst_map.putNoClobber(sema.gpa, inst, casted_arg);
5866
5867 if (is_comptime_call) {
5868 // TODO explain why function is being called at comptime
5869 const arg_val = try sema.resolveConstMaybeUndefVal(block, arg_src, casted_arg, "argument to function being called at comptime must be comptime known");
5870 switch (arg_val.tag()) {
5871 .generic_poison, .generic_poison_type => {
5872 // This function is currently evaluated as part of an as-of-yet unresolvable
5873 // parameter or return type.
5874 return error.GenericPoison;
5875 },
5876 else => {
5877 // Needed so that lazy values do not trigger
5878 // assertion due to type not being resolved
5879 // when the hash function is called.
5880 try sema.resolveLazyValue(block, arg_src, arg_val);
5881 },
5882 }
5883 should_memoize.* = should_memoize.* and !arg_val.canMutateComptimeVarState();
5884 memoized_call_key.args[arg_i.*] = .{
5885 .ty = param_ty,
5886 .val = arg_val,
5887 };
5888 }
5889
5890 arg_i.* += 1;
5891 },
5892 .param_anytype, .param_anytype_comptime => {
5893 // No coercion needed.
5894 const uncasted_arg = uncasted_args[arg_i.*];
5895 new_fn_info.param_types[arg_i.*] = sema.typeOf(uncasted_arg);
5896 try sema.inst_map.putNoClobber(sema.gpa, inst, uncasted_arg);
5897
5898 if (is_comptime_call) {
5899 // TODO explain why function is being called at comptime
5900 const arg_val = try sema.resolveConstMaybeUndefVal(block, arg_src, uncasted_arg, "argument to function being called at comptime must be comptime known");
5901 switch (arg_val.tag()) {
5902 .generic_poison, .generic_poison_type => {
5903 // This function is currently evaluated as part of an as-of-yet unresolvable
5904 // parameter or return type.
5905 return error.GenericPoison;
5906 },
5907 else => {
5908 // Needed so that lazy values do not trigger
5909 // assertion due to type not being resolved
5910 // when the hash function is called.
5911 try sema.resolveLazyValue(block, arg_src, arg_val);
5912 },
5913 }
5914 should_memoize.* = should_memoize.* and !arg_val.canMutateComptimeVarState();
5915 memoized_call_key.args[arg_i.*] = .{
5916 .ty = sema.typeOf(uncasted_arg),
5917 .val = arg_val,
5918 };
5919 }
5920
5921 arg_i.* += 1;
5922 },
5923 else => {},
5924 }
5925}
5926
5927fn analyzeCallArg(
5928 sema: *Sema,
5929 block: *Block,
5930 arg_src: LazySrcLoc,
5931 param_ty: Type,
5932 uncasted_arg: Air.Inst.Ref,
5933) !Air.Inst.Ref {
5934 try sema.resolveTypeFully(block, arg_src, param_ty);
5935 return sema.coerce(block, param_ty, uncasted_arg, arg_src);
5936}
5937
5938fn analyzeGenericCallArg(
5939 sema: *Sema,
5940 block: *Block,
5941 arg_src: LazySrcLoc,
5942 uncasted_arg: Air.Inst.Ref,
5943 comptime_arg: TypedValue,
5944 runtime_args: []Air.Inst.Ref,
5945 new_fn_info: Type.Payload.Function.Data,
5946 runtime_i: *u32,
5947) !void {
5948 const is_runtime = comptime_arg.val.tag() == .generic_poison and
5949 comptime_arg.ty.hasRuntimeBits() and
5950 !(try sema.typeRequiresComptime(block, arg_src, comptime_arg.ty));
5951 if (is_runtime) {
5952 const param_ty = new_fn_info.param_types[runtime_i.*];
5953 const casted_arg = try sema.coerce(block, param_ty, uncasted_arg, arg_src);
5954 try sema.queueFullTypeResolution(param_ty);
5955 runtime_args[runtime_i.*] = casted_arg;
5956 runtime_i.* += 1;
5957 }
5958}
5959
5960fn analyzeGenericCallArgVal(sema: *Sema, block: *Block, arg_src: LazySrcLoc, uncasted_arg: Air.Inst.Ref) !Value {
5961 const arg_val = try sema.resolveValue(block, arg_src, uncasted_arg, "parameter is comptime");
5962 try sema.resolveLazyValue(block, arg_src, arg_val);
5963 return arg_val;
5964}
5965
5838fn instantiateGenericCall(5966fn instantiateGenericCall(
5839 sema: *Sema,5967 sema: *Sema,
5840 block: *Block,5968 block: *Block,
...@@ -5849,7 +5977,7 @@ fn instantiateGenericCall(...@@ -5849,7 +5977,7 @@ fn instantiateGenericCall(
5849 const mod = sema.mod;5977 const mod = sema.mod;
5850 const gpa = sema.gpa;5978 const gpa = sema.gpa;
58515979
5852 const func_val = try sema.resolveConstValue(block, func_src, func);5980 const func_val = try sema.resolveConstValue(block, func_src, func, "generic function being called must be comptime known");
5853 const module_fn = switch (func_val.tag()) {5981 const module_fn = switch (func_val.tag()) {
5854 .function => func_val.castTag(.function).?.data,5982 .function => func_val.castTag(.function).?.data,
5855 .decl_ref => mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data,5983 .decl_ref => mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data,
...@@ -5900,10 +6028,16 @@ fn instantiateGenericCall(...@@ -5900,10 +6028,16 @@ fn instantiateGenericCall(
5900 }6028 }
59016029
5902 if (is_comptime) {6030 if (is_comptime) {
5903 const arg_src = call_src; // TODO better source location
5904 const arg_ty = sema.typeOf(uncasted_args[i]);6031 const arg_ty = sema.typeOf(uncasted_args[i]);
5905 const arg_val = try sema.resolveValue(block, arg_src, uncasted_args[i]);6032 const arg_val = sema.analyzeGenericCallArgVal(block, .unneeded, uncasted_args[i]) catch |err| switch (err) {
5906 try sema.resolveLazyValue(block, arg_src, arg_val);6033 error.NeededSourceLocation => {
6034 const decl = sema.mod.declPtr(block.src_decl);
6035 const arg_src = Module.argSrc(call_src.node_offset.x, sema.gpa, decl, i);
6036 _ = try sema.analyzeGenericCallArgVal(block, arg_src, uncasted_args[i]);
6037 return error.AnalysisFail;
6038 },
6039 else => |e| return e,
6040 };
5907 arg_val.hash(arg_ty, &hasher, mod);6041 arg_val.hash(arg_ty, &hasher, mod);
5908 if (is_anytype) {6042 if (is_anytype) {
5909 arg_ty.hashWithHasher(&hasher, mod);6043 arg_ty.hashWithHasher(&hasher, mod);
...@@ -6059,19 +6193,18 @@ fn instantiateGenericCall(...@@ -6059,19 +6193,18 @@ fn instantiateGenericCall(
6059 },6193 },
6060 else => continue,6194 else => continue,
6061 }6195 }
6062 const arg_src = call_src; // TODO: better source location
6063 const arg = uncasted_args[arg_i];6196 const arg = uncasted_args[arg_i];
6064 if (is_comptime) {6197 if (is_comptime) {
6065 if (try sema.resolveMaybeUndefVal(block, arg_src, arg)) |arg_val| {6198 if (try sema.resolveMaybeUndefVal(block, .unneeded, arg)) |arg_val| {
6066 const child_arg = try child_sema.addConstant(sema.typeOf(arg), arg_val);6199 const child_arg = try child_sema.addConstant(sema.typeOf(arg), arg_val);
6067 child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);6200 child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);
6068 } else {6201 } else {
6069 return sema.failWithNeededComptime(block, arg_src);6202 return sema.failWithNeededComptime(block, .unneeded, undefined);
6070 }6203 }
6071 } else if (is_anytype) {6204 } else if (is_anytype) {
6072 const arg_ty = sema.typeOf(arg);6205 const arg_ty = sema.typeOf(arg);
6073 if (try sema.typeRequiresComptime(block, arg_src, arg_ty)) {6206 if (try sema.typeRequiresComptime(block, .unneeded, arg_ty)) {
6074 const arg_val = try sema.resolveConstValue(block, arg_src, arg);6207 const arg_val = try sema.resolveConstValue(block, .unneeded, arg, undefined);
6075 const child_arg = try child_sema.addConstant(arg_ty, arg_val);6208 const child_arg = try child_sema.addConstant(arg_ty, arg_val);
6076 child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);6209 child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);
6077 } else {6210 } else {
...@@ -6093,7 +6226,7 @@ fn instantiateGenericCall(...@@ -6093,7 +6226,7 @@ fn instantiateGenericCall(
6093 }6226 }
6094 return err;6227 return err;
6095 };6228 };
6096 const new_func_val = child_sema.resolveConstValue(&child_block, .unneeded, new_func_inst) catch unreachable;6229 const new_func_val = child_sema.resolveConstValue(&child_block, .unneeded, new_func_inst, undefined) catch unreachable;
6097 const new_func = new_func_val.castTag(.function).?.data;6230 const new_func = new_func_val.castTag(.function).?.data;
6098 errdefer new_func.deinit(gpa);6231 errdefer new_func.deinit(gpa);
6099 assert(new_func == new_module_func);6232 assert(new_func == new_module_func);
...@@ -6129,8 +6262,7 @@ fn instantiateGenericCall(...@@ -6129,8 +6262,7 @@ fn instantiateGenericCall(
6129 const copied_arg_ty = try child_sema.typeOf(arg).copy(new_decl_arena_allocator);6262 const copied_arg_ty = try child_sema.typeOf(arg).copy(new_decl_arena_allocator);
6130 anytype_args[arg_i] = is_anytype;6263 anytype_args[arg_i] = is_anytype;
61316264
6132 const arg_src = call_src; // TODO: better source location6265 if (try sema.typeRequiresComptime(block, .unneeded, copied_arg_ty)) {
6133 if (try sema.typeRequiresComptime(block, arg_src, copied_arg_ty)) {
6134 is_comptime = true;6266 is_comptime = true;
6135 }6267 }
61366268
...@@ -6195,7 +6327,7 @@ fn instantiateGenericCall(...@@ -6195,7 +6327,7 @@ fn instantiateGenericCall(
6195 const callee_inst = try sema.analyzeDeclVal(block, func_src, callee.owner_decl);6327 const callee_inst = try sema.analyzeDeclVal(block, func_src, callee.owner_decl);
61966328
6197 // Make a runtime call to the new function, making sure to omit the comptime args.6329 // Make a runtime call to the new function, making sure to omit the comptime args.
6198 try sema.requireRuntimeBlock(block, call_src);6330 try sema.requireFunctionBlock(block, call_src);
61996331
6200 const comptime_args = callee.comptime_args.?;6332 const comptime_args = callee.comptime_args.?;
6201 const new_fn_info = mod.declPtr(callee.owner_decl).ty.fnInfo();6333 const new_fn_info = mod.declPtr(callee.owner_decl).ty.fnInfo();
...@@ -6209,18 +6341,30 @@ fn instantiateGenericCall(...@@ -6209,18 +6341,30 @@ fn instantiateGenericCall(
6209 .param_comptime, .param_anytype_comptime, .param, .param_anytype => {},6341 .param_comptime, .param_anytype_comptime, .param, .param_anytype => {},
6210 else => continue,6342 else => continue,
6211 }6343 }
6212 const arg_src = call_src; // TODO: better source location6344 sema.analyzeGenericCallArg(
6213 const is_runtime = comptime_args[total_i].val.tag() == .generic_poison and6345 block,
6214 comptime_args[total_i].ty.hasRuntimeBits() and6346 .unneeded,
6215 !(try sema.typeRequiresComptime(block, arg_src, comptime_args[total_i].ty));6347 uncasted_args[total_i],
6216 if (is_runtime) {6348 comptime_args[total_i],
6217 const param_ty = new_fn_info.param_types[runtime_i];6349 runtime_args,
6218 const uncasted_arg = uncasted_args[total_i];6350 new_fn_info,
6219 const casted_arg = try sema.coerce(block, param_ty, uncasted_arg, arg_src);6351 &runtime_i,
6220 try sema.queueFullTypeResolution(param_ty);6352 ) catch |err| switch (err) {
6221 runtime_args[runtime_i] = casted_arg;6353 error.NeededSourceLocation => {
6222 runtime_i += 1;6354 const decl = sema.mod.declPtr(block.src_decl);
6223 }6355 _ = try sema.analyzeGenericCallArg(
6356 block,
6357 Module.argSrc(call_src.node_offset.x, sema.gpa, decl, total_i),
6358 uncasted_args[total_i],
6359 comptime_args[total_i],
6360 runtime_args,
6361 new_fn_info,
6362 &runtime_i,
6363 );
6364 return error.AnalysisFail;
6365 },
6366 else => |e| return e,
6367 };
6224 total_i += 1;6368 total_i += 1;
6225 }6369 }
62266370
...@@ -6314,7 +6458,7 @@ fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -6314,7 +6458,7 @@ fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
6314 const elem_type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };6458 const elem_type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
6315 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };6459 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
6316 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;6460 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
6317 const len = try sema.resolveInt(block, len_src, extra.lhs, Type.u32);6461 const len = try sema.resolveInt(block, len_src, extra.lhs, Type.u32, "vector length must be comptime known");
6318 const elem_type = try sema.resolveType(block, elem_type_src, extra.rhs);6462 const elem_type = try sema.resolveType(block, elem_type_src, extra.rhs);
6319 try sema.checkVectorElemType(block, elem_type_src, elem_type);6463 try sema.checkVectorElemType(block, elem_type_src, elem_type);
6320 const vector_type = try Type.Tag.vector.create(sema.arena, .{6464 const vector_type = try Type.Tag.vector.create(sema.arena, .{
...@@ -6332,7 +6476,7 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -6332,7 +6476,7 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
6332 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;6476 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
6333 const len_src: LazySrcLoc = .{ .node_offset_array_type_len = inst_data.src_node };6477 const len_src: LazySrcLoc = .{ .node_offset_array_type_len = inst_data.src_node };
6334 const elem_src: LazySrcLoc = .{ .node_offset_array_type_elem = inst_data.src_node };6478 const elem_src: LazySrcLoc = .{ .node_offset_array_type_elem = inst_data.src_node };
6335 const len = try sema.resolveInt(block, len_src, extra.lhs, Type.usize);6479 const len = try sema.resolveInt(block, len_src, extra.lhs, Type.usize, "array length must be comptime known");
6336 const elem_type = try sema.resolveType(block, elem_src, extra.rhs);6480 const elem_type = try sema.resolveType(block, elem_src, extra.rhs);
6337 const array_ty = try Type.array(sema.arena, len, null, elem_type, sema.mod);6481 const array_ty = try Type.array(sema.arena, len, null, elem_type, sema.mod);
63386482
...@@ -6348,11 +6492,11 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -6348,11 +6492,11 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
6348 const len_src: LazySrcLoc = .{ .node_offset_array_type_len = inst_data.src_node };6492 const len_src: LazySrcLoc = .{ .node_offset_array_type_len = inst_data.src_node };
6349 const sentinel_src: LazySrcLoc = .{ .node_offset_array_type_sentinel = inst_data.src_node };6493 const sentinel_src: LazySrcLoc = .{ .node_offset_array_type_sentinel = inst_data.src_node };
6350 const elem_src: LazySrcLoc = .{ .node_offset_array_type_elem = inst_data.src_node };6494 const elem_src: LazySrcLoc = .{ .node_offset_array_type_elem = inst_data.src_node };
6351 const len = try sema.resolveInt(block, len_src, extra.len, Type.usize);6495 const len = try sema.resolveInt(block, len_src, extra.len, Type.usize, "array length must be comptime known");
6352 const elem_type = try sema.resolveType(block, elem_src, extra.elem_type);6496 const elem_type = try sema.resolveType(block, elem_src, extra.elem_type);
6353 const uncasted_sentinel = try sema.resolveInst(extra.sentinel);6497 const uncasted_sentinel = try sema.resolveInst(extra.sentinel);
6354 const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src);6498 const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src);
6355 const sentinel_val = try sema.resolveConstValue(block, sentinel_src, sentinel);6499 const sentinel_val = try sema.resolveConstValue(block, sentinel_src, sentinel, "array sentinel value must be comptime known");
6356 const array_ty = try Type.array(sema.arena, len, sentinel_val, elem_type, sema.mod);6500 const array_ty = try Type.array(sema.arena, len, sentinel_val, elem_type, sema.mod);
63576501
6358 return sema.addType(array_ty);6502 return sema.addType(array_ty);
...@@ -6452,7 +6596,7 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -6452,7 +6596,7 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
6452 }6596 }
6453 }6597 }
64546598
6455 try sema.requireRuntimeBlock(block, src);6599 try sema.requireRuntimeBlock(block, src, operand_src);
6456 return block.addBitCast(result_ty, operand);6600 return block.addBitCast(result_ty, operand);
6457}6601}
64586602
...@@ -6478,7 +6622,7 @@ fn zirIntToError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -6478,7 +6622,7 @@ fn zirIntToError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
6478 };6622 };
6479 return sema.addConstant(Type.anyerror, Value.initPayload(&payload.base));6623 return sema.addConstant(Type.anyerror, Value.initPayload(&payload.base));
6480 }6624 }
6481 try sema.requireRuntimeBlock(block, src);6625 try sema.requireRuntimeBlock(block, src, operand_src);
6482 if (block.wantSafety()) {6626 if (block.wantSafety()) {
6483 const is_lt_len = try block.addUnOp(.cmp_lt_errors_len, operand);6627 const is_lt_len = try block.addUnOp(.cmp_lt_errors_len, operand);
6484 try sema.addSafetyCheck(block, is_lt_len, .invalid_error_code);6628 try sema.addSafetyCheck(block, is_lt_len, .invalid_error_code);
...@@ -6598,7 +6742,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -6598,7 +6742,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
6598 return sema.addConstant(int_tag_ty, try val.copy(sema.arena));6742 return sema.addConstant(int_tag_ty, try val.copy(sema.arena));
6599 }6743 }
66006744
6601 try sema.requireRuntimeBlock(block, src);6745 try sema.requireRuntimeBlock(block, src, operand_src);
6602 return block.addBitCast(int_tag_ty, enum_tag);6746 return block.addBitCast(int_tag_ty, enum_tag);
6603}6747}
66046748
...@@ -6645,7 +6789,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -6645,7 +6789,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
6645 return sema.addConstant(dest_ty, int_val);6789 return sema.addConstant(dest_ty, int_val);
6646 }6790 }
66476791
6648 try sema.requireRuntimeBlock(block, src);6792 try sema.requireRuntimeBlock(block, src, operand_src);
6649 // TODO insert safety check to make sure the value matches an enum value6793 // TODO insert safety check to make sure the value matches an enum value
6650 return block.addTyOp(.intcast, dest_ty, operand);6794 return block.addTyOp(.intcast, dest_ty, operand);
6651}6795}
...@@ -6696,7 +6840,7 @@ fn analyzeOptionalPayloadPtr(...@@ -6696,7 +6840,7 @@ fn analyzeOptionalPayloadPtr(
6696 // If the pointer resulting from this function was stored at comptime,6840 // If the pointer resulting from this function was stored at comptime,
6697 // the optional non-null bit would be set that way. But in this case,6841 // the optional non-null bit would be set that way. But in this case,
6698 // we need to emit a runtime instruction to do it.6842 // we need to emit a runtime instruction to do it.
6699 try sema.requireRuntimeBlock(block, src);6843 try sema.requireFunctionBlock(block, src);
6700 _ = try block.addTyOp(.optional_payload_ptr_set, child_pointer, optional_ptr);6844 _ = try block.addTyOp(.optional_payload_ptr_set, child_pointer, optional_ptr);
6701 }6845 }
6702 return sema.addConstant(6846 return sema.addConstant(
...@@ -6722,7 +6866,7 @@ fn analyzeOptionalPayloadPtr(...@@ -6722,7 +6866,7 @@ fn analyzeOptionalPayloadPtr(
6722 }6866 }
6723 }6867 }
67246868
6725 try sema.requireRuntimeBlock(block, src);6869 try sema.requireRuntimeBlock(block, src, null);
6726 if (safety_check and block.wantSafety()) {6870 if (safety_check and block.wantSafety()) {
6727 const is_non_null = try block.addUnOp(.is_non_null_ptr, optional_ptr);6871 const is_non_null = try block.addUnOp(.is_non_null_ptr, optional_ptr);
6728 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);6872 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);
...@@ -6778,7 +6922,7 @@ fn zirOptionalPayload(...@@ -6778,7 +6922,7 @@ fn zirOptionalPayload(
6778 return sema.addConstant(result_ty, val);6922 return sema.addConstant(result_ty, val);
6779 }6923 }
67806924
6781 try sema.requireRuntimeBlock(block, src);6925 try sema.requireRuntimeBlock(block, src, null);
6782 if (safety_check and block.wantSafety()) {6926 if (safety_check and block.wantSafety()) {
6783 const is_non_null = try block.addUnOp(.is_non_null, operand);6927 const is_non_null = try block.addUnOp(.is_non_null, operand);
6784 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);6928 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);
...@@ -6827,7 +6971,7 @@ fn analyzeErrUnionPayload(...@@ -6827,7 +6971,7 @@ fn analyzeErrUnionPayload(
6827 return sema.addConstant(payload_ty, data);6971 return sema.addConstant(payload_ty, data);
6828 }6972 }
68296973
6830 try sema.requireRuntimeBlock(block, src);6974 try sema.requireRuntimeBlock(block, src, null);
68316975
6832 // If the error set has no fields then no safety check is needed.6976 // If the error set has no fields then no safety check is needed.
6833 if (safety_check and block.wantSafety() and6977 if (safety_check and block.wantSafety() and
...@@ -6887,7 +7031,7 @@ fn analyzeErrUnionPayloadPtr(...@@ -6887,7 +7031,7 @@ fn analyzeErrUnionPayloadPtr(
6887 // If the pointer resulting from this function was stored at comptime,7031 // If the pointer resulting from this function was stored at comptime,
6888 // the error union error code would be set that way. But in this case,7032 // the error union error code would be set that way. But in this case,
6889 // we need to emit a runtime instruction to do it.7033 // we need to emit a runtime instruction to do it.
6890 try sema.requireRuntimeBlock(block, src);7034 try sema.requireRuntimeBlock(block, src, null);
6891 _ = try block.addTyOp(.errunion_payload_ptr_set, operand_pointer_ty, operand);7035 _ = try block.addTyOp(.errunion_payload_ptr_set, operand_pointer_ty, operand);
6892 }7036 }
6893 return sema.addConstant(7037 return sema.addConstant(
...@@ -6913,7 +7057,7 @@ fn analyzeErrUnionPayloadPtr(...@@ -6913,7 +7057,7 @@ fn analyzeErrUnionPayloadPtr(
6913 }7057 }
6914 }7058 }
69157059
6916 try sema.requireRuntimeBlock(block, src);7060 try sema.requireRuntimeBlock(block, src, null);
69177061
6918 // If the error set has no fields then no safety check is needed.7062 // If the error set has no fields then no safety check is needed.
6919 if (safety_check and block.wantSafety() and7063 if (safety_check and block.wantSafety() and
...@@ -6951,7 +7095,7 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -6951,7 +7095,7 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
6951 return sema.addConstant(result_ty, val);7095 return sema.addConstant(result_ty, val);
6952 }7096 }
69537097
6954 try sema.requireRuntimeBlock(block, src);7098 try sema.requireRuntimeBlock(block, src, null);
6955 return block.addTyOp(.unwrap_errunion_err, result_ty, operand);7099 return block.addTyOp(.unwrap_errunion_err, result_ty, operand);
6956}7100}
69577101
...@@ -6981,7 +7125,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -6981,7 +7125,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
6981 }7125 }
6982 }7126 }
69837127
6984 try sema.requireRuntimeBlock(block, src);7128 try sema.requireRuntimeBlock(block, src, null);
6985 return block.addTyOp(.unwrap_errunion_err_ptr, result_ty, operand);7129 return block.addTyOp(.unwrap_errunion_err_ptr, result_ty, operand);
6986}7130}
69877131
...@@ -7037,7 +7181,7 @@ fn zirFunc(...@@ -7037,7 +7181,7 @@ fn zirFunc(
7037 const ret_ty_body = sema.code.extra[extra_index..][0..extra.data.ret_body_len];7181 const ret_ty_body = sema.code.extra[extra_index..][0..extra.data.ret_body_len];
7038 extra_index += ret_ty_body.len;7182 extra_index += ret_ty_body.len;
70397183
7040 const ret_ty_val = try sema.resolveGenericBody(block, ret_ty_src, ret_ty_body, inst, Type.type);7184 const ret_ty_val = try sema.resolveGenericBody(block, ret_ty_src, ret_ty_body, inst, Type.type, "return type must be comptime known");
7041 var buffer: Value.ToTypeBuffer = undefined;7185 var buffer: Value.ToTypeBuffer = undefined;
7042 break :blk try ret_ty_val.toType(&buffer).copy(sema.arena);7186 break :blk try ret_ty_val.toType(&buffer).copy(sema.arena);
7043 },7187 },
...@@ -7085,6 +7229,7 @@ fn resolveGenericBody(...@@ -7085,6 +7229,7 @@ fn resolveGenericBody(
7085 body: []const Zir.Inst.Index,7229 body: []const Zir.Inst.Index,
7086 func_inst: Zir.Inst.Index,7230 func_inst: Zir.Inst.Index,
7087 dest_ty: Type,7231 dest_ty: Type,
7232 reason: []const u8,
7088) !Value {7233) !Value {
7089 assert(body.len != 0);7234 assert(body.len != 0);
70907235
...@@ -7098,7 +7243,7 @@ fn resolveGenericBody(...@@ -7098,7 +7243,7 @@ fn resolveGenericBody(
7098 }7243 }
7099 const uncasted = sema.resolveBody(block, body, func_inst) catch |err| break :err err;7244 const uncasted = sema.resolveBody(block, body, func_inst) catch |err| break :err err;
7100 const result = sema.coerce(block, dest_ty, uncasted, src) catch |err| break :err err;7245 const result = sema.coerce(block, dest_ty, uncasted, src) catch |err| break :err err;
7101 const val = sema.resolveConstValue(block, src, result) catch |err| break :err err;7246 const val = sema.resolveConstValue(block, src, result, reason) catch |err| break :err err;
7102 return val;7247 return val;
7103 };7248 };
7104 switch (err) {7249 switch (err) {
...@@ -7205,6 +7350,7 @@ fn funcCommon(...@@ -7205,6 +7350,7 @@ fn funcCommon(
7205 opt_lib_name: ?[]const u8,7350 opt_lib_name: ?[]const u8,
7206 noalias_bits: u32,7351 noalias_bits: u32,
7207) CompileError!Air.Inst.Ref {7352) CompileError!Air.Inst.Ref {
7353 const fn_src = LazySrcLoc.nodeOffset(src_node_offset);
7208 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset };7354 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset };
7209 const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = src_node_offset };7355 const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = src_node_offset };
72107356
...@@ -7213,10 +7359,6 @@ fn funcCommon(...@@ -7213,10 +7359,6 @@ fn funcCommon(
7213 address_space == null or7359 address_space == null or
7214 section == .generic or7360 section == .generic or
7215 cc == null;7361 cc == null;
7216 // Check for generic params.
7217 for (block.params.items) |param| {
7218 if (param.ty.tag() == .generic_poison) is_generic = true;
7219 }
72207362
7221 var destroy_fn_on_error = false;7363 var destroy_fn_on_error = false;
7222 const new_func: *Module.Fn = new_func: {7364 const new_func: *Module.Fn = new_func: {
...@@ -7227,7 +7369,10 @@ fn funcCommon(...@@ -7227,7 +7369,10 @@ fn funcCommon(
7227 break :new_func new_func;7369 break :new_func new_func;
7228 }7370 }
7229 destroy_fn_on_error = true;7371 destroy_fn_on_error = true;
7230 break :new_func try sema.gpa.create(Module.Fn);7372 const new_func = try sema.gpa.create(Module.Fn);
7373 // Set this here so that the inferred return type can be printed correctly if it appears in an error.
7374 new_func.owner_decl = sema.owner_decl_index;
7375 break :new_func new_func;
7231 };7376 };
7232 errdefer if (destroy_fn_on_error) sema.gpa.destroy(new_func);7377 errdefer if (destroy_fn_on_error) sema.gpa.destroy(new_func);
72337378
...@@ -7261,18 +7406,47 @@ fn funcCommon(...@@ -7261,18 +7406,47 @@ fn funcCommon(
7261 }7406 }
7262 }7407 }
72637408
7409 // These locals are pulled out from the init expression below to work around
7410 // a stage1 compiler bug.
7411 // In the case of generic calling convention, or generic alignment, we use
7412 // default values which are only meaningful for the generic function, *not*
7413 // the instantiation, which can depend on comptime parameters.
7414 // Related proposal: https://github.com/ziglang/zig/issues/11834
7415 const cc_workaround = cc orelse .Unspecified;
7416 const align_workaround = alignment orelse 0;
7417
7264 const param_types = try sema.arena.alloc(Type, block.params.items.len);7418 const param_types = try sema.arena.alloc(Type, block.params.items.len);
7265 const comptime_params = try sema.arena.alloc(bool, block.params.items.len);7419 const comptime_params = try sema.arena.alloc(bool, block.params.items.len);
7266 for (block.params.items) |param, i| {7420 for (block.params.items) |param, i| {
7267 const param_src = LazySrcLoc.nodeOffset(src_node_offset); // TODO better soruce location
7268 param_types[i] = param.ty;7421 param_types[i] = param.ty;
7269 comptime_params[i] = param.is_comptime or7422 sema.analyzeParameter(
7270 try sema.typeRequiresComptime(block, param_src, param.ty);7423 block,
7271 is_generic = is_generic or comptime_params[i] or param.ty.tag() == .generic_poison;7424 fn_src,
7272 if (is_extern and is_generic) {7425 .unneeded,
7273 // TODO add note: function is generic because of this parameter7426 param,
7274 return sema.fail(block, param_src, "extern function cannot be generic", .{});7427 comptime_params,
7275 }7428 i,
7429 &is_generic,
7430 is_extern,
7431 cc_workaround,
7432 ) catch |err| switch (err) {
7433 error.NeededSourceLocation => {
7434 const decl = sema.mod.declPtr(block.src_decl);
7435 try sema.analyzeParameter(
7436 block,
7437 fn_src,
7438 Module.paramSrc(src_node_offset, sema.gpa, decl, i),
7439 param,
7440 comptime_params,
7441 i,
7442 &is_generic,
7443 is_extern,
7444 cc_workaround,
7445 );
7446 return error.AnalysisFail;
7447 },
7448 else => |e| return e,
7449 };
7276 }7450 }
72777451
7278 const ret_poison = if (!is_generic) rp: {7452 const ret_poison = if (!is_generic) rp: {
...@@ -7302,14 +7476,34 @@ fn funcCommon(...@@ -7302,14 +7476,34 @@ fn funcCommon(
7302 });7476 });
7303 };7477 };
73047478
7305 // These locals are pulled out from the init expression below to work around7479 if (!bare_return_type.isValidReturnType()) {
7306 // a stage1 compiler bug.7480 const opaque_str = if (bare_return_type.zigTypeTag() == .Opaque) "opaque " else "";
7307 // In the case of generic calling convention, or generic alignment, we use7481 const msg = msg: {
7308 // default values which are only meaningful for the generic function, *not*7482 const msg = try sema.errMsg(block, ret_ty_src, "{s}return type '{}' not allowed", .{
7309 // the instantiation, which can depend on comptime parameters.7483 opaque_str, bare_return_type.fmt(sema.mod),
7310 // Related proposal: https://github.com/ziglang/zig/issues/118347484 });
7311 const cc_workaround = cc orelse .Unspecified;7485 errdefer msg.destroy(sema.gpa);
7312 const align_workaround = alignment orelse 0;7486
7487 try sema.addDeclaredHereNote(msg, bare_return_type);
7488 break :msg msg;
7489 };
7490 return sema.failWithOwnedErrorMsg(block, msg);
7491 }
7492 if (!Type.fnCallingConventionAllowsZigTypes(cc_workaround) and !(try sema.validateExternType(return_type, .ret_ty))) {
7493 const msg = msg: {
7494 const msg = try sema.errMsg(block, ret_ty_src, "return type '{}' not allowed in function with calling convention '{s}'", .{
7495 return_type.fmt(sema.mod), @tagName(cc_workaround),
7496 });
7497 errdefer msg.destroy(sema.gpa);
7498
7499 const src_decl = sema.mod.declPtr(block.src_decl);
7500 try sema.explainWhyTypeIsNotExtern(block, ret_ty_src, msg, ret_ty_src.toSrcLoc(src_decl), return_type, .ret_ty);
7501
7502 try sema.addDeclaredHereNote(msg, return_type);
7503 break :msg msg;
7504 };
7505 return sema.failWithOwnedErrorMsg(block, msg);
7506 }
73137507
7314 const arch = sema.mod.getTarget().cpu.arch;7508 const arch = sema.mod.getTarget().cpu.arch;
7315 if (switch (cc_workaround) {7509 if (switch (cc_workaround) {
...@@ -7442,6 +7636,79 @@ fn funcCommon(...@@ -7442,6 +7636,79 @@ fn funcCommon(
7442 return sema.addConstant(fn_ty, Value.initPayload(&fn_payload.base));7636 return sema.addConstant(fn_ty, Value.initPayload(&fn_payload.base));
7443}7637}
74447638
7639fn analyzeParameter(
7640 sema: *Sema,
7641 block: *Block,
7642 func_src: LazySrcLoc,
7643 param_src: LazySrcLoc,
7644 param: Block.Param,
7645 comptime_params: []bool,
7646 i: usize,
7647 is_generic: *bool,
7648 is_extern: bool,
7649 cc: std.builtin.CallingConvention,
7650) !void {
7651 const requires_comptime = try sema.typeRequiresComptime(block, param_src, param.ty);
7652 comptime_params[i] = param.is_comptime or requires_comptime;
7653 const this_generic = comptime_params[i] or param.ty.tag() == .generic_poison;
7654 is_generic.* = is_generic.* or this_generic;
7655 if (is_extern and this_generic) {
7656 // TODO this check should exist somewhere for notes.
7657 if (param_src == .unneeded) return error.NeededSourceLocation;
7658 const msg = msg: {
7659 const msg = try sema.errMsg(block, func_src, "extern function cannot be generic", .{});
7660 errdefer msg.destroy(sema.gpa);
7661
7662 try sema.errNote(block, param_src, msg, "function is generic because of this parameter", .{});
7663 break :msg msg;
7664 };
7665 return sema.failWithOwnedErrorMsg(block, msg);
7666 }
7667 if (this_generic and !Type.fnCallingConventionAllowsZigTypes(cc)) {
7668 return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)});
7669 }
7670 if (!param.ty.isValidParamType()) {
7671 const opaque_str = if (param.ty.zigTypeTag() == .Opaque) "opaque " else "";
7672 const msg = msg: {
7673 const msg = try sema.errMsg(block, param_src, "parameter of {s}type '{}' not allowed", .{
7674 opaque_str, param.ty.fmt(sema.mod),
7675 });
7676 errdefer msg.destroy(sema.gpa);
7677
7678 try sema.addDeclaredHereNote(msg, param.ty);
7679 break :msg msg;
7680 };
7681 return sema.failWithOwnedErrorMsg(block, msg);
7682 }
7683 if (!Type.fnCallingConventionAllowsZigTypes(cc) and !(try sema.validateExternType(param.ty, .param_ty))) {
7684 const msg = msg: {
7685 const msg = try sema.errMsg(block, param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{
7686 param.ty.fmt(sema.mod), @tagName(cc),
7687 });
7688 errdefer msg.destroy(sema.gpa);
7689
7690 const src_decl = sema.mod.declPtr(block.src_decl);
7691 try sema.explainWhyTypeIsNotExtern(block, param_src, msg, param_src.toSrcLoc(src_decl), param.ty, .param_ty);
7692
7693 try sema.addDeclaredHereNote(msg, param.ty);
7694 break :msg msg;
7695 };
7696 return sema.failWithOwnedErrorMsg(block, msg);
7697 }
7698 if (requires_comptime and !param.is_comptime) {
7699 const msg = msg: {
7700 const msg = try sema.errMsg(block, param_src, "parametter of type '{}' must be declared comptime", .{
7701 param.ty.fmt(sema.mod),
7702 });
7703 errdefer msg.destroy(sema.gpa);
7704
7705 try sema.addDeclaredHereNote(msg, param.ty);
7706 break :msg msg;
7707 };
7708 return sema.failWithOwnedErrorMsg(block, msg);
7709 }
7710}
7711
7445fn zirParam(7712fn zirParam(
7446 sema: *Sema,7713 sema: *Sema,
7447 block: *Block,7714 block: *Block,
...@@ -7629,7 +7896,7 @@ fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -7629,7 +7896,7 @@ fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
7629 if (try sema.resolveMaybeUndefVal(block, ptr_src, ptr)) |ptr_val| {7896 if (try sema.resolveMaybeUndefVal(block, ptr_src, ptr)) |ptr_val| {
7630 return sema.addConstant(Type.usize, ptr_val);7897 return sema.addConstant(Type.usize, ptr_val);
7631 }7898 }
7632 try sema.requireRuntimeBlock(block, ptr_src);7899 try sema.requireRuntimeBlock(block, ptr_src, ptr_src);
7633 return block.addUnOp(.ptrtoint, ptr);7900 return block.addUnOp(.ptrtoint, ptr);
7634}7901}
76357902
...@@ -7681,7 +7948,7 @@ fn zirFieldValNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -7681,7 +7948,7 @@ fn zirFieldValNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
7681 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };7948 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
7682 const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;7949 const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;
7683 const object = try sema.resolveInst(extra.lhs);7950 const object = try sema.resolveInst(extra.lhs);
7684 const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name);7951 const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name, "field name must be comptime known");
7685 return sema.fieldVal(block, src, object, field_name, field_name_src);7952 return sema.fieldVal(block, src, object, field_name, field_name_src);
7686}7953}
76877954
...@@ -7694,7 +7961,7 @@ fn zirFieldPtrNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -7694,7 +7961,7 @@ fn zirFieldPtrNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
7694 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };7961 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
7695 const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;7962 const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;
7696 const object_ptr = try sema.resolveInst(extra.lhs);7963 const object_ptr = try sema.resolveInst(extra.lhs);
7697 const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name);7964 const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name, "field name must be comptime known");
7698 return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src);7965 return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src);
7699}7966}
77007967
...@@ -7706,7 +7973,7 @@ fn zirFieldCallBindNamed(sema: *Sema, block: *Block, extended: Zir.Inst.Extended...@@ -7706,7 +7973,7 @@ fn zirFieldCallBindNamed(sema: *Sema, block: *Block, extended: Zir.Inst.Extended
7706 const src = LazySrcLoc.nodeOffset(extra.node);7973 const src = LazySrcLoc.nodeOffset(extra.node);
7707 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };7974 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
7708 const object_ptr = try sema.resolveInst(extra.lhs);7975 const object_ptr = try sema.resolveInst(extra.lhs);
7709 const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name);7976 const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name, "field name must be comptime known");
7710 return sema.fieldCallBind(block, src, object_ptr, field_name, field_name_src);7977 return sema.fieldCallBind(block, src, object_ptr, field_name, field_name_src);
7711}7978}
77127979
...@@ -7722,12 +7989,13 @@ fn zirIntCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -7722,12 +7989,13 @@ fn zirIntCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
7722 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);7989 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
7723 const operand = try sema.resolveInst(extra.rhs);7990 const operand = try sema.resolveInst(extra.rhs);
77247991
7725 return sema.intCast(block, dest_ty, dest_ty_src, operand, operand_src, true);7992 return sema.intCast(block, inst_data.src(), dest_ty, dest_ty_src, operand, operand_src, true);
7726}7993}
77277994
7728fn intCast(7995fn intCast(
7729 sema: *Sema,7996 sema: *Sema,
7730 block: *Block,7997 block: *Block,
7998 src: LazySrcLoc,
7731 dest_ty: Type,7999 dest_ty: Type,
7732 dest_ty_src: LazySrcLoc,8000 dest_ty_src: LazySrcLoc,
7733 operand: Air.Inst.Ref,8001 operand: Air.Inst.Ref,
...@@ -7750,7 +8018,7 @@ fn intCast(...@@ -7750,7 +8018,7 @@ fn intCast(
7750 if ((try sema.typeHasOnePossibleValue(block, dest_ty_src, dest_ty))) |opv| {8018 if ((try sema.typeHasOnePossibleValue(block, dest_ty_src, dest_ty))) |opv| {
7751 // requirement: intCast(u0, input) iff input == 08019 // requirement: intCast(u0, input) iff input == 0
7752 if (runtime_safety and block.wantSafety()) {8020 if (runtime_safety and block.wantSafety()) {
7753 try sema.requireRuntimeBlock(block, operand_src);8021 try sema.requireRuntimeBlock(block, src, operand_src);
7754 const target = sema.mod.getTarget();8022 const target = sema.mod.getTarget();
7755 const wanted_info = dest_scalar_ty.intInfo(target);8023 const wanted_info = dest_scalar_ty.intInfo(target);
7756 const wanted_bits = wanted_info.bits;8024 const wanted_bits = wanted_info.bits;
...@@ -7765,7 +8033,7 @@ fn intCast(...@@ -7765,7 +8033,7 @@ fn intCast(
7765 return sema.addConstant(dest_ty, opv);8033 return sema.addConstant(dest_ty, opv);
7766 }8034 }
77678035
7768 try sema.requireRuntimeBlock(block, operand_src);8036 try sema.requireRuntimeBlock(block, src, operand_src);
7769 if (runtime_safety and block.wantSafety()) {8037 if (runtime_safety and block.wantSafety()) {
7770 const target = sema.mod.getTarget();8038 const target = sema.mod.getTarget();
7771 const actual_info = operand_scalar_ty.intInfo(target);8039 const actual_info = operand_scalar_ty.intInfo(target);
...@@ -7972,7 +8240,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -7972,7 +8240,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
7972 if (dst_bits >= src_bits) {8240 if (dst_bits >= src_bits) {
7973 return sema.coerce(block, dest_ty, operand, operand_src);8241 return sema.coerce(block, dest_ty, operand, operand_src);
7974 }8242 }
7975 try sema.requireRuntimeBlock(block, operand_src);8243 try sema.requireRuntimeBlock(block, inst_data.src(), operand_src);
7976 return block.addTyOp(.fptrunc, dest_ty, operand);8244 return block.addTyOp(.fptrunc, dest_ty, operand);
7977}8245}
79788246
...@@ -8096,7 +8364,6 @@ fn zirSwitchCapture(...@@ -8096,7 +8364,6 @@ fn zirSwitchCapture(
8096 const switch_info = zir_datas[capture_info.switch_inst].pl_node;8364 const switch_info = zir_datas[capture_info.switch_inst].pl_node;
8097 const switch_extra = sema.code.extraData(Zir.Inst.SwitchBlock, switch_info.payload_index);8365 const switch_extra = sema.code.extraData(Zir.Inst.SwitchBlock, switch_info.payload_index);
8098 const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = switch_info.src_node };8366 const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = switch_info.src_node };
8099 const switch_src = switch_info.src();
8100 const operand_is_ref = switch_extra.data.bits.is_ref;8367 const operand_is_ref = switch_extra.data.bits.is_ref;
8101 const cond_inst = Zir.refToIndex(switch_extra.data.operand).?;8368 const cond_inst = Zir.refToIndex(switch_extra.data.operand).?;
8102 const cond_info = sema.code.instructions.items(.data)[cond_inst].un_node;8369 const cond_info = sema.code.instructions.items(.data)[cond_inst].un_node;
...@@ -8141,24 +8408,30 @@ fn zirSwitchCapture(...@@ -8141,24 +8408,30 @@ fn zirSwitchCapture(
81418408
8142 const first_item = try sema.resolveInst(items[0]);8409 const first_item = try sema.resolveInst(items[0]);
8143 // Previous switch validation ensured this will succeed8410 // Previous switch validation ensured this will succeed
8144 const first_item_val = sema.resolveConstValue(block, .unneeded, first_item) catch unreachable;8411 const first_item_val = sema.resolveConstValue(block, .unneeded, first_item, undefined) catch unreachable;
81458412
8146 const first_field_index = @intCast(u32, enum_ty.enumTagFieldIndex(first_item_val, sema.mod).?);8413 const first_field_index = @intCast(u32, enum_ty.enumTagFieldIndex(first_item_val, sema.mod).?);
8147 const first_field = union_obj.fields.values()[first_field_index];8414 const first_field = union_obj.fields.values()[first_field_index];
81488415
8149 for (items[1..]) |item| {8416 for (items[1..]) |item, i| {
8150 const item_ref = try sema.resolveInst(item);8417 const item_ref = try sema.resolveInst(item);
8151 // Previous switch validation ensured this will succeed8418 // Previous switch validation ensured this will succeed
8152 const item_val = sema.resolveConstValue(block, .unneeded, item_ref) catch unreachable;8419 const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable;
81538420
8154 const field_index = enum_ty.enumTagFieldIndex(item_val, sema.mod).?;8421 const field_index = enum_ty.enumTagFieldIndex(item_val, sema.mod).?;
8155 const field = union_obj.fields.values()[field_index];8422 const field = union_obj.fields.values()[field_index];
8156 if (!field.ty.eql(first_field.ty, sema.mod)) {8423 if (!field.ty.eql(first_field.ty, sema.mod)) {
8157 const first_item_src = switch_src; // TODO better source location
8158 const item_src = switch_src;
8159 const msg = msg: {8424 const msg = msg: {
8160 const msg = try sema.errMsg(block, switch_src, "capture group with incompatible types", .{});8425 const raw_capture_src = Module.SwitchProngSrc{ .multi_capture = capture_info.prong_index };
8426 const capture_src = raw_capture_src.resolve(sema.gpa, sema.mod.declPtr(block.src_decl), switch_info.src_node, .first);
8427
8428 const msg = try sema.errMsg(block, capture_src, "capture group with incompatible types", .{});
8161 errdefer msg.destroy(sema.gpa);8429 errdefer msg.destroy(sema.gpa);
8430
8431 const raw_first_item_src = Module.SwitchProngSrc{ .multi = .{ .prong = capture_info.prong_index, .item = 0 } };
8432 const first_item_src = raw_first_item_src.resolve(sema.gpa, sema.mod.declPtr(block.src_decl), switch_info.src_node, .first);
8433 const raw_item_src = Module.SwitchProngSrc{ .multi = .{ .prong = capture_info.prong_index, .item = 1 + @intCast(u32, i) } };
8434 const item_src = raw_item_src.resolve(sema.gpa, sema.mod.declPtr(block.src_decl), switch_info.src_node, .first);
8162 try sema.errNote(block, first_item_src, msg, "type '{}' here", .{first_field.ty.fmt(sema.mod)});8435 try sema.errNote(block, first_item_src, msg, "type '{}' here", .{first_field.ty.fmt(sema.mod)});
8163 try sema.errNote(block, item_src, msg, "type '{}' here", .{field.ty.fmt(sema.mod)});8436 try sema.errNote(block, item_src, msg, "type '{}' here", .{field.ty.fmt(sema.mod)});
8164 break :msg msg;8437 break :msg msg;
...@@ -8186,7 +8459,7 @@ fn zirSwitchCapture(...@@ -8186,7 +8459,7 @@ fn zirSwitchCapture(
8186 }),8459 }),
8187 );8460 );
8188 }8461 }
8189 try sema.requireRuntimeBlock(block, operand_src);8462 try sema.requireRuntimeBlock(block, operand_src, null);
8190 return block.addStructFieldPtr(operand_ptr, first_field_index, field_ty_ptr);8463 return block.addStructFieldPtr(operand_ptr, first_field_index, field_ty_ptr);
8191 }8464 }
81928465
...@@ -8196,7 +8469,7 @@ fn zirSwitchCapture(...@@ -8196,7 +8469,7 @@ fn zirSwitchCapture(
8196 operand_val.castTag(.@"union").?.data.val,8469 operand_val.castTag(.@"union").?.data.val,
8197 );8470 );
8198 }8471 }
8199 try sema.requireRuntimeBlock(block, operand_src);8472 try sema.requireRuntimeBlock(block, operand_src, null);
8200 return block.addStructFieldVal(operand, first_field_index, first_field.ty);8473 return block.addStructFieldVal(operand, first_field_index, first_field.ty);
8201 },8474 },
8202 .ErrorSet => {8475 .ErrorSet => {
...@@ -8206,7 +8479,7 @@ fn zirSwitchCapture(...@@ -8206,7 +8479,7 @@ fn zirSwitchCapture(
8206 for (items) |item| {8479 for (items) |item| {
8207 const item_ref = try sema.resolveInst(item);8480 const item_ref = try sema.resolveInst(item);
8208 // Previous switch validation ensured this will succeed8481 // Previous switch validation ensured this will succeed
8209 const item_val = sema.resolveConstValue(block, .unneeded, item_ref) catch unreachable;8482 const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable;
8210 names.putAssumeCapacityNoClobber(8483 names.putAssumeCapacityNoClobber(
8211 item_val.getError().?,8484 item_val.getError().?,
8212 {},8485 {},
...@@ -8220,7 +8493,7 @@ fn zirSwitchCapture(...@@ -8220,7 +8493,7 @@ fn zirSwitchCapture(
8220 } else {8493 } else {
8221 const item_ref = try sema.resolveInst(items[0]);8494 const item_ref = try sema.resolveInst(items[0]);
8222 // Previous switch validation ensured this will succeed8495 // Previous switch validation ensured this will succeed
8223 const item_val = sema.resolveConstValue(block, .unneeded, item_ref) catch unreachable;8496 const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable;
82248497
8225 const item_ty = try Type.Tag.error_set_single.create(sema.arena, item_val.getError().?);8498 const item_ty = try Type.Tag.error_set_single.create(sema.arena, item_val.getError().?);
8226 return sema.bitCast(block, item_ty, operand, operand_src);8499 return sema.bitCast(block, item_ty, operand, operand_src);
...@@ -8247,7 +8520,7 @@ fn zirSwitchCond(...@@ -8247,7 +8520,7 @@ fn zirSwitchCond(
8247) CompileError!Air.Inst.Ref {8520) CompileError!Air.Inst.Ref {
8248 const inst_data = sema.code.instructions.items(.data)[inst].un_node;8521 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
8249 const src = inst_data.src();8522 const src = inst_data.src();
8250 const operand_src = src; // TODO make this point at the switch operand8523 const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = inst_data.src_node };
8251 const operand_ptr = try sema.resolveInst(inst_data.operand);8524 const operand_ptr = try sema.resolveInst(inst_data.operand);
8252 const operand = if (is_ref)8525 const operand = if (is_ref)
8253 try sema.analyzeLoad(block, src, operand_ptr, operand_src)8526 try sema.analyzeLoad(block, src, operand_ptr, operand_src)
...@@ -8345,12 +8618,19 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8345,12 +8618,19 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8345 },8618 },
8346 };8619 };
83478620
8621 const union_originally = blk: {
8622 const zir_data = sema.code.instructions.items(.data);
8623 const cond_index = Zir.refToIndex(extra.data.operand).?;
8624 const raw_operand = sema.resolveInst(zir_data[cond_index].un_node.operand) catch unreachable;
8625 break :blk sema.typeOf(raw_operand).zigTypeTag() == .Union;
8626 };
8627
8348 const operand_ty = sema.typeOf(operand);8628 const operand_ty = sema.typeOf(operand);
83498629
8350 var else_error_ty: ?Type = null;8630 var else_error_ty: ?Type = null;
83518631
8352 // Validate usage of '_' prongs.8632 // Validate usage of '_' prongs.
8353 if (special_prong == .under and !operand_ty.isNonexhaustiveEnum()) {8633 if (special_prong == .under and (!operand_ty.isNonexhaustiveEnum() or union_originally)) {
8354 const msg = msg: {8634 const msg = msg: {
8355 const msg = try sema.errMsg(8635 const msg = try sema.errMsg(
8356 block,8636 block,
...@@ -8375,6 +8655,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8375,6 +8655,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
83758655
8376 // Validate for duplicate items, missing else prong, and invalid range.8656 // Validate for duplicate items, missing else prong, and invalid range.
8377 switch (operand_ty.zigTypeTag()) {8657 switch (operand_ty.zigTypeTag()) {
8658 .Union => unreachable, // handled in zirSwitchCond
8378 .Enum => {8659 .Enum => {
8379 var seen_fields = try gpa.alloc(?Module.SwitchProngSrc, operand_ty.enumFieldCount());8660 var seen_fields = try gpa.alloc(?Module.SwitchProngSrc, operand_ty.enumFieldCount());
8380 defer gpa.free(seen_fields);8661 defer gpa.free(seen_fields);
...@@ -8432,60 +8713,53 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8432,60 +8713,53 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8432 }8713 }
8433 const all_tags_handled = for (seen_fields) |seen_src| {8714 const all_tags_handled = for (seen_fields) |seen_src| {
8434 if (seen_src == null) break false;8715 if (seen_src == null) break false;
8435 } else !operand_ty.isNonexhaustiveEnum();8716 } else true;
84368717
8437 switch (special_prong) {8718 if (special_prong == .@"else") {
8438 .none => {8719 if (all_tags_handled and !operand_ty.isNonexhaustiveEnum()) return sema.fail(
8439 if (!all_tags_handled) {8720 block,
8440 const msg = msg: {8721 special_prong_src,
8441 const msg = try sema.errMsg(8722 "unreachable else prong; all cases already handled",
8442 block,8723 .{},
8443 src,8724 );
8444 "switch must handle all possibilities",8725 } else if (!all_tags_handled) {
8445 .{},8726 const msg = msg: {
8446 );8727 const msg = try sema.errMsg(
8447 errdefer msg.destroy(sema.gpa);
8448 for (seen_fields) |seen_src, i| {
8449 if (seen_src != null) continue;
8450
8451 const field_name = operand_ty.enumFieldName(i);
8452
8453 // TODO have this point to the tag decl instead of here
8454 try sema.errNote(
8455 block,
8456 src,
8457 msg,
8458 "unhandled enumeration value: '{s}'",
8459 .{field_name},
8460 );
8461 }
8462 try sema.mod.errNoteNonLazy(
8463 operand_ty.declSrcLoc(sema.mod),
8464 msg,
8465 "enum '{}' declared here",
8466 .{operand_ty.fmt(sema.mod)},
8467 );
8468 break :msg msg;
8469 };
8470 return sema.failWithOwnedErrorMsg(block, msg);
8471 }
8472 },
8473 .under => {
8474 if (all_tags_handled) return sema.fail(
8475 block,8728 block,
8476 special_prong_src,8729 src,
8477 "unreachable '_' prong; all cases already handled",8730 "switch must handle all possibilities",
8478 .{},8731 .{},
8479 );8732 );
8480 },8733 errdefer msg.destroy(sema.gpa);
8481 .@"else" => {8734 for (seen_fields) |seen_src, i| {
8482 if (all_tags_handled) return sema.fail(8735 if (seen_src != null) continue;
8483 block,8736
8484 special_prong_src,8737 const field_name = operand_ty.enumFieldName(i);
8485 "unreachable else prong; all cases already handled",8738 try sema.addFieldErrNote(
8486 .{},8739 block,
8740 operand_ty,
8741 i,
8742 msg,
8743 "unhandled enumeration value: '{s}'",
8744 .{field_name},
8745 );
8746 }
8747 try sema.mod.errNoteNonLazy(
8748 operand_ty.declSrcLoc(sema.mod),
8749 msg,
8750 "enum '{}' declared here",
8751 .{operand_ty.fmt(sema.mod)},
8487 );8752 );
8488 },8753 break :msg msg;
8754 };
8755 return sema.failWithOwnedErrorMsg(block, msg);
8756 } else if (special_prong == .none and operand_ty.isNonexhaustiveEnum() and !union_originally) {
8757 return sema.fail(
8758 block,
8759 src,
8760 "switch on non-exhaustive enum must include 'else' or '_' prong",
8761 .{},
8762 );
8489 }8763 }
8490 },8764 },
8491 .ErrorSet => {8765 .ErrorSet => {
...@@ -8625,7 +8899,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8625,7 +8899,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8625 else_error_ty = try Type.Tag.error_set_merged.create(sema.arena, names);8899 else_error_ty = try Type.Tag.error_set_merged.create(sema.arena, names);
8626 }8900 }
8627 },8901 },
8628 .Union => return sema.fail(block, src, "TODO validate switch .Union", .{}),
8629 .Int, .ComptimeInt => {8902 .Int, .ComptimeInt => {
8630 var range_set = RangeSet.init(gpa, sema.mod);8903 var range_set = RangeSet.init(gpa, sema.mod);
8631 defer range_set.deinit();8904 defer range_set.deinit();
...@@ -8923,7 +9196,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8923,7 +9196,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
89239196
8924 const item = try sema.resolveInst(item_ref);9197 const item = try sema.resolveInst(item_ref);
8925 // Validation above ensured these will succeed.9198 // Validation above ensured these will succeed.
8926 const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable;9199 const item_val = sema.resolveConstValue(&child_block, .unneeded, item, undefined) catch unreachable;
8927 if (operand_val.eql(item_val, operand_ty, sema.mod)) {9200 if (operand_val.eql(item_val, operand_ty, sema.mod)) {
8928 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);9201 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);
8929 }9202 }
...@@ -8945,7 +9218,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8945,7 +9218,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8945 for (items) |item_ref| {9218 for (items) |item_ref| {
8946 const item = try sema.resolveInst(item_ref);9219 const item = try sema.resolveInst(item_ref);
8947 // Validation above ensured these will succeed.9220 // Validation above ensured these will succeed.
8948 const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable;9221 const item_val = sema.resolveConstValue(&child_block, .unneeded, item, undefined) catch unreachable;
8949 if (operand_val.eql(item_val, operand_ty, sema.mod)) {9222 if (operand_val.eql(item_val, operand_ty, sema.mod)) {
8950 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);9223 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);
8951 }9224 }
...@@ -8959,8 +9232,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8959,8 +9232,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8959 extra_index += 1;9232 extra_index += 1;
89609233
8961 // Validation above ensured these will succeed.9234 // Validation above ensured these will succeed.
8962 const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first) catch unreachable;9235 const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first, undefined) catch unreachable;
8963 const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last) catch unreachable;9236 const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last, undefined) catch unreachable;
8964 if ((try sema.compare(block, src, operand_val, .gte, first_tv.val, operand_ty)) and9237 if ((try sema.compare(block, src, operand_val, .gte, first_tv.val, operand_ty)) and
8965 (try sema.compare(block, src, operand_val, .lte, last_tv.val, operand_ty)))9238 (try sema.compare(block, src, operand_val, .lte, last_tv.val, operand_ty)))
8966 {9239 {
...@@ -8981,7 +9254,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8981,7 +9254,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8981 return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges);9254 return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges);
8982 }9255 }
89839256
8984 try sema.requireRuntimeBlock(block, src);9257 try sema.requireRuntimeBlock(block, src, operand_src);
89859258
8986 const estimated_cases_extra = (scalar_cases_len + multi_cases_len) *9259 const estimated_cases_extra = (scalar_cases_len + multi_cases_len) *
8987 @typeInfo(Air.SwitchBr.Case).Struct.fields.len + 2;9260 @typeInfo(Air.SwitchBr.Case).Struct.fields.len + 2;
...@@ -9270,14 +9543,14 @@ fn resolveSwitchItemVal(...@@ -9270,14 +9543,14 @@ fn resolveSwitchItemVal(
9270 // Constructing a LazySrcLoc is costly because we only have the switch AST node.9543 // Constructing a LazySrcLoc is costly because we only have the switch AST node.
9271 // Only if we know for sure we need to report a compile error do we resolve the9544 // Only if we know for sure we need to report a compile error do we resolve the
9272 // full source locations.9545 // full source locations.
9273 if (sema.resolveConstValue(block, .unneeded, item)) |val| {9546 if (sema.resolveConstValue(block, .unneeded, item, undefined)) |val| {
9274 return TypedValue{ .ty = item_ty, .val = val };9547 return TypedValue{ .ty = item_ty, .val = val };
9275 } else |err| switch (err) {9548 } else |err| switch (err) {
9276 error.NeededSourceLocation => {9549 error.NeededSourceLocation => {
9277 const src = switch_prong_src.resolve(sema.gpa, sema.mod.declPtr(block.src_decl), switch_node_offset, range_expand);9550 const src = switch_prong_src.resolve(sema.gpa, sema.mod.declPtr(block.src_decl), switch_node_offset, range_expand);
9278 return TypedValue{9551 return TypedValue{
9279 .ty = item_ty,9552 .ty = item_ty,
9280 .val = try sema.resolveConstValue(block, src, item),9553 .val = try sema.resolveConstValue(block, src, item, "switch prong values must be comptime known"),
9281 };9554 };
9282 },9555 },
9283 else => |e| return e,9556 else => |e| return e,
...@@ -9463,7 +9736,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -9463,7 +9736,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
9463 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };9736 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
9464 const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };9737 const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
9465 const unresolved_ty = try sema.resolveType(block, ty_src, extra.lhs);9738 const unresolved_ty = try sema.resolveType(block, ty_src, extra.lhs);
9466 const field_name = try sema.resolveConstString(block, name_src, extra.rhs);9739 const field_name = try sema.resolveConstString(block, name_src, extra.rhs, "field name must be comptime known");
9467 const ty = try sema.resolveTypeFields(block, ty_src, unresolved_ty);9740 const ty = try sema.resolveTypeFields(block, ty_src, unresolved_ty);
94689741
9469 const has_field = hf: {9742 const has_field = hf: {
...@@ -9505,7 +9778,7 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -9505,7 +9778,7 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
9505 const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };9778 const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
9506 const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };9779 const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
9507 const container_type = try sema.resolveType(block, lhs_src, extra.lhs);9780 const container_type = try sema.resolveType(block, lhs_src, extra.lhs);
9508 const decl_name = try sema.resolveConstString(block, rhs_src, extra.rhs);9781 const decl_name = try sema.resolveConstString(block, rhs_src, extra.rhs, "decl name must be comptime known");
95099782
9510 try checkNamespaceType(sema, block, lhs_src, container_type);9783 try checkNamespaceType(sema, block, lhs_src, container_type);
95119784
...@@ -9552,7 +9825,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -9552,7 +9825,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
9552 const mod = sema.mod;9825 const mod = sema.mod;
9553 const inst_data = sema.code.instructions.items(.data)[inst].un_node;9826 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
9554 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };9827 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
9555 const name = try sema.resolveConstString(block, operand_src, inst_data.operand);9828 const name = try sema.resolveConstString(block, operand_src, inst_data.operand, "file path name must be comptime known");
95569829
9557 const embed_file = mod.embedFile(block.getFileScope(), name) catch |err| switch (err) {9830 const embed_file = mod.embedFile(block.getFileScope(), name) catch |err| switch (err) {
9558 error.ImportOutsidePkgPath => {9831 error.ImportOutsidePkgPath => {
...@@ -9706,13 +9979,13 @@ fn zirShl(...@@ -9706,13 +9979,13 @@ fn zirShl(
9706 try lhs_ty.maxInt(sema.arena, target),9979 try lhs_ty.maxInt(sema.arena, target),
9707 );9980 );
9708 const rhs_limited = try sema.analyzeMinMax(block, rhs_src, rhs, max_int, .min, rhs_src, rhs_src);9981 const rhs_limited = try sema.analyzeMinMax(block, rhs_src, rhs, max_int, .min, rhs_src, rhs_src);
9709 break :rhs try sema.intCast(block, lhs_ty, rhs_src, rhs_limited, rhs_src, false);9982 break :rhs try sema.intCast(block, src, lhs_ty, rhs_src, rhs_limited, rhs_src, false);
9710 } else {9983 } else {
9711 break :rhs rhs;9984 break :rhs rhs;
9712 }9985 }
9713 } else rhs;9986 } else rhs;
97149987
9715 try sema.requireRuntimeBlock(block, runtime_src);9988 try sema.requireRuntimeBlock(block, src, runtime_src);
9716 if (block.wantSafety()) {9989 if (block.wantSafety()) {
9717 const maybe_op_ov: ?Air.Inst.Tag = switch (air_tag) {9990 const maybe_op_ov: ?Air.Inst.Tag = switch (air_tag) {
9718 .shl_exact => .shl_with_overflow,9991 .shl_exact => .shl_with_overflow,
...@@ -9823,7 +10096,7 @@ fn zirShr(...@@ -9823,7 +10096,7 @@ fn zirShr(
9823 }10096 }
9824 } else rhs_src;10097 } else rhs_src;
982510098
9826 try sema.requireRuntimeBlock(block, runtime_src);10099 try sema.requireRuntimeBlock(block, src, runtime_src);
9827 return block.addBinOp(air_tag, lhs, rhs);10100 return block.addBinOp(air_tag, lhs, rhs);
9828}10101}
982910102
...@@ -9882,7 +10155,7 @@ fn zirBitwise(...@@ -9882,7 +10155,7 @@ fn zirBitwise(
9882 }10155 }
9883 };10156 };
988410157
9885 try sema.requireRuntimeBlock(block, runtime_src);10158 try sema.requireRuntimeBlock(block, src, runtime_src);
9886 return block.addBinOp(air_tag, casted_lhs, casted_rhs);10159 return block.addBinOp(air_tag, casted_lhs, casted_rhs);
9887}10160}
988810161
...@@ -9926,7 +10199,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -9926,7 +10199,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
9926 }10199 }
9927 }10200 }
992810201
9929 try sema.requireRuntimeBlock(block, src);10202 try sema.requireRuntimeBlock(block, src, null);
9930 return block.addTyOp(.not, operand_type, operand);10203 return block.addTyOp(.not, operand_type, operand);
9931}10204}
993210205
...@@ -9939,6 +10212,7 @@ fn analyzeTupleCat(...@@ -9939,6 +10212,7 @@ fn analyzeTupleCat(
9939) CompileError!Air.Inst.Ref {10212) CompileError!Air.Inst.Ref {
9940 const lhs_ty = sema.typeOf(lhs);10213 const lhs_ty = sema.typeOf(lhs);
9941 const rhs_ty = sema.typeOf(rhs);10214 const rhs_ty = sema.typeOf(rhs);
10215 const src = LazySrcLoc.nodeOffset(src_node);
9942 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = src_node };10216 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = src_node };
9943 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = src_node };10217 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = src_node };
994410218
...@@ -9986,7 +10260,7 @@ fn analyzeTupleCat(...@@ -9986,7 +10260,7 @@ fn analyzeTupleCat(
9986 return sema.addConstant(tuple_ty, tuple_val);10260 return sema.addConstant(tuple_ty, tuple_val);
9987 };10261 };
998810262
9989 try sema.requireRuntimeBlock(block, runtime_src);10263 try sema.requireRuntimeBlock(block, src, runtime_src);
999010264
9991 const element_refs = try sema.arena.alloc(Air.Inst.Ref, final_len);10265 const element_refs = try sema.arena.alloc(Air.Inst.Ref, final_len);
9992 for (lhs_tuple.types) |_, i| {10266 for (lhs_tuple.types) |_, i| {
...@@ -10049,8 +10323,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -10049,8 +10323,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
10049 const rhs_sent = try sema.addConstant(rhs_info.elem_type, rhs_sent_val);10323 const rhs_sent = try sema.addConstant(rhs_info.elem_type, rhs_sent_val);
10050 const lhs_sent_casted = try sema.coerce(block, resolved_elem_ty, lhs_sent, lhs_src);10324 const lhs_sent_casted = try sema.coerce(block, resolved_elem_ty, lhs_sent, lhs_src);
10051 const rhs_sent_casted = try sema.coerce(block, resolved_elem_ty, rhs_sent, rhs_src);10325 const rhs_sent_casted = try sema.coerce(block, resolved_elem_ty, rhs_sent, rhs_src);
10052 const lhs_sent_casted_val = try sema.resolveConstValue(block, lhs_src, lhs_sent_casted);10326 const lhs_sent_casted_val = try sema.resolveConstValue(block, lhs_src, lhs_sent_casted, "array sentinel value must be comptime known");
10053 const rhs_sent_casted_val = try sema.resolveConstValue(block, rhs_src, rhs_sent_casted);10327 const rhs_sent_casted_val = try sema.resolveConstValue(block, rhs_src, rhs_sent_casted, "array sentinel value must be comptime known");
10054 if (try sema.valuesEqual(block, src, lhs_sent_casted_val, rhs_sent_casted_val, resolved_elem_ty)) {10328 if (try sema.valuesEqual(block, src, lhs_sent_casted_val, rhs_sent_casted_val, resolved_elem_ty)) {
10055 break :s lhs_sent_casted_val;10329 break :s lhs_sent_casted_val;
10056 } else {10330 } else {
...@@ -10058,14 +10332,14 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -10058,14 +10332,14 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
10058 }10332 }
10059 } else {10333 } else {
10060 const lhs_sent_casted = try sema.coerce(block, resolved_elem_ty, lhs_sent, lhs_src);10334 const lhs_sent_casted = try sema.coerce(block, resolved_elem_ty, lhs_sent, lhs_src);
10061 const lhs_sent_casted_val = try sema.resolveConstValue(block, lhs_src, lhs_sent_casted);10335 const lhs_sent_casted_val = try sema.resolveConstValue(block, lhs_src, lhs_sent_casted, "array sentinel value must be comptime known");
10062 break :s lhs_sent_casted_val;10336 break :s lhs_sent_casted_val;
10063 }10337 }
10064 } else {10338 } else {
10065 if (rhs_info.sentinel) |rhs_sent_val| {10339 if (rhs_info.sentinel) |rhs_sent_val| {
10066 const rhs_sent = try sema.addConstant(rhs_info.elem_type, rhs_sent_val);10340 const rhs_sent = try sema.addConstant(rhs_info.elem_type, rhs_sent_val);
10067 const rhs_sent_casted = try sema.coerce(block, resolved_elem_ty, rhs_sent, rhs_src);10341 const rhs_sent_casted = try sema.coerce(block, resolved_elem_ty, rhs_sent, rhs_src);
10068 const rhs_sent_casted_val = try sema.resolveConstValue(block, rhs_src, rhs_sent_casted);10342 const rhs_sent_casted_val = try sema.resolveConstValue(block, rhs_src, rhs_sent_casted, "array sentinel value must be comptime known");
10069 break :s rhs_sent_casted_val;10343 break :s rhs_sent_casted_val;
10070 } else {10344 } else {
10071 break :s null;10345 break :s null;
...@@ -10120,7 +10394,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -10120,7 +10394,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
10120 } else break :rs rhs_src;10394 } else break :rs rhs_src;
10121 } else lhs_src;10395 } else lhs_src;
1012210396
10123 try sema.requireRuntimeBlock(block, runtime_src);10397 try sema.requireRuntimeBlock(block, src, runtime_src);
1012410398
10125 if (ptr_addrspace) |ptr_as| {10399 if (ptr_addrspace) |ptr_as| {
10126 const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{10400 const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{
...@@ -10186,7 +10460,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins...@@ -10186,7 +10460,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
10186 // has a sentinel, and this code should compute the length based10460 // has a sentinel, and this code should compute the length based
10187 // on the sentinel value.10461 // on the sentinel value.
10188 .Slice, .Many => {10462 .Slice, .Many => {
10189 const val = try sema.resolveConstValue(block, src, operand);10463 const val = try sema.resolveConstValue(block, src, operand, "slice value being concatenated must be comptime known");
10190 return Type.ArrayInfo{10464 return Type.ArrayInfo{
10191 .elem_type = ptr_info.pointee_type,10465 .elem_type = ptr_info.pointee_type,
10192 .sentinel = ptr_info.sentinel,10466 .sentinel = ptr_info.sentinel,
...@@ -10215,6 +10489,7 @@ fn analyzeTupleMul(...@@ -10215,6 +10489,7 @@ fn analyzeTupleMul(
10215) CompileError!Air.Inst.Ref {10489) CompileError!Air.Inst.Ref {
10216 const operand_ty = sema.typeOf(operand);10490 const operand_ty = sema.typeOf(operand);
10217 const operand_tuple = operand_ty.tupleFields();10491 const operand_tuple = operand_ty.tupleFields();
10492 const src = LazySrcLoc.nodeOffset(src_node);
10218 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = src_node };10493 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = src_node };
10219 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = src_node };10494 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = src_node };
1022010495
...@@ -10258,7 +10533,7 @@ fn analyzeTupleMul(...@@ -10258,7 +10533,7 @@ fn analyzeTupleMul(
10258 return sema.addConstant(tuple_ty, tuple_val);10533 return sema.addConstant(tuple_ty, tuple_val);
10259 };10534 };
1026010535
10261 try sema.requireRuntimeBlock(block, runtime_src);10536 try sema.requireRuntimeBlock(block, src, runtime_src);
1026210537
10263 const element_refs = try sema.arena.alloc(Air.Inst.Ref, final_len);10538 const element_refs = try sema.arena.alloc(Air.Inst.Ref, final_len);
10264 for (operand_tuple.types) |_, i| {10539 for (operand_tuple.types) |_, i| {
...@@ -10286,7 +10561,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -10286,7 +10561,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
10286 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };10561 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
1028710562
10288 // In `**` rhs must be comptime-known, but lhs can be runtime-known10563 // In `**` rhs must be comptime-known, but lhs can be runtime-known
10289 const factor = try sema.resolveInt(block, rhs_src, extra.rhs, Type.usize);10564 const factor = try sema.resolveInt(block, rhs_src, extra.rhs, Type.usize, "array multiplication factor must be comptime known");
1029010565
10291 if (lhs_ty.isTuple()) {10566 if (lhs_ty.isTuple()) {
10292 return sema.analyzeTupleMul(block, inst_data.src_node, lhs, factor);10567 return sema.analyzeTupleMul(block, inst_data.src_node, lhs, factor);
...@@ -10337,7 +10612,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -10337,7 +10612,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
10337 return sema.addConstantMaybeRef(block, src, result_ty, val, ptr_addrspace != null);10612 return sema.addConstantMaybeRef(block, src, result_ty, val, ptr_addrspace != null);
10338 }10613 }
1033910614
10340 try sema.requireRuntimeBlock(block, lhs_src);10615 try sema.requireRuntimeBlock(block, src, lhs_src);
1034110616
10342 if (ptr_addrspace) |ptr_as| {10617 if (ptr_addrspace) |ptr_as| {
10343 const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{10618 const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{
...@@ -10411,7 +10686,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -10411,7 +10686,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
10411 const target = sema.mod.getTarget();10686 const target = sema.mod.getTarget();
10412 return sema.addConstant(rhs_ty, try rhs_val.floatNeg(rhs_ty, sema.arena, target));10687 return sema.addConstant(rhs_ty, try rhs_val.floatNeg(rhs_ty, sema.arena, target));
10413 }10688 }
10414 try sema.requireRuntimeBlock(block, rhs_src);10689 try sema.requireRuntimeBlock(block, src, null);
10415 return block.addUnOp(.neg, rhs);10690 return block.addUnOp(.neg, rhs);
10416 }10691 }
1041710692
...@@ -10495,7 +10770,7 @@ fn zirOverflowArithmetic(...@@ -10495,7 +10770,7 @@ fn zirOverflowArithmetic(
10495 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);10770 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
10496 const dest_ty = lhs_ty;10771 const dest_ty = lhs_ty;
10497 if (dest_ty.scalarType().zigTypeTag() != .Int) {10772 if (dest_ty.scalarType().zigTypeTag() != .Int) {
10498 return sema.fail(block, src, "expected vector of integers or integer type, found '{}'", .{dest_ty.fmt(mod)});10773 return sema.fail(block, src, "expected vector of integers or integer tag type, found '{}'", .{dest_ty.fmt(mod)});
10499 }10774 }
1050010775
10501 const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, lhs);10776 const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, lhs);
...@@ -10635,7 +10910,8 @@ fn zirOverflowArithmetic(...@@ -10635,7 +10910,8 @@ fn zirOverflowArithmetic(
10635 else => unreachable,10910 else => unreachable,
10636 };10911 };
1063710912
10638 try sema.requireRuntimeBlock(block, src);10913 const runtime_src = if (maybe_lhs_val == null) lhs_src else rhs_src;
10914 try sema.requireRuntimeBlock(block, src, runtime_src);
1063910915
10640 const tuple = try block.addInst(.{10916 const tuple = try block.addInst(.{
10641 .tag = air_tag,10917 .tag = air_tag,
...@@ -11542,7 +11818,7 @@ fn analyzeArithmetic(...@@ -11542,7 +11818,7 @@ fn analyzeArithmetic(
11542 }11818 }
11543 };11819 };
1154411820
11545 try sema.requireRuntimeBlock(block, rs.src);11821 try sema.requireRuntimeBlock(block, src, rs.src);
11546 if (block.wantSafety()) {11822 if (block.wantSafety()) {
11547 if (scalar_tag == .Int) {11823 if (scalar_tag == .Int) {
11548 const maybe_op_ov: ?Air.Inst.Tag = switch (rs.air_tag) {11824 const maybe_op_ov: ?Air.Inst.Tag = switch (rs.air_tag) {
...@@ -11666,7 +11942,7 @@ fn analyzePtrArithmetic(...@@ -11666,7 +11942,7 @@ fn analyzePtrArithmetic(
11666 } else break :rs ptr_src;11942 } else break :rs ptr_src;
11667 };11943 };
1166811944
11669 try sema.requireRuntimeBlock(block, runtime_src);11945 try sema.requireRuntimeBlock(block, op_src, runtime_src);
11670 return block.addInst(.{11946 return block.addInst(.{
11671 .tag = air_tag,11947 .tag = air_tag,
11672 .data = .{ .ty_pl = .{11948 .data = .{ .ty_pl = .{
...@@ -11685,7 +11961,7 @@ fn zirLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.In...@@ -11685,7 +11961,7 @@ fn zirLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.In
1168511961
11686 const inst_data = sema.code.instructions.items(.data)[inst].un_node;11962 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
11687 const src = inst_data.src();11963 const src = inst_data.src();
11688 const ptr_src: LazySrcLoc = .{ .node_offset_deref_ptr = inst_data.src_node };11964 const ptr_src = src; // TODO better source location
11689 const ptr = try sema.resolveInst(inst_data.operand);11965 const ptr = try sema.resolveInst(inst_data.operand);
11690 return sema.analyzeLoad(block, src, ptr, ptr_src);11966 return sema.analyzeLoad(block, src, ptr, ptr_src);
11691}11967}
...@@ -11733,7 +12009,7 @@ fn zirAsm(...@@ -11733,7 +12009,7 @@ fn zirAsm(
11733 }12009 }
1173412010
11735 if (block.is_comptime) {12011 if (block.is_comptime) {
11736 try sema.requireRuntimeBlock(block, src);12012 try sema.requireRuntimeBlock(block, src, null);
11737 }12013 }
1173812014
11739 var extra_i = extra.end;12015 var extra_i = extra.end;
...@@ -11895,10 +12171,10 @@ fn zirCmpEq(...@@ -11895,10 +12171,10 @@ fn zirCmpEq(
11895 }12171 }
1189612172
11897 if (lhs_ty_tag == .Union and (rhs_ty_tag == .EnumLiteral or rhs_ty_tag == .Enum)) {12173 if (lhs_ty_tag == .Union and (rhs_ty_tag == .EnumLiteral or rhs_ty_tag == .Enum)) {
11898 return sema.analyzeCmpUnionTag(block, lhs, lhs_src, rhs, rhs_src, op);12174 return sema.analyzeCmpUnionTag(block, src, lhs, lhs_src, rhs, rhs_src, op);
11899 }12175 }
11900 if (rhs_ty_tag == .Union and (lhs_ty_tag == .EnumLiteral or lhs_ty_tag == .Enum)) {12176 if (rhs_ty_tag == .Union and (lhs_ty_tag == .EnumLiteral or lhs_ty_tag == .Enum)) {
11901 return sema.analyzeCmpUnionTag(block, rhs, rhs_src, lhs, lhs_src, op);12177 return sema.analyzeCmpUnionTag(block, src, rhs, rhs_src, lhs, lhs_src, op);
11902 }12178 }
1190312179
11904 if (lhs_ty_tag == .ErrorSet and rhs_ty_tag == .ErrorSet) {12180 if (lhs_ty_tag == .ErrorSet and rhs_ty_tag == .ErrorSet) {
...@@ -11925,7 +12201,7 @@ fn zirCmpEq(...@@ -11925,7 +12201,7 @@ fn zirCmpEq(
11925 break :src lhs_src;12201 break :src lhs_src;
11926 }12202 }
11927 };12203 };
11928 try sema.requireRuntimeBlock(block, runtime_src);12204 try sema.requireRuntimeBlock(block, src, runtime_src);
11929 return block.addBinOp(air_tag, lhs, rhs);12205 return block.addBinOp(air_tag, lhs, rhs);
11930 }12206 }
11931 if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) {12207 if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) {
...@@ -11943,6 +12219,7 @@ fn zirCmpEq(...@@ -11943,6 +12219,7 @@ fn zirCmpEq(
11943fn analyzeCmpUnionTag(12219fn analyzeCmpUnionTag(
11944 sema: *Sema,12220 sema: *Sema,
11945 block: *Block,12221 block: *Block,
12222 src: LazySrcLoc,
11946 un: Air.Inst.Ref,12223 un: Air.Inst.Ref,
11947 un_src: LazySrcLoc,12224 un_src: LazySrcLoc,
11948 tag: Air.Inst.Ref,12225 tag: Air.Inst.Ref,
...@@ -11964,7 +12241,7 @@ fn analyzeCmpUnionTag(...@@ -11964,7 +12241,7 @@ fn analyzeCmpUnionTag(
11964 const coerced_tag = try sema.coerce(block, union_tag_ty, tag, tag_src);12241 const coerced_tag = try sema.coerce(block, union_tag_ty, tag, tag_src);
11965 const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src);12242 const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src);
1196612243
11967 return sema.cmpSelf(block, coerced_union, coerced_tag, op, un_src, tag_src);12244 return sema.cmpSelf(block, src, coerced_union, coerced_tag, op, un_src, tag_src);
11968}12245}
1196912246
11970/// Only called for non-equality operators. See also `zirCmpEq`.12247/// Only called for non-equality operators. See also `zirCmpEq`.
...@@ -12020,7 +12297,7 @@ fn analyzeCmp(...@@ -12020,7 +12297,7 @@ fn analyzeCmp(
12020 }12297 }
12021 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);12298 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
12022 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);12299 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
12023 return sema.cmpSelf(block, casted_lhs, casted_rhs, op, lhs_src, rhs_src);12300 return sema.cmpSelf(block, src, casted_lhs, casted_rhs, op, lhs_src, rhs_src);
12024}12301}
1202512302
12026fn compareOperatorName(comp: std.math.CompareOperator) []const u8 {12303fn compareOperatorName(comp: std.math.CompareOperator) []const u8 {
...@@ -12037,6 +12314,7 @@ fn compareOperatorName(comp: std.math.CompareOperator) []const u8 {...@@ -12037,6 +12314,7 @@ fn compareOperatorName(comp: std.math.CompareOperator) []const u8 {
12037fn cmpSelf(12314fn cmpSelf(
12038 sema: *Sema,12315 sema: *Sema,
12039 block: *Block,12316 block: *Block,
12317 src: LazySrcLoc,
12040 casted_lhs: Air.Inst.Ref,12318 casted_lhs: Air.Inst.Ref,
12041 casted_rhs: Air.Inst.Ref,12319 casted_rhs: Air.Inst.Ref,
12042 op: std.math.CompareOperator,12320 op: std.math.CompareOperator,
...@@ -12064,7 +12342,7 @@ fn cmpSelf(...@@ -12064,7 +12342,7 @@ fn cmpSelf(
12064 } else {12342 } else {
12065 if (resolved_type.zigTypeTag() == .Bool) {12343 if (resolved_type.zigTypeTag() == .Bool) {
12066 // We can lower bool eq/neq more efficiently.12344 // We can lower bool eq/neq more efficiently.
12067 return sema.runtimeBoolCmp(block, op, casted_rhs, lhs_val.toBool(), rhs_src);12345 return sema.runtimeBoolCmp(block, src, op, casted_rhs, lhs_val.toBool(), rhs_src);
12068 }12346 }
12069 break :src rhs_src;12347 break :src rhs_src;
12070 }12348 }
...@@ -12074,13 +12352,13 @@ fn cmpSelf(...@@ -12074,13 +12352,13 @@ fn cmpSelf(
12074 if (resolved_type.zigTypeTag() == .Bool) {12352 if (resolved_type.zigTypeTag() == .Bool) {
12075 if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| {12353 if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| {
12076 if (rhs_val.isUndef()) return sema.addConstUndef(Type.bool);12354 if (rhs_val.isUndef()) return sema.addConstUndef(Type.bool);
12077 return sema.runtimeBoolCmp(block, op, casted_lhs, rhs_val.toBool(), lhs_src);12355 return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(), lhs_src);
12078 }12356 }
12079 }12357 }
12080 break :src lhs_src;12358 break :src lhs_src;
12081 }12359 }
12082 };12360 };
12083 try sema.requireRuntimeBlock(block, runtime_src);12361 try sema.requireRuntimeBlock(block, src, runtime_src);
12084 if (resolved_type.zigTypeTag() == .Vector) {12362 if (resolved_type.zigTypeTag() == .Vector) {
12085 const result_ty = try Type.vector(sema.arena, resolved_type.vectorLen(), Type.@"bool");12363 const result_ty = try Type.vector(sema.arena, resolved_type.vectorLen(), Type.@"bool");
12086 const result_ty_ref = try sema.addType(result_ty);12364 const result_ty_ref = try sema.addType(result_ty);
...@@ -12097,13 +12375,14 @@ fn cmpSelf(...@@ -12097,13 +12375,14 @@ fn cmpSelf(
12097fn runtimeBoolCmp(12375fn runtimeBoolCmp(
12098 sema: *Sema,12376 sema: *Sema,
12099 block: *Block,12377 block: *Block,
12378 src: LazySrcLoc,
12100 op: std.math.CompareOperator,12379 op: std.math.CompareOperator,
12101 lhs: Air.Inst.Ref,12380 lhs: Air.Inst.Ref,
12102 rhs: bool,12381 rhs: bool,
12103 runtime_src: LazySrcLoc,12382 runtime_src: LazySrcLoc,
12104) CompileError!Air.Inst.Ref {12383) CompileError!Air.Inst.Ref {
12105 if ((op == .neq) == rhs) {12384 if ((op == .neq) == rhs) {
12106 try sema.requireRuntimeBlock(block, runtime_src);12385 try sema.requireRuntimeBlock(block, src, runtime_src);
12107 return block.addTyOp(.not, Type.bool, lhs);12386 return block.addTyOp(.not, Type.bool, lhs);
12108 } else {12387 } else {
12109 return lhs;12388 return lhs;
...@@ -12225,7 +12504,7 @@ fn zirRetAddr(...@@ -12225,7 +12504,7 @@ fn zirRetAddr(
12225 extended: Zir.Inst.Extended.InstData,12504 extended: Zir.Inst.Extended.InstData,
12226) CompileError!Air.Inst.Ref {12505) CompileError!Air.Inst.Ref {
12227 const src = LazySrcLoc.nodeOffset(@bitCast(i32, extended.operand));12506 const src = LazySrcLoc.nodeOffset(@bitCast(i32, extended.operand));
12228 try sema.requireRuntimeBlock(block, src);12507 try sema.requireRuntimeBlock(block, src, null);
12229 return try block.addNoOp(.ret_addr);12508 return try block.addNoOp(.ret_addr);
12230}12509}
1223112510
...@@ -12235,7 +12514,7 @@ fn zirFrameAddress(...@@ -12235,7 +12514,7 @@ fn zirFrameAddress(
12235 extended: Zir.Inst.Extended.InstData,12514 extended: Zir.Inst.Extended.InstData,
12236) CompileError!Air.Inst.Ref {12515) CompileError!Air.Inst.Ref {
12237 const src = LazySrcLoc.nodeOffset(@bitCast(i32, extended.operand));12516 const src = LazySrcLoc.nodeOffset(@bitCast(i32, extended.operand));
12238 try sema.requireRuntimeBlock(block, src);12517 try sema.requireRuntimeBlock(block, src, null);
12239 return try block.addNoOp(.frame_addr);12518 return try block.addNoOp(.frame_addr);
12240}12519}
1224112520
...@@ -13304,7 +13583,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -13304,7 +13583,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
13304 else13583 else
13305 Air.Inst.Ref.bool_true;13584 Air.Inst.Ref.bool_true;
13306 }13585 }
13307 try sema.requireRuntimeBlock(block, src);13586 try sema.requireRuntimeBlock(block, src, null);
13308 return block.addTyOp(.not, Type.bool, operand);13587 return block.addTyOp(.not, Type.bool, operand);
13309}13588}
1331013589
...@@ -13689,7 +13968,7 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -13689,7 +13968,7 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
13689 if (block.is_comptime or inst_data.force_comptime) {13968 if (block.is_comptime or inst_data.force_comptime) {
13690 return sema.fail(block, src, "reached unreachable code", .{});13969 return sema.fail(block, src, "reached unreachable code", .{});
13691 }13970 }
13692 try sema.requireRuntimeBlock(block, src);13971 try sema.requireFunctionBlock(block, src);
13693 // TODO Add compile error for @optimizeFor occurring too late in a scope.13972 // TODO Add compile error for @optimizeFor occurring too late in a scope.
13694 try block.addUnreachable(src, true);13973 try block.addUnreachable(src, true);
13695 return always_noreturn;13974 return always_noreturn;
...@@ -13751,7 +14030,6 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir...@@ -13751,7 +14030,6 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir
13751 const operand = try sema.analyzeLoad(block, src, ret_ptr, src);14030 const operand = try sema.analyzeLoad(block, src, ret_ptr, src);
13752 return sema.analyzeRet(block, operand, src);14031 return sema.analyzeRet(block, operand, src);
13753 }14032 }
13754 try sema.requireRuntimeBlock(block, src);
13755 _ = try block.addUnOp(.ret_load, ret_ptr);14033 _ = try block.addUnOp(.ret_load, ret_ptr);
13756 return always_noreturn;14034 return always_noreturn;
13757}14035}
...@@ -13834,22 +14112,21 @@ fn floatOpAllowed(tag: Zir.Inst.Tag) bool {...@@ -13834,22 +14112,21 @@ fn floatOpAllowed(tag: Zir.Inst.Tag) bool {
13834 };14112 };
13835}14113}
1383614114
13837fn zirPtrTypeSimple(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {14115fn zirOverflowArithmeticPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13838 const tracy = trace(@src());14116 const tracy = trace(@src());
13839 defer tracy.end();14117 defer tracy.end();
1384014118
13841 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type_simple;14119 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
13842 const elem_ty_src = sema.src; // TODO better source location14120 const elem_ty_src = inst_data.src();
13843 const elem_type = try sema.resolveType(block, elem_ty_src, inst_data.elem_type);14121 const elem_type = try sema.resolveType(block, elem_ty_src, inst_data.operand);
13844 const ty = try Type.ptr(sema.arena, sema.mod, .{14122 const ty = try Type.ptr(sema.arena, sema.mod, .{
13845 .pointee_type = elem_type,14123 .pointee_type = elem_type,
13846 .@"addrspace" = .generic,14124 .@"addrspace" = .generic,
13847 .mutable = inst_data.is_mutable,14125 .mutable = true,
13848 .@"allowzero" = inst_data.is_allowzero or inst_data.size == .C,14126 .@"allowzero" = false,
13849 .@"volatile" = inst_data.is_volatile,14127 .@"volatile" = false,
13850 .size = inst_data.size,14128 .size = .One,
13851 });14129 });
13852 try sema.validatePtrTy(block, elem_ty_src, ty);
13853 return sema.addType(ty);14130 return sema.addType(ty);
13854}14131}
1385514132
...@@ -13857,14 +14134,15 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -13857,14 +14134,15 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
13857 const tracy = trace(@src());14134 const tracy = trace(@src());
13858 defer tracy.end();14135 defer tracy.end();
1385914136
13860 const src: LazySrcLoc = sema.src; // TODO better source location
13861 const elem_ty_src: LazySrcLoc = sema.src; // TODO better source location
13862 const sentinel_src: LazySrcLoc = sema.src; // TODO better source location
13863 const addrspace_src: LazySrcLoc = sema.src; // TODO better source location
13864 const bitoffset_src: LazySrcLoc = sema.src; // TODO better source location
13865 const hostsize_src: LazySrcLoc = sema.src; // TODO better source location
13866 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type;14137 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type;
13867 const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index);14138 const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index);
14139 const elem_ty_src: LazySrcLoc = .{ .node_offset_ptr_elem = extra.data.src_node };
14140 const sentinel_src: LazySrcLoc = .{ .node_offset_ptr_sentinel = extra.data.src_node };
14141 const align_src: LazySrcLoc = .{ .node_offset_ptr_align = extra.data.src_node };
14142 const addrspace_src: LazySrcLoc = .{ .node_offset_ptr_addrspace = extra.data.src_node };
14143 const bitoffset_src: LazySrcLoc = .{ .node_offset_ptr_bitoffset = extra.data.src_node };
14144 const hostsize_src: LazySrcLoc = .{ .node_offset_ptr_hostsize = extra.data.src_node };
14145
13868 const unresolved_elem_ty = try sema.resolveType(block, elem_ty_src, extra.data.elem_type);14146 const unresolved_elem_ty = try sema.resolveType(block, elem_ty_src, extra.data.elem_type);
13869 const target = sema.mod.getTarget();14147 const target = sema.mod.getTarget();
1387014148
...@@ -13873,14 +14151,14 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -13873,14 +14151,14 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
13873 const sentinel = if (inst_data.flags.has_sentinel) blk: {14151 const sentinel = if (inst_data.flags.has_sentinel) blk: {
13874 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);14152 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
13875 extra_i += 1;14153 extra_i += 1;
13876 break :blk (try sema.resolveInstConst(block, sentinel_src, ref)).val;14154 break :blk (try sema.resolveInstConst(block, sentinel_src, ref, "pointer sentinel value must be comptime known")).val;
13877 } else null;14155 } else null;
1387814156
13879 const abi_align: u32 = if (inst_data.flags.has_align) blk: {14157 const abi_align: u32 = if (inst_data.flags.has_align) blk: {
13880 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);14158 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
13881 extra_i += 1;14159 extra_i += 1;
13882 const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), src);14160 const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), align_src);
13883 const val = try sema.resolveConstValue(block, src, coerced);14161 const val = try sema.resolveConstValue(block, align_src, coerced, "pointer alignment must be comptime known");
13884 // Check if this happens to be the lazy alignment of our element type, in14162 // Check if this happens to be the lazy alignment of our element type, in
13885 // which case we can make this 0 without resolving it.14163 // which case we can make this 0 without resolving it.
13886 if (val.castTag(.lazy_align)) |payload| {14164 if (val.castTag(.lazy_align)) |payload| {
...@@ -13888,8 +14166,9 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -13888,8 +14166,9 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
13888 break :blk 0;14166 break :blk 0;
13889 }14167 }
13890 }14168 }
13891 const abi_align = (try val.getUnsignedIntAdvanced(target, sema.kit(block, src))).?;14169 const abi_align = @intCast(u32, (try val.getUnsignedIntAdvanced(target, sema.kit(block, align_src))).?);
13892 break :blk @intCast(u32, abi_align);14170 try sema.validateAlign(block, align_src, abi_align);
14171 break :blk abi_align;
13893 } else 0;14172 } else 0;
1389414173
13895 const address_space = if (inst_data.flags.has_addrspace) blk: {14174 const address_space = if (inst_data.flags.has_addrspace) blk: {
...@@ -13901,19 +14180,19 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -13901,19 +14180,19 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
13901 const bit_offset = if (inst_data.flags.has_bit_range) blk: {14180 const bit_offset = if (inst_data.flags.has_bit_range) blk: {
13902 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);14181 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
13903 extra_i += 1;14182 extra_i += 1;
13904 const bit_offset = try sema.resolveInt(block, bitoffset_src, ref, Type.u16);14183 const bit_offset = try sema.resolveInt(block, bitoffset_src, ref, Type.u16, "pointer bit-offset must be comptime known");
13905 break :blk @intCast(u16, bit_offset);14184 break :blk @intCast(u16, bit_offset);
13906 } else 0;14185 } else 0;
1390714186
13908 const host_size: u16 = if (inst_data.flags.has_bit_range) blk: {14187 const host_size: u16 = if (inst_data.flags.has_bit_range) blk: {
13909 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);14188 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
13910 extra_i += 1;14189 extra_i += 1;
13911 const host_size = try sema.resolveInt(block, hostsize_src, ref, Type.u16);14190 const host_size = try sema.resolveInt(block, hostsize_src, ref, Type.u16, "pointer host size must be comptime known");
13912 break :blk @intCast(u16, host_size);14191 break :blk @intCast(u16, host_size);
13913 } else 0;14192 } else 0;
1391414193
13915 if (host_size != 0 and bit_offset >= host_size * 8) {14194 if (host_size != 0 and bit_offset >= host_size * 8) {
13916 return sema.fail(block, src, "bit offset starts after end of host integer", .{});14195 return sema.fail(block, bitoffset_src, "bit offset starts after end of host integer", .{});
13917 }14196 }
1391814197
13919 const elem_ty = if (abi_align == 0)14198 const elem_ty = if (abi_align == 0)
...@@ -13923,48 +14202,53 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -13923,48 +14202,53 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
13923 try sema.resolveTypeLayout(block, elem_ty_src, elem_ty);14202 try sema.resolveTypeLayout(block, elem_ty_src, elem_ty);
13924 break :t elem_ty;14203 break :t elem_ty;
13925 };14204 };
13926 const ty = try Type.ptr(sema.arena, sema.mod, .{
13927 .pointee_type = elem_ty,
13928 .sentinel = sentinel,
13929 .@"align" = abi_align,
13930 .@"addrspace" = address_space,
13931 .bit_offset = bit_offset,
13932 .host_size = host_size,
13933 .mutable = inst_data.flags.is_mutable,
13934 .@"allowzero" = inst_data.flags.is_allowzero,
13935 .@"volatile" = inst_data.flags.is_volatile,
13936 .size = inst_data.size,
13937 });
13938 try sema.validatePtrTy(block, elem_ty_src, ty);
13939 return sema.addType(ty);
13940}
1394114205
13942fn validatePtrTy(sema: *Sema, block: *Block, elem_src: LazySrcLoc, ty: Type) CompileError!void {14206 if (elem_ty.zigTypeTag() == .NoReturn) {
13943 const ptr_info = ty.ptrInfo().data;14207 return sema.fail(block, elem_ty_src, "pointer to noreturn not allowed", .{});
13944 const pointee_tag = ptr_info.pointee_type.zigTypeTag();14208 } else if (elem_ty.zigTypeTag() == .Fn) {
13945 if (pointee_tag == .NoReturn) {14209 if (inst_data.size != .One) {
13946 return sema.fail(block, elem_src, "pointer to noreturn not allowed", .{});14210 return sema.fail(block, elem_ty_src, "function pointers must be single pointers", .{});
13947 } else if (ptr_info.size == .Many and pointee_tag == .Opaque) {14211 }
13948 return sema.fail(block, elem_src, "unknown-length pointer to opaque not allowed", .{});14212 const fn_align = elem_ty.fnInfo().alignment;
13949 } else if (ptr_info.size == .C) {14213 if (inst_data.flags.has_align and abi_align != 0 and fn_align != 0 and
13950 const elem_ty = ptr_info.pointee_type;14214 abi_align != fn_align)
14215 {
14216 return sema.fail(block, align_src, "function pointer alignment disagrees with function alignment", .{});
14217 }
14218 } else if (inst_data.size == .Many and elem_ty.zigTypeTag() == .Opaque) {
14219 return sema.fail(block, elem_ty_src, "unknown-length pointer to opaque not allowed", .{});
14220 } else if (inst_data.size == .C) {
13951 if (!(try sema.validateExternType(elem_ty, .other))) {14221 if (!(try sema.validateExternType(elem_ty, .other))) {
13952 const msg = msg: {14222 const msg = msg: {
13953 const msg = try sema.errMsg(block, elem_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)});14223 const msg = try sema.errMsg(block, elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)});
13954 errdefer msg.destroy(sema.gpa);14224 errdefer msg.destroy(sema.gpa);
1395514225
13956 const src_decl = sema.mod.declPtr(block.src_decl);14226 const src_decl = sema.mod.declPtr(block.src_decl);
13957 try sema.explainWhyTypeIsNotExtern(block, elem_src, msg, elem_src.toSrcLoc(src_decl), elem_ty, .other);14227 try sema.explainWhyTypeIsNotExtern(block, elem_ty_src, msg, elem_ty_src.toSrcLoc(src_decl), elem_ty, .other);
1395814228
13959 try sema.addDeclaredHereNote(msg, elem_ty);14229 try sema.addDeclaredHereNote(msg, elem_ty);
13960 break :msg msg;14230 break :msg msg;
13961 };14231 };
13962 return sema.failWithOwnedErrorMsg(block, msg);14232 return sema.failWithOwnedErrorMsg(block, msg);
13963 }14233 }
13964 if (pointee_tag == .Opaque) {14234 if (elem_ty.zigTypeTag() == .Opaque) {
13965 return sema.fail(block, elem_src, "C pointers cannot point to opaque types", .{});14235 return sema.fail(block, elem_ty_src, "C pointers cannot point to opaque types", .{});
13966 }14236 }
13967 }14237 }
14238
14239 const ty = try Type.ptr(sema.arena, sema.mod, .{
14240 .pointee_type = elem_ty,
14241 .sentinel = sentinel,
14242 .@"align" = abi_align,
14243 .@"addrspace" = address_space,
14244 .bit_offset = bit_offset,
14245 .host_size = host_size,
14246 .mutable = inst_data.flags.is_mutable,
14247 .@"allowzero" = inst_data.flags.is_allowzero,
14248 .@"volatile" = inst_data.flags.is_volatile,
14249 .size = inst_data.size,
14250 });
14251 return sema.addType(ty);
13968}14252}
1396914253
13970fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {14254fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -14018,7 +14302,7 @@ fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -14018,7 +14302,7 @@ fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
14018 const init_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };14302 const init_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
14019 const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;14303 const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;
14020 const union_ty = try sema.resolveType(block, ty_src, extra.union_type);14304 const union_ty = try sema.resolveType(block, ty_src, extra.union_type);
14021 const field_name = try sema.resolveConstString(block, field_src, extra.field_name);14305 const field_name = try sema.resolveConstString(block, field_src, extra.field_name, "name of field being initialized must be comptime known");
14022 const init = try sema.resolveInst(extra.init);14306 const init = try sema.resolveInst(extra.init);
14023 return sema.unionInit(block, init, init_src, union_ty, ty_src, field_name, field_src);14307 return sema.unionInit(block, init, init_src, union_ty, ty_src, field_name, field_src);
14024}14308}
...@@ -14045,7 +14329,7 @@ fn unionInit(...@@ -14045,7 +14329,7 @@ fn unionInit(
14045 }));14329 }));
14046 }14330 }
1404714331
14048 try sema.requireRuntimeBlock(block, init_src);14332 try sema.requireRuntimeBlock(block, init_src, null);
14049 _ = union_ty_src;14333 _ = union_ty_src;
14050 try sema.queueFullTypeResolution(union_ty);14334 try sema.queueFullTypeResolution(union_ty);
14051 return block.addUnionInit(union_ty, field_index, init);14335 return block.addUnionInit(union_ty, field_index, init);
...@@ -14150,7 +14434,7 @@ fn zirStructInit(...@@ -14150,7 +14434,7 @@ fn zirStructInit(
14150 return alloc;14434 return alloc;
14151 }14435 }
1415214436
14153 try sema.requireRuntimeBlock(block, src);14437 try sema.requireRuntimeBlock(block, src, null);
14154 try sema.queueFullTypeResolution(resolved_ty);14438 try sema.queueFullTypeResolution(resolved_ty);
14155 return block.addUnionInit(resolved_ty, field_index, init_inst);14439 return block.addUnionInit(resolved_ty, field_index, init_inst);
14156 } else if (resolved_ty.isAnonStruct()) {14440 } else if (resolved_ty.isAnonStruct()) {
...@@ -14255,7 +14539,7 @@ fn finishStructInit(...@@ -14255,7 +14539,7 @@ fn finishStructInit(
14255 return alloc;14539 return alloc;
14256 }14540 }
1425714541
14258 try sema.requireRuntimeBlock(block, dest_src);14542 try sema.requireRuntimeBlock(block, dest_src, null);
14259 try sema.queueFullTypeResolution(struct_ty);14543 try sema.queueFullTypeResolution(struct_ty);
14260 return block.addAggregateInit(struct_ty, field_inits);14544 return block.addAggregateInit(struct_ty, field_inits);
14261}14545}
...@@ -14277,13 +14561,23 @@ fn zirStructInitAnon(...@@ -14277,13 +14561,23 @@ fn zirStructInitAnon(
14277 var runtime_src: ?LazySrcLoc = null;14561 var runtime_src: ?LazySrcLoc = null;
14278 var extra_index = extra.end;14562 var extra_index = extra.end;
14279 for (types) |*field_ty, i| {14563 for (types) |*field_ty, i| {
14564 const init_src = src; // TODO better source location
14280 const item = sema.code.extraData(Zir.Inst.StructInitAnon.Item, extra_index);14565 const item = sema.code.extraData(Zir.Inst.StructInitAnon.Item, extra_index);
14281 extra_index = item.end;14566 extra_index = item.end;
1428214567
14283 names[i] = sema.code.nullTerminatedString(item.data.field_name);14568 names[i] = sema.code.nullTerminatedString(item.data.field_name);
14284 const init = try sema.resolveInst(item.data.init);14569 const init = try sema.resolveInst(item.data.init);
14285 field_ty.* = sema.typeOf(init);14570 field_ty.* = sema.typeOf(init);
14286 const init_src = src; // TODO better source location14571 if (types[i].zigTypeTag() == .Opaque) {
14572 const msg = msg: {
14573 const msg = try sema.errMsg(block, init_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
14574 errdefer msg.destroy(sema.gpa);
14575
14576 try sema.addDeclaredHereNote(msg, types[i]);
14577 break :msg msg;
14578 };
14579 return sema.failWithOwnedErrorMsg(block, msg);
14580 }
14287 if (try sema.resolveMaybeUndefVal(block, init_src, init)) |init_val| {14581 if (try sema.resolveMaybeUndefVal(block, init_src, init)) |init_val| {
14288 values[i] = init_val;14582 values[i] = init_val;
14289 } else {14583 } else {
...@@ -14305,7 +14599,7 @@ fn zirStructInitAnon(...@@ -14305,7 +14599,7 @@ fn zirStructInitAnon(
14305 return sema.addConstantMaybeRef(block, src, tuple_ty, tuple_val, is_ref);14599 return sema.addConstantMaybeRef(block, src, tuple_ty, tuple_val, is_ref);
14306 };14600 };
1430714601
14308 try sema.requireRuntimeBlock(block, runtime_src);14602 try sema.requireRuntimeBlock(block, src, runtime_src);
1430914603
14310 if (is_ref) {14604 if (is_ref) {
14311 const target = sema.mod.getTarget();14605 const target = sema.mod.getTarget();
...@@ -14397,7 +14691,7 @@ fn zirArrayInit(...@@ -14397,7 +14691,7 @@ fn zirArrayInit(
14397 return sema.addConstantMaybeRef(block, src, array_ty, array_val, is_ref);14691 return sema.addConstantMaybeRef(block, src, array_ty, array_val, is_ref);
14398 };14692 };
1439914693
14400 try sema.requireRuntimeBlock(block, runtime_src);14694 try sema.requireRuntimeBlock(block, src, runtime_src);
14401 try sema.queueFullTypeResolution(array_ty);14695 try sema.queueFullTypeResolution(array_ty);
1440214696
14403 if (is_ref) {14697 if (is_ref) {
...@@ -14460,9 +14754,19 @@ fn zirArrayInitAnon(...@@ -14460,9 +14754,19 @@ fn zirArrayInitAnon(
14460 const opt_runtime_src = rs: {14754 const opt_runtime_src = rs: {
14461 var runtime_src: ?LazySrcLoc = null;14755 var runtime_src: ?LazySrcLoc = null;
14462 for (operands) |operand, i| {14756 for (operands) |operand, i| {
14757 const operand_src = src; // TODO better source location
14463 const elem = try sema.resolveInst(operand);14758 const elem = try sema.resolveInst(operand);
14464 types[i] = sema.typeOf(elem);14759 types[i] = sema.typeOf(elem);
14465 const operand_src = src; // TODO better source location14760 if (types[i].zigTypeTag() == .Opaque) {
14761 const msg = msg: {
14762 const msg = try sema.errMsg(block, operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
14763 errdefer msg.destroy(sema.gpa);
14764
14765 try sema.addDeclaredHereNote(msg, types[i]);
14766 break :msg msg;
14767 };
14768 return sema.failWithOwnedErrorMsg(block, msg);
14769 }
14466 if (try sema.resolveMaybeUndefVal(block, operand_src, elem)) |val| {14770 if (try sema.resolveMaybeUndefVal(block, operand_src, elem)) |val| {
14467 values[i] = val;14771 values[i] = val;
14468 } else {14772 } else {
...@@ -14483,7 +14787,7 @@ fn zirArrayInitAnon(...@@ -14483,7 +14787,7 @@ fn zirArrayInitAnon(
14483 return sema.addConstantMaybeRef(block, src, tuple_ty, tuple_val, is_ref);14787 return sema.addConstantMaybeRef(block, src, tuple_ty, tuple_val, is_ref);
14484 };14788 };
1448514789
14486 try sema.requireRuntimeBlock(block, runtime_src);14790 try sema.requireRuntimeBlock(block, src, runtime_src);
1448714791
14488 if (is_ref) {14792 if (is_ref) {
14489 const target = sema.mod.getTarget();14793 const target = sema.mod.getTarget();
...@@ -14542,7 +14846,7 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -14542,7 +14846,7 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
14542 const ty_src = inst_data.src();14846 const ty_src = inst_data.src();
14543 const field_src = inst_data.src();14847 const field_src = inst_data.src();
14544 const aggregate_ty = try sema.resolveType(block, ty_src, extra.container_type);14848 const aggregate_ty = try sema.resolveType(block, ty_src, extra.container_type);
14545 const field_name = try sema.resolveConstString(block, field_src, extra.field_name);14849 const field_name = try sema.resolveConstString(block, field_src, extra.field_name, "field name must be comptime known");
14546 return sema.fieldType(block, aggregate_ty, field_name, field_src, ty_src);14850 return sema.fieldType(block, aggregate_ty, field_name, field_src, ty_src);
14547}14851}
1454814852
...@@ -14732,7 +15036,7 @@ fn zirUnaryMath(...@@ -14732,7 +15036,7 @@ fn zirUnaryMath(
14732 );15036 );
14733 }15037 }
1473415038
14735 try sema.requireRuntimeBlock(block, operand_src);15039 try sema.requireRuntimeBlock(block, operand_src, null);
14736 return block.addUnOp(air_tag, operand);15040 return block.addUnOp(air_tag, operand);
14737 },15041 },
14738 .ComptimeFloat, .Float => {15042 .ComptimeFloat, .Float => {
...@@ -14743,7 +15047,7 @@ fn zirUnaryMath(...@@ -14743,7 +15047,7 @@ fn zirUnaryMath(
14743 return sema.addConstant(operand_ty, result_val);15047 return sema.addConstant(operand_ty, result_val);
14744 }15048 }
1474515049
14746 try sema.requireRuntimeBlock(block, operand_src);15050 try sema.requireRuntimeBlock(block, operand_src, null);
14747 return block.addUnOp(air_tag, operand);15051 return block.addUnOp(air_tag, operand);
14748 },15052 },
14749 else => unreachable,15053 else => unreachable,
...@@ -14761,7 +15065,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -14761,7 +15065,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
14761 try sema.resolveTypeLayout(block, operand_src, operand_ty);15065 try sema.resolveTypeLayout(block, operand_src, operand_ty);
14762 const enum_ty = switch (operand_ty.zigTypeTag()) {15066 const enum_ty = switch (operand_ty.zigTypeTag()) {
14763 .EnumLiteral => {15067 .EnumLiteral => {
14764 const val = try sema.resolveConstValue(block, operand_src, operand);15068 const val = try sema.resolveConstValue(block, .unneeded, operand, undefined);
14765 const bytes = val.castTag(.enum_literal).?.data;15069 const bytes = val.castTag(.enum_literal).?.data;
14766 return sema.addStrLit(block, bytes);15070 return sema.addStrLit(block, bytes);
14767 },15071 },
...@@ -14813,7 +15117,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -14813,7 +15117,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
14813 const uncasted_operand = try sema.resolveInst(inst_data.operand);15117 const uncasted_operand = try sema.resolveInst(inst_data.operand);
14814 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };15118 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
14815 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);15119 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);
14816 const val = try sema.resolveConstValue(block, operand_src, type_info);15120 const val = try sema.resolveConstValue(block, operand_src, type_info, "operand to @Type must be comptime known");
14817 const union_val = val.cast(Value.Payload.Union).?.data;15121 const union_val = val.cast(Value.Payload.Union).?.data;
14818 const tag_ty = type_info_ty.unionTagType().?;15122 const tag_ty = type_info_ty.unionTagType().?;
14819 const target = mod.getTarget();15123 const target = mod.getTarget();
...@@ -15497,10 +15801,10 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -15497,10 +15801,10 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
15497 const result_val = try sema.floatToInt(block, operand_src, val, operand_ty, dest_ty);15801 const result_val = try sema.floatToInt(block, operand_src, val, operand_ty, dest_ty);
15498 return sema.addConstant(dest_ty, result_val);15802 return sema.addConstant(dest_ty, result_val);
15499 } else if (dest_ty.zigTypeTag() == .ComptimeInt) {15803 } else if (dest_ty.zigTypeTag() == .ComptimeInt) {
15500 return sema.failWithNeededComptime(block, operand_src);15804 return sema.failWithNeededComptime(block, operand_src, "value being casted to 'comptime_int' must be comptime known");
15501 }15805 }
1550215806
15503 try sema.requireRuntimeBlock(block, operand_src);15807 try sema.requireRuntimeBlock(block, inst_data.src(), operand_src);
15504 return block.addTyOp(.float_to_int, dest_ty, operand);15808 return block.addTyOp(.float_to_int, dest_ty, operand);
15505}15809}
1550615810
...@@ -15521,10 +15825,10 @@ fn zirIntToFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -15521,10 +15825,10 @@ fn zirIntToFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
15521 const result_val = try val.intToFloat(sema.arena, operand_ty, dest_ty, target);15825 const result_val = try val.intToFloat(sema.arena, operand_ty, dest_ty, target);
15522 return sema.addConstant(dest_ty, result_val);15826 return sema.addConstant(dest_ty, result_val);
15523 } else if (dest_ty.zigTypeTag() == .ComptimeFloat) {15827 } else if (dest_ty.zigTypeTag() == .ComptimeFloat) {
15524 return sema.failWithNeededComptime(block, operand_src);15828 return sema.failWithNeededComptime(block, operand_src, "value being casted to 'comptime_float' must be comptime known");
15525 }15829 }
1552615830
15527 try sema.requireRuntimeBlock(block, operand_src);15831 try sema.requireRuntimeBlock(block, inst_data.src(), operand_src);
15528 return block.addTyOp(.int_to_float, dest_ty, operand);15832 return block.addTyOp(.int_to_float, dest_ty, operand);
15529}15833}
1553015834
...@@ -15560,7 +15864,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15560,7 +15864,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15560 return sema.addConstant(type_res, Value.initPayload(&val_payload.base));15864 return sema.addConstant(type_res, Value.initPayload(&val_payload.base));
15561 }15865 }
1556215866
15563 try sema.requireRuntimeBlock(block, src);15867 try sema.requireRuntimeBlock(block, src, operand_src);
15564 if (block.wantSafety()) {15868 if (block.wantSafety()) {
15565 if (!type_res.isAllowzeroPtr()) {15869 if (!type_res.isAllowzeroPtr()) {
15566 const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize);15870 const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize);
...@@ -15657,7 +15961,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -15657,7 +15961,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
15657 return sema.addConstant(dest_ty, val);15961 return sema.addConstant(dest_ty, val);
15658 }15962 }
1565915963
15660 try sema.requireRuntimeBlock(block, src);15964 try sema.requireRuntimeBlock(block, src, operand_src);
15661 if (block.wantSafety() and !dest_ty.isAnyError()) {15965 if (block.wantSafety() and !dest_ty.isAnyError()) {
15662 const err_int_inst = try block.addBitCast(Type.u16, operand);15966 const err_int_inst = try block.addBitCast(Type.u16, operand);
15663 // TODO: Output a switch instead of chained OR's.15967 // TODO: Output a switch instead of chained OR's.
...@@ -15812,7 +16116,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15812,7 +16116,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15812 );16116 );
15813 }16117 }
1581416118
15815 try sema.requireRuntimeBlock(block, src);16119 try sema.requireRuntimeBlock(block, src, operand_src);
15816 return block.addTyOp(.trunc, dest_ty, operand);16120 return block.addTyOp(.trunc, dest_ty, operand);
15817}16121}
1581816122
...@@ -15855,6 +16159,7 @@ fn zirBitCount(...@@ -15855,6 +16159,7 @@ fn zirBitCount(
15855 comptimeOp: fn (val: Value, ty: Type, target: std.Target) u64,16159 comptimeOp: fn (val: Value, ty: Type, target: std.Target) u64,
15856) CompileError!Air.Inst.Ref {16160) CompileError!Air.Inst.Ref {
15857 const inst_data = sema.code.instructions.items(.data)[inst].un_node;16161 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
16162 const src = inst_data.src();
15858 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };16163 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
15859 const operand = try sema.resolveInst(inst_data.operand);16164 const operand = try sema.resolveInst(inst_data.operand);
15860 const operand_ty = sema.typeOf(operand);16165 const operand_ty = sema.typeOf(operand);
...@@ -15887,7 +16192,7 @@ fn zirBitCount(...@@ -15887,7 +16192,7 @@ fn zirBitCount(
15887 try Value.Tag.aggregate.create(sema.arena, elems),16192 try Value.Tag.aggregate.create(sema.arena, elems),
15888 );16193 );
15889 } else {16194 } else {
15890 try sema.requireRuntimeBlock(block, operand_src);16195 try sema.requireRuntimeBlock(block, src, operand_src);
15891 return block.addTyOp(air_tag, result_ty, operand);16196 return block.addTyOp(air_tag, result_ty, operand);
15892 }16197 }
15893 },16198 },
...@@ -15896,7 +16201,7 @@ fn zirBitCount(...@@ -15896,7 +16201,7 @@ fn zirBitCount(
15896 if (val.isUndef()) return sema.addConstUndef(result_scalar_ty);16201 if (val.isUndef()) return sema.addConstUndef(result_scalar_ty);
15897 return sema.addIntUnsigned(result_scalar_ty, comptimeOp(val, operand_ty, target));16202 return sema.addIntUnsigned(result_scalar_ty, comptimeOp(val, operand_ty, target));
15898 } else {16203 } else {
15899 try sema.requireRuntimeBlock(block, operand_src);16204 try sema.requireRuntimeBlock(block, src, operand_src);
15900 return block.addTyOp(air_tag, result_scalar_ty, operand);16205 return block.addTyOp(air_tag, result_scalar_ty, operand);
15901 }16206 }
15902 },16207 },
...@@ -15906,6 +16211,7 @@ fn zirBitCount(...@@ -15906,6 +16211,7 @@ fn zirBitCount(
1590616211
15907fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {16212fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15908 const inst_data = sema.code.instructions.items(.data)[inst].un_node;16213 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
16214 const src = inst_data.src();
15909 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };16215 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
15910 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };16216 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
15911 const operand = try sema.resolveInst(inst_data.operand);16217 const operand = try sema.resolveInst(inst_data.operand);
...@@ -15934,7 +16240,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15934,7 +16240,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15934 return sema.addConstant(operand_ty, result_val);16240 return sema.addConstant(operand_ty, result_val);
15935 } else operand_src;16241 } else operand_src;
1593616242
15937 try sema.requireRuntimeBlock(block, runtime_src);16243 try sema.requireRuntimeBlock(block, src, runtime_src);
15938 return block.addTyOp(.byte_swap, operand_ty, operand);16244 return block.addTyOp(.byte_swap, operand_ty, operand);
15939 },16245 },
15940 .Vector => {16246 .Vector => {
...@@ -15955,7 +16261,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15955,7 +16261,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15955 );16261 );
15956 } else operand_src;16262 } else operand_src;
1595716263
15958 try sema.requireRuntimeBlock(block, runtime_src);16264 try sema.requireRuntimeBlock(block, src, runtime_src);
15959 return block.addTyOp(.byte_swap, operand_ty, operand);16265 return block.addTyOp(.byte_swap, operand_ty, operand);
15960 },16266 },
15961 else => unreachable,16267 else => unreachable,
...@@ -15964,6 +16270,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15964,6 +16270,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1596416270
15965fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {16271fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15966 const inst_data = sema.code.instructions.items(.data)[inst].un_node;16272 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
16273 const src = inst_data.src();
15967 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };16274 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
15968 const operand = try sema.resolveInst(inst_data.operand);16275 const operand = try sema.resolveInst(inst_data.operand);
15969 const operand_ty = sema.typeOf(operand);16276 const operand_ty = sema.typeOf(operand);
...@@ -15982,7 +16289,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -15982,7 +16289,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
15982 return sema.addConstant(operand_ty, result_val);16289 return sema.addConstant(operand_ty, result_val);
15983 } else operand_src;16290 } else operand_src;
1598416291
15985 try sema.requireRuntimeBlock(block, runtime_src);16292 try sema.requireRuntimeBlock(block, src, runtime_src);
15986 return block.addTyOp(.bit_reverse, operand_ty, operand);16293 return block.addTyOp(.bit_reverse, operand_ty, operand);
15987 },16294 },
15988 .Vector => {16295 .Vector => {
...@@ -16003,7 +16310,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -16003,7 +16310,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
16003 );16310 );
16004 } else operand_src;16311 } else operand_src;
1600516312
16006 try sema.requireRuntimeBlock(block, runtime_src);16313 try sema.requireRuntimeBlock(block, src, runtime_src);
16007 return block.addTyOp(.bit_reverse, operand_ty, operand);16314 return block.addTyOp(.bit_reverse, operand_ty, operand);
16008 },16315 },
16009 else => unreachable,16316 else => unreachable,
...@@ -16030,7 +16337,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -16030,7 +16337,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
16030 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;16337 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
1603116338
16032 const ty = try sema.resolveType(block, lhs_src, extra.lhs);16339 const ty = try sema.resolveType(block, lhs_src, extra.lhs);
16033 const field_name = try sema.resolveConstString(block, rhs_src, extra.rhs);16340 const field_name = try sema.resolveConstString(block, rhs_src, extra.rhs, "name of field must be comptime known");
16034 const target = sema.mod.getTarget();16341 const target = sema.mod.getTarget();
1603516342
16036 try sema.resolveTypeLayout(block, lhs_src, ty);16343 try sema.resolveTypeLayout(block, lhs_src, ty);
...@@ -16451,19 +16758,19 @@ fn resolveExportOptions(...@@ -16451,19 +16758,19 @@ fn resolveExportOptions(
16451 const options = try sema.coerce(block, export_options_ty, air_ref, src);16758 const options = try sema.coerce(block, export_options_ty, air_ref, src);
1645216759
16453 const name_operand = try sema.fieldVal(block, src, options, "name", src);16760 const name_operand = try sema.fieldVal(block, src, options, "name", src);
16454 const name_val = try sema.resolveConstValue(block, src, name_operand);16761 const name_val = try sema.resolveConstValue(block, src, name_operand, "name of exported value must be comptime known");
16455 const name_ty = Type.initTag(.const_slice_u8);16762 const name_ty = Type.initTag(.const_slice_u8);
16456 const name = try name_val.toAllocatedBytes(name_ty, sema.arena, sema.mod);16763 const name = try name_val.toAllocatedBytes(name_ty, sema.arena, sema.mod);
1645716764
16458 const linkage_operand = try sema.fieldVal(block, src, options, "linkage", src);16765 const linkage_operand = try sema.fieldVal(block, src, options, "linkage", src);
16459 const linkage_val = try sema.resolveConstValue(block, src, linkage_operand);16766 const linkage_val = try sema.resolveConstValue(block, src, linkage_operand, "linkage of exported value must be comptime known");
16460 const linkage = linkage_val.toEnum(std.builtin.GlobalLinkage);16767 const linkage = linkage_val.toEnum(std.builtin.GlobalLinkage);
1646116768
16462 const section = try sema.fieldVal(block, src, options, "section", src);16769 const section = try sema.fieldVal(block, src, options, "section", src);
16463 const section_val = try sema.resolveConstValue(block, src, section);16770 const section_val = try sema.resolveConstValue(block, src, section, "linksection of exported value must be comptime known");
1646416771
16465 const visibility_operand = try sema.fieldVal(block, src, options, "visibility", src);16772 const visibility_operand = try sema.fieldVal(block, src, options, "visibility", src);
16466 const visibility_val = try sema.resolveConstValue(block, src, visibility_operand);16773 const visibility_val = try sema.resolveConstValue(block, src, visibility_operand, "visibility of exported value must be comptime known");
16467 const visibility = visibility_val.toEnum(std.builtin.SymbolVisibility);16774 const visibility = visibility_val.toEnum(std.builtin.SymbolVisibility);
1646816775
16469 if (name.len < 1) {16776 if (name.len < 1) {
...@@ -16494,11 +16801,12 @@ fn resolveBuiltinEnum(...@@ -16494,11 +16801,12 @@ fn resolveBuiltinEnum(
16494 src: LazySrcLoc,16801 src: LazySrcLoc,
16495 zir_ref: Zir.Inst.Ref,16802 zir_ref: Zir.Inst.Ref,
16496 comptime name: []const u8,16803 comptime name: []const u8,
16804 reason: []const u8,
16497) CompileError!@field(std.builtin, name) {16805) CompileError!@field(std.builtin, name) {
16498 const ty = try sema.getBuiltinType(block, src, name);16806 const ty = try sema.getBuiltinType(block, src, name);
16499 const air_ref = try sema.resolveInst(zir_ref);16807 const air_ref = try sema.resolveInst(zir_ref);
16500 const coerced = try sema.coerce(block, ty, air_ref, src);16808 const coerced = try sema.coerce(block, ty, air_ref, src);
16501 const val = try sema.resolveConstValue(block, src, coerced);16809 const val = try sema.resolveConstValue(block, src, coerced, reason);
16502 return val.toEnum(@field(std.builtin, name));16810 return val.toEnum(@field(std.builtin, name));
16503}16811}
1650416812
...@@ -16507,8 +16815,9 @@ fn resolveAtomicOrder(...@@ -16507,8 +16815,9 @@ fn resolveAtomicOrder(
16507 block: *Block,16815 block: *Block,
16508 src: LazySrcLoc,16816 src: LazySrcLoc,
16509 zir_ref: Zir.Inst.Ref,16817 zir_ref: Zir.Inst.Ref,
16818 reason: []const u8,
16510) CompileError!std.builtin.AtomicOrder {16819) CompileError!std.builtin.AtomicOrder {
16511 return resolveBuiltinEnum(sema, block, src, zir_ref, "AtomicOrder");16820 return resolveBuiltinEnum(sema, block, src, zir_ref, "AtomicOrder", reason);
16512}16821}
1651316822
16514fn resolveAtomicRmwOp(16823fn resolveAtomicRmwOp(
...@@ -16517,7 +16826,7 @@ fn resolveAtomicRmwOp(...@@ -16517,7 +16826,7 @@ fn resolveAtomicRmwOp(
16517 src: LazySrcLoc,16826 src: LazySrcLoc,
16518 zir_ref: Zir.Inst.Ref,16827 zir_ref: Zir.Inst.Ref,
16519) CompileError!std.builtin.AtomicRmwOp {16828) CompileError!std.builtin.AtomicRmwOp {
16520 return resolveBuiltinEnum(sema, block, src, zir_ref, "AtomicRmwOp");16829 return resolveBuiltinEnum(sema, block, src, zir_ref, "AtomicRmwOp", "@atomicRmW operation must be comptime known");
16521}16830}
1652216831
16523fn zirCmpxchg(16832fn zirCmpxchg(
...@@ -16550,8 +16859,8 @@ fn zirCmpxchg(...@@ -16550,8 +16859,8 @@ fn zirCmpxchg(
16550 const uncasted_ptr = try sema.resolveInst(extra.ptr);16859 const uncasted_ptr = try sema.resolveInst(extra.ptr);
16551 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false);16860 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false);
16552 const new_value = try sema.coerce(block, elem_ty, try sema.resolveInst(extra.new_value), new_value_src);16861 const new_value = try sema.coerce(block, elem_ty, try sema.resolveInst(extra.new_value), new_value_src);
16553 const success_order = try sema.resolveAtomicOrder(block, success_order_src, extra.success_order);16862 const success_order = try sema.resolveAtomicOrder(block, success_order_src, extra.success_order, "atomic order of cmpxchg success must be comptime known");
16554 const failure_order = try sema.resolveAtomicOrder(block, failure_order_src, extra.failure_order);16863 const failure_order = try sema.resolveAtomicOrder(block, failure_order_src, extra.failure_order, "atomic order of cmpxchg failure must be comptime known");
1655516864
16556 if (@enumToInt(success_order) < @enumToInt(std.builtin.AtomicOrder.Monotonic)) {16865 if (@enumToInt(success_order) < @enumToInt(std.builtin.AtomicOrder.Monotonic)) {
16557 return sema.fail(block, success_order_src, "success atomic ordering must be Monotonic or stricter", .{});16866 return sema.fail(block, success_order_src, "success atomic ordering must be Monotonic or stricter", .{});
...@@ -16596,7 +16905,7 @@ fn zirCmpxchg(...@@ -16596,7 +16905,7 @@ fn zirCmpxchg(
16596 const flags: u32 = @as(u32, @enumToInt(success_order)) |16905 const flags: u32 = @as(u32, @enumToInt(success_order)) |
16597 (@as(u32, @enumToInt(failure_order)) << 3);16906 (@as(u32, @enumToInt(failure_order)) << 3);
1659816907
16599 try sema.requireRuntimeBlock(block, runtime_src);16908 try sema.requireRuntimeBlock(block, src, runtime_src);
16600 return block.addInst(.{16909 return block.addInst(.{
16601 .tag = air_tag,16910 .tag = air_tag,
16602 .data = .{ .ty_pl = .{16911 .data = .{ .ty_pl = .{
...@@ -16616,7 +16925,7 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -16616,7 +16925,7 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
16616 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;16925 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
16617 const len_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };16926 const len_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
16618 const scalar_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };16927 const scalar_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
16619 const len = @intCast(u32, try sema.resolveInt(block, len_src, extra.lhs, Type.u32));16928 const len = @intCast(u32, try sema.resolveInt(block, len_src, extra.lhs, Type.u32, "vector splat destination length must be comptime known"));
16620 const scalar = try sema.resolveInst(extra.rhs);16929 const scalar = try sema.resolveInst(extra.rhs);
16621 const scalar_ty = sema.typeOf(scalar);16930 const scalar_ty = sema.typeOf(scalar);
16622 try sema.checkVectorElemType(block, scalar_src, scalar_ty);16931 try sema.checkVectorElemType(block, scalar_src, scalar_ty);
...@@ -16633,7 +16942,7 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -16633,7 +16942,7 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
16633 );16942 );
16634 }16943 }
1663516944
16636 try sema.requireRuntimeBlock(block, scalar_src);16945 try sema.requireRuntimeBlock(block, inst_data.src(), scalar_src);
16637 return block.addTyOp(.splat, vector_ty, scalar);16946 return block.addTyOp(.splat, vector_ty, scalar);
16638}16947}
1663916948
...@@ -16642,7 +16951,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -16642,7 +16951,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
16642 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;16951 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
16643 const op_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };16952 const op_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
16644 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };16953 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
16645 const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, "ReduceOp");16954 const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, "ReduceOp", "@reduce operation must be comptime known");
16646 const operand = try sema.resolveInst(extra.rhs);16955 const operand = try sema.resolveInst(extra.rhs);
16647 const operand_ty = sema.typeOf(operand);16956 const operand_ty = sema.typeOf(operand);
16648 const target = sema.mod.getTarget();16957 const target = sema.mod.getTarget();
...@@ -16697,7 +17006,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -16697,7 +17006,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
16697 return sema.addConstant(scalar_ty, accum);17006 return sema.addConstant(scalar_ty, accum);
16698 }17007 }
1669917008
16700 try sema.requireRuntimeBlock(block, operand_src);17009 try sema.requireRuntimeBlock(block, inst_data.src(), operand_src);
16701 return block.addInst(.{17010 return block.addInst(.{
16702 .tag = .reduce,17011 .tag = .reduce,
16703 .data = .{ .reduce = .{17012 .data = .{ .reduce = .{
...@@ -16729,7 +17038,7 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -16729,7 +17038,7 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
16729 .elem_type = Type.@"i32",17038 .elem_type = Type.@"i32",
16730 });17039 });
16731 mask = try sema.coerce(block, mask_ty, mask, mask_src);17040 mask = try sema.coerce(block, mask_ty, mask, mask_src);
16732 const mask_val = try sema.resolveConstMaybeUndefVal(block, mask_src, mask);17041 const mask_val = try sema.resolveConstMaybeUndefVal(block, mask_src, mask, "shuffle mask must be comptime known");
16733 return sema.analyzeShuffle(block, inst_data.src_node, elem_ty, a, b, mask_val, @intCast(u32, mask_len));17042 return sema.analyzeShuffle(block, inst_data.src_node, elem_ty, a, b, mask_val, @intCast(u32, mask_len));
16734}17043}
1673517044
...@@ -16901,6 +17210,7 @@ fn analyzeShuffle(...@@ -16901,6 +17210,7 @@ fn analyzeShuffle(
16901fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {17210fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
16902 const extra = sema.code.extraData(Zir.Inst.Select, extended.operand).data;17211 const extra = sema.code.extraData(Zir.Inst.Select, extended.operand).data;
1690317212
17213 const src = LazySrcLoc.nodeOffset(extra.node);
16904 const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };17214 const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
16905 const pred_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };17215 const pred_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
16906 const a_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = extra.node };17216 const a_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = extra.node };
...@@ -16972,7 +17282,7 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -16972,7 +17282,7 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
16972 break :rs pred_src;17282 break :rs pred_src;
16973 };17283 };
1697417284
16975 try sema.requireRuntimeBlock(block, runtime_src);17285 try sema.requireRuntimeBlock(block, src, runtime_src);
16976 return block.addInst(.{17286 return block.addInst(.{
16977 .tag = .select,17287 .tag = .select,
16978 .data = .{ .pl_op = .{17288 .data = .{ .pl_op = .{
...@@ -16996,7 +17306,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -16996,7 +17306,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
16996 const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type);17306 const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type);
16997 const uncasted_ptr = try sema.resolveInst(extra.ptr);17307 const uncasted_ptr = try sema.resolveInst(extra.ptr);
16998 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, true);17308 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, true);
16999 const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering);17309 const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering, "atomic order of @atomicLoad must be comptime known");
1700017310
17001 switch (order) {17311 switch (order) {
17002 .Release, .AcqRel => {17312 .Release, .AcqRel => {
...@@ -17020,7 +17330,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -17020,7 +17330,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
17020 }17330 }
17021 }17331 }
1702217332
17023 try sema.requireRuntimeBlock(block, ptr_src);17333 try sema.requireRuntimeBlock(block, inst_data.src(), ptr_src);
17024 return block.addInst(.{17334 return block.addInst(.{
17025 .tag = .atomic_load,17335 .tag = .atomic_load,
17026 .data = .{ .atomic_load = .{17336 .data = .{ .atomic_load = .{
...@@ -17060,7 +17370,7 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -17060,7 +17370,7 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
17060 },17370 },
17061 else => {},17371 else => {},
17062 }17372 }
17063 const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering);17373 const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering, "atomic order of @atomicRmW must be comptime known");
1706417374
17065 if (order == .Unordered) {17375 if (order == .Unordered) {
17066 return sema.fail(block, order_src, "@atomicRmw atomic ordering must not be Unordered", .{});17376 return sema.fail(block, order_src, "@atomicRmw atomic ordering must not be Unordered", .{});
...@@ -17101,7 +17411,7 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -17101,7 +17411,7 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1710117411
17102 const flags: u32 = @as(u32, @enumToInt(order)) | (@as(u32, @enumToInt(op)) << 3);17412 const flags: u32 = @as(u32, @enumToInt(order)) | (@as(u32, @enumToInt(op)) << 3);
1710317413
17104 try sema.requireRuntimeBlock(block, runtime_src);17414 try sema.requireRuntimeBlock(block, src, runtime_src);
17105 return block.addInst(.{17415 return block.addInst(.{
17106 .tag = .atomic_rmw,17416 .tag = .atomic_rmw,
17107 .data = .{ .pl_op = .{17417 .data = .{ .pl_op = .{
...@@ -17128,7 +17438,7 @@ fn zirAtomicStore(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -17128,7 +17438,7 @@ fn zirAtomicStore(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
17128 const elem_ty = sema.typeOf(operand);17438 const elem_ty = sema.typeOf(operand);
17129 const uncasted_ptr = try sema.resolveInst(extra.ptr);17439 const uncasted_ptr = try sema.resolveInst(extra.ptr);
17130 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false);17440 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false);
17131 const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering);17441 const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering, "atomic order of @atomicStore must be comptime known");
1713217442
17133 const air_tag: Air.Inst.Tag = switch (order) {17443 const air_tag: Air.Inst.Tag = switch (order) {
17134 .Acquire, .AcqRel => {17444 .Acquire, .AcqRel => {
...@@ -17200,7 +17510,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -17200,7 +17510,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
17200 break :rs mulend1_src;17510 break :rs mulend1_src;
17201 };17511 };
1720217512
17203 try sema.requireRuntimeBlock(block, runtime_src);17513 try sema.requireRuntimeBlock(block, src, runtime_src);
17204 return block.addInst(.{17514 return block.addInst(.{
17205 .tag = .mul_add,17515 .tag = .mul_add,
17206 .data = .{ .pl_op = .{17516 .data = .{ .pl_op = .{
...@@ -17233,10 +17543,10 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -17233,10 +17543,10 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
17233 const coerced_options = try sema.coerce(block, call_options_ty, options, options_src);17543 const coerced_options = try sema.coerce(block, call_options_ty, options, options_src);
1723417544
17235 const modifier = try sema.fieldVal(block, options_src, coerced_options, "modifier", options_src);17545 const modifier = try sema.fieldVal(block, options_src, coerced_options, "modifier", options_src);
17236 const modifier_val = try sema.resolveConstValue(block, options_src, modifier);17546 const modifier_val = try sema.resolveConstValue(block, options_src, modifier, "call modifier must be comptime known");
1723717547
17238 const stack = try sema.fieldVal(block, options_src, coerced_options, "stack", options_src);17548 const stack = try sema.fieldVal(block, options_src, coerced_options, "stack", options_src);
17239 const stack_val = try sema.resolveConstValue(block, options_src, stack);17549 const stack_val = try sema.resolveConstValue(block, options_src, stack, "call stack value must be comptime known");
1724017550
17241 if (!stack_val.isNull()) {17551 if (!stack_val.isNull()) {
17242 return sema.fail(block, options_src, "TODO: implement @call with stack", .{});17552 return sema.fail(block, options_src, "TODO: implement @call with stack", .{});
...@@ -17297,7 +17607,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -17297,7 +17607,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1729717607
17298 // Desugar bound functions here17608 // Desugar bound functions here
17299 if (sema.typeOf(func).tag() == .bound_fn) {17609 if (sema.typeOf(func).tag() == .bound_fn) {
17300 const bound_func = try sema.resolveValue(block, func_src, func);17610 const bound_func = try sema.resolveValue(block, .unneeded, func, undefined);
17301 const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data;17611 const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data;
17302 func = bound_data.func_inst;17612 func = bound_data.func_inst;
17303 resolved_args = try sema.arena.alloc(Air.Inst.Ref, args_ty.structFieldCount() + 1);17613 resolved_args = try sema.arena.alloc(Air.Inst.Ref, args_ty.structFieldCount() + 1);
...@@ -17324,7 +17634,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -17324,7 +17634,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
17324 const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };17634 const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
1732517635
17326 const struct_ty = try sema.resolveType(block, ty_src, extra.parent_type);17636 const struct_ty = try sema.resolveType(block, ty_src, extra.parent_type);
17327 const field_name = try sema.resolveConstString(block, name_src, extra.field_name);17637 const field_name = try sema.resolveConstString(block, name_src, extra.field_name, "field name must be comptime known");
17328 const field_ptr = try sema.resolveInst(extra.field_ptr);17638 const field_ptr = try sema.resolveInst(extra.field_ptr);
17329 const field_ptr_ty = sema.typeOf(field_ptr);17639 const field_ptr_ty = sema.typeOf(field_ptr);
1733017640
...@@ -17389,7 +17699,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -17389,7 +17699,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
17389 return sema.addConstant(result_ptr, payload.data.container_ptr);17699 return sema.addConstant(result_ptr, payload.data.container_ptr);
17390 }17700 }
1739117701
17392 try sema.requireRuntimeBlock(block, src);17702 try sema.requireRuntimeBlock(block, src, ptr_src);
17393 return block.addInst(.{17703 return block.addInst(.{
17394 .tag = .field_parent_ptr,17704 .tag = .field_parent_ptr,
17395 .data = .{ .ty_pl = .{17705 .data = .{ .ty_pl = .{
...@@ -17470,7 +17780,7 @@ fn analyzeMinMax(...@@ -17470,7 +17780,7 @@ fn analyzeMinMax(
17470 break :rs lhs_src;17780 break :rs lhs_src;
17471 };17781 };
1747217782
17473 try sema.requireRuntimeBlock(block, runtime_src);17783 try sema.requireRuntimeBlock(block, src, runtime_src);
17474 return block.addBinOp(air_tag, simd_op.lhs, simd_op.rhs);17784 return block.addBinOp(air_tag, simd_op.lhs, simd_op.rhs);
17475}17785}
1747617786
...@@ -17518,7 +17828,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -17518,7 +17828,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
17518 } else break :rs src_src;17828 } else break :rs src_src;
17519 } else dest_src;17829 } else dest_src;
1752017830
17521 try sema.requireRuntimeBlock(block, runtime_src);17831 try sema.requireRuntimeBlock(block, src, runtime_src);
17522 _ = try block.addInst(.{17832 _ = try block.addInst(.{
17523 .tag = .memcpy,17833 .tag = .memcpy,
17524 .data = .{ .pl_op = .{17834 .data = .{ .pl_op = .{
...@@ -17560,7 +17870,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -17560,7 +17870,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
17560 } else break :rs len_src;17870 } else break :rs len_src;
17561 } else dest_src;17871 } else dest_src;
1756217872
17563 try sema.requireRuntimeBlock(block, runtime_src);17873 try sema.requireRuntimeBlock(block, src, runtime_src);
17564 _ = try block.addInst(.{17874 _ = try block.addInst(.{
17565 .tag = .memset,17875 .tag = .memset,
17566 .data = .{ .pl_op = .{17876 .data = .{ .pl_op = .{
...@@ -17656,7 +17966,7 @@ fn zirVarExtended(...@@ -17656,7 +17966,7 @@ fn zirVarExtended(
17656 uncasted_init;17966 uncasted_init;
1765717967
17658 break :blk (try sema.resolveMaybeUndefVal(block, init_src, init)) orelse17968 break :blk (try sema.resolveMaybeUndefVal(block, init_src, init)) orelse
17659 return sema.failWithNeededComptime(block, init_src);17969 return sema.failWithNeededComptime(block, init_src, "container level variable initializers must be comptime known");
17660 } else Value.initTag(.unreachable_value);17970 } else Value.initTag(.unreachable_value);
1766117971
17662 try sema.validateVarType(block, name_src, var_ty, small.is_extern);17972 try sema.validateVarType(block, name_src, var_ty, small.is_extern);
...@@ -17694,15 +18004,15 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -17694,15 +18004,15 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
17694 defer tracy.end();18004 defer tracy.end();
1769518005
17696 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;18006 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
17697 const src = inst_data.src();
17698 const extra = sema.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index);18007 const extra = sema.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index);
17699 const target = sema.mod.getTarget();18008 const target = sema.mod.getTarget();
1770018009
17701 const align_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at align18010 const align_src: LazySrcLoc = .{ .node_offset_fn_type_align = inst_data.src_node };
17702 const addrspace_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at addrspace18011 const addrspace_src: LazySrcLoc = .{ .node_offset_fn_type_addrspace = inst_data.src_node };
17703 const section_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at section18012 const section_src: LazySrcLoc = .{ .node_offset_fn_type_section = inst_data.src_node };
17704 const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = inst_data.src_node };18013 const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = inst_data.src_node };
17705 const ret_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at the return type18014 const ret_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = inst_data.src_node };
18015 const has_body = extra.data.body_len != 0;
1770618016
17707 var extra_index: usize = extra.end;18017 var extra_index: usize = extra.end;
1770818018
...@@ -17712,17 +18022,25 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -17712,17 +18022,25 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
17712 break :blk lib_name;18022 break :blk lib_name;
17713 } else null;18023 } else null;
1771418024
18025 if (has_body and
18026 (extra.data.bits.has_align_body or extra.data.bits.has_align_ref) and
18027 !target_util.supportsFunctionAlignment(target))
18028 {
18029 return sema.fail(block, align_src, "target does not support function alignment", .{});
18030 }
18031
17715 const @"align": ?u32 = if (extra.data.bits.has_align_body) blk: {18032 const @"align": ?u32 = if (extra.data.bits.has_align_body) blk: {
17716 const body_len = sema.code.extra[extra_index];18033 const body_len = sema.code.extra[extra_index];
17717 extra_index += 1;18034 extra_index += 1;
17718 const body = sema.code.extra[extra_index..][0..body_len];18035 const body = sema.code.extra[extra_index..][0..body_len];
17719 extra_index += body.len;18036 extra_index += body.len;
1772018037
17721 const val = try sema.resolveGenericBody(block, align_src, body, inst, Type.u29);18038 const val = try sema.resolveGenericBody(block, align_src, body, inst, Type.u29, "alignment must be comptime known");
17722 if (val.tag() == .generic_poison) {18039 if (val.tag() == .generic_poison) {
17723 break :blk null;18040 break :blk null;
17724 }18041 }
17725 const alignment = @intCast(u32, val.toUnsignedInt(target));18042 const alignment = @intCast(u32, val.toUnsignedInt(target));
18043 try sema.validateAlign(block, align_src, alignment);
17726 if (alignment == target_util.defaultFunctionAlignment(target)) {18044 if (alignment == target_util.defaultFunctionAlignment(target)) {
17727 break :blk 0;18045 break :blk 0;
17728 } else {18046 } else {
...@@ -17731,13 +18049,14 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -17731,13 +18049,14 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
17731 } else if (extra.data.bits.has_align_ref) blk: {18049 } else if (extra.data.bits.has_align_ref) blk: {
17732 const align_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);18050 const align_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
17733 extra_index += 1;18051 extra_index += 1;
17734 const align_tv = sema.resolveInstConst(block, align_src, align_ref) catch |err| switch (err) {18052 const align_tv = sema.resolveInstConst(block, align_src, align_ref, "alignment must be comptime known") catch |err| switch (err) {
17735 error.GenericPoison => {18053 error.GenericPoison => {
17736 break :blk null;18054 break :blk null;
17737 },18055 },
17738 else => |e| return e,18056 else => |e| return e,
17739 };18057 };
17740 const alignment = @intCast(u32, align_tv.val.toUnsignedInt(target));18058 const alignment = @intCast(u32, align_tv.val.toUnsignedInt(target));
18059 try sema.validateAlign(block, align_src, alignment);
17741 if (alignment == target_util.defaultFunctionAlignment(target)) {18060 if (alignment == target_util.defaultFunctionAlignment(target)) {
17742 break :blk 0;18061 break :blk 0;
17743 } else {18062 } else {
...@@ -17752,7 +18071,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -17752,7 +18071,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
17752 extra_index += body.len;18071 extra_index += body.len;
1775318072
17754 const addrspace_ty = try sema.getBuiltinType(block, addrspace_src, "AddressSpace");18073 const addrspace_ty = try sema.getBuiltinType(block, addrspace_src, "AddressSpace");
17755 const val = try sema.resolveGenericBody(block, addrspace_src, body, inst, addrspace_ty);18074 const val = try sema.resolveGenericBody(block, addrspace_src, body, inst, addrspace_ty, "addrespace must be comptime known");
17756 if (val.tag() == .generic_poison) {18075 if (val.tag() == .generic_poison) {
17757 break :blk null;18076 break :blk null;
17758 }18077 }
...@@ -17760,7 +18079,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -17760,7 +18079,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
17760 } else if (extra.data.bits.has_addrspace_ref) blk: {18079 } else if (extra.data.bits.has_addrspace_ref) blk: {
17761 const addrspace_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);18080 const addrspace_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
17762 extra_index += 1;18081 extra_index += 1;
17763 const addrspace_tv = sema.resolveInstConst(block, addrspace_src, addrspace_ref) catch |err| switch (err) {18082 const addrspace_tv = sema.resolveInstConst(block, addrspace_src, addrspace_ref, "addrespace must be comptime known") catch |err| switch (err) {
17764 error.GenericPoison => {18083 error.GenericPoison => {
17765 break :blk null;18084 break :blk null;
17766 },18085 },
...@@ -17775,7 +18094,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -17775,7 +18094,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
17775 const body = sema.code.extra[extra_index..][0..body_len];18094 const body = sema.code.extra[extra_index..][0..body_len];
17776 extra_index += body.len;18095 extra_index += body.len;
1777718096
17778 const val = try sema.resolveGenericBody(block, section_src, body, inst, Type.initTag(.const_slice_u8));18097 const val = try sema.resolveGenericBody(block, section_src, body, inst, Type.initTag(.const_slice_u8), "linksection must be comptime known");
17779 if (val.tag() == .generic_poison) {18098 if (val.tag() == .generic_poison) {
17780 break :blk FuncLinkSection{ .generic = {} };18099 break :blk FuncLinkSection{ .generic = {} };
17781 }18100 }
...@@ -17784,7 +18103,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -17784,7 +18103,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
17784 } else if (extra.data.bits.has_section_ref) blk: {18103 } else if (extra.data.bits.has_section_ref) blk: {
17785 const section_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);18104 const section_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
17786 extra_index += 1;18105 extra_index += 1;
17787 const section_tv = sema.resolveInstConst(block, section_src, section_ref) catch |err| switch (err) {18106 const section_tv = sema.resolveInstConst(block, section_src, section_ref, "linksection must be comptime known") catch |err| switch (err) {
17788 error.GenericPoison => {18107 error.GenericPoison => {
17789 break :blk FuncLinkSection{ .generic = {} };18108 break :blk FuncLinkSection{ .generic = {} };
17790 },18109 },
...@@ -17801,7 +18120,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -17801,7 +18120,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
17801 extra_index += body.len;18120 extra_index += body.len;
1780218121
17803 const cc_ty = try sema.getBuiltinType(block, addrspace_src, "CallingConvention");18122 const cc_ty = try sema.getBuiltinType(block, addrspace_src, "CallingConvention");
17804 const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty);18123 const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, "calling convention must be comptime known");
17805 if (val.tag() == .generic_poison) {18124 if (val.tag() == .generic_poison) {
17806 break :blk null;18125 break :blk null;
17807 }18126 }
...@@ -17809,7 +18128,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -17809,7 +18128,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
17809 } else if (extra.data.bits.has_cc_ref) blk: {18128 } else if (extra.data.bits.has_cc_ref) blk: {
17810 const cc_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);18129 const cc_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
17811 extra_index += 1;18130 extra_index += 1;
17812 const cc_tv = sema.resolveInstConst(block, cc_src, cc_ref) catch |err| switch (err) {18131 const cc_tv = sema.resolveInstConst(block, cc_src, cc_ref, "calling convention must be comptime known") catch |err| switch (err) {
17813 error.GenericPoison => {18132 error.GenericPoison => {
17814 break :blk null;18133 break :blk null;
17815 },18134 },
...@@ -17824,14 +18143,14 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -17824,14 +18143,14 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
17824 const body = sema.code.extra[extra_index..][0..body_len];18143 const body = sema.code.extra[extra_index..][0..body_len];
17825 extra_index += body.len;18144 extra_index += body.len;
1782618145
17827 const val = try sema.resolveGenericBody(block, ret_src, body, inst, Type.type);18146 const val = try sema.resolveGenericBody(block, ret_src, body, inst, Type.type, "return type must be comptime known");
17828 var buffer: Value.ToTypeBuffer = undefined;18147 var buffer: Value.ToTypeBuffer = undefined;
17829 const ty = try val.toType(&buffer).copy(sema.arena);18148 const ty = try val.toType(&buffer).copy(sema.arena);
17830 break :blk ty;18149 break :blk ty;
17831 } else if (extra.data.bits.has_ret_ty_ref) blk: {18150 } else if (extra.data.bits.has_ret_ty_ref) blk: {
17832 const ret_ty_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);18151 const ret_ty_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
17833 extra_index += 1;18152 extra_index += 1;
17834 const ret_ty_tv = sema.resolveInstConst(block, ret_src, ret_ty_ref) catch |err| switch (err) {18153 const ret_ty_tv = sema.resolveInstConst(block, ret_src, ret_ty_ref, "return type must be comptime known") catch |err| switch (err) {
17835 error.GenericPoison => {18154 error.GenericPoison => {
17836 break :blk Type.initTag(.generic_poison);18155 break :blk Type.initTag(.generic_poison);
17837 },18156 },
...@@ -17849,7 +18168,6 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -17849,7 +18168,6 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
17849 } else 0;18168 } else 0;
1785018169
17851 var src_locs: Zir.Inst.Func.SrcLocs = undefined;18170 var src_locs: Zir.Inst.Func.SrcLocs = undefined;
17852 const has_body = extra.data.body_len != 0;
17853 if (has_body) {18171 if (has_body) {
17854 extra_index += extra.data.body_len;18172 extra_index += extra.data.body_len;
17855 src_locs = sema.code.extraData(Zir.Inst.Func.SrcLocs, extra_index).data;18173 src_locs = sema.code.extraData(Zir.Inst.Func.SrcLocs, extra_index).data;
...@@ -17886,7 +18204,7 @@ fn zirCUndef(...@@ -17886,7 +18204,7 @@ fn zirCUndef(
17886 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;18204 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
17887 const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };18205 const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
1788818206
17889 const name = try sema.resolveConstString(block, src, extra.operand);18207 const name = try sema.resolveConstString(block, src, extra.operand, "name of macro being undefined must be comptime known");
17890 try block.c_import_buf.?.writer().print("#undefine {s}\n", .{name});18208 try block.c_import_buf.?.writer().print("#undefine {s}\n", .{name});
17891 return Air.Inst.Ref.void_value;18209 return Air.Inst.Ref.void_value;
17892}18210}
...@@ -17899,7 +18217,7 @@ fn zirCInclude(...@@ -17899,7 +18217,7 @@ fn zirCInclude(
17899 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;18217 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
17900 const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };18218 const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
1790118219
17902 const name = try sema.resolveConstString(block, src, extra.operand);18220 const name = try sema.resolveConstString(block, src, extra.operand, "path being included must be comptime known");
17903 try block.c_import_buf.?.writer().print("#include <{s}>\n", .{name});18221 try block.c_import_buf.?.writer().print("#include <{s}>\n", .{name});
17904 return Air.Inst.Ref.void_value;18222 return Air.Inst.Ref.void_value;
17905}18223}
...@@ -17913,10 +18231,10 @@ fn zirCDefine(...@@ -17913,10 +18231,10 @@ fn zirCDefine(
17913 const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };18231 const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
17914 const val_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };18232 const val_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
1791518233
17916 const name = try sema.resolveConstString(block, name_src, extra.lhs);18234 const name = try sema.resolveConstString(block, name_src, extra.lhs, "name of macro being undefined must be comptime known");
17917 const rhs = try sema.resolveInst(extra.rhs);18235 const rhs = try sema.resolveInst(extra.rhs);
17918 if (sema.typeOf(rhs).zigTypeTag() != .Void) {18236 if (sema.typeOf(rhs).zigTypeTag() != .Void) {
17919 const value = try sema.resolveConstString(block, val_src, extra.rhs);18237 const value = try sema.resolveConstString(block, val_src, extra.rhs, "value of macro being undefined must be comptime known");
17920 try block.c_import_buf.?.writer().print("#define {s} {s}\n", .{ name, value });18238 try block.c_import_buf.?.writer().print("#define {s} {s}\n", .{ name, value });
17921 } else {18239 } else {
17922 try block.c_import_buf.?.writer().print("#define {s}\n", .{name});18240 try block.c_import_buf.?.writer().print("#define {s}\n", .{name});
...@@ -17937,8 +18255,8 @@ fn zirWasmMemorySize(...@@ -17937,8 +18255,8 @@ fn zirWasmMemorySize(
17937 return sema.fail(block, builtin_src, "builtin @wasmMemorySize is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});18255 return sema.fail(block, builtin_src, "builtin @wasmMemorySize is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});
17938 }18256 }
1793918257
17940 const index = @intCast(u32, try sema.resolveInt(block, index_src, extra.operand, Type.u32));18258 const index = @intCast(u32, try sema.resolveInt(block, index_src, extra.operand, Type.u32, "wasm memory size index must be comptime known"));
17941 try sema.requireRuntimeBlock(block, builtin_src);18259 try sema.requireRuntimeBlock(block, builtin_src, null);
17942 return block.addInst(.{18260 return block.addInst(.{
17943 .tag = .wasm_memory_size,18261 .tag = .wasm_memory_size,
17944 .data = .{ .pl_op = .{18262 .data = .{ .pl_op = .{
...@@ -17962,10 +18280,10 @@ fn zirWasmMemoryGrow(...@@ -17962,10 +18280,10 @@ fn zirWasmMemoryGrow(
17962 return sema.fail(block, builtin_src, "builtin @wasmMemoryGrow is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});18280 return sema.fail(block, builtin_src, "builtin @wasmMemoryGrow is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});
17963 }18281 }
1796418282
17965 const index = @intCast(u32, try sema.resolveInt(block, index_src, extra.lhs, Type.u32));18283 const index = @intCast(u32, try sema.resolveInt(block, index_src, extra.lhs, Type.u32, "wasm memory size index must be comptime known"));
17966 const delta = try sema.coerce(block, Type.u32, try sema.resolveInst(extra.rhs), delta_src);18284 const delta = try sema.coerce(block, Type.u32, try sema.resolveInst(extra.rhs), delta_src);
1796718285
17968 try sema.requireRuntimeBlock(block, builtin_src);18286 try sema.requireRuntimeBlock(block, builtin_src, null);
17969 return block.addInst(.{18287 return block.addInst(.{
17970 .tag = .wasm_memory_grow,18288 .tag = .wasm_memory_grow,
17971 .data = .{ .pl_op = .{18289 .data = .{ .pl_op = .{
...@@ -17990,15 +18308,15 @@ fn zirPrefetch(...@@ -17990,15 +18308,15 @@ fn zirPrefetch(
17990 const target = sema.mod.getTarget();18308 const target = sema.mod.getTarget();
1799118309
17992 const rw = try sema.fieldVal(block, opts_src, options, "rw", opts_src);18310 const rw = try sema.fieldVal(block, opts_src, options, "rw", opts_src);
17993 const rw_val = try sema.resolveConstValue(block, opts_src, rw);18311 const rw_val = try sema.resolveConstValue(block, opts_src, rw, "prefetch read/write must be comptime known");
17994 const rw_tag = rw_val.toEnum(std.builtin.PrefetchOptions.Rw);18312 const rw_tag = rw_val.toEnum(std.builtin.PrefetchOptions.Rw);
1799518313
17996 const locality = try sema.fieldVal(block, opts_src, options, "locality", opts_src);18314 const locality = try sema.fieldVal(block, opts_src, options, "locality", opts_src);
17997 const locality_val = try sema.resolveConstValue(block, opts_src, locality);18315 const locality_val = try sema.resolveConstValue(block, opts_src, locality, "prefetch locality must be comptime known");
17998 const locality_int = @intCast(u2, locality_val.toUnsignedInt(target));18316 const locality_int = @intCast(u2, locality_val.toUnsignedInt(target));
1799918317
18000 const cache = try sema.fieldVal(block, opts_src, options, "cache", opts_src);18318 const cache = try sema.fieldVal(block, opts_src, options, "cache", opts_src);
18001 const cache_val = try sema.resolveConstValue(block, opts_src, cache);18319 const cache_val = try sema.resolveConstValue(block, opts_src, cache, "prefetch cache must be comptime known");
18002 const cache_tag = cache_val.toEnum(std.builtin.PrefetchOptions.Cache);18320 const cache_tag = cache_val.toEnum(std.builtin.PrefetchOptions.Cache);
1800318321
18004 if (!block.is_comptime) {18322 if (!block.is_comptime) {
...@@ -18035,16 +18353,16 @@ fn zirBuiltinExtern(...@@ -18035,16 +18353,16 @@ fn zirBuiltinExtern(
18035 const options = try sema.coerce(block, extern_options_ty, options_inst, options_src);18353 const options = try sema.coerce(block, extern_options_ty, options_inst, options_src);
1803618354
18037 const name = try sema.fieldVal(block, options_src, options, "name", options_src);18355 const name = try sema.fieldVal(block, options_src, options, "name", options_src);
18038 const name_val = try sema.resolveConstValue(block, options_src, name);18356 const name_val = try sema.resolveConstValue(block, options_src, name, "name of the extern symbol must be comptime known");
1803918357
18040 const library_name_inst = try sema.fieldVal(block, options_src, options, "library_name", options_src);18358 const library_name_inst = try sema.fieldVal(block, options_src, options, "library_name", options_src);
18041 const library_name_val = try sema.resolveConstValue(block, options_src, library_name_inst);18359 const library_name_val = try sema.resolveConstValue(block, options_src, library_name_inst, "library in which extern symbol is must be comptime known");
1804218360
18043 const linkage = try sema.fieldVal(block, options_src, options, "linkage", options_src);18361 const linkage = try sema.fieldVal(block, options_src, options, "linkage", options_src);
18044 const linkage_val = try sema.resolveConstValue(block, options_src, linkage);18362 const linkage_val = try sema.resolveConstValue(block, options_src, linkage, "linkage of the extern symbol must be comptime known");
1804518363
18046 const is_thread_local = try sema.fieldVal(block, options_src, options, "is_thread_local", options_src);18364 const is_thread_local = try sema.fieldVal(block, options_src, options, "is_thread_local", options_src);
18047 const is_thread_local_val = try sema.resolveConstValue(block, options_src, is_thread_local);18365 const is_thread_local_val = try sema.resolveConstValue(block, options_src, is_thread_local, "threadlocality of the extern symbol must be comptime known");
1804818366
18049 var library_name: ?[]const u8 = null;18367 var library_name: ?[]const u8 = null;
18050 if (!library_name_val.isNull()) {18368 if (!library_name_val.isNull()) {
...@@ -18121,19 +18439,30 @@ fn zirBuiltinExtern(...@@ -18121,19 +18439,30 @@ fn zirBuiltinExtern(
18121 new_decl.value_arena = arena_state;18439 new_decl.value_arena = arena_state;
1812218440
18123 const ref = try sema.analyzeDeclRef(new_decl_index);18441 const ref = try sema.analyzeDeclRef(new_decl_index);
18124 try sema.requireRuntimeBlock(block, src);18442 try sema.requireRuntimeBlock(block, src, null);
18125 return block.addBitCast(ty, ref);18443 return block.addBitCast(ty, ref);
18126}18444}
1812718445
18446/// Asserts that the block is not comptime.
18128fn requireFunctionBlock(sema: *Sema, block: *Block, src: LazySrcLoc) !void {18447fn requireFunctionBlock(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
18448 assert(!block.is_comptime);
18129 if (sema.func == null and !block.is_typeof and !block.is_coerce_result_ptr) {18449 if (sema.func == null and !block.is_typeof and !block.is_coerce_result_ptr) {
18130 return sema.fail(block, src, "instruction illegal outside function body", .{});18450 return sema.fail(block, src, "instruction illegal outside function body", .{});
18131 }18451 }
18132}18452}
1813318453
18134fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc) !void {18454fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc, runtime_src: ?LazySrcLoc) !void {
18135 if (block.is_comptime) {18455 if (block.is_comptime) {
18136 return sema.failWithNeededComptime(block, src);18456 const msg = msg: {
18457 const msg = try sema.errMsg(block, src, "unable to evalutate comptime expression", .{});
18458 errdefer msg.destroy(sema.gpa);
18459
18460 if (runtime_src) |some| {
18461 try sema.errNote(block, some, msg, "operation is runtime due to this operand", .{});
18462 }
18463 break :msg msg;
18464 };
18465 return sema.failWithOwnedErrorMsg(block, msg);
18137 }18466 }
18138 try sema.requireFunctionBlock(block, src);18467 try sema.requireFunctionBlock(block, src);
18139}18468}
...@@ -18337,6 +18666,8 @@ const ExternPosition = enum {...@@ -18337,6 +18666,8 @@ const ExternPosition = enum {
18337 other,18666 other,
18338};18667};
1833918668
18669/// Returns true if `ty` is allowed in extern types.
18670/// Does *NOT* require `ty` to be resolved in any way.
18340fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileError!bool {18671fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileError!bool {
18341 switch (ty.zigTypeTag()) {18672 switch (ty.zigTypeTag()) {
18342 .Type,18673 .Type,
...@@ -18350,7 +18681,7 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr...@@ -18350,7 +18681,7 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr
18350 .BoundFn,18681 .BoundFn,
18351 .Frame,18682 .Frame,
18352 => return false,18683 => return false,
18353 .Void => return position == .union_field,18684 .Void => return position == .union_field or position == .ret_ty,
18354 .NoReturn => return position == .ret_ty,18685 .NoReturn => return position == .ret_ty,
18355 .Opaque,18686 .Opaque,
18356 .Bool,18687 .Bool,
...@@ -18362,7 +18693,7 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr...@@ -18362,7 +18693,7 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr
18362 8, 16, 32, 64, 128 => return true,18693 8, 16, 32, 64, 128 => return true,
18363 else => return false,18694 else => return false,
18364 },18695 },
18365 .Fn => return !ty.fnCallingConventionAllowsZigTypes(),18696 .Fn => return !Type.fnCallingConventionAllowsZigTypes(ty.fnCallingConvention()),
18366 .Enum => {18697 .Enum => {
18367 var buf: Type.Payload.Bits = undefined;18698 var buf: Type.Payload.Bits = undefined;
18368 return sema.validateExternType(ty.intTagType(&buf), position);18699 return sema.validateExternType(ty.intTagType(&buf), position);
...@@ -18433,9 +18764,9 @@ fn explainWhyTypeIsNotExtern(...@@ -18433,9 +18764,9 @@ fn explainWhyTypeIsNotExtern(
18433 .Union => try mod.errNoteNonLazy(src_loc, msg, "only unions with packed or extern layout are extern compatible", .{}),18764 .Union => try mod.errNoteNonLazy(src_loc, msg, "only unions with packed or extern layout are extern compatible", .{}),
18434 .Array => {18765 .Array => {
18435 if (position == .ret_ty) {18766 if (position == .ret_ty) {
18436 try mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a return type", .{});18767 return mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a return type", .{});
18437 } else if (position == .param_ty) {18768 } else if (position == .param_ty) {
18438 try mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a parameter type", .{});18769 return mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a parameter type", .{});
18439 }18770 }
18440 try sema.explainWhyTypeIsNotExtern(block, src, msg, src_loc, ty.elemType2(), position);18771 try sema.explainWhyTypeIsNotExtern(block, src, msg, src_loc, ty.elemType2(), position);
18441 },18772 },
...@@ -18972,7 +19303,7 @@ fn fieldPtr(...@@ -18972,7 +19303,7 @@ fn fieldPtr(
18972 }),19303 }),
18973 );19304 );
18974 }19305 }
18975 try sema.requireRuntimeBlock(block, src);19306 try sema.requireRuntimeBlock(block, src, null);
1897619307
18977 return block.addTyOp(.ptr_slice_ptr_ptr, result_ty, inner_ptr);19308 return block.addTyOp(.ptr_slice_ptr_ptr, result_ty, inner_ptr);
18978 } else if (mem.eql(u8, field_name, "len")) {19309 } else if (mem.eql(u8, field_name, "len")) {
...@@ -18992,7 +19323,7 @@ fn fieldPtr(...@@ -18992,7 +19323,7 @@ fn fieldPtr(
18992 }),19323 }),
18993 );19324 );
18994 }19325 }
18995 try sema.requireRuntimeBlock(block, src);19326 try sema.requireRuntimeBlock(block, src, null);
1899619327
18997 return block.addTyOp(.ptr_slice_len_ptr, result_ty, inner_ptr);19328 return block.addTyOp(.ptr_slice_len_ptr, result_ty, inner_ptr);
18998 } else {19329 } else {
...@@ -19005,7 +19336,7 @@ fn fieldPtr(...@@ -19005,7 +19336,7 @@ fn fieldPtr(
19005 }19336 }
19006 },19337 },
19007 .Type => {19338 .Type => {
19008 _ = try sema.resolveConstValue(block, object_ptr_src, object_ptr);19339 _ = try sema.resolveConstValue(block, .unneeded, object_ptr, undefined);
19009 const result = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src);19340 const result = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src);
19010 const inner = if (is_pointer_to)19341 const inner = if (is_pointer_to)
19011 try sema.analyzeLoad(block, src, result, object_ptr_src)19342 try sema.analyzeLoad(block, src, result, object_ptr_src)
...@@ -19238,7 +19569,7 @@ fn finishFieldCallBind(...@@ -19238,7 +19569,7 @@ fn finishFieldCallBind(
19238 return sema.analyzeLoad(block, src, pointer, src);19569 return sema.analyzeLoad(block, src, pointer, src);
19239 }19570 }
1924019571
19241 try sema.requireRuntimeBlock(block, src);19572 try sema.requireRuntimeBlock(block, src, null);
19242 const ptr_inst = try block.addStructFieldPtr(object_ptr, field_index, ptr_field_ty);19573 const ptr_inst = try block.addStructFieldPtr(object_ptr, field_index, ptr_field_ty);
19243 return sema.analyzeLoad(block, src, ptr_inst, src);19574 return sema.analyzeLoad(block, src, ptr_inst, src);
19244}19575}
...@@ -19425,7 +19756,7 @@ fn structFieldPtrByIndex(...@@ -19425,7 +19756,7 @@ fn structFieldPtrByIndex(
19425 );19756 );
19426 }19757 }
1942719758
19428 try sema.requireRuntimeBlock(block, src);19759 try sema.requireRuntimeBlock(block, src, null);
19429 return block.addStructFieldPtr(struct_ptr, field_index, ptr_field_ty);19760 return block.addStructFieldPtr(struct_ptr, field_index, ptr_field_ty);
19430}19761}
1943119762
...@@ -19469,7 +19800,7 @@ fn structFieldVal(...@@ -19469,7 +19800,7 @@ fn structFieldVal(
19469 return sema.addConstant(field.ty, field_values[field_index]);19800 return sema.addConstant(field.ty, field_values[field_index]);
19470 }19801 }
1947119802
19472 try sema.requireRuntimeBlock(block, src);19803 try sema.requireRuntimeBlock(block, src, null);
19473 return block.addStructFieldVal(struct_byval, field_index, field.ty);19804 return block.addStructFieldVal(struct_byval, field_index, field.ty);
19474 },19805 },
19475 else => unreachable,19806 else => unreachable,
...@@ -19533,7 +19864,7 @@ fn tupleFieldValByIndex(...@@ -19533,7 +19864,7 @@ fn tupleFieldValByIndex(
19533 return sema.addConstant(field_ty, field_values[field_index]);19864 return sema.addConstant(field_ty, field_values[field_index]);
19534 }19865 }
1953519866
19536 try sema.requireRuntimeBlock(block, src);19867 try sema.requireRuntimeBlock(block, src, null);
19537 return block.addStructFieldVal(tuple_byval, field_index, field_ty);19868 return block.addStructFieldVal(tuple_byval, field_index, field_ty);
19538}19869}
1953919870
...@@ -19597,7 +19928,7 @@ fn unionFieldPtr(...@@ -19597,7 +19928,7 @@ fn unionFieldPtr(
19597 );19928 );
19598 }19929 }
1959919930
19600 try sema.requireRuntimeBlock(block, src);19931 try sema.requireRuntimeBlock(block, src, null);
19601 return block.addStructFieldPtr(union_ptr, field_index, ptr_field_ty);19932 return block.addStructFieldPtr(union_ptr, field_index, ptr_field_ty);
19602}19933}
1960319934
...@@ -19655,7 +19986,7 @@ fn unionFieldVal(...@@ -19655,7 +19986,7 @@ fn unionFieldVal(
19655 }19986 }
19656 }19987 }
1965719988
19658 try sema.requireRuntimeBlock(block, src);19989 try sema.requireRuntimeBlock(block, src, null);
19659 return block.addStructFieldVal(union_byval, field_index, field.ty);19990 return block.addStructFieldVal(union_byval, field_index, field.ty);
19660}19991}
1966119992
...@@ -19684,7 +20015,7 @@ fn elemPtr(...@@ -19684,7 +20015,7 @@ fn elemPtr(
19684 // In all below cases, we have to deref the ptr operand to get the actual indexable pointer.20015 // In all below cases, we have to deref the ptr operand to get the actual indexable pointer.
19685 const indexable = try sema.analyzeLoad(block, indexable_ptr_src, indexable_ptr, indexable_ptr_src);20016 const indexable = try sema.analyzeLoad(block, indexable_ptr_src, indexable_ptr, indexable_ptr_src);
19686 switch (indexable_ty.ptrSize()) {20017 switch (indexable_ty.ptrSize()) {
19687 .Slice => return sema.elemPtrSlice(block, indexable_ptr_src, indexable, elem_index_src, elem_index),20018 .Slice => return sema.elemPtrSlice(block, src, indexable_ptr_src, indexable, elem_index_src, elem_index),
19688 .Many, .C => {20019 .Many, .C => {
19689 const maybe_ptr_val = try sema.resolveDefinedValue(block, indexable_ptr_src, indexable);20020 const maybe_ptr_val = try sema.resolveDefinedValue(block, indexable_ptr_src, indexable);
19690 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);20021 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
...@@ -19698,19 +20029,19 @@ fn elemPtr(...@@ -19698,19 +20029,19 @@ fn elemPtr(
19698 };20029 };
19699 const result_ty = try sema.elemPtrType(indexable_ty, null);20030 const result_ty = try sema.elemPtrType(indexable_ty, null);
1970020031
19701 try sema.requireRuntimeBlock(block, runtime_src);20032 try sema.requireRuntimeBlock(block, src, runtime_src);
19702 return block.addPtrElemPtr(indexable, elem_index, result_ty);20033 return block.addPtrElemPtr(indexable, elem_index, result_ty);
19703 },20034 },
19704 .One => {20035 .One => {
19705 assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by isIndexable20036 assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by isIndexable
19706 return sema.elemPtrArray(block, indexable_ptr_src, indexable, elem_index_src, elem_index, init);20037 return sema.elemPtrArray(block, src, indexable_ptr_src, indexable, elem_index_src, elem_index, init);
19707 },20038 },
19708 }20039 }
19709 },20040 },
19710 .Array, .Vector => return sema.elemPtrArray(block, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init),20041 .Array, .Vector => return sema.elemPtrArray(block, src, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init),
19711 .Struct => {20042 .Struct => {
19712 // Tuple field access.20043 // Tuple field access.
19713 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index);20044 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index, "tuple field access index must be comptime known");
19714 const index = @intCast(u32, index_val.toUnsignedInt(target));20045 const index = @intCast(u32, index_val.toUnsignedInt(target));
19715 return sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index);20046 return sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index);
19716 },20047 },
...@@ -19740,7 +20071,7 @@ fn elemVal(...@@ -19740,7 +20071,7 @@ fn elemVal(
1974020071
19741 switch (indexable_ty.zigTypeTag()) {20072 switch (indexable_ty.zigTypeTag()) {
19742 .Pointer => switch (indexable_ty.ptrSize()) {20073 .Pointer => switch (indexable_ty.ptrSize()) {
19743 .Slice => return sema.elemValSlice(block, indexable_src, indexable, elem_index_src, elem_index),20074 .Slice => return sema.elemValSlice(block, src, indexable_src, indexable, elem_index_src, elem_index),
19744 .Many, .C => {20075 .Many, .C => {
19745 const maybe_indexable_val = try sema.resolveDefinedValue(block, indexable_src, indexable);20076 const maybe_indexable_val = try sema.resolveDefinedValue(block, indexable_src, indexable);
19746 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);20077 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
...@@ -19756,7 +20087,7 @@ fn elemVal(...@@ -19756,7 +20087,7 @@ fn elemVal(
19756 break :rs indexable_src;20087 break :rs indexable_src;
19757 };20088 };
1975820089
19759 try sema.requireRuntimeBlock(block, runtime_src);20090 try sema.requireRuntimeBlock(block, src, runtime_src);
19760 return block.addBinOp(.ptr_elem_val, indexable, elem_index);20091 return block.addBinOp(.ptr_elem_val, indexable, elem_index);
19761 },20092 },
19762 .One => {20093 .One => {
...@@ -19765,14 +20096,14 @@ fn elemVal(...@@ -19765,14 +20096,14 @@ fn elemVal(
19765 return sema.analyzeLoad(block, indexable_src, elem_ptr, elem_index_src);20096 return sema.analyzeLoad(block, indexable_src, elem_ptr, elem_index_src);
19766 },20097 },
19767 },20098 },
19768 .Array => return elemValArray(sema, block, indexable_src, indexable, elem_index_src, elem_index),20099 .Array => return sema.elemValArray(block, src, indexable_src, indexable, elem_index_src, elem_index),
19769 .Vector => {20100 .Vector => {
19770 // TODO: If the index is a vector, the result should be a vector.20101 // TODO: If the index is a vector, the result should be a vector.
19771 return elemValArray(sema, block, indexable_src, indexable, elem_index_src, elem_index);20102 return sema.elemValArray(block, src, indexable_src, indexable, elem_index_src, elem_index);
19772 },20103 },
19773 .Struct => {20104 .Struct => {
19774 // Tuple field access.20105 // Tuple field access.
19775 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index);20106 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index, "tuple field access index must be comptime known");
19776 const index = @intCast(u32, index_val.toUnsignedInt(target));20107 const index = @intCast(u32, index_val.toUnsignedInt(target));
19777 return tupleField(sema, block, indexable_src, indexable, elem_index_src, index);20108 return tupleField(sema, block, indexable_src, indexable, elem_index_src, index);
19778 },20109 },
...@@ -19850,7 +20181,7 @@ fn tupleFieldPtr(...@@ -19850,7 +20181,7 @@ fn tupleFieldPtr(
1985020181
19851 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_ptr_src);20182 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_ptr_src);
1985220183
19853 try sema.requireRuntimeBlock(block, tuple_ptr_src);20184 try sema.requireRuntimeBlock(block, tuple_ptr_src, null);
19854 return block.addStructFieldPtr(tuple_ptr, field_index, ptr_field_ty);20185 return block.addStructFieldPtr(tuple_ptr, field_index, ptr_field_ty);
19855}20186}
1985620187
...@@ -19890,13 +20221,14 @@ fn tupleField(...@@ -19890,13 +20221,14 @@ fn tupleField(
1989020221
19891 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src);20222 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src);
1989220223
19893 try sema.requireRuntimeBlock(block, tuple_src);20224 try sema.requireRuntimeBlock(block, tuple_src, null);
19894 return block.addStructFieldVal(tuple, field_index, field_ty);20225 return block.addStructFieldVal(tuple, field_index, field_ty);
19895}20226}
1989620227
19897fn elemValArray(20228fn elemValArray(
19898 sema: *Sema,20229 sema: *Sema,
19899 block: *Block,20230 block: *Block,
20231 src: LazySrcLoc,
19900 array_src: LazySrcLoc,20232 array_src: LazySrcLoc,
19901 array: Air.Inst.Ref,20233 array: Air.Inst.Ref,
19902 elem_index_src: LazySrcLoc,20234 elem_index_src: LazySrcLoc,
...@@ -19943,7 +20275,7 @@ fn elemValArray(...@@ -19943,7 +20275,7 @@ fn elemValArray(
19943 try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ty, array_ty, array_src);20275 try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ty, array_ty, array_src);
1994420276
19945 const runtime_src = if (maybe_undef_array_val != null) elem_index_src else array_src;20277 const runtime_src = if (maybe_undef_array_val != null) elem_index_src else array_src;
19946 try sema.requireRuntimeBlock(block, runtime_src);20278 try sema.requireRuntimeBlock(block, src, runtime_src);
19947 if (block.wantSafety()) {20279 if (block.wantSafety()) {
19948 // Runtime check is only needed if unable to comptime check20280 // Runtime check is only needed if unable to comptime check
19949 if (maybe_index_val == null) {20281 if (maybe_index_val == null) {
...@@ -19958,6 +20290,7 @@ fn elemValArray(...@@ -19958,6 +20290,7 @@ fn elemValArray(
19958fn elemPtrArray(20290fn elemPtrArray(
19959 sema: *Sema,20291 sema: *Sema,
19960 block: *Block,20292 block: *Block,
20293 src: LazySrcLoc,
19961 array_ptr_src: LazySrcLoc,20294 array_ptr_src: LazySrcLoc,
19962 array_ptr: Air.Inst.Ref,20295 array_ptr: Air.Inst.Ref,
19963 elem_index_src: LazySrcLoc,20296 elem_index_src: LazySrcLoc,
...@@ -20003,7 +20336,7 @@ fn elemPtrArray(...@@ -20003,7 +20336,7 @@ fn elemPtrArray(
20003 }20336 }
2000420337
20005 const runtime_src = if (maybe_undef_array_ptr_val != null) elem_index_src else array_ptr_src;20338 const runtime_src = if (maybe_undef_array_ptr_val != null) elem_index_src else array_ptr_src;
20006 try sema.requireRuntimeBlock(block, runtime_src);20339 try sema.requireRuntimeBlock(block, src, runtime_src);
2000720340
20008 // Runtime check is only needed if unable to comptime check.20341 // Runtime check is only needed if unable to comptime check.
20009 if (block.wantSafety() and offset == null) {20342 if (block.wantSafety() and offset == null) {
...@@ -20018,6 +20351,7 @@ fn elemPtrArray(...@@ -20018,6 +20351,7 @@ fn elemPtrArray(
20018fn elemValSlice(20351fn elemValSlice(
20019 sema: *Sema,20352 sema: *Sema,
20020 block: *Block,20353 block: *Block,
20354 src: LazySrcLoc,
20021 slice_src: LazySrcLoc,20355 slice_src: LazySrcLoc,
20022 slice: Air.Inst.Ref,20356 slice: Air.Inst.Ref,
20023 elem_index_src: LazySrcLoc,20357 elem_index_src: LazySrcLoc,
...@@ -20057,7 +20391,7 @@ fn elemValSlice(...@@ -20057,7 +20391,7 @@ fn elemValSlice(
2005720391
20058 try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ty, slice_ty, slice_src);20392 try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ty, slice_ty, slice_src);
2005920393
20060 try sema.requireRuntimeBlock(block, runtime_src);20394 try sema.requireRuntimeBlock(block, src, runtime_src);
20061 if (block.wantSafety()) {20395 if (block.wantSafety()) {
20062 const len_inst = if (maybe_slice_val) |slice_val|20396 const len_inst = if (maybe_slice_val) |slice_val|
20063 try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(sema.mod))20397 try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(sema.mod))
...@@ -20073,6 +20407,7 @@ fn elemValSlice(...@@ -20073,6 +20407,7 @@ fn elemValSlice(
20073fn elemPtrSlice(20407fn elemPtrSlice(
20074 sema: *Sema,20408 sema: *Sema,
20075 block: *Block,20409 block: *Block,
20410 src: LazySrcLoc,
20076 slice_src: LazySrcLoc,20411 slice_src: LazySrcLoc,
20077 slice: Air.Inst.Ref,20412 slice: Air.Inst.Ref,
20078 elem_index_src: LazySrcLoc,20413 elem_index_src: LazySrcLoc,
...@@ -20113,7 +20448,7 @@ fn elemPtrSlice(...@@ -20113,7 +20448,7 @@ fn elemPtrSlice(
20113 try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ptr_ty, slice_ty, slice_src);20448 try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ptr_ty, slice_ty, slice_src);
2011420449
20115 const runtime_src = if (maybe_undef_slice_val != null) elem_index_src else slice_src;20450 const runtime_src = if (maybe_undef_slice_val != null) elem_index_src else slice_src;
20116 try sema.requireRuntimeBlock(block, runtime_src);20451 try sema.requireRuntimeBlock(block, src, runtime_src);
20117 if (block.wantSafety()) {20452 if (block.wantSafety()) {
20118 const len_inst = len: {20453 const len_inst = len: {
20119 if (maybe_undef_slice_val) |slice_val|20454 if (maybe_undef_slice_val) |slice_val|
...@@ -20177,7 +20512,7 @@ fn coerceExtra(...@@ -20177,7 +20512,7 @@ fn coerceExtra(
20177 // Keep the comptime Value representation; take the new type.20512 // Keep the comptime Value representation; take the new type.
20178 return sema.addConstant(dest_ty, val);20513 return sema.addConstant(dest_ty, val);
20179 }20514 }
20180 try sema.requireRuntimeBlock(block, inst_src);20515 try sema.requireRuntimeBlock(block, inst_src, null);
20181 return block.addBitCast(dest_ty, inst);20516 return block.addBitCast(dest_ty, inst);
20182 }20517 }
2018320518
...@@ -20222,7 +20557,7 @@ fn coerceExtra(...@@ -20222,7 +20557,7 @@ fn coerceExtra(
2022220557
20223 // Function body to function pointer.20558 // Function body to function pointer.
20224 if (inst_ty.zigTypeTag() == .Fn) {20559 if (inst_ty.zigTypeTag() == .Fn) {
20225 const fn_val = try sema.resolveConstValue(block, inst_src, inst);20560 const fn_val = try sema.resolveConstValue(block, .unneeded, inst, undefined);
20226 const fn_decl = fn_val.castTag(.function).?.data.owner_decl;20561 const fn_decl = fn_val.castTag(.function).?.data.owner_decl;
20227 const inst_as_ptr = try sema.analyzeDeclRef(fn_decl);20562 const inst_as_ptr = try sema.analyzeDeclRef(fn_decl);
20228 return sema.coerce(block, dest_ty, inst_as_ptr, inst_src);20563 return sema.coerce(block, dest_ty, inst_as_ptr, inst_src);
...@@ -20489,7 +20824,7 @@ fn coerceExtra(...@@ -20489,7 +20824,7 @@ fn coerceExtra(
20489 // small enough unsigned ints can get casted to large enough signed ints20824 // small enough unsigned ints can get casted to large enough signed ints
20490 (dst_info.signedness == .signed and dst_info.bits > src_info.bits))20825 (dst_info.signedness == .signed and dst_info.bits > src_info.bits))
20491 {20826 {
20492 try sema.requireRuntimeBlock(block, inst_src);20827 try sema.requireRuntimeBlock(block, inst_src, null);
20493 return block.addTyOp(.intcast, dest_ty, inst);20828 return block.addTyOp(.intcast, dest_ty, inst);
20494 }20829 }
20495 },20830 },
...@@ -20500,7 +20835,7 @@ fn coerceExtra(...@@ -20500,7 +20835,7 @@ fn coerceExtra(
20500 },20835 },
20501 .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag()) {20836 .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag()) {
20502 .ComptimeFloat => {20837 .ComptimeFloat => {
20503 const val = try sema.resolveConstValue(block, inst_src, inst);20838 const val = try sema.resolveConstValue(block, .unneeded, inst, undefined);
20504 const result_val = try val.floatCast(sema.arena, dest_ty, target);20839 const result_val = try val.floatCast(sema.arena, dest_ty, target);
20505 return try sema.addConstant(dest_ty, result_val);20840 return try sema.addConstant(dest_ty, result_val);
20506 },20841 },
...@@ -20516,13 +20851,15 @@ fn coerceExtra(...@@ -20516,13 +20851,15 @@ fn coerceExtra(
20516 );20851 );
20517 }20852 }
20518 return try sema.addConstant(dest_ty, result_val);20853 return try sema.addConstant(dest_ty, result_val);
20854 } else if (dest_ty.zigTypeTag() == .ComptimeFloat) {
20855 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_float' must be comptime known");
20519 }20856 }
2052020857
20521 // float widening20858 // float widening
20522 const src_bits = inst_ty.floatBits(target);20859 const src_bits = inst_ty.floatBits(target);
20523 const dst_bits = dest_ty.floatBits(target);20860 const dst_bits = dest_ty.floatBits(target);
20524 if (dst_bits >= src_bits) {20861 if (dst_bits >= src_bits) {
20525 try sema.requireRuntimeBlock(block, inst_src);20862 try sema.requireRuntimeBlock(block, inst_src, null);
20526 return block.addTyOp(.fpext, dest_ty, inst);20863 return block.addTyOp(.fpext, dest_ty, inst);
20527 }20864 }
20528 },20865 },
...@@ -20549,7 +20886,7 @@ fn coerceExtra(...@@ -20549,7 +20886,7 @@ fn coerceExtra(
20549 .Enum => switch (inst_ty.zigTypeTag()) {20886 .Enum => switch (inst_ty.zigTypeTag()) {
20550 .EnumLiteral => {20887 .EnumLiteral => {
20551 // enum literal to enum20888 // enum literal to enum
20552 const val = try sema.resolveConstValue(block, inst_src, inst);20889 const val = try sema.resolveConstValue(block, .unneeded, inst, undefined);
20553 const bytes = val.castTag(.enum_literal).?.data;20890 const bytes = val.castTag(.enum_literal).?.data;
20554 const field_index = dest_ty.enumFieldIndex(bytes) orelse {20891 const field_index = dest_ty.enumFieldIndex(bytes) orelse {
20555 const msg = msg: {20892 const msg = msg: {
...@@ -20956,17 +21293,17 @@ const InMemoryCoercionResult = union(enum) {...@@ -20956,17 +21293,17 @@ const InMemoryCoercionResult = union(enum) {
20956 }21293 }
20957 }21294 }
20958 if (!actual_noalias) {21295 if (!actual_noalias) {
20959 try sema.errNote(block, src, msg, "regular paramter {d} cannot cast into a noalias paramter", .{index});21296 try sema.errNote(block, src, msg, "regular parameter {d} cannot cast into a noalias parameter", .{index});
20960 } else {21297 } else {
20961 try sema.errNote(block, src, msg, "noalias paramter {d} cannot cast into a regular paramter", .{index});21298 try sema.errNote(block, src, msg, "noalias parameter {d} cannot cast into a regular parameter", .{index});
20962 }21299 }
20963 break;21300 break;
20964 },21301 },
20965 .fn_param_comptime => |param| {21302 .fn_param_comptime => |param| {
20966 if (param.wanted) {21303 if (param.wanted) {
20967 try sema.errNote(block, src, msg, "non-comptime paramter {d} cannot cast into a comptime paramter", .{param.index});21304 try sema.errNote(block, src, msg, "non-comptime parameter {d} cannot cast into a comptime parameter", .{param.index});
20968 } else {21305 } else {
20969 try sema.errNote(block, src, msg, "comptime paramter {d} cannot cast into a non-comptime paramter", .{param.index});21306 try sema.errNote(block, src, msg, "comptime parameter {d} cannot cast into a non-comptime parameter", .{param.index});
20970 }21307 }
20971 break;21308 break;
20972 },21309 },
...@@ -21712,7 +22049,12 @@ fn storePtr2(...@@ -21712,7 +22049,12 @@ fn storePtr2(
21712 return;22049 return;
21713 }22050 }
2171422051
21715 try sema.requireRuntimeBlock(block, runtime_src);22052 if (block.is_comptime) {
22053 // TODO ideally this would tell why the block is comptime
22054 return sema.fail(block, ptr_src, "cannot store to runtime value in comptime block", .{});
22055 }
22056
22057 try sema.requireRuntimeBlock(block, src, runtime_src);
21716 try sema.queueFullTypeResolution(elem_ty);22058 try sema.queueFullTypeResolution(elem_ty);
21717 if (is_ret) {22059 if (is_ret) {
21718 _ = try block.addBinOp(.store, ptr, operand);22060 _ = try block.addBinOp(.store, ptr, operand);
...@@ -22644,7 +22986,7 @@ fn bitCast(...@@ -22644,7 +22986,7 @@ fn bitCast(
22644 const result_val = try sema.bitCastVal(block, inst_src, val, old_ty, dest_ty, 0);22986 const result_val = try sema.bitCastVal(block, inst_src, val, old_ty, dest_ty, 0);
22645 return sema.addConstant(dest_ty, result_val);22987 return sema.addConstant(dest_ty, result_val);
22646 }22988 }
22647 try sema.requireRuntimeBlock(block, inst_src);22989 try sema.requireRuntimeBlock(block, inst_src, null);
22648 return block.addBitCast(dest_ty, inst);22990 return block.addBitCast(dest_ty, inst);
22649}22991}
2265022992
...@@ -22727,7 +23069,7 @@ fn coerceArrayPtrToSlice(...@@ -22727,7 +23069,7 @@ fn coerceArrayPtrToSlice(
22727 });23069 });
22728 return sema.addConstant(dest_ty, slice_val);23070 return sema.addConstant(dest_ty, slice_val);
22729 }23071 }
22730 try sema.requireRuntimeBlock(block, inst_src);23072 try sema.requireRuntimeBlock(block, inst_src, null);
22731 return block.addTyOp(.array_to_slice, dest_ty, inst);23073 return block.addTyOp(.array_to_slice, dest_ty, inst);
22732}23074}
2273323075
...@@ -22743,7 +23085,7 @@ fn coerceCompatiblePtrs(...@@ -22743,7 +23085,7 @@ fn coerceCompatiblePtrs(
22743 // The comptime Value representation is compatible with both types.23085 // The comptime Value representation is compatible with both types.
22744 return sema.addConstant(dest_ty, val);23086 return sema.addConstant(dest_ty, val);
22745 }23087 }
22746 try sema.requireRuntimeBlock(block, inst_src);23088 try sema.requireRuntimeBlock(block, inst_src, null);
22747 return sema.bitCast(block, dest_ty, inst, inst_src);23089 return sema.bitCast(block, dest_ty, inst, inst_src);
22748}23090}
2274923091
...@@ -22807,7 +23149,7 @@ fn coerceEnumToUnion(...@@ -22807,7 +23149,7 @@ fn coerceEnumToUnion(
22807 }));23149 }));
22808 }23150 }
2280923151
22810 try sema.requireRuntimeBlock(block, inst_src);23152 try sema.requireRuntimeBlock(block, inst_src, null);
2281123153
22812 if (tag_ty.isNonexhaustiveEnum()) {23154 if (tag_ty.isNonexhaustiveEnum()) {
22813 const msg = msg: {23155 const msg = msg: {
...@@ -22947,7 +23289,7 @@ fn coerceArrayLike(...@@ -22947,7 +23289,7 @@ fn coerceArrayLike(
22947 // These types share the same comptime value representation.23289 // These types share the same comptime value representation.
22948 return sema.addConstant(dest_ty, inst_val);23290 return sema.addConstant(dest_ty, inst_val);
22949 }23291 }
22950 try sema.requireRuntimeBlock(block, inst_src);23292 try sema.requireRuntimeBlock(block, inst_src, null);
22951 return block.addBitCast(dest_ty, inst);23293 return block.addBitCast(dest_ty, inst);
22952 }23294 }
2295323295
...@@ -22960,8 +23302,9 @@ fn coerceArrayLike(...@@ -22960,8 +23302,9 @@ fn coerceArrayLike(
22960 Type.usize,23302 Type.usize,
22961 try Value.Tag.int_u64.create(sema.arena, i),23303 try Value.Tag.int_u64.create(sema.arena, i),
22962 );23304 );
23305 const src = inst_src; // TODO better source location
22963 const elem_src = inst_src; // TODO better source location23306 const elem_src = inst_src; // TODO better source location
22964 const elem_ref = try elemValArray(sema, block, inst_src, inst, elem_src, index_ref);23307 const elem_ref = try sema.elemValArray(block, src, inst_src, inst, elem_src, index_ref);
22965 const coerced = try sema.coerce(block, dest_elem_ty, elem_ref, elem_src);23308 const coerced = try sema.coerce(block, dest_elem_ty, elem_ref, elem_src);
22966 element_refs[i] = coerced;23309 element_refs[i] = coerced;
22967 if (runtime_src == null) {23310 if (runtime_src == null) {
...@@ -22974,7 +23317,7 @@ fn coerceArrayLike(...@@ -22974,7 +23317,7 @@ fn coerceArrayLike(
22974 }23317 }
2297523318
22976 if (runtime_src) |rs| {23319 if (runtime_src) |rs| {
22977 try sema.requireRuntimeBlock(block, rs);23320 try sema.requireRuntimeBlock(block, inst_src, rs);
22978 return block.addAggregateInit(dest_ty, element_refs);23321 return block.addAggregateInit(dest_ty, element_refs);
22979 }23322 }
2298023323
...@@ -23037,7 +23380,7 @@ fn coerceTupleToArray(...@@ -23037,7 +23380,7 @@ fn coerceTupleToArray(
23037 }23380 }
2303823381
23039 if (runtime_src) |rs| {23382 if (runtime_src) |rs| {
23040 try sema.requireRuntimeBlock(block, rs);23383 try sema.requireRuntimeBlock(block, inst_src, rs);
23041 return block.addAggregateInit(dest_ty, element_refs);23384 return block.addAggregateInit(dest_ty, element_refs);
23042 }23385 }
2304323386
...@@ -23168,7 +23511,7 @@ fn coerceTupleToStruct(...@@ -23168,7 +23511,7 @@ fn coerceTupleToStruct(
23168 }23511 }
2316923512
23170 if (runtime_src) |rs| {23513 if (runtime_src) |rs| {
23171 try sema.requireRuntimeBlock(block, rs);23514 try sema.requireRuntimeBlock(block, inst_src, rs);
23172 return block.addAggregateInit(struct_ty, field_refs);23515 return block.addAggregateInit(struct_ty, field_refs);
23173 }23516 }
2317423517
...@@ -23282,7 +23625,7 @@ fn analyzeRef(...@@ -23282,7 +23625,7 @@ fn analyzeRef(
23282 ));23625 ));
23283 }23626 }
2328423627
23285 try sema.requireRuntimeBlock(block, src);23628 try sema.requireRuntimeBlock(block, src, null);
23286 const address_space = target_util.defaultAddressSpace(sema.mod.getTarget(), .local);23629 const address_space = target_util.defaultAddressSpace(sema.mod.getTarget(), .local);
23287 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{23630 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
23288 .pointee_type = operand_ty,23631 .pointee_type = operand_ty,
...@@ -23326,10 +23669,12 @@ fn analyzeLoad(...@@ -23326,10 +23669,12 @@ fn analyzeLoad(
23326 }23669 }
23327 }23670 }
2332823671
23329 const valid_rt = try sema.validateRunTimeType(block, src, elem_ty, false);23672 if (block.is_comptime) {
23330 if (!valid_rt) return sema.failWithNeededComptime(block, src);23673 // TODO ideally this would tell why the block is comptime
23674 return sema.fail(block, ptr_src, "cannot load runtime value in comptime block", .{});
23675 }
2333123676
23332 try sema.requireRuntimeBlock(block, src);23677 try sema.requireFunctionBlock(block, src);
23333 return block.addTyOp(.load, elem_ty, ptr);23678 return block.addTyOp(.load, elem_ty, ptr);
23334}23679}
2333523680
...@@ -23346,7 +23691,7 @@ fn analyzeSlicePtr(...@@ -23346,7 +23691,7 @@ fn analyzeSlicePtr(
23346 if (val.isUndef()) return sema.addConstUndef(result_ty);23691 if (val.isUndef()) return sema.addConstUndef(result_ty);
23347 return sema.addConstant(result_ty, val.slicePtr());23692 return sema.addConstant(result_ty, val.slicePtr());
23348 }23693 }
23349 try sema.requireRuntimeBlock(block, slice_src);23694 try sema.requireRuntimeBlock(block, slice_src, null);
23350 return block.addTyOp(.slice_ptr, result_ty, slice);23695 return block.addTyOp(.slice_ptr, result_ty, slice);
23351}23696}
2335223697
...@@ -23362,7 +23707,7 @@ fn analyzeSliceLen(...@@ -23362,7 +23707,7 @@ fn analyzeSliceLen(
23362 }23707 }
23363 return sema.addIntUnsigned(Type.usize, slice_val.sliceLen(sema.mod));23708 return sema.addIntUnsigned(Type.usize, slice_val.sliceLen(sema.mod));
23364 }23709 }
23365 try sema.requireRuntimeBlock(block, src);23710 try sema.requireRuntimeBlock(block, src, null);
23366 return block.addTyOp(.slice_len, Type.usize, slice_inst);23711 return block.addTyOp(.slice_len, Type.usize, slice_inst);
23367}23712}
2336823713
...@@ -23386,7 +23731,7 @@ fn analyzeIsNull(...@@ -23386,7 +23731,7 @@ fn analyzeIsNull(
23386 return Air.Inst.Ref.bool_false;23731 return Air.Inst.Ref.bool_false;
23387 }23732 }
23388 }23733 }
23389 try sema.requireRuntimeBlock(block, src);23734 try sema.requireRuntimeBlock(block, src, null);
23390 const air_tag: Air.Inst.Tag = if (invert_logic) .is_non_null else .is_null;23735 const air_tag: Air.Inst.Tag = if (invert_logic) .is_non_null else .is_null;
23391 return block.addUnOp(air_tag, operand);23736 return block.addUnOp(air_tag, operand);
23392}23737}
...@@ -23476,7 +23821,7 @@ fn analyzeIsNonErr(...@@ -23476,7 +23821,7 @@ fn analyzeIsNonErr(
23476) CompileError!Air.Inst.Ref {23821) CompileError!Air.Inst.Ref {
23477 const result = try sema.analyzeIsNonErrComptimeOnly(block, src, operand);23822 const result = try sema.analyzeIsNonErrComptimeOnly(block, src, operand);
23478 if (result == .none) {23823 if (result == .none) {
23479 try sema.requireRuntimeBlock(block, src);23824 try sema.requireRuntimeBlock(block, src, null);
23480 return block.addUnOp(.is_non_err, operand);23825 return block.addUnOp(.is_non_err, operand);
23481 } else {23826 } else {
23482 return result;23827 return result;
...@@ -23661,7 +24006,7 @@ fn analyzeSlice(...@@ -23661,7 +24006,7 @@ fn analyzeSlice(
23661 const sentinel = s: {24006 const sentinel = s: {
23662 if (sentinel_opt != .none) {24007 if (sentinel_opt != .none) {
23663 const casted = try sema.coerce(block, elem_ty, sentinel_opt, sentinel_src);24008 const casted = try sema.coerce(block, elem_ty, sentinel_opt, sentinel_src);
23664 break :s try sema.resolveConstValue(block, sentinel_src, casted);24009 break :s try sema.resolveConstValue(block, sentinel_src, casted, "slice sentinel must be comptime known");
23665 }24010 }
23666 // If we are slicing to the end of something that is sentinel-terminated24011 // If we are slicing to the end of something that is sentinel-terminated
23667 // then the resulting slice type is also sentinel-terminated.24012 // then the resulting slice type is also sentinel-terminated.
...@@ -23738,7 +24083,14 @@ fn analyzeSlice(...@@ -23738,7 +24083,14 @@ fn analyzeSlice(
23738 .size = .Slice,24083 .size = .Slice,
23739 });24084 });
2374024085
23741 try sema.requireRuntimeBlock(block, src);24086 const runtime_src = if ((try sema.resolveMaybeUndefVal(block, ptr_src, ptr_or_slice)) == null)
24087 ptr_src
24088 else if ((try sema.resolveMaybeUndefVal(block, src, start)) == null)
24089 start_src
24090 else
24091 end_src;
24092
24093 try sema.requireRuntimeBlock(block, src, runtime_src);
23742 if (block.wantSafety()) {24094 if (block.wantSafety()) {
23743 // requirement: slicing C ptr is non-null24095 // requirement: slicing C ptr is non-null
23744 if (ptr_ptr_child_ty.isCPtr()) {24096 if (ptr_ptr_child_ty.isCPtr()) {
...@@ -23846,7 +24198,7 @@ fn cmpNumeric(...@@ -23846,7 +24198,7 @@ fn cmpNumeric(
23846 // a full resolution of their value, for example `@sizeOf(@Frame(function))` is known to24198 // a full resolution of their value, for example `@sizeOf(@Frame(function))` is known to
23847 // always be nonzero, and we benefit from not forcing the full evaluation and stack frame layout24199 // always be nonzero, and we benefit from not forcing the full evaluation and stack frame layout
23848 // of this function if we don't need to.24200 // of this function if we don't need to.
23849 try sema.requireRuntimeBlock(block, runtime_src);24201 try sema.requireRuntimeBlock(block, src, runtime_src);
2385024202
23851 // For floats, emit a float comparison instruction.24203 // For floats, emit a float comparison instruction.
23852 const lhs_is_float = switch (lhs_ty_tag) {24204 const lhs_is_float = switch (lhs_ty_tag) {
...@@ -24034,7 +24386,7 @@ fn cmpVector(...@@ -24034,7 +24386,7 @@ fn cmpVector(
24034 }24386 }
24035 };24387 };
2403624388
24037 try sema.requireRuntimeBlock(block, runtime_src);24389 try sema.requireRuntimeBlock(block, src, runtime_src);
24038 const result_ty_inst = try sema.addType(result_ty);24390 const result_ty_inst = try sema.addType(result_ty);
24039 return block.addCmpVector(lhs, rhs, op, result_ty_inst);24391 return block.addCmpVector(lhs, rhs, op, result_ty_inst);
24040}24392}
...@@ -24050,7 +24402,7 @@ fn wrapOptional(...@@ -24050,7 +24402,7 @@ fn wrapOptional(
24050 return sema.addConstant(dest_ty, try Value.Tag.opt_payload.create(sema.arena, val));24402 return sema.addConstant(dest_ty, try Value.Tag.opt_payload.create(sema.arena, val));
24051 }24403 }
2405224404
24053 try sema.requireRuntimeBlock(block, inst_src);24405 try sema.requireRuntimeBlock(block, inst_src, null);
24054 return block.addTyOp(.wrap_optional, dest_ty, inst);24406 return block.addTyOp(.wrap_optional, dest_ty, inst);
24055}24407}
2405624408
...@@ -24066,7 +24418,7 @@ fn wrapErrorUnionPayload(...@@ -24066,7 +24418,7 @@ fn wrapErrorUnionPayload(
24066 if (try sema.resolveMaybeUndefVal(block, inst_src, coerced)) |val| {24418 if (try sema.resolveMaybeUndefVal(block, inst_src, coerced)) |val| {
24067 return sema.addConstant(dest_ty, try Value.Tag.eu_payload.create(sema.arena, val));24419 return sema.addConstant(dest_ty, try Value.Tag.eu_payload.create(sema.arena, val));
24068 }24420 }
24069 try sema.requireRuntimeBlock(block, inst_src);24421 try sema.requireRuntimeBlock(block, inst_src, null);
24070 try sema.queueFullTypeResolution(dest_payload_ty);24422 try sema.queueFullTypeResolution(dest_payload_ty);
24071 return block.addTyOp(.wrap_errunion_payload, dest_ty, coerced);24423 return block.addTyOp(.wrap_errunion_payload, dest_ty, coerced);
24072}24424}
...@@ -24122,7 +24474,7 @@ fn wrapErrorUnionSet(...@@ -24122,7 +24474,7 @@ fn wrapErrorUnionSet(
24122 return sema.addConstant(dest_ty, val);24474 return sema.addConstant(dest_ty, val);
24123 }24475 }
2412424476
24125 try sema.requireRuntimeBlock(block, inst_src);24477 try sema.requireRuntimeBlock(block, inst_src, null);
24126 const coerced = try sema.coerce(block, dest_err_set_ty, inst, inst_src);24478 const coerced = try sema.coerce(block, dest_err_set_ty, inst, inst_src);
24127 return block.addTyOp(.wrap_errunion_err, dest_ty, coerced);24479 return block.addTyOp(.wrap_errunion_err, dest_ty, coerced);
24128}24480}
...@@ -24140,7 +24492,7 @@ fn unionToTag(...@@ -24140,7 +24492,7 @@ fn unionToTag(
24140 if (try sema.resolveMaybeUndefVal(block, un_src, un)) |un_val| {24492 if (try sema.resolveMaybeUndefVal(block, un_src, un)) |un_val| {
24141 return sema.addConstant(enum_ty, un_val.unionTag());24493 return sema.addConstant(enum_ty, un_val.unionTag());
24142 }24494 }
24143 try sema.requireRuntimeBlock(block, un_src);24495 try sema.requireRuntimeBlock(block, un_src, null);
24144 return block.addTyOp(.get_union_tag, enum_ty, un);24496 return block.addTyOp(.get_union_tag, enum_ty, un);
24145}24497}
2414624498
...@@ -24889,20 +25241,6 @@ fn resolveStructFully(...@@ -24889,20 +25241,6 @@ fn resolveStructFully(
24889 struct_obj.status = .fully_resolved_wip;25241 struct_obj.status = .fully_resolved_wip;
24890 for (struct_obj.fields.values()) |field| {25242 for (struct_obj.fields.values()) |field| {
24891 try sema.resolveTypeFully(block, src, field.ty);25243 try sema.resolveTypeFully(block, src, field.ty);
24892
24893 if (struct_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .other))) {
24894 const msg = msg: {
24895 const msg = try sema.errMsg(block, src, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)});
24896 errdefer msg.destroy(sema.gpa);
24897
24898 const src_decl = sema.mod.declPtr(block.src_decl);
24899 try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), field.ty, .other);
24900
24901 try sema.addDeclaredHereNote(msg, field.ty);
24902 break :msg msg;
24903 };
24904 return sema.failWithOwnedErrorMsg(block, msg);
24905 }
24906 }25244 }
24907 struct_obj.status = .fully_resolved;25245 struct_obj.status = .fully_resolved;
24908 }25246 }
...@@ -24936,20 +25274,6 @@ fn resolveUnionFully(...@@ -24936,20 +25274,6 @@ fn resolveUnionFully(
24936 union_obj.status = .fully_resolved_wip;25274 union_obj.status = .fully_resolved_wip;
24937 for (union_obj.fields.values()) |field| {25275 for (union_obj.fields.values()) |field| {
24938 try sema.resolveTypeFully(block, src, field.ty);25276 try sema.resolveTypeFully(block, src, field.ty);
24939
24940 if (union_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .union_field))) {
24941 const msg = msg: {
24942 const msg = try sema.errMsg(block, src, "extern unions cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)});
24943 errdefer msg.destroy(sema.gpa);
24944
24945 const src_decl = sema.mod.declPtr(block.src_decl);
24946 try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), field.ty, .union_field);
24947
24948 try sema.addDeclaredHereNote(msg, field.ty);
24949 break :msg msg;
24950 };
24951 return sema.failWithOwnedErrorMsg(block, msg);
24952 }
24953 }25277 }
24954 union_obj.status = .fully_resolved;25278 union_obj.status = .fully_resolved;
24955 }25279 }
...@@ -25033,7 +25357,7 @@ fn resolveTypeFieldsUnion(...@@ -25033,7 +25357,7 @@ fn resolveTypeFieldsUnion(
25033 }25357 }
2503425358
25035 union_obj.status = .field_types_wip;25359 union_obj.status = .field_types_wip;
25036 try semaUnionFields(block, sema.mod, union_obj);25360 try semaUnionFields(sema.mod, union_obj);
25037 union_obj.status = .have_field_types;25361 union_obj.status = .have_field_types;
25038}25362}
2503925363
...@@ -25287,6 +25611,33 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void...@@ -25287,6 +25611,33 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
25287 const field = &struct_obj.fields.values()[i];25611 const field = &struct_obj.fields.values()[i];
25288 field.ty = try field_ty.copy(decl_arena_allocator);25612 field.ty = try field_ty.copy(decl_arena_allocator);
2528925613
25614 if (struct_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .other))) {
25615 const msg = msg: {
25616 const tree = try sema.getAstTree(&block_scope);
25617 const fields_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, i);
25618 const msg = try sema.errMsg(&block_scope, fields_src, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)});
25619 errdefer msg.destroy(sema.gpa);
25620
25621 try sema.explainWhyTypeIsNotExtern(&block_scope, fields_src, msg, fields_src.toSrcLoc(decl), field.ty, .other);
25622
25623 try sema.addDeclaredHereNote(msg, field.ty);
25624 break :msg msg;
25625 };
25626 return sema.failWithOwnedErrorMsg(&block_scope, msg);
25627 }
25628 if (field_ty.zigTypeTag() == .Opaque) {
25629 const msg = msg: {
25630 const tree = try sema.getAstTree(&block_scope);
25631 const field_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, i);
25632 const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
25633 errdefer msg.destroy(sema.gpa);
25634
25635 try sema.addDeclaredHereNote(msg, field_ty);
25636 break :msg msg;
25637 };
25638 return sema.failWithOwnedErrorMsg(&block_scope, msg);
25639 }
25640
25290 if (zir_field.align_body_len > 0) {25641 if (zir_field.align_body_len > 0) {
25291 const body = zir.extra[extra_index..][0..zir_field.align_body_len];25642 const body = zir.extra[extra_index..][0..zir_field.align_body_len];
25292 extra_index += body.len;25643 extra_index += body.len;
...@@ -25311,7 +25662,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void...@@ -25311,7 +25662,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
25311 const field = &struct_obj.fields.values()[i];25662 const field = &struct_obj.fields.values()[i];
25312 const coerced = try sema.coerce(&block_scope, field.ty, init, src);25663 const coerced = try sema.coerce(&block_scope, field.ty, init, src);
25313 const default_val = (try sema.resolveMaybeUndefVal(&block_scope, src, coerced)) orelse25664 const default_val = (try sema.resolveMaybeUndefVal(&block_scope, src, coerced)) orelse
25314 return sema.failWithNeededComptime(&block_scope, src);25665 return sema.failWithNeededComptime(&block_scope, src, "struct field default value must be comptime known");
25315 field.default_val = try default_val.copy(decl_arena_allocator);25666 field.default_val = try default_val.copy(decl_arena_allocator);
25316 }25667 }
25317 }25668 }
...@@ -25320,7 +25671,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void...@@ -25320,7 +25671,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
25320 struct_obj.have_field_inits = true;25671 struct_obj.have_field_inits = true;
25321}25672}
2532225673
25323fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) CompileError!void {25674fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
25324 const tracy = trace(@src());25675 const tracy = trace(@src());
25325 defer tracy.end();25676 defer tracy.end();
2532625677
...@@ -25425,10 +25776,14 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil...@@ -25425,10 +25776,14 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
25425 var enum_value_map: ?*Module.EnumNumbered.ValueMap = null;25776 var enum_value_map: ?*Module.EnumNumbered.ValueMap = null;
25426 var tag_ty_field_names: ?Module.EnumFull.NameMap = null;25777 var tag_ty_field_names: ?Module.EnumFull.NameMap = null;
25427 if (tag_type_ref != .none) {25778 if (tag_type_ref != .none) {
25428 const provided_ty = try sema.resolveType(&block_scope, src, tag_type_ref);25779 const tag_ty_src: LazySrcLoc = .{ .node_offset_container_tag = src.node_offset.x };
25780 const provided_ty = try sema.resolveType(&block_scope, tag_ty_src, tag_type_ref);
25429 if (small.auto_enum_tag) {25781 if (small.auto_enum_tag) {
25430 // The provided type is an integer type and we must construct the enum tag type here.25782 // The provided type is an integer type and we must construct the enum tag type here.
25431 int_tag_ty = provided_ty;25783 int_tag_ty = provided_ty;
25784 if (int_tag_ty.zigTypeTag() != .Int and int_tag_ty.zigTypeTag() != .ComptimeInt) {
25785 return sema.fail(&block_scope, tag_ty_src, "expected integer tag type, found '{}'", .{int_tag_ty.fmt(sema.mod)});
25786 }
25432 union_obj.tag_ty = try sema.generateUnionTagTypeNumbered(&block_scope, fields_len, provided_ty, union_obj);25787 union_obj.tag_ty = try sema.generateUnionTagTypeNumbered(&block_scope, fields_len, provided_ty, union_obj);
25433 const enum_obj = union_obj.tag_ty.castTag(.enum_numbered).?.data;25788 const enum_obj = union_obj.tag_ty.castTag(.enum_numbered).?.data;
25434 enum_field_names = &enum_obj.fields;25789 enum_field_names = &enum_obj.fields;
...@@ -25437,8 +25792,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil...@@ -25437,8 +25792,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
25437 // The provided type is the enum tag type.25792 // The provided type is the enum tag type.
25438 union_obj.tag_ty = try provided_ty.copy(decl_arena_allocator);25793 union_obj.tag_ty = try provided_ty.copy(decl_arena_allocator);
25439 if (union_obj.tag_ty.zigTypeTag() != .Enum) {25794 if (union_obj.tag_ty.zigTypeTag() != .Enum) {
25440 const tag_ty_src = src; // TODO better source location25795 return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{union_obj.tag_ty.fmt(sema.mod)});
25441 return sema.fail(block, tag_ty_src, "expected enum tag type, found '{}'", .{union_obj.tag_ty.fmt(sema.mod)});
25442 }25796 }
25443 // The fields of the union must match the enum exactly.25797 // The fields of the union must match the enum exactly.
25444 // Store a copy of the enum field names so we can check for25798 // Store a copy of the enum field names so we can check for
...@@ -25504,7 +25858,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil...@@ -25504,7 +25858,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
25504 if (tag_ref != .none) {25858 if (tag_ref != .none) {
25505 const tag_src = src; // TODO better source location25859 const tag_src = src; // TODO better source location
25506 const coerced = try sema.coerce(&block_scope, int_tag_ty, tag_ref, tag_src);25860 const coerced = try sema.coerce(&block_scope, int_tag_ty, tag_ref, tag_src);
25507 const val = try sema.resolveConstValue(&block_scope, tag_src, coerced);25861 const val = try sema.resolveConstValue(&block_scope, tag_src, coerced, "enum tag value must be comptime known");
25508 last_tag_val = val;25862 last_tag_val = val;
2550925863
25510 // This puts the memory into the union arena, not the enum arena, but25864 // This puts the memory into the union arena, not the enum arena, but
...@@ -25516,7 +25870,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil...@@ -25516,7 +25870,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
25516 });25870 });
25517 } else {25871 } else {
25518 const val = if (last_tag_val) |val|25872 const val = if (last_tag_val) |val|
25519 try sema.intAdd(block, src, val, Value.one, int_tag_ty)25873 try sema.intAdd(&block_scope, src, val, Value.one, int_tag_ty)
25520 else25874 else
25521 Value.zero;25875 Value.zero;
25522 last_tag_val = val;25876 last_tag_val = val;
...@@ -25570,15 +25924,44 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil...@@ -25570,15 +25924,44 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
25570 const enum_has_field = names.orderedRemove(field_name);25924 const enum_has_field = names.orderedRemove(field_name);
25571 if (!enum_has_field) {25925 if (!enum_has_field) {
25572 const msg = msg: {25926 const msg = msg: {
25573 const msg = try sema.errMsg(block, src, "enum '{}' has no field named '{s}'", .{ union_obj.tag_ty.fmt(sema.mod), field_name });25927 const tree = try sema.getAstTree(&block_scope);
25928 const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i);
25929 const msg = try sema.errMsg(&block_scope, field_src, "enum '{}' has no field named '{s}'", .{ union_obj.tag_ty.fmt(sema.mod), field_name });
25574 errdefer msg.destroy(sema.gpa);25930 errdefer msg.destroy(sema.gpa);
25575 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);25931 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
25576 break :msg msg;25932 break :msg msg;
25577 };25933 };
25578 return sema.failWithOwnedErrorMsg(block, msg);25934 return sema.failWithOwnedErrorMsg(&block_scope, msg);
25579 }25935 }
25580 }25936 }
2558125937
25938 if (union_obj.layout == .Extern and !(try sema.validateExternType(field_ty, .union_field))) {
25939 const msg = msg: {
25940 const tree = try sema.getAstTree(&block_scope);
25941 const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i);
25942 const msg = try sema.errMsg(&block_scope, field_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});
25943 errdefer msg.destroy(sema.gpa);
25944
25945 try sema.explainWhyTypeIsNotExtern(&block_scope, field_src, msg, field_src.toSrcLoc(decl), field_ty, .union_field);
25946
25947 try sema.addDeclaredHereNote(msg, field_ty);
25948 break :msg msg;
25949 };
25950 return sema.failWithOwnedErrorMsg(&block_scope, msg);
25951 }
25952 if (field_ty.zigTypeTag() == .Opaque) {
25953 const msg = msg: {
25954 const tree = try sema.getAstTree(&block_scope);
25955 const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i);
25956 const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{});
25957 errdefer msg.destroy(sema.gpa);
25958
25959 try sema.addDeclaredHereNote(msg, field_ty);
25960 break :msg msg;
25961 };
25962 return sema.failWithOwnedErrorMsg(&block_scope, msg);
25963 }
25964
25582 gop.value_ptr.* = .{25965 gop.value_ptr.* = .{
25583 .ty = try field_ty.copy(decl_arena_allocator),25966 .ty = try field_ty.copy(decl_arena_allocator),
25584 .abi_align = 0,25967 .abi_align = 0,
...@@ -25597,18 +25980,18 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil...@@ -25597,18 +25980,18 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
25597 if (tag_ty_field_names) |names| {25980 if (tag_ty_field_names) |names| {
25598 if (names.count() > 0) {25981 if (names.count() > 0) {
25599 const msg = msg: {25982 const msg = msg: {
25600 const msg = try sema.errMsg(block, src, "enum field(s) missing in union", .{});25983 const msg = try sema.errMsg(&block_scope, src, "enum field(s) missing in union", .{});
25601 errdefer msg.destroy(sema.gpa);25984 errdefer msg.destroy(sema.gpa);
2560225985
25603 const enum_ty = union_obj.tag_ty;25986 const enum_ty = union_obj.tag_ty;
25604 for (names.keys()) |field_name| {25987 for (names.keys()) |field_name| {
25605 const field_index = enum_ty.enumFieldIndex(field_name).?;25988 const field_index = enum_ty.enumFieldIndex(field_name).?;
25606 try sema.addFieldErrNote(block, enum_ty, field_index, msg, "field '{s}' missing, declared here", .{field_name});25989 try sema.addFieldErrNote(&block_scope, enum_ty, field_index, msg, "field '{s}' missing, declared here", .{field_name});
25607 }25990 }
25608 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);25991 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
25609 break :msg msg;25992 break :msg msg;
25610 };25993 };
25611 return sema.failWithOwnedErrorMsg(block, msg);25994 return sema.failWithOwnedErrorMsg(&block_scope, msg);
25612 }25995 }
25613 }25996 }
25614}25997}
...@@ -26247,7 +26630,7 @@ pub fn analyzeAddrspace(...@@ -26247,7 +26630,7 @@ pub fn analyzeAddrspace(
26247 zir_ref: Zir.Inst.Ref,26630 zir_ref: Zir.Inst.Ref,
26248 ctx: AddressSpaceContext,26631 ctx: AddressSpaceContext,
26249) !std.builtin.AddressSpace {26632) !std.builtin.AddressSpace {
26250 const addrspace_tv = try sema.resolveInstConst(block, src, zir_ref);26633 const addrspace_tv = try sema.resolveInstConst(block, src, zir_ref, "addresspace must be comptime known");
26251 const address_space = addrspace_tv.val.toEnum(std.builtin.AddressSpace);26634 const address_space = addrspace_tv.val.toEnum(std.builtin.AddressSpace);
26252 const target = sema.mod.getTarget();26635 const target = sema.mod.getTarget();
26253 const arch = target.cpu.arch;26636 const arch = target.cpu.arch;
src/Zir.zig+7-14
...@@ -534,9 +534,9 @@ pub const Inst = struct {...@@ -534,9 +534,9 @@ pub const Inst = struct {
534 /// Obtains the return type of the in-scope function.534 /// Obtains the return type of the in-scope function.
535 /// Uses the `node` union field.535 /// Uses the `node` union field.
536 ret_type,536 ret_type,
537 /// Create a pointer type that does not have a sentinel, alignment, address space, or bit range specified.537 /// Create a pointer type for overflow arithmetic.
538 /// Uses the `ptr_type_simple` union field.538 /// TODO remove when doing https://github.com/ziglang/zig/issues/10248
539 ptr_type_simple,539 overflow_arithmetic_ptr,
540 /// Create a pointer type which can have a sentinel, alignment, address space, and/or bit range.540 /// Create a pointer type which can have a sentinel, alignment, address space, and/or bit range.
541 /// Uses the `ptr_type` union field.541 /// Uses the `ptr_type` union field.
542 ptr_type,542 ptr_type,
...@@ -1121,7 +1121,7 @@ pub const Inst = struct {...@@ -1121,7 +1121,7 @@ pub const Inst = struct {
1121 .err_union_code,1121 .err_union_code,
1122 .err_union_code_ptr,1122 .err_union_code_ptr,
1123 .ptr_type,1123 .ptr_type,
1124 .ptr_type_simple,1124 .overflow_arithmetic_ptr,
1125 .ensure_err_payload_void,1125 .ensure_err_payload_void,
1126 .enum_literal,1126 .enum_literal,
1127 .merge_error_sets,1127 .merge_error_sets,
...@@ -1417,7 +1417,7 @@ pub const Inst = struct {...@@ -1417,7 +1417,7 @@ pub const Inst = struct {
1417 .err_union_code,1417 .err_union_code,
1418 .err_union_code_ptr,1418 .err_union_code_ptr,
1419 .ptr_type,1419 .ptr_type,
1420 .ptr_type_simple,1420 .overflow_arithmetic_ptr,
1421 .enum_literal,1421 .enum_literal,
1422 .merge_error_sets,1422 .merge_error_sets,
1423 .error_union_type,1423 .error_union_type,
...@@ -1659,7 +1659,7 @@ pub const Inst = struct {...@@ -1659,7 +1659,7 @@ pub const Inst = struct {
1659 .ret_err_value_code = .str_tok,1659 .ret_err_value_code = .str_tok,
1660 .ret_ptr = .node,1660 .ret_ptr = .node,
1661 .ret_type = .node,1661 .ret_type = .node,
1662 .ptr_type_simple = .ptr_type_simple,1662 .overflow_arithmetic_ptr = .un_node,
1663 .ptr_type = .ptr_type,1663 .ptr_type = .ptr_type,
1664 .slice_start = .pl_node,1664 .slice_start = .pl_node,
1665 .slice_end = .pl_node,1665 .slice_end = .pl_node,
...@@ -2499,13 +2499,6 @@ pub const Inst = struct {...@@ -2499,13 +2499,6 @@ pub const Inst = struct {
2499 node: i32,2499 node: i32,
2500 int: u64,2500 int: u64,
2501 float: f64,2501 float: f64,
2502 ptr_type_simple: struct {
2503 is_allowzero: bool,
2504 is_mutable: bool,
2505 is_volatile: bool,
2506 size: std.builtin.Type.Pointer.Size,
2507 elem_type: Ref,
2508 },
2509 ptr_type: struct {2502 ptr_type: struct {
2510 flags: packed struct {2503 flags: packed struct {
2511 is_allowzero: bool,2504 is_allowzero: bool,
...@@ -2608,7 +2601,6 @@ pub const Inst = struct {...@@ -2608,7 +2601,6 @@ pub const Inst = struct {
2608 node,2601 node,
2609 int,2602 int,
2610 float,2603 float,
2611 ptr_type_simple,
2612 ptr_type,2604 ptr_type,
2613 int_type,2605 int_type,
2614 bool_br,2606 bool_br,
...@@ -2869,6 +2861,7 @@ pub const Inst = struct {...@@ -2869,6 +2861,7 @@ pub const Inst = struct {
2869 /// 4. host_size: Ref // if `has_bit_range` flag is set2861 /// 4. host_size: Ref // if `has_bit_range` flag is set
2870 pub const PtrType = struct {2862 pub const PtrType = struct {
2871 elem_type: Ref,2863 elem_type: Ref,
2864 src_node: i32,
2872 };2865 };
28732866
2874 pub const ArrayTypeSentinel = struct {2867 pub const ArrayTypeSentinel = struct {
src/print_zir.zig+3-20
...@@ -233,6 +233,7 @@ const Writer = struct {...@@ -233,6 +233,7 @@ const Writer = struct {
233 .validate_struct_init_ty,233 .validate_struct_init_ty,
234 .make_ptr_const,234 .make_ptr_const,
235 .validate_deref,235 .validate_deref,
236 .overflow_arithmetic_ptr,
236 => try self.writeUnNode(stream, inst),237 => try self.writeUnNode(stream, inst),
237238
238 .ref,239 .ref,
...@@ -247,7 +248,6 @@ const Writer = struct {...@@ -247,7 +248,6 @@ const Writer = struct {
247248
248 .array_type_sentinel => try self.writeArrayTypeSentinel(stream, inst),249 .array_type_sentinel => try self.writeArrayTypeSentinel(stream, inst),
249 .param_type => try self.writeParamType(stream, inst),250 .param_type => try self.writeParamType(stream, inst),
250 .ptr_type_simple => try self.writePtrTypeSimple(stream, inst),
251 .ptr_type => try self.writePtrType(stream, inst),251 .ptr_type => try self.writePtrType(stream, inst),
252 .int => try self.writeInt(stream, inst),252 .int => try self.writeInt(stream, inst),
253 .int_big => try self.writeIntBig(stream, inst),253 .int_big => try self.writeIntBig(stream, inst),
...@@ -601,24 +601,6 @@ const Writer = struct {...@@ -601,24 +601,6 @@ const Writer = struct {
601 try stream.print(", {d})", .{inst_data.param_index});601 try stream.print(", {d})", .{inst_data.param_index});
602 }602 }
603603
604 fn writePtrTypeSimple(
605 self: *Writer,
606 stream: anytype,
607 inst: Zir.Inst.Index,
608 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {
609 const inst_data = self.code.instructions.items(.data)[inst].ptr_type_simple;
610 const str_allowzero = if (inst_data.is_allowzero) "allowzero, " else "";
611 const str_const = if (!inst_data.is_mutable) "const, " else "";
612 const str_volatile = if (inst_data.is_volatile) "volatile, " else "";
613 try self.writeInstRef(stream, inst_data.elem_type);
614 try stream.print(", {s}{s}{s}{s})", .{
615 str_allowzero,
616 str_const,
617 str_volatile,
618 @tagName(inst_data.size),
619 });
620 }
621
622 fn writePtrType(604 fn writePtrType(
623 self: *Writer,605 self: *Writer,
624 stream: anytype,606 stream: anytype,
...@@ -660,7 +642,8 @@ const Writer = struct {...@@ -660,7 +642,8 @@ const Writer = struct {
660 try self.writeInstRef(stream, @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]));642 try self.writeInstRef(stream, @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]));
661 try stream.writeAll(")");643 try stream.writeAll(")");
662 }644 }
663 try stream.writeAll(")");645 try stream.writeAll(") ");
646 try self.writeSrc(stream, LazySrcLoc.nodeOffset(extra.data.src_node));
664 }647 }
665648
666 fn writeInt(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {649 fn writeInt(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
src/target.zig+8
...@@ -744,6 +744,7 @@ pub fn llvmMachineAbi(target: std.Target) ?[:0]const u8 {...@@ -744,6 +744,7 @@ pub fn llvmMachineAbi(target: std.Target) ?[:0]const u8 {
744 }744 }
745}745}
746746
747/// This function returns 1 if function alignment is not observable or settable.
747pub fn defaultFunctionAlignment(target: std.Target) u32 {748pub fn defaultFunctionAlignment(target: std.Target) u32 {
748 return switch (target.cpu.arch) {749 return switch (target.cpu.arch) {
749 .arm, .armeb => 4,750 .arm, .armeb => 4,
...@@ -753,3 +754,10 @@ pub fn defaultFunctionAlignment(target: std.Target) u32 {...@@ -753,3 +754,10 @@ pub fn defaultFunctionAlignment(target: std.Target) u32 {
753 else => 1,754 else => 1,
754 };755 };
755}756}
757
758pub fn supportsFunctionAlignment(target: std.Target) bool {
759 return switch (target.cpu.arch) {
760 .wasm32, .wasm64 => false,
761 else => true,
762 };
763}
src/type.zig+20-2
...@@ -4643,13 +4643,27 @@ pub const Type = extern union {...@@ -4643,13 +4643,27 @@ pub const Type = extern union {
4643 }4643 }
46444644
4645 /// Asserts the type is a function.4645 /// Asserts the type is a function.
4646 pub fn fnCallingConventionAllowsZigTypes(self: Type) bool {4646 pub fn fnCallingConventionAllowsZigTypes(cc: std.builtin.CallingConvention) bool {
4647 return switch (self.fnCallingConvention()) {4647 return switch (cc) {
4648 .Unspecified, .Async, .Inline, .PtxKernel => true,4648 .Unspecified, .Async, .Inline, .PtxKernel => true,
4649 else => false,4649 else => false,
4650 };4650 };
4651 }4651 }
46524652
4653 pub fn isValidParamType(self: Type) bool {
4654 return switch (self.zigTypeTagOrPoison() catch return true) {
4655 .Undefined, .Null, .Opaque, .NoReturn => false,
4656 else => true,
4657 };
4658 }
4659
4660 pub fn isValidReturnType(self: Type) bool {
4661 return switch (self.zigTypeTagOrPoison() catch return true) {
4662 .Undefined, .Null, .Opaque => false,
4663 else => true,
4664 };
4665 }
4666
4653 /// Asserts the type is a function.4667 /// Asserts the type is a function.
4654 pub fn fnIsVarArgs(self: Type) bool {4668 pub fn fnIsVarArgs(self: Type) bool {
4655 return switch (self.tag()) {4669 return switch (self.tag()) {
...@@ -5650,6 +5664,10 @@ pub const Type = extern union {...@@ -5650,6 +5664,10 @@ pub const Type = extern union {
5650 const union_obj = ty.cast(Payload.Union).?.data;5664 const union_obj = ty.cast(Payload.Union).?.data;
5651 return union_obj.srcLoc(mod);5665 return union_obj.srcLoc(mod);
5652 },5666 },
5667 .@"opaque" => {
5668 const opaque_obj = ty.cast(Payload.Opaque).?.data;
5669 return opaque_obj.srcLoc(mod);
5670 },
5653 .atomic_order,5671 .atomic_order,
5654 .atomic_rmw_op,5672 .atomic_rmw_op,
5655 .calling_convention,5673 .calling_convention,
test/behavior/align.zig+2-3
...@@ -299,8 +299,7 @@ test "implicitly decreasing fn alignment" {...@@ -299,8 +299,7 @@ test "implicitly decreasing fn alignment" {
299 try testImplicitlyDecreaseFnAlign(alignedBig, 5678);299 try testImplicitlyDecreaseFnAlign(alignedBig, 5678);
300}300}
301301
302// TODO make it a compile error to put align on the fn proto instead of on the ptr302fn testImplicitlyDecreaseFnAlign(ptr: *const fn () align(1) i32, answer: i32) !void {
303fn testImplicitlyDecreaseFnAlign(ptr: *align(1) const fn () i32, answer: i32) !void {
304 try expect(ptr() == answer);303 try expect(ptr() == answer);
305}304}
306305
...@@ -326,7 +325,7 @@ test "@alignCast functions" {...@@ -326,7 +325,7 @@ test "@alignCast functions" {
326fn fnExpectsOnly1(ptr: *const fn () align(1) i32) i32 {325fn fnExpectsOnly1(ptr: *const fn () align(1) i32) i32 {
327 return fnExpects4(@alignCast(4, ptr));326 return fnExpects4(@alignCast(4, ptr));
328}327}
329fn fnExpects4(ptr: *align(4) const fn () i32) i32 {328fn fnExpects4(ptr: *const fn () align(4) i32) i32 {
330 return ptr();329 return ptr();
331}330}
332fn simple4() align(4) i32 {331fn simple4() align(4) i32 {
test/behavior/bugs/1310.zig+3-1
...@@ -4,7 +4,7 @@ const builtin = @import("builtin");...@@ -4,7 +4,7 @@ const builtin = @import("builtin");
44
5pub const VM = ?[*]const struct_InvocationTable_;5pub const VM = ?[*]const struct_InvocationTable_;
6pub const struct_InvocationTable_ = extern struct {6pub const struct_InvocationTable_ = extern struct {
7 GetVM: ?fn (?[*]VM) callconv(.C) c_int,7 GetVM: ?*const fn (?[*]VM) callconv(.C) c_int,
8};8};
99
10pub const struct_VM_ = extern struct {10pub const struct_VM_ = extern struct {
...@@ -23,5 +23,7 @@ fn agent_callback(_vm: [*]VM, options: [*]u8) callconv(.C) i32 {...@@ -23,5 +23,7 @@ fn agent_callback(_vm: [*]VM, options: [*]u8) callconv(.C) i32 {
23}23}
2424
25test "fixed" {25test "fixed" {
26 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
27 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
26 try expect(agent_callback(undefined, undefined) == 11);28 try expect(agent_callback(undefined, undefined) == 11);
27}29}
test/behavior/union.zig-1
...@@ -1016,7 +1016,6 @@ test "switching on non exhaustive union" {...@@ -1016,7 +1016,6 @@ test "switching on non exhaustive union" {
1016 switch (a) {1016 switch (a) {
1017 .a => |val| try expect(val == 2),1017 .a => |val| try expect(val == 2),
1018 .b => return error.Fail,1018 .b => return error.Fail,
1019 _ => return error.Fail,
1020 }1019 }
1021 }1020 }
1022 };1021 };
test/cases/compile_errors/C_pointer_pointing_to_non_C_ABI_compatible_type_or_has_align_attr.zig created+14
...@@ -0,0 +1,14 @@
1const Foo = struct {};
2export fn a() void {
3 const T = [*c]Foo;
4 var t: T = undefined;
5 _ = t;
6}
7
8// error
9// backend=stage2
10// target=native
11//
12// :3:19: error: C pointers cannot point to non-C-ABI-compatible type 'tmp.Foo'
13// :3:19: note: only structs with packed or extern layout are extern compatible
14// :1:13: note: struct declared here
test/cases/compile_errors/C_pointer_to_anyopaque.zig created+11
...@@ -0,0 +1,11 @@
1export fn a() void {
2 var x: *anyopaque = undefined;
3 var y: [*c]anyopaque = x;
4 _ = y;
5}
6
7// error
8// backend=stage2
9// target=native
10//
11// :3:16: error: C pointers cannot point to opaque types
test/cases/compile_errors/align_n_expr_function_pointers_is_a_compile_error.zig created+9
...@@ -0,0 +1,9 @@
1export fn foo() align(1) void {
2 return;
3}
4
5// error
6// backend=stage2
7// target=wasm32-freestanding-none
8//
9// :1:23: error: target does not support function alignment
test/cases/compile_errors/array_access_of_non_array.zig created+15
...@@ -0,0 +1,15 @@
1export fn f() void {
2 var bad : bool = undefined;
3 bad[0] = bad[0];
4}
5export fn g() void {
6 var bad : bool = undefined;
7 _ = bad[0];
8}
9
10// error
11// backend=stage2
12// target=native
13//
14// :3:8: error: element access of non-indexable type 'bool'
15// :7:12: error: element access of non-indexable type 'bool'
test/cases/compile_errors/array_access_with_non_integer_index.zig created+17
...@@ -0,0 +1,17 @@
1export fn f() void {
2 var array = "aoeu";
3 var bad = false;
4 array[bad] = array[bad];
5}
6export fn g() void {
7 var array = "aoeu";
8 var bad = false;
9 _ = array[bad];
10}
11
12// error
13// backend=stage2
14// target=native
15//
16// :4:11: error: expected type 'usize', found 'bool'
17// :9:15: error: expected type 'usize', found 'bool'
test/cases/compile_errors/array_in_c_exported_function.zig created+16
...@@ -0,0 +1,16 @@
1export fn zig_array(x: [10]u8) void {
2 try std.testing.expect(std.mem.eql(u8, &x, "1234567890"));
3}
4const std = @import("std");
5export fn zig_return_array() [10]u8 {
6 return "1234567890".*;
7}
8
9// error
10// backend=stage2
11// target=native
12//
13// :1:21: error: parameter of type '[10]u8' not allowed in function with calling convention 'C'
14// :1:21: note: arrays are not allowed as a parameter type
15// :5:30: error: return type '[10]u8' not allowed in function with calling convention 'C'
16// :5:30: note: arrays are not allowed as a return type
test/cases/compile_errors/asm_at_compile_time.zig+1-1
...@@ -14,5 +14,5 @@ fn doSomeAsm() void {...@@ -14,5 +14,5 @@ fn doSomeAsm() void {
14// backend=llvm14// backend=llvm
15// target=native15// target=native
16//16//
17// :6:5: error: unable to resolve comptime value17// :6:5: error: unable to evalutate comptime expression
18// :2:14: note: called from here18// :2:14: note: called from here
test/cases/compile_errors/c_pointer_to_void.zig+2-2
...@@ -7,5 +7,5 @@ export fn entry() void {...@@ -7,5 +7,5 @@ export fn entry() void {
7// backend=stage27// backend=stage2
8// target=native8// target=native
9//9//
10// :1:1: error: C pointers cannot point to non-C-ABI-compatible type 'void'10// :2:16: error: C pointers cannot point to non-C-ABI-compatible type 'void'
11// :1:1: note: 'void' is a zero bit type; for C 'void' use 'anyopaque'11// :2:16: note: 'void' is a zero bit type; for C 'void' use 'anyopaque'
test/cases/compile_errors/call method on bound fn referring to var instance.zig +1-1
...@@ -17,4 +17,4 @@ fn bad(ok: bool) void {...@@ -17,4 +17,4 @@ fn bad(ok: bool) void {
17// target=native17// target=native
18// backend=stage218// backend=stage2
19//19//
20// :12:18: error: unable to resolve comptime value20// :12:18: error: cannot load runtime value in comptime block
test/cases/compile_errors/calling_var_args_extern_function_passing_array_instead_of_pointer.zig+1-1
...@@ -7,4 +7,4 @@ pub extern fn foo(format: *const u8, ...) void;...@@ -7,4 +7,4 @@ pub extern fn foo(format: *const u8, ...) void;
7// backend=stage27// backend=stage2
8// target=native8// target=native
9//9//
10// :2:8: error: expected type '*const u8', found '[5:0]u8'10// :2:16: error: expected type '*const u8', found '[5:0]u8'
test/cases/compile_errors/capture_group_on_switch_prong_with_incompatible_payload_types.zig created+21
...@@ -0,0 +1,21 @@
1const Union = union(enum) {
2 A: usize,
3 B: isize,
4};
5comptime {
6 var u = Union{ .A = 8 };
7 switch (u) {
8 .A, .B => |e| {
9 _ = e;
10 unreachable;
11 },
12 }
13}
14
15// error
16// backend=stage2
17// target=native
18//
19// :8:20: error: capture group with incompatible types
20// :8:10: note: type 'usize' here
21// :8:14: note: type 'isize' here
test/cases/compile_errors/casting_bit_offset_pointer_to_regular_pointer.zig+3-3
...@@ -18,6 +18,6 @@ export fn entry() usize { return @sizeOf(@TypeOf(&foo)); }...@@ -18,6 +18,6 @@ export fn entry() usize { return @sizeOf(@TypeOf(&foo)); }
18// backend=stage218// backend=stage2
19// target=native19// target=native
20//20//
21// :8:15: error: expected type '*const u3', found '*align(0:3:1) const u3'21// :8:16: error: expected type '*const u3', found '*align(0:3:1) const u3'
22// :8:15: note: pointer host size '1' cannot cast into pointer host size '0'22// :8:16: note: pointer host size '1' cannot cast into pointer host size '0'
23// :8:15: note: pointer bit offset '3' cannot cast into pointer bit offset '0'23// :8:16: note: pointer bit offset '3' cannot cast into pointer bit offset '0'
test/cases/compile_errors/container_init_with_non-type.zig+1-1
...@@ -7,4 +7,4 @@ export fn entry() usize { return @sizeOf(@TypeOf(a)); }...@@ -7,4 +7,4 @@ export fn entry() usize { return @sizeOf(@TypeOf(a)); }
7// backend=stage27// backend=stage2
8// target=native8// target=native
9//9//
10// :2:15: error: expected type 'type', found 'i32'10// :2:11: error: expected type 'type', found 'i32'
test/cases/compile_errors/control_reaches_end_of_non-void_function.zig created+9
...@@ -0,0 +1,9 @@
1fn a() i32 {}
2export fn entry() void { _ = a(); }
3
4// error
5// backend=stage2
6// target=native
7//
8// :1:13: error: expected type 'i32', found 'void'
9// :1:8: note: function return type declared here
test/cases/compile_errors/dereference_anyopaque.zig+8-4
...@@ -45,7 +45,11 @@ pub export fn entry() void {...@@ -45,7 +45,11 @@ pub export fn entry() void {
45// backend=llvm45// backend=llvm
46//46//
47// :11:22: error: comparison of 'void' with null47// :11:22: error: comparison of 'void' with null
48// :25:51: error: unable to resolve comptime value48// :25:51: error: values of type 'anyopaque' must be comptime known, but operand value is runtime known
49// :25:51: error: unable to resolve comptime value49// :25:51: note: opaque type 'anyopaque' has undefined size
50// :25:51: error: unable to resolve comptime value50// :25:51: error: values of type 'fn(*anyopaque, usize, u29, u29, usize) error{OutOfMemory}![]u8' must be comptime known, but operand value is runtime known
51// :25:51: error: unable to resolve comptime value51// :25:51: note: use '*const fn(*anyopaque, usize, u29, u29, usize) error{OutOfMemory}![]u8' for a function pointer type
52// :25:51: error: values of type 'fn(*anyopaque, []u8, u29, usize, u29, usize) ?usize' must be comptime known, but operand value is runtime known
53// :25:51: note: use '*const fn(*anyopaque, []u8, u29, usize, u29, usize) ?usize' for a function pointer type
54// :25:51: error: values of type 'fn(*anyopaque, []u8, u29, usize) void' must be comptime known, but operand value is runtime known
55// :25:51: note: use '*const fn(*anyopaque, []u8, u29, usize) void' for a function pointer type
test/cases/compile_errors/directly_embedding_opaque_type_in_struct_and_union.zig created+38
...@@ -0,0 +1,38 @@
1const O = opaque {};
2const Foo = struct {
3 o: O,
4};
5const Bar = union {
6 One: i32,
7 Two: O,
8};
9export fn a() void {
10 var foo: Foo = undefined;
11 _ = foo;
12}
13export fn b() void {
14 var bar: Bar = undefined;
15 _ = bar;
16}
17export fn c() void {
18 const baz = &@as(opaque {}, undefined);
19 const qux = .{baz.*};
20 _ = qux;
21}
22export fn d() void {
23 const baz = &@as(opaque {}, undefined);
24 const qux = .{ .a = baz.* };
25 _ = qux;
26}
27
28// error
29// backend=stage2
30// target=native
31//
32// :3:5: error: opaque types have unknown size and therefore cannot be directly embedded in structs
33// :1:11: note: opaque declared here
34// :7:5: error: opaque types have unknown size and therefore cannot be directly embedded in unions
35// :19:18: error: opaque types have unknown size and therefore cannot be directly embedded in structs
36// :18:22: note: opaque declared here
37// :24:18: error: opaque types have unknown size and therefore cannot be directly embedded in structs
38// :23:22: note: opaque declared here
test/cases/compile_errors/disallow_coercion_from_non-null-terminated_pointer_to_null-terminated_pointer.zig created+13
...@@ -0,0 +1,13 @@
1extern fn puts(s: [*:0]const u8) c_int;
2pub export fn entry() void {
3 const no_zero_array = [_]u8{'h', 'e', 'l', 'l', 'o'};
4 const no_zero_ptr: [*]const u8 = &no_zero_array;
5 _ = puts(no_zero_ptr);
6}
7
8// error
9// backend=stage2
10// target=native
11//
12// :5:14: error: expected type '[*:0]const u8', found '[*]const u8'
13// :5:14: note: destination pointer requires '0' sentinel
test/cases/compile_errors/endless_loop_in_function_evaluation.zig created+15
...@@ -0,0 +1,15 @@
1const seventh_fib_number = fibonacci(7);
2fn fibonacci(x: i32) i32 {
3 return fibonacci(x - 1) + fibonacci(x - 2);
4}
5
6export fn entry() usize { return @sizeOf(@TypeOf(&seventh_fib_number)); }
7
8// error
9// backend=stage2
10// target=native
11//
12// :3:21: error: evaluation exceeded 1000 backwards branches
13// :3:21: note: use @setEvalBranchQuota() to raise the branch limit from 1000
14// :3:21: note: called from here (999 times)
15// :1:37: note: called from here
test/cases/compile_errors/error_note_for_function_parameter_incompatibility.zig+3-3
...@@ -8,6 +8,6 @@ export fn entry() void {...@@ -8,6 +8,6 @@ export fn entry() void {
8// backend=stage28// backend=stage2
9// target=native9// target=native
10//10//
11// :4:17: error: expected type '*const fn(i32) void', found '*const fn(bool) void'11// :4:18: error: expected type '*const fn(i32) void', found '*const fn(bool) void'
12// :4:17: note: pointer type child 'fn(bool) void' cannot cast into pointer type child 'fn(i32) void'12// :4:18: note: pointer type child 'fn(bool) void' cannot cast into pointer type child 'fn(i32) void'
13// :4:17: note: parameter 0 'bool' cannot cast into 'i32'13// :4:18: note: parameter 0 'bool' cannot cast into 'i32'
test/cases/compile_errors/export_function_with_comptime_parameter.zig created+9
...@@ -0,0 +1,9 @@
1export fn foo(comptime x: anytype, y: i32) i32{
2 return x + y;
3}
4
5// error
6// backend=stage2
7// target=native
8//
9// :1:15: error: generic parameters not allowed in function with calling convention 'C'
test/cases/compile_errors/export_generic_function.zig created+10
...@@ -0,0 +1,10 @@
1export fn foo(num: anytype) i32 {
2 _ = num;
3 return 0;
4}
5
6// error
7// backend=stage2
8// target=native
9//
10// :1:15: error: generic parameters not allowed in function with calling convention 'C'
test/cases/compile_errors/extern_function_with_comptime_parameter.zig created+20
...@@ -0,0 +1,20 @@
1extern fn foo(comptime x: i32, y: i32) i32;
2fn f() i32 {
3 return foo(1, 2);
4}
5pub extern fn entry1(b: u32, comptime a: [2]u8, c: i32) void;
6pub extern fn entry2(b: u32, noalias a: anytype, i43) void;
7comptime { _ = f; }
8comptime { _ = entry1; }
9comptime { _ = entry2; }
10
11// error
12// backend=stage2
13// target=native
14//
15// :5:12: error: extern function cannot be generic
16// :5:30: note: function is generic because of this parameter
17// :6:12: error: extern function cannot be generic
18// :6:30: note: function is generic because of this parameter
19// :1:8: error: extern function cannot be generic
20// :1:15: note: function is generic because of this parameter
test/cases/compile_errors/extern_struct_with_extern-compatible_but_inferred_integer_tag_type.zig+3-3
...@@ -39,7 +39,7 @@ export fn entry() void {...@@ -39,7 +39,7 @@ export fn entry() void {
39// backend=stage239// backend=stage2
40// target=native40// target=native
41//41//
42// :33:8: error: extern structs cannot contain fields of type 'tmp.E'42// :31:5: error: extern structs cannot contain fields of type 'tmp.E'
43// :33:8: note: enum tag type 'u9' is not extern compatible43// :31:5: note: enum tag type 'u9' is not extern compatible
44// :33:8: note: only integers with power of two bits are extern compatible44// :31:5: note: only integers with power of two bits are extern compatible
45// :1:15: note: enum declared here45// :1:15: note: enum declared here
test/cases/compile_errors/extern_struct_with_non-extern-compatible_integer_tag_type.zig+3-3
...@@ -11,7 +11,7 @@ export fn entry() void {...@@ -11,7 +11,7 @@ export fn entry() void {
11// backend=stage211// backend=stage2
12// target=native12// target=native
13//13//
14// :5:8: error: extern structs cannot contain fields of type 'tmp.E'14// :3:5: error: extern structs cannot contain fields of type 'tmp.E'
15// :5:8: note: enum tag type 'u31' is not extern compatible15// :3:5: note: enum tag type 'u31' is not extern compatible
16// :5:8: note: only integers with power of two bits are extern compatible16// :3:5: note: only integers with power of two bits are extern compatible
17// :1:15: note: enum declared here17// :1:15: note: enum declared here
test/cases/compile_errors/extern_union_given_enum_tag_type.zig created+20
...@@ -0,0 +1,20 @@
1const Letter = enum {
2 A,
3 B,
4 C,
5};
6const Payload = extern union(Letter) {
7 A: i32,
8 B: f64,
9 C: bool,
10};
11export fn entry() void {
12 var a = Payload { .A = 1234 };
13 _ = a;
14}
15
16// error
17// backend=stage2
18// target=native
19//
20// :6:30: error: extern union does not support enum tag type
test/cases/compile_errors/function_alignment_non_power_of_2.zig created+8
...@@ -0,0 +1,8 @@
1extern fn foo() align(3) void;
2export fn entry() void { return foo(); }
3
4// error
5// backend=stage2
6// target=native
7//
8// :1:23: error: alignment value '3' is not a power of two
test/cases/compile_errors/function_call_assigned_to_incorrect_type.zig+1
...@@ -11,3 +11,4 @@ fn concat() [16]f32 {...@@ -11,3 +11,4 @@ fn concat() [16]f32 {
11// target=native11// target=native
12//12//
13// :3:17: error: expected type '[4]f32', found '[16]f32'13// :3:17: error: expected type '[4]f32', found '[16]f32'
14// :3:17: note: array of length 16 cannot cast into an array of length 4
test/cases/compile_errors/function_parameter_is_opaque.zig created+30
...@@ -0,0 +1,30 @@
1const FooType = opaque {};
2export fn entry1() void {
3 const someFuncPtr: fn (FooType) void = undefined;
4 _ = someFuncPtr;
5}
6
7export fn entry2() void {
8 const someFuncPtr: fn (@TypeOf(null)) void = undefined;
9 _ = someFuncPtr;
10}
11
12fn foo(p: FooType) void {_ = p;}
13export fn entry3() void {
14 _ = foo;
15}
16
17fn bar(p: @TypeOf(null)) void {_ = p;}
18export fn entry4() void {
19 _ = bar;
20}
21
22// error
23// backend=stage2
24// target=native
25//
26// :3:28: error: parameter of opaque type 'tmp.FooType' not allowed
27// :1:17: note: opaque declared here
28// :8:28: error: parameter of type '@TypeOf(null)' not allowed
29// :12:8: error: parameter of opaque type 'tmp.FooType' not allowed
30// :17:8: error: parameter of type '@TypeOf(null)' not allowed
test/cases/compile_errors/function_ptr_alignment.zig created+28
...@@ -0,0 +1,28 @@
1comptime {
2 var a: *align(2) @TypeOf(foo) = undefined;
3 _ = a;
4}
5fn foo() void {}
6
7comptime {
8 var a: *align(1) fn () void = undefined;
9 _ = a;
10}
11comptime {
12 var a: *align(2) fn () align(2) void = undefined;
13 _ = a;
14}
15comptime {
16 var a: *align(2) fn () void = undefined;
17 _ = a;
18}
19comptime {
20 var a: *align(1) fn () align(2) void = undefined;
21 _ = a;
22}
23
24// error
25// backend=stage2
26// target=native
27//
28// :20:19: error: function pointer alignment disagrees with function alignment
test/cases/compile_errors/function_returning_opaque_type.zig created+19
...@@ -0,0 +1,19 @@
1const FooType = opaque {};
2export fn bar() !FooType {
3 return error.InvalidValue;
4}
5export fn bav() !@TypeOf(null) {
6 return error.InvalidValue;
7}
8export fn baz() !@TypeOf(undefined) {
9 return error.InvalidValue;
10}
11
12// error
13// backend=stage2
14// target=native
15//
16// :2:18: error: opaque return type 'tmp.FooType' not allowed
17// :1:17: note: opaque declared here
18// :5:18: error: return type '@TypeOf(null)' not allowed
19// :8:18: error: return type '@TypeOf(undefined)' not allowed
test/cases/compile_errors/function_with_non-extern_non-packed_enum_parameter.zig created+11
...@@ -0,0 +1,11 @@
1const Foo = enum { A, B, C };
2export fn entry(foo: Foo) void { _ = foo; }
3
4// error
5// backend=stage2
6// target=native
7//
8// :2:17: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'C'
9// :2:17: note: enum tag type 'u2' is not extern compatible
10// :2:17: note: only integers with power of two bits are extern compatible
11// :1:13: note: enum declared here
test/cases/compile_errors/function_with_non-extern_non-packed_struct_parameter.zig created+14
...@@ -0,0 +1,14 @@
1const Foo = struct {
2 A: i32,
3 B: f32,
4 C: bool,
5};
6export fn entry(foo: Foo) void { _ = foo; }
7
8// error
9// backend=stage2
10// target=native
11//
12// :6:17: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'C'
13// :6:17: note: only structs with packed or extern layout are extern compatible
14// :1:13: note: struct declared here
test/cases/compile_errors/function_with_non-extern_non-packed_union_parameter.zig created+14
...@@ -0,0 +1,14 @@
1const Foo = union {
2 A: i32,
3 B: f32,
4 C: bool,
5};
6export fn entry(foo: Foo) void { _ = foo; }
7
8// error
9// backend=stage2
10// target=native
11//
12// :6:17: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'C'
13// :6:17: note: only unions with packed or extern layout are extern compatible
14// :1:13: note: union declared here
test/cases/compile_errors/generic_function_instance_with_non-constant_expression.zig created+13
...@@ -0,0 +1,13 @@
1fn foo(comptime x: i32, y: i32) i32 { return x + y; }
2fn test1(a: i32, b: i32) i32 {
3 return foo(a, b);
4}
5
6export fn entry() usize { return @sizeOf(@TypeOf(&test1)); }
7
8// error
9// backend=stage2
10// target=native
11//
12// :3:16: error: unable to resolve comptime value
13// :3:16: note: parameter is comptime
test/cases/compile_errors/helpful_return_type_error_message.zig created+32
...@@ -0,0 +1,32 @@
1export fn foo() u32 {
2 return error.Ohno;
3}
4fn bar() !u32 {
5 return error.Ohno;
6}
7export fn baz() void {
8 try bar();
9}
10export fn qux() u32 {
11 return bar();
12}
13export fn quux() u32 {
14 var buf: u32 = 0;
15 buf = bar();
16}
17
18// error
19// backend=stage2
20// target=native
21//
22// :2:18: error: expected type 'u32', found 'error{Ohno}'
23// :1:17: note: function cannot return an error
24// :8:5: error: expected type 'void', found '@typeInfo(@typeInfo(@TypeOf(tmp.bar)).Fn.return_type.?).ErrorUnion.error_set'
25// :7:17: note: function cannot return an error
26// :11:15: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(tmp.bar)).Fn.return_type.?).ErrorUnion.error_set!u32'
27// :10:17: note: function cannot return an error
28// :11:15: note: cannot convert error union to payload type
29// :11:15: note: consider using `try`, `catch`, or `if`
30// :15:14: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(tmp.bar)).Fn.return_type.?).ErrorUnion.error_set!u32'
31// :15:14: note: cannot convert error union to payload type
32// :15:14: note: consider using `try`, `catch`, or `if`
test/cases/compile_errors/implicit_cast_from_array_to_mutable_slice.zig created+11
...@@ -0,0 +1,11 @@
1var global_array: [10]i32 = undefined;
2fn foo(param: []i32) void {_ = param;}
3export fn entry() void {
4 foo(global_array);
5}
6
7// error
8// backend=llvm
9// target=native
10//
11// :4:9: error: array literal requires address-of operator (&) to coerce to slice type '[]i32'
test/cases/compile_errors/implicitly_increasing_pointer_alignment.zig created+20
...@@ -0,0 +1,20 @@
1const Foo = packed struct {
2 a: u8,
3 b: u32,
4};
5
6export fn entry() void {
7 var foo = Foo { .a = 1, .b = 10 };
8 bar(&foo.b);
9}
10
11fn bar(x: *u32) void {
12 x.* += 1;
13}
14
15// error
16// backend=stage2
17// target=native
18//
19// :8:9: error: expected type '*u32', found '*align(1) u32'
20// :8:9: note: pointer alignment '1' cannot cast into pointer alignment '4'
test/cases/compile_errors/int-float_conversion_to_comptime_int-float.zig+2
...@@ -12,4 +12,6 @@ export fn bar() void {...@@ -12,4 +12,6 @@ export fn bar() void {
12// target=native12// target=native
13//13//
14// :3:35: error: unable to resolve comptime value14// :3:35: error: unable to resolve comptime value
15// :3:35: note: value being casted to 'comptime_int' must be comptime known
15// :7:37: error: unable to resolve comptime value16// :7:37: error: unable to resolve comptime value
17// :7:37: note: value being casted to 'comptime_float' must be comptime known
test/cases/compile_errors/invalid_optional_type_in_extern_struct.zig+2-2
...@@ -7,5 +7,5 @@ export fn testf(fluff: *stroo) void { _ = fluff; }...@@ -7,5 +7,5 @@ export fn testf(fluff: *stroo) void { _ = fluff; }
7// backend=stage27// backend=stage2
8// target=native8// target=native
9//9//
10// :4:8: error: extern structs cannot contain fields of type '?[*c]u8'10// :2:5: error: extern structs cannot contain fields of type '?[*c]u8'
11// :4:8: note: only pointer like optionals are extern compatible11// :2:5: note: only pointer like optionals are extern compatible
test/cases/compile_errors/load_too_many_bytes_from_comptime_reinterpreted_pointer.zig created+13
...@@ -0,0 +1,13 @@
1export fn entry() void {
2 const float: f32 = 5.99999999999994648725e-01;
3 const float_ptr = &float;
4 const int_ptr = @ptrCast(*const i64, float_ptr);
5 const int_val = int_ptr.*;
6 _ = int_val;
7}
8
9// error
10// backend=stage2
11// target=native
12//
13// :5:28: error: dereference of '*const i64' exceeds bounds of containing decl of type 'f32'
test/cases/compile_errors/non-const_expression_function_call_with_struct_return_value_outside_function.zig+1-1
...@@ -14,5 +14,5 @@ export fn entry() usize { return @sizeOf(@TypeOf(a)); }...@@ -14,5 +14,5 @@ export fn entry() usize { return @sizeOf(@TypeOf(a)); }
14// backend=stage214// backend=stage2
15// target=native15// target=native
16//16//
17// :6:26: error: unable to resolve comptime value17// :6:26: error: cannot store to runtime value in comptime block
18// :4:17: note: called from here18// :4:17: note: called from here
test/cases/compile_errors/non-enum_tag_type_passed_to_union.zig created+13
...@@ -0,0 +1,13 @@
1const Foo = union(u32) {
2 A: i32,
3};
4export fn entry() void {
5 const x = @typeInfo(Foo).Union.tag_type.?;
6 _ = x;
7}
8
9// error
10// backend=stage2
11// target=native
12//
13// :1:19: error: expected enum tag type, found 'u32'
test/cases/compile_errors/non-integer_tag_type_to_automatic_union_enum.zig created+13
...@@ -0,0 +1,13 @@
1const Foo = union(enum(f32)) {
2 A: i32,
3};
4export fn entry() void {
5 const x = @typeInfo(Foo).Union.tag_type.?;
6 _ = x;
7}
8
9// error
10// backend=stage2
11// target=native
12//
13// :1:24: error: expected integer tag type, found 'f32'
test/cases/compile_errors/non-integer_tag_type_to_enum.zig created+13
...@@ -0,0 +1,13 @@
1const Foo = enum(f32) {
2 A,
3};
4export fn entry() void {
5 var f: Foo = undefined;
6 _ = f;
7}
8
9// error
10// backend=stage2
11// target=native
12//
13// :1:18: error: expected integer tag type, found 'f32'
test/cases/compile_errors/non-pure_function_returns_type.zig+1-1
...@@ -21,5 +21,5 @@ export fn function_with_return_type_type() void {...@@ -21,5 +21,5 @@ export fn function_with_return_type_type() void {
21// backend=stage221// backend=stage2
22// target=native22// target=native
23//23//
24// :3:7: error: unable to resolve comptime value24// :3:7: error: cannot load runtime value in comptime block
25// :16:19: note: called from here25// :16:19: note: called from here
test/cases/compile_errors/non_constant_expression_in_array_size.zig+1-1
...@@ -10,5 +10,5 @@ export fn entry() usize { return @offsetOf(Foo, "y"); }...@@ -10,5 +10,5 @@ export fn entry() usize { return @offsetOf(Foo, "y"); }
10// backend=stage210// backend=stage2
11// target=native11// target=native
12//12//
13// :5:25: error: unable to resolve comptime value13// :5:25: error: cannot load runtime value in comptime block
14// :2:15: note: called from here14// :2:15: note: called from here
test/cases/compile_errors/opaque_type_with_field.zig created+11
...@@ -0,0 +1,11 @@
1const Opaque = opaque { foo: i32 };
2export fn entry() void {
3 const foo: ?*Opaque = null;
4 _ = foo;
5}
6
7// error
8// backend=stage2
9// target=native
10//
11// :1:25: error: opaque types cannot have fields
test/cases/compile_errors/pass_const_ptr_to_mutable_ptr_fn.zig created+18
...@@ -0,0 +1,18 @@
1fn foo() bool {
2 const a = @as([]const u8, "a",);
3 const b = &a;
4 return ptrEql(b, b);
5}
6fn ptrEql(a: *[]const u8, b: *[]const u8) bool {
7 _ = a; _ = b;
8 return true;
9}
10
11export fn entry() usize { return @sizeOf(@TypeOf(&foo)); }
12
13// error
14// backend=stage2
15// target=native
16//
17// :4:19: error: expected type '*[]const u8', found '*const []const u8'
18// :4:19: note: cast discards const qualifier
test/cases/compile_errors/pointer_to_noreturn.zig created+8
...@@ -0,0 +1,8 @@
1fn a() *noreturn {}
2export fn entry() void { _ = a(); }
3
4// error
5// backend=stage2
6// target=native
7//
8// :1:9: error: pointer to noreturn not allowed
test/cases/compile_errors/slice_passed_as_array_init_type_with_elems.zig+2-2
...@@ -7,5 +7,5 @@ export fn entry() void {...@@ -7,5 +7,5 @@ export fn entry() void {
7// backend=stage27// backend=stage2
8// target=native8// target=native
9//9//
10// :2:19: error: type '[]u8' does not support array initialization syntax10// :2:15: error: type '[]u8' does not support array initialization syntax
11// :2:19: note: inferred array length is specified with an underscore: '[_]u8'11// :2:15: note: inferred array length is specified with an underscore: '[_]u8'
test/cases/compile_errors/stage1/aligned_variable_of_zero-bit_type.zig created+10
...@@ -0,0 +1,10 @@
1export fn f() void {
2 var s: struct {} align(4) = undefined;
3 _ = s;
4}
5
6// error
7// backend=stage1
8// target=native
9//
10// tmp.zig:2:5: error: variable 's' of zero-bit type 'struct:2:12' has no in-memory representation, it cannot be aligned
test/cases/compile_errors/stage1/attempt_to_use_0_bit_type_in_extern_fn.zig created+17
...@@ -0,0 +1,17 @@
1extern fn foo(ptr: fn(*void) callconv(.C) void) void;
2
3export fn entry() void {
4 foo(bar);
5}
6
7fn bar(x: *void) callconv(.C) void { _ = x; }
8export fn entry2() void {
9 bar(&{});
10}
11
12// error
13// backend=stage1
14// target=native
15//
16// tmp.zig:1:23: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'
17// tmp.zig:7:11: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'
test/cases/compile_errors/stage1/implicit_casting_undefined_c_pointer_to_zig_pointer.zig created+11
...@@ -0,0 +1,11 @@
1comptime {
2 var c_ptr: [*c]u8 = undefined;
3 var zig_ptr: *u8 = c_ptr;
4 _ = zig_ptr;
5}
6
7// error
8// backend=stage1
9// target=native
10//
11// tmp.zig:3:24: error: use of undefined value here causes undefined behavior
test/cases/compile_errors/stage1/issue_2687_coerce_from_undefined_array_pointer_to_slice.zig created+27
...@@ -0,0 +1,27 @@
1export fn foo1() void {
2 const a: *[1]u8 = undefined;
3 var b: []u8 = a;
4 _ = b;
5}
6export fn foo2() void {
7 comptime {
8 var a: *[1]u8 = undefined;
9 var b: []u8 = a;
10 _ = b;
11 }
12}
13export fn foo3() void {
14 comptime {
15 const a: *[1]u8 = undefined;
16 var b: []u8 = a;
17 _ = b;
18 }
19}
20
21// error
22// backend=stage1
23// target=native
24//
25// tmp.zig:3:19: error: use of undefined value here causes undefined behavior
26// tmp.zig:9:23: error: use of undefined value here causes undefined behavior
27// tmp.zig:16:23: error: use of undefined value here causes undefined behavior
test/cases/compile_errors/stage1/obj/C_pointer_pointing_to_non_C_ABI_compatible_type_or_has_align_attr.zig deleted-12
...@@ -1,12 +0,0 @@
1const Foo = struct {};
2export fn a() void {
3 const T = [*c]Foo;
4 var t: T = undefined;
5 _ = t;
6}
7
8// error
9// backend=stage1
10// target=native
11//
12// tmp.zig:3:19: error: C pointers cannot point to non-C-ABI-compatible type 'Foo'
test/cases/compile_errors/stage1/obj/C_pointer_to_anyopaque.zig deleted-11
...@@ -1,11 +0,0 @@
1export fn a() void {
2 var x: *anyopaque = undefined;
3 var y: [*c]anyopaque = x;
4 _ = y;
5}
6
7// error
8// backend=stage1
9// target=native
10//
11// tmp.zig:3:16: error: C pointers cannot point to opaque types
test/cases/compile_errors/stage1/obj/align_n_expr_function_pointers_is_a_compile_error.zig deleted-9
...@@ -1,9 +0,0 @@
1export fn foo() align(1) void {
2 return;
3}
4
5// error
6// backend=stage1
7// target=wasm32-freestanding-none
8//
9// tmp.zig:1:23: error: align(N) expr is not allowed on function prototypes in wasm32/wasm64
test/cases/compile_errors/stage1/obj/aligned_variable_of_zero-bit_type.zig deleted-10
...@@ -1,10 +0,0 @@
1export fn f() void {
2 var s: struct {} align(4) = undefined;
3 _ = s;
4}
5
6// error
7// backend=stage1
8// target=native
9//
10// tmp.zig:2:5: error: variable 's' of zero-bit type 'struct:2:12' has no in-memory representation, it cannot be aligned
test/cases/compile_errors/stage1/obj/array_access_of_non_array.zig deleted-15
...@@ -1,15 +0,0 @@
1export fn f() void {
2 var bad : bool = undefined;
3 bad[0] = bad[0];
4}
5export fn g() void {
6 var bad : bool = undefined;
7 _ = bad[0];
8}
9
10// error
11// backend=stage1
12// target=native
13//
14// tmp.zig:3:8: error: array access of non-array type 'bool'
15// tmp.zig:7:12: error: array access of non-array type 'bool'
test/cases/compile_errors/stage1/obj/array_access_with_non_integer_index.zig deleted-17
...@@ -1,17 +0,0 @@
1export fn f() void {
2 var array = "aoeu";
3 var bad = false;
4 array[bad] = array[bad];
5}
6export fn g() void {
7 var array = "aoeu";
8 var bad = false;
9 _ = array[bad];
10}
11
12// error
13// backend=stage1
14// target=native
15//
16// tmp.zig:4:11: error: expected type 'usize', found 'bool'
17// tmp.zig:9:15: error: expected type 'usize', found 'bool'
test/cases/compile_errors/stage1/obj/array_in_c_exported_function.zig deleted-14
...@@ -1,14 +0,0 @@
1export fn zig_array(x: [10]u8) void {
2 try std.testing.expect(std.mem.eql(u8, &x, "1234567890"));
3}
4const std = @import("std");
5export fn zig_return_array() [10]u8 {
6 return "1234567890".*;
7}
8
9// error
10// backend=stage1
11// target=native
12//
13// tmp.zig:1:24: error: parameter of type '[10]u8' not allowed in function with calling convention 'C'
14// tmp.zig:5:30: error: return type '[10]u8' not allowed in function with calling convention 'C'
test/cases/compile_errors/stage1/obj/attempt_to_use_0_bit_type_in_extern_fn.zig deleted-17
...@@ -1,17 +0,0 @@
1extern fn foo(ptr: fn(*void) callconv(.C) void) void;
2
3export fn entry() void {
4 foo(bar);
5}
6
7fn bar(x: *void) callconv(.C) void { _ = x; }
8export fn entry2() void {
9 bar(&{});
10}
11
12// error
13// backend=stage1
14// target=native
15//
16// tmp.zig:1:23: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'
17// tmp.zig:7:11: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'
test/cases/compile_errors/stage1/obj/capture_group_on_switch_prong_with_incompatible_payload_types.zig deleted-21
...@@ -1,21 +0,0 @@
1const Union = union(enum) {
2 A: usize,
3 B: isize,
4};
5comptime {
6 var u = Union{ .A = 8 };
7 switch (u) {
8 .A, .B => |e| {
9 _ = e;
10 unreachable;
11 },
12 }
13}
14
15// error
16// backend=stage1
17// target=native
18//
19// tmp.zig:8:20: error: capture group with incompatible types
20// tmp.zig:8:9: note: type 'usize' here
21// tmp.zig:8:13: note: type 'isize' here
test/cases/compile_errors/stage1/obj/control_reaches_end_of_non-void_function.zig deleted-8
...@@ -1,8 +0,0 @@
1fn a() i32 {}
2export fn entry() void { _ = a(); }
3
4// error
5// backend=stage1
6// target=native
7//
8// tmp.zig:1:12: error: expected type 'i32', found 'void'
test/cases/compile_errors/stage1/obj/directly_embedding_opaque_type_in_struct_and_union.zig deleted-29
...@@ -1,29 +0,0 @@
1const O = opaque {};
2const Foo = struct {
3 o: O,
4};
5const Bar = union {
6 One: i32,
7 Two: O,
8};
9export fn a() void {
10 var foo: Foo = undefined;
11 _ = foo;
12}
13export fn b() void {
14 var bar: Bar = undefined;
15 _ = bar;
16}
17export fn c() void {
18 var baz: *opaque {} = undefined;
19 const qux = .{baz.*};
20 _ = qux;
21}
22
23// error
24// backend=stage1
25// target=native
26//
27// tmp.zig:3:5: error: opaque types have unknown size and therefore cannot be directly embedded in structs
28// tmp.zig:7:5: error: opaque types have unknown size and therefore cannot be directly embedded in unions
29// tmp.zig:19:22: error: opaque types have unknown size and therefore cannot be directly embedded in structs
test/cases/compile_errors/stage1/obj/disallow_coercion_from_non-null-terminated_pointer_to_null-terminated_pointer.zig deleted-12
...@@ -1,12 +0,0 @@
1extern fn puts(s: [*:0]const u8) c_int;
2pub fn main() void {
3 const no_zero_array = [_]u8{'h', 'e', 'l', 'l', 'o'};
4 const no_zero_ptr: [*]const u8 = &no_zero_array;
5 _ = puts(no_zero_ptr);
6}
7
8// error
9// backend=stage1
10// target=native
11//
12// tmp.zig:5:14: error: expected type '[*:0]const u8', found '[*]const u8'
test/cases/compile_errors/stage1/obj/endless_loop_in_function_evaluation.zig deleted-12
...@@ -1,12 +0,0 @@
1const seventh_fib_number = fibonacci(7);
2fn fibonacci(x: i32) i32 {
3 return fibonacci(x - 1) + fibonacci(x - 2);
4}
5
6export fn entry() usize { return @sizeOf(@TypeOf(seventh_fib_number)); }
7
8// error
9// backend=stage1
10// target=native
11//
12// tmp.zig:3:21: error: evaluation exceeded 1000 backwards branches
test/cases/compile_errors/stage1/obj/export_function_with_comptime_parameter.zig deleted-9
...@@ -1,9 +0,0 @@
1export fn foo(comptime x: i32, y: i32) i32{
2 return x + y;
3}
4
5// error
6// backend=stage1
7// target=native
8//
9// tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'
test/cases/compile_errors/stage1/obj/export_generic_function.zig deleted-10
...@@ -1,10 +0,0 @@
1export fn foo(num: anytype) i32 {
2 _ = num;
3 return 0;
4}
5
6// error
7// backend=stage1
8// target=native
9//
10// tmp.zig:1:15: error: parameter of type 'anytype' not allowed in function with calling convention 'C'
test/cases/compile_errors/stage1/obj/extern_function_with_comptime_parameter.zig deleted-11
...@@ -1,11 +0,0 @@
1extern fn foo(comptime x: i32, y: i32) i32;
2fn f() i32 {
3 return foo(1, 2);
4}
5export fn entry() usize { return @sizeOf(@TypeOf(f)); }
6
7// error
8// backend=stage1
9// target=native
10//
11// tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'
test/cases/compile_errors/stage1/obj/extern_union_given_enum_tag_type.zig deleted-20
...@@ -1,20 +0,0 @@
1const Letter = enum {
2 A,
3 B,
4 C,
5};
6const Payload = extern union(Letter) {
7 A: i32,
8 B: f64,
9 C: bool,
10};
11export fn entry() void {
12 var a = Payload { .A = 1234 };
13 _ = a;
14}
15
16// error
17// backend=stage1
18// target=native
19//
20// tmp.zig:6:30: error: extern union does not support enum tag type
test/cases/compile_errors/stage1/obj/function_alignment_non_power_of_2.zig deleted-8
...@@ -1,8 +0,0 @@
1extern fn foo() align(3) void;
2export fn entry() void { return foo(); }
3
4// error
5// backend=stage1
6// target=native
7//
8// tmp.zig:1:23: error: alignment value 3 is not a power of 2
test/cases/compile_errors/stage1/obj/function_parameter_is_opaque.zig deleted-29
...@@ -1,29 +0,0 @@
1const FooType = opaque {};
2export fn entry1() void {
3 const someFuncPtr: fn (FooType) void = undefined;
4 _ = someFuncPtr;
5}
6
7export fn entry2() void {
8 const someFuncPtr: fn (@TypeOf(null)) void = undefined;
9 _ = someFuncPtr;
10}
11
12fn foo(p: FooType) void {_ = p;}
13export fn entry3() void {
14 _ = foo;
15}
16
17fn bar(p: @TypeOf(null)) void {_ = p;}
18export fn entry4() void {
19 _ = bar;
20}
21
22// error
23// backend=stage1
24// target=native
25//
26// tmp.zig:3:28: error: parameter of opaque type 'FooType' not allowed
27// tmp.zig:8:28: error: parameter of type '@Type(.Null)' not allowed
28// tmp.zig:12:11: error: parameter of opaque type 'FooType' not allowed
29// tmp.zig:17:11: error: parameter of type '@Type(.Null)' not allowed
test/cases/compile_errors/stage1/obj/function_returning_opaque_type.zig deleted-19
...@@ -1,19 +0,0 @@
1const FooType = opaque {};
2export fn bar() !FooType {
3 return error.InvalidValue;
4}
5export fn bav() !@TypeOf(null) {
6 return error.InvalidValue;
7}
8export fn baz() !@TypeOf(undefined) {
9 return error.InvalidValue;
10}
11
12// error
13// backend=stage1
14// target=native
15//
16// tmp.zig:2:18: error: Opaque return type 'FooType' not allowed
17// tmp.zig:1:1: note: type declared here
18// tmp.zig:5:18: error: Null return type '@Type(.Null)' not allowed
19// tmp.zig:8:18: error: Undefined return type '@Type(.Undefined)' not allowed
test/cases/compile_errors/stage1/obj/function_with_non-extern_non-packed_enum_parameter.zig deleted-8
...@@ -1,8 +0,0 @@
1const Foo = enum { A, B, C };
2export fn entry(foo: Foo) void { _ = foo; }
3
4// error
5// backend=stage1
6// target=native
7//
8// tmp.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'
test/cases/compile_errors/stage1/obj/function_with_non-extern_non-packed_struct_parameter.zig deleted-12
...@@ -1,12 +0,0 @@
1const Foo = struct {
2 A: i32,
3 B: f32,
4 C: bool,
5};
6export fn entry(foo: Foo) void { _ = foo; }
7
8// error
9// backend=stage1
10// target=native
11//
12// tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'
test/cases/compile_errors/stage1/obj/function_with_non-extern_non-packed_union_parameter.zig deleted-12
...@@ -1,12 +0,0 @@
1const Foo = union {
2 A: i32,
3 B: f32,
4 C: bool,
5};
6export fn entry(foo: Foo) void { _ = foo; }
7
8// error
9// backend=stage1
10// target=native
11//
12// tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'
test/cases/compile_errors/stage1/obj/generic_function_instance_with_non-constant_expression.zig deleted-12
...@@ -1,12 +0,0 @@
1fn foo(comptime x: i32, y: i32) i32 { return x + y; }
2fn test1(a: i32, b: i32) i32 {
3 return foo(a, b);
4}
5
6export fn entry() usize { return @sizeOf(@TypeOf(test1)); }
7
8// error
9// backend=stage1
10// target=native
11//
12// tmp.zig:3:16: error: runtime value cannot be passed to comptime arg
test/cases/compile_errors/stage1/obj/implicit_cast_from_array_to_mutable_slice.zig deleted-11
...@@ -1,11 +0,0 @@
1var global_array: [10]i32 = undefined;
2fn foo(param: []i32) void {_ = param;}
3export fn entry() void {
4 foo(global_array);
5}
6
7// error
8// backend=stage1
9// target=native
10//
11// tmp.zig:4:9: error: expected type '[]i32', found '[10]i32'
test/cases/compile_errors/stage1/obj/implicit_casting_undefined_c_pointer_to_zig_pointer.zig deleted-11
...@@ -1,11 +0,0 @@
1comptime {
2 var c_ptr: [*c]u8 = undefined;
3 var zig_ptr: *u8 = c_ptr;
4 _ = zig_ptr;
5}
6
7// error
8// backend=stage1
9// target=native
10//
11// tmp.zig:3:24: error: use of undefined value here causes undefined behavior
test/cases/compile_errors/stage1/obj/implicitly_increasing_pointer_alignment.zig deleted-19
...@@ -1,19 +0,0 @@
1const Foo = packed struct {
2 a: u8,
3 b: u32,
4};
5
6export fn entry() void {
7 var foo = Foo { .a = 1, .b = 10 };
8 bar(&foo.b);
9}
10
11fn bar(x: *u32) void {
12 x.* += 1;
13}
14
15// error
16// backend=stage1
17// target=native
18//
19// tmp.zig:8:13: error: expected type '*u32', found '*align(1) u32'
test/cases/compile_errors/stage1/obj/issue_2687_coerce_from_undefined_array_pointer_to_slice.zig deleted-27
...@@ -1,27 +0,0 @@
1export fn foo1() void {
2 const a: *[1]u8 = undefined;
3 var b: []u8 = a;
4 _ = b;
5}
6export fn foo2() void {
7 comptime {
8 var a: *[1]u8 = undefined;
9 var b: []u8 = a;
10 _ = b;
11 }
12}
13export fn foo3() void {
14 comptime {
15 const a: *[1]u8 = undefined;
16 var b: []u8 = a;
17 _ = b;
18 }
19}
20
21// error
22// backend=stage1
23// target=native
24//
25// tmp.zig:3:19: error: use of undefined value here causes undefined behavior
26// tmp.zig:9:23: error: use of undefined value here causes undefined behavior
27// tmp.zig:16:23: error: use of undefined value here causes undefined behavior
test/cases/compile_errors/stage1/obj/load_too_many_bytes_from_comptime_reinterpreted_pointer.zig deleted-13
...@@ -1,13 +0,0 @@
1export fn entry() void {
2 const float: f32 = 5.99999999999994648725e-01;
3 const float_ptr = &float;
4 const int_ptr = @ptrCast(*const i64, float_ptr);
5 const int_val = int_ptr.*;
6 _ = int_val;
7}
8
9// error
10// backend=stage1
11// target=native
12//
13// tmp.zig:5:28: error: attempt to read 8 bytes from pointer to f32 which is 4 bytes
test/cases/compile_errors/stage1/obj/non-enum_tag_type_passed_to_union.zig deleted-13
...@@ -1,13 +0,0 @@
1const Foo = union(u32) {
2 A: i32,
3};
4export fn entry() void {
5 const x = @typeInfo(Foo).Union.tag_type.?;
6 _ = x;
7}
8
9// error
10// backend=stage1
11// target=native
12//
13// tmp.zig:1:19: error: expected enum tag type, found 'u32'
test/cases/compile_errors/stage1/obj/non-integer_tag_type_to_automatic_union_enum.zig deleted-13
...@@ -1,13 +0,0 @@
1const Foo = union(enum(f32)) {
2 A: i32,
3};
4export fn entry() void {
5 const x = @typeInfo(Foo).Union.tag_type.?;
6 _ = x;
7}
8
9// error
10// backend=stage1
11// target=native
12//
13// tmp.zig:1:24: error: expected integer tag type, found 'f32'
test/cases/compile_errors/stage1/obj/opaque_type_with_field.zig deleted-11
...@@ -1,11 +0,0 @@
1const Opaque = opaque { foo: i32 };
2export fn entry() void {
3 const foo: ?*Opaque = null;
4 _ = foo;
5}
6
7// error
8// backend=stage1
9// target=native
10//
11// tmp.zig:1:25: error: opaque types cannot have fields
test/cases/compile_errors/stage1/obj/pass_const_ptr_to_mutable_ptr_fn.zig deleted-17
...@@ -1,17 +0,0 @@
1fn foo() bool {
2 const a = @as([]const u8, "a",);
3 const b = &a;
4 return ptrEql(b, b);
5}
6fn ptrEql(a: *[]const u8, b: *[]const u8) bool {
7 _ = a; _ = b;
8 return true;
9}
10
11export fn entry() usize { return @sizeOf(@TypeOf(foo)); }
12
13// error
14// backend=stage1
15// target=native
16//
17// tmp.zig:4:19: error: expected type '*[]const u8', found '*const []const u8'
test/cases/compile_errors/stage1/obj/pointer_to_noreturn.zig deleted-8
...@@ -1,8 +0,0 @@
1fn a() *noreturn {}
2export fn entry() void { _ = a(); }
3
4// error
5// backend=stage1
6// target=native
7//
8// tmp.zig:1:9: error: pointer to noreturn not allowed
test/cases/compile_errors/stage1/obj/unknown_length_pointer_to_opaque.zig deleted-7
...@@ -1,7 +0,0 @@
1export const T = [*]opaque {};
2
3// error
4// backend=stage1
5// target=native
6//
7// tmp.zig:1:21: error: unknown-length pointer to opaque
test/cases/compile_errors/stage1/obj/unreachable_parameter.zig deleted-8
...@@ -1,8 +0,0 @@
1fn f(a: noreturn) void { _ = a; }
2export fn entry() void { f(); }
3
4// error
5// backend=stage1
6// target=native
7//
8// tmp.zig:1:9: error: parameter of type 'noreturn' not allowed
test/cases/compile_errors/stage1/obj/use_anyopaque_as_return_type_of_fn_ptr.zig deleted-10
...@@ -1,10 +0,0 @@
1export fn entry() void {
2 const a: fn () anyopaque = undefined;
3 _ = a;
4}
5
6// error
7// backend=stage1
8// target=native
9//
10// tmp.zig:2:20: error: return type cannot be opaque
test/cases/compile_errors/stage1/obj/use_implicit_casts_to_assign_null_to_non-nullable_pointer.zig deleted-14
...@@ -1,14 +0,0 @@
1export fn entry() void {
2 var x: i32 = 1234;
3 var p: *i32 = &x;
4 var pp: *?*i32 = &p;
5 pp.* = null;
6 var y = p.*;
7 _ = y;
8}
9
10// error
11// backend=stage1
12// target=native
13//
14// tmp.zig:4:23: error: expected type '*?*i32', found '**i32'
test/cases/compile_errors/stage1/obj/using_an_unknown_len_ptr_type_instead_of_array.zig deleted-13
...@@ -1,13 +0,0 @@
1const resolutions = [*][*]const u8{
2 "[320 240 ]",
3 null,
4};
5comptime {
6 _ = resolutions;
7}
8
9// error
10// backend=stage1
11// target=native
12//
13// tmp.zig:1:21: error: expected array type or [_], found '[*][*]const u8'
test/cases/compile_errors/stage1/obj/wrong_initializer_for_union_payload_of_type_type.zig deleted-16
...@@ -1,16 +0,0 @@
1const U = union(enum) {
2 A: type,
3};
4const S = struct {
5 u: U,
6};
7export fn entry() void {
8 comptime var v: S = undefined;
9 v.u.A = U{ .A = i32 };
10}
11
12// error
13// backend=stage1
14// target=native
15//
16// tmp.zig:9:8: error: use of undefined value here causes undefined behavior
test/cases/compile_errors/stage1/obj/wrong_pointer_coerced_to_pointer_to_opaque_{}.zig deleted-12
...@@ -1,12 +0,0 @@
1const Derp = opaque {};
2extern fn bar(d: *Derp) void;
3export fn foo() void {
4 var x = @as(u8, 1);
5 bar(@ptrCast(*anyopaque, &x));
6}
7
8// error
9// backend=stage1
10// target=native
11//
12// tmp.zig:5:9: error: expected type '*Derp', found '*anyopaque'
test/cases/compile_errors/stage1/test/helpful_return_type_error_message.zig deleted-32
...@@ -1,32 +0,0 @@
1export fn foo() u32 {
2 return error.Ohno;
3}
4fn bar() !u32 {
5 return error.Ohno;
6}
7export fn baz() void {
8 try bar();
9}
10export fn qux() u32 {
11 return bar();
12}
13export fn quux() u32 {
14 var buf: u32 = 0;
15 buf = bar();
16}
17
18// error
19// backend=stage2
20// target=native
21//
22// :2:18: error: expected type 'u32', found 'error{Ohno}'
23// :1:17: note: function cannot return an error
24// :8:5: error: expected type 'void', found '@typeInfo(@typeInfo(@TypeOf(tmp.bar)).Fn.return_type.?).ErrorUnion.error_set'
25// :7:17: note: function cannot return an error
26// :11:15: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(tmp.bar)).Fn.return_type.?).ErrorUnion.error_set!u32'
27// :10:17: note: function cannot return an error
28// :11:15: note: cannot convert error union to payload type
29// :11:15: note: consider using `try`, `catch`, or `if`
30// :15:14: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(tmp.bar)).Fn.return_type.?).ErrorUnion.error_set!u32'
31// :15:14: note: cannot convert error union to payload type
32// :15:14: note: consider using `try`, `catch`, or `if`
test/cases/compile_errors/stage1/test/switching_with_non-exhaustive_enums.zig deleted-35
...@@ -1,35 +0,0 @@
1const E = enum(u8) {
2 a,
3 b,
4 _,
5};
6const U = union(E) {
7 a: i32,
8 b: u32,
9};
10pub export fn entry() void {
11 var e: E = .b;
12 switch (e) { // error: switch not handling the tag `b`
13 .a => {},
14 _ => {},
15 }
16 switch (e) { // error: switch on non-exhaustive enum must include `else` or `_` prong
17 .a => {},
18 .b => {},
19 }
20 var u = U{.a = 2};
21 switch (u) { // error: `_` prong not allowed when switching on tagged union
22 .a => {},
23 .b => {},
24 _ => {},
25 }
26}
27
28// error
29// backend=stage1
30// target=native
31// is_test=1
32//
33// tmp.zig:12:5: error: enumeration value 'E.b' not handled in switch
34// tmp.zig:16:5: error: switch on non-exhaustive enum must include `else` or `_` prong
35// tmp.zig:21:5: error: `_` prong not allowed when switching on tagged union
test/cases/compile_errors/stage2/union_enum_field_missing.zig+1-1
...@@ -16,6 +16,6 @@ export fn entry() usize {...@@ -16,6 +16,6 @@ export fn entry() usize {
16// error16// error
17// target=native17// target=native
18//18//
19// :7:1: error: enum field(s) missing in union19// :7:11: error: enum field(s) missing in union
20// :4:5: note: field 'c' missing, declared here20// :4:5: note: field 'c' missing, declared here
21// :1:11: note: enum declared here21// :1:11: note: enum declared here
test/cases/compile_errors/stage2/union_extra_field.zig+1-1
...@@ -16,5 +16,5 @@ export fn entry() usize {...@@ -16,5 +16,5 @@ export fn entry() usize {
16// error16// error
17// target=native17// target=native
18//18//
19// :6:1: error: enum 'tmp.E' has no field named 'd'19// :10:5: error: enum 'tmp.E' has no field named 'd'
20// :1:11: note: enum declared here20// :1:11: note: enum declared here
test/cases/compile_errors/switch_expression-missing_enumeration_prong.zig+1-1
...@@ -19,5 +19,5 @@ export fn entry() usize { return @sizeOf(@TypeOf(&f)); }...@@ -19,5 +19,5 @@ export fn entry() usize { return @sizeOf(@TypeOf(&f)); }
19// target=native19// target=native
20//20//
21// :8:5: error: switch must handle all possibilities21// :8:5: error: switch must handle all possibilities
22// :8:5: note: unhandled enumeration value: 'Four'22// :5:5: note: unhandled enumeration value: 'Four'
23// :1:16: note: enum 'tmp.Number' declared here23// :1:16: note: enum 'tmp.Number' declared here
test/cases/compile_errors/switch_on_enum_with_1_field_with_no_prongs.zig+1-1
...@@ -10,5 +10,5 @@ export fn entry() void {...@@ -10,5 +10,5 @@ export fn entry() void {
10// target=native10// target=native
11//11//
12// :5:5: error: switch must handle all possibilities12// :5:5: error: switch must handle all possibilities
13// :5:5: note: unhandled enumeration value: 'M'13// :1:20: note: unhandled enumeration value: 'M'
14// :1:13: note: enum 'tmp.Foo' declared here14// :1:13: note: enum 'tmp.Foo' declared here
test/cases/compile_errors/switching_with_non-exhaustive_enums.zig created+42
...@@ -0,0 +1,42 @@
1const E = enum(u8) {
2 a,
3 b,
4 _,
5};
6const U = union(E) {
7 a: i32,
8 b: u32,
9};
10pub export fn entry1() void {
11 var e: E = .b;
12 switch (e) { // error: switch not handling the tag `b`
13 .a => {},
14 _ => {},
15 }
16}
17pub export fn entry2() void {
18 var e: E = .b;
19 switch (e) { // error: switch on non-exhaustive enum must include `else` or `_` prong
20 .a => {},
21 .b => {},
22 }
23}
24pub export fn entry3() void {
25 var u = U{.a = 2};
26 switch (u) { // error: `_` prong not allowed when switching on tagged union
27 .a => {},
28 .b => {},
29 _ => {},
30 }
31}
32
33// error
34// backend=stage2
35// target=native
36//
37// :12:5: error: switch must handle all possibilities
38// :3:5: note: unhandled enumeration value: 'b'
39// :1:11: note: enum 'tmp.E' declared here
40// :19:5: error: switch on non-exhaustive enum must include 'else' or '_' prong
41// :26:5: error: '_' prong only allowed when switching on non-exhaustive enums
42// :29:11: note: '_' prong here
test/cases/compile_errors/type_checking_function_pointers.zig+3-3
...@@ -10,6 +10,6 @@ export fn entry() void {...@@ -10,6 +10,6 @@ export fn entry() void {
10// backend=stage210// backend=stage2
11// target=native11// target=native
12//12//
13// :6:6: error: expected type '*const fn(*const u8) void', found '*const fn(u8) void'13// :6:7: error: expected type '*const fn(*const u8) void', found '*const fn(u8) void'
14// :6:6: note: pointer type child 'fn(u8) void' cannot cast into pointer type child 'fn(*const u8) void'14// :6:7: note: pointer type child 'fn(u8) void' cannot cast into pointer type child 'fn(*const u8) void'
15// :6:6: note: parameter 0 'u8' cannot cast into '*const u8'15// :6:7: note: parameter 0 'u8' cannot cast into '*const u8'
test/cases/compile_errors/union_with_specified_enum_omits_field.zig+1-1
...@@ -15,6 +15,6 @@ export fn entry() usize {...@@ -15,6 +15,6 @@ export fn entry() usize {
15// backend=stage215// backend=stage2
16// target=native16// target=native
17//17//
18// :6:1: error: enum field(s) missing in union18// :6:17: error: enum field(s) missing in union
19// :4:5: note: field 'C' missing, declared here19// :4:5: note: field 'C' missing, declared here
20// :1:16: note: enum declared here20// :1:16: note: enum declared here
test/cases/compile_errors/unknown_length_pointer_to_opaque.zig created+7
...@@ -0,0 +1,7 @@
1export const T = [*]opaque {};
2
3// error
4// backend=stage2
5// target=native
6//
7// :1:21: error: unknown-length pointer to opaque not allowed
test/cases/compile_errors/unreachable_parameter.zig created+8
...@@ -0,0 +1,8 @@
1fn f(a: noreturn) void { _ = a; }
2export fn entry() void { f(); }
3
4// error
5// backend=stage2
6// target=native
7//
8// :1:6: error: parameter of type 'noreturn' not allowed
test/cases/compile_errors/use_anyopaque_as_return_type_of_fn_ptr.zig created+10
...@@ -0,0 +1,10 @@
1export fn entry() void {
2 const a: fn () anyopaque = undefined;
3 _ = a;
4}
5
6// error
7// backend=stage2
8// target=native
9//
10// :2:20: error: opaque return type 'anyopaque' not allowed
test/cases/compile_errors/use_implicit_casts_to_assign_null_to_non-nullable_pointer.zig created+16
...@@ -0,0 +1,16 @@
1export fn entry() void {
2 var x: i32 = 1234;
3 var p: *i32 = &x;
4 var pp: *?*i32 = &p;
5 pp.* = null;
6 var y = p.*;
7 _ = y;
8}
9
10// error
11// backend=stage2
12// target=native
13//
14// :4:22: error: expected type '*?*i32', found '**i32'
15// :4:22: note: pointer type child '*i32' cannot cast into pointer type child '?*i32'
16// :4:22: note: mutable '*i32' allows illegal null values stored to type '?*i32'
test/cases/compile_errors/using_an_unknown_len_ptr_type_instead_of_array.zig created+13
...@@ -0,0 +1,13 @@
1const resolutions = [*][*]const u8{
2 "[320 240 ]",
3 null,
4};
5comptime {
6 _ = resolutions;
7}
8
9// error
10// backend=stage2
11// target=native
12//
13// :1:22: error: type '[*][*]const u8' does not support array initialization syntax
test/cases/compile_errors/wrong_initializer_for_union_payload_of_type_type.zig created+17
...@@ -0,0 +1,17 @@
1const U = union(enum) {
2 A: type,
3};
4const S = struct {
5 u: U,
6};
7export fn entry() void {
8 comptime var v: S = undefined;
9 v.u.A = U{ .A = i32 };
10}
11
12// error
13// backend=stage2
14// target=native
15//
16// :9:14: error: expected type 'type', found 'tmp.U'
17// :1:11: note: union declared here
test/cases/compile_errors/wrong_pointer_coerced_to_pointer_to_opaque_{}.zig created+14
...@@ -0,0 +1,14 @@
1const Derp = opaque {};
2extern fn bar(d: *Derp) void;
3export fn foo() void {
4 var x = @as(u8, 1);
5 bar(@ptrCast(*anyopaque, &x));
6}
7
8// error
9// backend=stage2
10// target=native
11//
12// :5:9: error: expected type '*tmp.Derp', found '*anyopaque'
13// :5:9: note: pointer type child 'anyopaque' cannot cast into pointer type child 'tmp.Derp'
14// :1:14: note: opaque declared here
test/cases/extern_variable_has_no_type.0.zig+1-1
...@@ -6,4 +6,4 @@ extern var foo: i32;...@@ -6,4 +6,4 @@ extern var foo: i32;
66
7// error7// error
8//8//
9// :2:15: error: unable to resolve comptime value9// :2:15: error: cannot load runtime value in comptime block
test/cases/x86_64-linux/assert_function.8.zig+1
...@@ -22,3 +22,4 @@ pub fn assert(ok: bool) void {...@@ -22,3 +22,4 @@ pub fn assert(ok: bool) void {
22// error22// error
23//23//
24// :3:21: error: unable to resolve comptime value24// :3:21: error: unable to resolve comptime value
25// :3:21: note: condition in comptime branch must be comptime known
test/cases/x86_64-macos/assert_function.8.zig+1
...@@ -17,3 +17,4 @@ pub fn assert(ok: bool) void {...@@ -17,3 +17,4 @@ pub fn assert(ok: bool) void {
17// error17// error
18//18//
19// :5:21: error: unable to resolve comptime value19// :5:21: error: unable to resolve comptime value
20// :5:21: note: condition in comptime branch must be comptime known
test/stage2/cbe.zig+3-3
...@@ -51,8 +51,8 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -51,8 +51,8 @@ pub fn addCases(ctx: *TestContext) !void {
51 \\}51 \\}
52 \\var y: @import("std").builtin.CallingConvention = .C;52 \\var y: @import("std").builtin.CallingConvention = .C;
53 , &.{53 , &.{
54 ":2:22: error: unable to resolve comptime value",54 ":2:22: error: cannot load runtime value in comptime block",
55 ":5:26: error: unable to resolve comptime value",55 ":5:26: error: cannot load runtime value in comptime block",
56 });56 });
57 }57 }
5858
...@@ -772,7 +772,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -772,7 +772,7 @@ pub fn addCases(ctx: *TestContext) !void {
772 \\}772 \\}
773 , &.{773 , &.{
774 ":4:5: error: switch must handle all possibilities",774 ":4:5: error: switch must handle all possibilities",
775 ":4:5: note: unhandled enumeration value: 'b'",775 ":1:21: note: unhandled enumeration value: 'b'",
776 ":1:11: note: enum 'tmp.E' declared here",776 ":1:11: note: enum 'tmp.E' declared here",
777 });777 });
778778