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;
1111const assert = std.debug.assert;
1212
1313const zig_version = std.builtin.Version{ .major = 0, .minor = 10, .patch = 0 };
14const stack_size = 32 * 1024 * 1024;
1415
1516pub fn build(b: *Builder) !void {
1617 b.setPreferredReleaseMode(.ReleaseFast);
......@@ -41,6 +42,7 @@ pub fn build(b: *Builder) !void {
4142 const toolchain_step = b.step("test-toolchain", "Run the tests for the toolchain");
4243
4344 var test_cases = b.addTest("src/test.zig");
45 test_cases.stack_size = stack_size;
4446 test_cases.setBuildMode(mode);
4547 test_cases.addPackagePath("test_cases", "test/cases.zig");
4648 test_cases.single_threaded = single_threaded;
......@@ -141,6 +143,7 @@ pub fn build(b: *Builder) !void {
141143 };
142144
143145 const exe = b.addExecutable("zig", main_file);
146 exe.stack_size = stack_size;
144147 exe.strip = strip;
145148 exe.build_id = b.option(bool, "build-id", "Include a build id note") orelse false;
146149 exe.install();
src/AstGen.zig+26-47
......@@ -1347,7 +1347,7 @@ fn arrayInitExpr(
13471347 }
13481348 }
13491349 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);
13511351 break :inst .{
13521352 .array = array_type_inst,
13531353 .elem = .none,
......@@ -2332,7 +2332,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
23322332 .err_union_code,
23332333 .err_union_code_ptr,
23342334 .ptr_type,
2335 .ptr_type_simple,
2335 .overflow_arithmetic_ptr,
23362336 .enum_literal,
23372337 .merge_error_sets,
23382338 .error_union_type,
......@@ -3110,24 +3110,6 @@ fn ptrType(
31103110
31113111 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
31313113 var sentinel_ref: Zir.Inst.Ref = .none;
31323114 var align_ref: Zir.Inst.Ref = .none;
31333115 var addrspace_ref: Zir.Inst.Ref = .none;
......@@ -3160,7 +3142,10 @@ fn ptrType(
31603142 try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.PtrType).Struct.fields.len +
31613143 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 });
31643149 if (sentinel_ref != .none) {
31653150 gz.astgen.extra.appendAssumeCapacity(@enumToInt(sentinel_ref));
31663151 }
......@@ -4314,7 +4299,7 @@ fn unionDeclInner(
43144299 members: []const Ast.Node.Index,
43154300 layout: std.builtin.Type.ContainerLayout,
43164301 arg_node: Ast.Node.Index,
4317 have_auto_enum: bool,
4302 auto_enum_tok: ?Ast.TokenIndex,
43184303) InnerError!Zir.Inst.Ref {
43194304 const decl_inst = try gz.reserveInstructionIndex();
43204305
......@@ -4348,6 +4333,15 @@ fn unionDeclInner(
43484333 const decl_count = try astgen.scanDecls(&namespace, members);
43494334 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
43514345 const arg_inst: Zir.Inst.Ref = if (arg_node != 0)
43524346 try typeExpr(&block_scope, &namespace.base, arg_node)
43534347 else
......@@ -4382,7 +4376,7 @@ fn unionDeclInner(
43824376 if (have_type) {
43834377 const field_type = try typeExpr(&block_scope, &namespace.base, member.ast.type_expr);
43844378 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) {
43864380 return astgen.failNode(member_node, "union field missing type", .{});
43874381 }
43884382 if (have_align) {
......@@ -4404,7 +4398,7 @@ fn unionDeclInner(
44044398 },
44054399 );
44064400 }
4407 if (!have_auto_enum) {
4401 if (auto_enum_tok == null) {
44084402 return astgen.failNodeNotes(
44094403 node,
44104404 "explicitly valued tagged union requires inferred enum tag type",
......@@ -4440,7 +4434,7 @@ fn unionDeclInner(
44404434 .body_len = body_len,
44414435 .fields_len = field_count,
44424436 .decls_len = decl_count,
4443 .auto_enum_tag = have_auto_enum,
4437 .auto_enum_tag = auto_enum_tok != null,
44444438 });
44454439
44464440 wip_members.finishBits(bits_per_field);
......@@ -4496,9 +4490,7 @@ fn containerDecl(
44964490 else => unreachable,
44974491 } else std.builtin.Type.ContainerLayout.Auto;
44984492
4499 const have_auto_enum = container_decl.ast.enum_token != null;
4500
4501 const result = try unionDeclInner(gz, scope, node, container_decl.ast.members, layout, container_decl.ast.arg, have_auto_enum);
4493 const result = try unionDeclInner(gz, scope, node, container_decl.ast.members, layout, container_decl.ast.arg, container_decl.ast.enum_token);
45024494 return rvalue(gz, rl, result, node);
45034495 },
45044496 .keyword_enum => {
......@@ -4732,7 +4724,10 @@ fn containerDecl(
47324724 defer wip_members.deinit();
47334725
47344726 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 }
47364731 }
47374732
47384733 try gz.setOpaque(decl_inst, .{
......@@ -7588,15 +7583,7 @@ fn builtinCall(
75887583 .shl_with_overflow => {
75897584 const int_type = try typeExpr(gz, scope, params[0]);
75907585 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 = .{
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 } });
7586 const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]);
76007587 const lhs = try expr(gz, scope, .{ .ty = int_type }, params[1]);
76017588 const rhs = try expr(gz, scope, .{ .ty = log2_int_type }, params[2]);
76027589 const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[3]);
......@@ -7987,15 +7974,7 @@ fn overflowArithmetic(
79877974 tag: Zir.Inst.Extended,
79887975) InnerError!Zir.Inst.Ref {
79897976 const int_type = try typeExpr(gz, scope, params[0]);
7990 const ptr_type = try gz.add(.{ .tag = .ptr_type_simple, .data = .{
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 } });
7977 const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]);
79997978 const lhs = try expr(gz, scope, .{ .ty = int_type }, params[1]);
80007979 const rhs = try expr(gz, scope, .{ .ty = int_type }, params[2]);
80017980 const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[3]);
src/Module.zig+375-17
......@@ -2348,7 +2348,92 @@ pub const SrcLoc = struct {
23482348 }
23492349 } else unreachable;
23502350 },
2351
2351 .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 },
23522437 .node_offset_fn_type_cc => |node_off| {
23532438 const tree = try src_loc.file_scope.getTree(gpa);
23542439 const node_datas = tree.nodes.items(.data);
......@@ -2374,6 +2459,7 @@ pub const SrcLoc = struct {
23742459
23752460 .node_offset_fn_type_ret_ty => |node_off| {
23762461 const tree = try src_loc.file_scope.getTree(gpa);
2462 const node_datas = tree.nodes.items(.data);
23772463 const node_tags = tree.nodes.items(.tag);
23782464 const node = src_loc.declRelativeToNodeIndex(node_off);
23792465 var params: [1]Ast.Node.Index = undefined;
......@@ -2382,10 +2468,55 @@ pub const SrcLoc = struct {
23822468 .fn_proto_multi => tree.fnProtoMulti(node),
23832469 .fn_proto_one => tree.fnProtoOne(&params, node),
23842470 .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 },
23852481 else => unreachable,
23862482 };
23872483 return nodeToSpan(tree, full.ast.return_type);
23882484 },
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
23902521 .node_offset_anyframe_type => |node_off| {
23912522 const tree = try src_loc.file_scope.getTree(gpa);
......@@ -2466,6 +2597,113 @@ pub const SrcLoc = struct {
24662597
24672598 return nodeToSpan(tree, node_datas[node].lhs);
24682599 },
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 },
24692707 }
24702708 }
24712709
......@@ -2694,6 +2932,27 @@ pub const LazySrcLoc = union(enum) {
26942932 /// range nodes. The error applies to all of them.
26952933 /// The Decl is determined contextually.
26962934 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,
26972956 /// The source location points to the calling convention of a function type
26982957 /// expression, found by taking this AST node index offset from the containing
26992958 /// Decl AST node, which points to a function type AST node. Next, navigate to
......@@ -2706,6 +2965,8 @@ pub const LazySrcLoc = union(enum) {
27062965 /// the return type node.
27072966 /// The Decl is determined contextually.
27082967 node_offset_fn_type_ret_ty: i32,
2968 node_offset_param: i32,
2969 token_offset_param: i32,
27092970 /// The source location points to the type expression of an `anyframe->T`
27102971 /// expression, found by taking this AST node index offset from the containing
27112972 /// Decl AST node, which points to a `anyframe->T` expression AST node. Next, navigate
......@@ -2739,6 +3000,27 @@ pub const LazySrcLoc = union(enum) {
27393000 /// The source location points to the operand of an unary expression.
27403001 /// The Decl is determined contextually.
27413002 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
27433025 pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease;
27443026
......@@ -2795,14 +3077,27 @@ pub const LazySrcLoc = union(enum) {
27953077 .node_offset_switch_operand,
27963078 .node_offset_switch_special_prong,
27973079 .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,
27983084 .node_offset_fn_type_cc,
27993085 .node_offset_fn_type_ret_ty,
3086 .node_offset_param,
3087 .token_offset_param,
28003088 .node_offset_anyframe_type,
28013089 .node_offset_lib_name,
28023090 .node_offset_array_type_len,
28033091 .node_offset_array_type_sentinel,
28043092 .node_offset_array_type_elem,
28053093 .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,
28063101 => .{
28073102 .file_scope = decl.getFileScope(),
28083103 .parent_decl_node = decl.src_node,
......@@ -3957,18 +4252,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
39574252 var wip_captures = try WipCaptureScope.init(gpa, new_decl_arena_allocator, null);
39584253 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
39724255 if (sema.analyzeStructDecl(new_decl, main_struct_inst, struct_obj)) |_| {
39734256 try wip_captures.finalize();
39744257 new_decl.analysis = .complete;
......@@ -4077,7 +4360,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
40774360 const result_ref = (try sema.analyzeBodyBreak(&block_scope, body)).?.operand;
40784361 try wip_captures.finalize();
40794362 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);
40814364 const decl_align: u32 = blk: {
40824365 const align_ref = decl.zirAlignRef();
40834366 if (align_ref == .none) break :blk 0;
......@@ -4086,7 +4369,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
40864369 const decl_linksection: ?[*:0]const u8 = blk: {
40874370 const linksection_ref = decl.zirLinksectionRef();
40884371 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");
40904373 break :blk (try decl_arena_allocator.dupeZ(u8, bytes)).ptr;
40914374 };
40924375 const target = sema.mod.getTarget();
......@@ -4518,7 +4801,7 @@ pub fn scanNamespace(
45184801 extra_start: usize,
45194802 decls_len: u32,
45204803 parent_decl: *Decl,
4521) SemaError!usize {
4804) Allocator.Error!usize {
45224805 const tracy = trace(@src());
45234806 defer tracy.end();
45244807
......@@ -4565,7 +4848,7 @@ const ScanDeclIter = struct {
45654848 unnamed_test_index: usize = 0,
45664849};
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 {
45694852 const tracy = trace(@src());
45704853 defer tracy.end();
45714854
......@@ -5382,6 +5665,7 @@ pub const SwitchProngSrc = union(enum) {
53825665 scalar: u32,
53835666 multi: Multi,
53845667 range: Multi,
5668 multi_capture: u32,
53855669
53865670 pub const Multi = struct {
53875671 prong: u32,
......@@ -5437,6 +5721,9 @@ pub const SwitchProngSrc = union(enum) {
54375721 .scalar => |i| if (!is_multi and i == scalar_i) return LazySrcLoc.nodeOffset(
54385722 decl.nodeIndexToRelative(case.ast.values[0]),
54395723 ),
5724 .multi_capture => |i| if (is_multi and i == multi_i) {
5725 return LazySrcLoc{ .node_offset_switch_prong_capture = decl.nodeIndexToRelative(case_node) };
5726 },
54405727 .multi => |s| if (is_multi and s.prong == multi_i) {
54415728 var item_i: u32 = 0;
54425729 for (case.ast.values) |item_node| {
......@@ -5578,6 +5865,77 @@ fn queryFieldSrc(
55785865 unreachable;
55795866}
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
55815939/// Called from `performAllTheWork`, after all AstGen workers have finished,
55825940/// and before the main semantic analysis loop begins.
55835941pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {
src/Sema.zig+974-591
......@@ -768,7 +768,7 @@ fn analyzeBodyInner(
768768 .optional_type => try sema.zirOptionalType(block, inst),
769769 .param_type => try sema.zirParamType(block, inst),
770770 .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),
772772 .ref => try sema.zirRef(block, inst),
773773 .ret_err_value_code => try sema.zirRetErrValueCode(inst),
774774 .shr => try sema.zirShr(block, inst, .shr),
......@@ -892,7 +892,7 @@ fn analyzeBodyInner(
892892 .shl_sat => try sema.zirShl(block, inst, .shl_sat),
893893
894894 .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
897897 // Instructions that we know to *always* be noreturn based solely on their tag.
898898 // These functions match the return type of analyzeBody so that we can
......@@ -1173,7 +1173,7 @@ fn analyzeBodyInner(
11731173 } else {
11741174 const src_node = sema.code.instructions.items(.data)[inst].node;
11751175 const src = LazySrcLoc.nodeOffset(src_node);
1176 try sema.requireRuntimeBlock(block, src);
1176 try sema.requireFunctionBlock(block, src);
11771177 break always_noreturn;
11781178 }
11791179 },
......@@ -1303,7 +1303,7 @@ fn analyzeBodyInner(
13031303 const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);
13041304 const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len];
13051305 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");
13071307 const inline_body = if (cond.val.toBool()) then_body else else_body;
13081308 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse
13091309 break always_noreturn;
......@@ -1319,7 +1319,7 @@ fn analyzeBodyInner(
13191319 const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);
13201320 const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len];
13211321 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");
13231323 const inline_body = if (cond.val.toBool()) then_body else else_body;
13241324 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse
13251325 break always_noreturn;
......@@ -1339,7 +1339,7 @@ fn analyzeBodyInner(
13391339 const err_union = try sema.resolveInst(extra.data.operand);
13401340 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union);
13411341 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");
13431343 if (is_non_err_tv.val.toBool()) {
13441344 const err_union_ty = sema.typeOf(err_union);
13451345 break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, err_union, operand_src, false);
......@@ -1395,7 +1395,7 @@ fn analyzeBodyInner(
13951395 const err_union = try sema.analyzeLoad(block, src, operand, operand_src);
13961396 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union);
13971397 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");
13991399 if (is_non_err_tv.val.toBool()) {
14001400 break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false);
14011401 }
......@@ -1478,11 +1478,12 @@ fn resolveConstBool(
14781478 block: *Block,
14791479 src: LazySrcLoc,
14801480 zir_ref: Zir.Inst.Ref,
1481 reason: []const u8,
14811482) !bool {
14821483 const air_inst = try sema.resolveInst(zir_ref);
14831484 const wanted_type = Type.bool;
14841485 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);
14861487 return val.toBool();
14871488}
14881489
......@@ -1491,11 +1492,12 @@ pub fn resolveConstString(
14911492 block: *Block,
14921493 src: LazySrcLoc,
14931494 zir_ref: Zir.Inst.Ref,
1495 reason: []const u8,
14941496) ![]u8 {
14951497 const air_inst = try sema.resolveInst(zir_ref);
14961498 const wanted_type = Type.initTag(.const_slice_u8);
14971499 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);
14991501 return val.toAllocatedBytes(wanted_type, sema.arena, sema.mod);
15001502}
15011503
......@@ -1514,7 +1516,7 @@ fn analyzeAsType(
15141516) !Type {
15151517 const wanted_type = Type.initTag(.@"type");
15161518 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");
15181520 var buffer: Value.ToTypeBuffer = undefined;
15191521 const ty = val.toType(&buffer);
15201522 return ty.copy(sema.arena);
......@@ -1567,12 +1569,13 @@ fn resolveValue(
15671569 block: *Block,
15681570 src: LazySrcLoc,
15691571 air_ref: Air.Inst.Ref,
1572 reason: []const u8,
15701573) CompileError!Value {
15711574 if (try sema.resolveMaybeUndefValAllowVariables(block, src, air_ref)) |val| {
15721575 if (val.tag() == .generic_poison) return error.GenericPoison;
15731576 return val;
15741577 }
1575 return sema.failWithNeededComptime(block, src);
1578 return sema.failWithNeededComptime(block, src, reason);
15761579}
15771580
15781581/// Value Tag `variable` will cause a compile error.
......@@ -1582,15 +1585,16 @@ fn resolveConstMaybeUndefVal(
15821585 block: *Block,
15831586 src: LazySrcLoc,
15841587 inst: Air.Inst.Ref,
1588 reason: []const u8,
15851589) CompileError!Value {
15861590 if (try sema.resolveMaybeUndefValAllowVariables(block, src, inst)) |val| {
15871591 switch (val.tag()) {
1588 .variable => return sema.failWithNeededComptime(block, src),
1592 .variable => return sema.failWithNeededComptime(block, src, reason),
15891593 .generic_poison => return error.GenericPoison,
15901594 else => return val,
15911595 }
15921596 }
1593 return sema.failWithNeededComptime(block, src);
1597 return sema.failWithNeededComptime(block, src, reason);
15941598}
15951599
15961600/// Will not return Value Tags: `variable`, `undef`. Instead they will emit compile errors.
......@@ -1600,16 +1604,17 @@ fn resolveConstValue(
16001604 block: *Block,
16011605 src: LazySrcLoc,
16021606 air_ref: Air.Inst.Ref,
1607 reason: []const u8,
16031608) CompileError!Value {
16041609 if (try sema.resolveMaybeUndefValAllowVariables(block, src, air_ref)) |val| {
16051610 switch (val.tag()) {
16061611 .undef => return sema.failWithUseOfUndef(block, src),
1607 .variable => return sema.failWithNeededComptime(block, src),
1612 .variable => return sema.failWithNeededComptime(block, src, reason),
16081613 .generic_poison => return error.GenericPoison,
16091614 else => return val,
16101615 }
16111616 }
1612 return sema.failWithNeededComptime(block, src);
1617 return sema.failWithNeededComptime(block, src, reason);
16131618}
16141619
16151620/// Value Tag `variable` causes this function to return `null`.
......@@ -1697,8 +1702,15 @@ fn resolveMaybeUndefValAllowVariables(
16971702 }
16981703}
16991704
1700fn failWithNeededComptime(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError {
1701 return sema.fail(block, src, "unable to resolve comptime value", .{});
1705fn failWithNeededComptime(sema: *Sema, block: *Block, src: LazySrcLoc, reason: []const u8) CompileError {
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);
17021714}
17031715
17041716fn failWithUseOfUndef(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError {
......@@ -1870,15 +1882,24 @@ fn analyzeAsAlign(
18701882 src: LazySrcLoc,
18711883 air_ref: Air.Inst.Ref,
18721884) !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");
18741886 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 {
18751897 if (alignment == 0) return sema.fail(block, src, "alignment must be >= 1", .{});
18761898 if (!std.math.isPowerOfTwo(alignment)) {
18771899 return sema.fail(block, src, "alignment value '{d}' is not a power of two", .{
18781900 alignment,
18791901 });
18801902 }
1881 return alignment;
18821903}
18831904
18841905pub fn resolveAlign(
......@@ -1897,9 +1918,10 @@ fn resolveInt(
18971918 src: LazySrcLoc,
18981919 zir_ref: Zir.Inst.Ref,
18991920 dest_ty: Type,
1921 reason: []const u8,
19001922) !u64 {
19011923 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);
19031925}
19041926
19051927fn analyzeAsInt(
......@@ -1908,9 +1930,10 @@ fn analyzeAsInt(
19081930 src: LazySrcLoc,
19091931 air_ref: Air.Inst.Ref,
19101932 dest_ty: Type,
1933 reason: []const u8,
19111934) !u64 {
19121935 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);
19141937 const target = sema.mod.getTarget();
19151938 return (try val.getUnsignedIntAdvanced(target, sema.kit(block, src))).?;
19161939}
......@@ -1922,9 +1945,10 @@ pub fn resolveInstConst(
19221945 block: *Block,
19231946 src: LazySrcLoc,
19241947 zir_ref: Zir.Inst.Ref,
1948 reason: []const u8,
19251949) CompileError!TypedValue {
19261950 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);
19281952 return TypedValue{
19291953 .ty = sema.typeOf(air_ref),
19301954 .val = val,
......@@ -1938,9 +1962,10 @@ pub fn resolveInstValue(
19381962 block: *Block,
19391963 src: LazySrcLoc,
19401964 zir_ref: Zir.Inst.Ref,
1965 reason: []const u8,
19411966) CompileError!TypedValue {
19421967 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);
19441969 return TypedValue{
19451970 .ty = sema.typeOf(air_ref),
19461971 .val = val,
......@@ -1974,7 +1999,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
19741999 defer trash_block.instructions.deinit(sema.gpa);
19752000 const operand = try trash_block.addBitCast(pointee_ty, .void_value);
19762001
1977 try sema.requireRuntimeBlock(block, src);
2002 try sema.requireFunctionBlock(block, src);
19782003 const ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
19792004 .pointee_type = pointee_ty,
19802005 .@"align" = inferred_alloc.alignment,
......@@ -2259,7 +2284,7 @@ fn createAnonymousDeclTypeNamed(
22592284 const arg = sema.inst_map.get(zir_inst).?;
22602285 // The comptime call code in analyzeCall already did this, so we're
22612286 // 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
22642289 if (arg_i != 0) try buf.appendSlice(",");
22652290 try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg), sema.mod)});
......@@ -2319,6 +2344,7 @@ fn zirEnumDecl(
23192344 extra_index += 1;
23202345 break :blk LazySrcLoc.nodeOffset(node_offset);
23212346 } else sema.src;
2347 const tag_ty_src: LazySrcLoc = .{ .node_offset_container_tag = src.node_offset.x };
23222348
23232349 const tag_type_ref = if (small.has_tag_type) blk: {
23242350 const tag_type_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
......@@ -2344,8 +2370,10 @@ fn zirEnumDecl(
23442370 break :blk decls_len;
23452371 } else 0;
23462372
2373 var done = false;
2374
23472375 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
2348 errdefer new_decl_arena.deinit();
2376 errdefer if (!done) new_decl_arena.deinit();
23492377 const new_decl_arena_allocator = new_decl_arena.allocator();
23502378
23512379 const enum_obj = try new_decl_arena_allocator.create(Module.EnumFull);
......@@ -2362,7 +2390,7 @@ fn zirEnumDecl(
23622390 }, small.name_strategy, "enum", inst);
23632391 const new_decl = mod.declPtr(new_decl_index);
23642392 new_decl.owns_tv = true;
2365 errdefer mod.abortAnonDecl(new_decl_index);
2393 errdefer if (!done) mod.abortAnonDecl(new_decl_index);
23662394
23672395 enum_obj.* = .{
23682396 .owner_decl = new_decl_index,
......@@ -2381,19 +2409,28 @@ fn zirEnumDecl(
23812409 &enum_obj.namespace, new_decl, new_decl.name,
23822410 });
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
23842420 extra_index = try mod.scanNamespace(&enum_obj.namespace, extra_index, decls_len, new_decl);
23852421
23862422 const body = sema.code.extra[extra_index..][0..body_len];
23872423 if (fields_len == 0) {
23882424 assert(body.len == 0);
23892425 if (tag_type_ref != .none) {
2390 // TODO better source location
2391 const ty = try sema.resolveType(block, src, tag_type_ref);
2426 const ty = try sema.resolveType(block, tag_ty_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 }
23922430 enum_obj.tag_ty = try ty.copy(new_decl_arena_allocator);
23932431 enum_obj.tag_ty_inferred = false;
23942432 }
2395 try new_decl.finalizeNewArena(&new_decl_arena);
2396 return sema.analyzeDeclVal(block, src, new_decl_index);
2433 return decl_val;
23972434 }
23982435 extra_index += body.len;
23992436
......@@ -2446,13 +2483,15 @@ fn zirEnumDecl(
24462483 try wip_captures.finalize();
24472484
24482485 if (tag_type_ref != .none) {
2449 // TODO better source location
2450 const ty = try sema.resolveType(block, src, tag_type_ref);
2451 enum_obj.tag_ty = try ty.copy(new_decl_arena_allocator);
2486 const ty = try sema.resolveType(block, tag_ty_src, tag_type_ref);
2487 if (ty.zigTypeTag() != .Int and ty.zigTypeTag() != .ComptimeInt) {
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);
24522491 enum_obj.tag_ty_inferred = false;
24532492 } else {
24542493 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);
24562495 enum_obj.tag_ty_inferred = true;
24572496 }
24582497 }
......@@ -2463,12 +2502,12 @@ fn zirEnumDecl(
24632502 }
24642503 }
24652504
2466 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
2505 try enum_obj.fields.ensureTotalCapacity(decl_arena_allocator, fields_len);
24672506 const any_values = for (sema.code.extra[body_end..][0..bit_bags_count]) |bag| {
24682507 if (bag != 0) break true;
24692508 } else false;
24702509 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, .{
24722511 .ty = enum_obj.tag_ty,
24732512 .mod = mod,
24742513 });
......@@ -2493,7 +2532,7 @@ fn zirEnumDecl(
24932532 extra_index += 1;
24942533
24952534 // 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
24982537 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);
24992538 if (gop.found_existing) {
......@@ -2515,9 +2554,9 @@ fn zirEnumDecl(
25152554 // TODO: if we need to report an error here, use a source location
25162555 // that points to this default value expression rather than the struct.
25172556 // 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;
25192558 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);
25212560 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{
25222561 .ty = enum_obj.tag_ty,
25232562 .mod = mod,
......@@ -2528,16 +2567,14 @@ fn zirEnumDecl(
25282567 else
25292568 Value.zero;
25302569 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);
25322571 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{
25332572 .ty = enum_obj.tag_ty,
25342573 .mod = mod,
25352574 });
25362575 }
25372576 }
2538
2539 try new_decl.finalizeNewArena(&new_decl_arena);
2540 return sema.analyzeDeclVal(block, src, new_decl_index);
2577 return decl_val;
25412578}
25422579
25432580fn zirUnionDecl(
......@@ -2738,7 +2775,6 @@ fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
27382775
27392776 const inst_data = sema.code.instructions.items(.data)[inst].node;
27402777 const src = LazySrcLoc.nodeOffset(inst_data);
2741 try sema.requireFunctionBlock(block, src);
27422778
27432779 if (block.is_comptime or try sema.typeRequiresComptime(block, src, sema.fn_ret_ty)) {
27442780 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
27702806 return sema.analyzeRef(block, inst_data.src(), operand);
27712807}
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
27832809fn zirEnsureResultUsed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
27842810 const tracy = trace(@src());
27852811 defer tracy.end();
......@@ -2925,7 +2951,7 @@ fn zirAllocExtended(
29252951 try sema.validateVarType(block, ty_src, var_ty, false);
29262952 }
29272953 const target = sema.mod.getTarget();
2928 try sema.requireRuntimeBlock(block, src);
2954 try sema.requireFunctionBlock(block, src);
29292955 try sema.resolveTypeLayout(block, src, var_ty);
29302956 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
29312957 .pointee_type = var_ty,
......@@ -3024,7 +3050,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
30243050 return sema.addConstant(const_ptr_ty, val);
30253051 }
30263052
3027 try sema.requireRuntimeBlock(block, src);
3053 try sema.requireFunctionBlock(block, src);
30283054 return block.addBitCast(const_ptr_ty, alloc);
30293055}
30303056
......@@ -3061,7 +3087,7 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
30613087 .pointee_type = var_ty,
30623088 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
30633089 });
3064 try sema.requireRuntimeBlock(block, var_decl_src);
3090 try sema.requireFunctionBlock(block, var_decl_src);
30653091 try sema.queueFullTypeResolution(var_ty);
30663092 return block.addTy(.alloc, ptr_type);
30673093}
......@@ -3083,7 +3109,7 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
30833109 .pointee_type = var_ty,
30843110 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
30853111 });
3086 try sema.requireRuntimeBlock(block, var_decl_src);
3112 try sema.requireFunctionBlock(block, var_decl_src);
30873113 try sema.queueFullTypeResolution(var_ty);
30883114 return block.addTy(.alloc, ptr_type);
30893115}
......@@ -3272,7 +3298,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
32723298 return;
32733299 }
32743300
3275 try sema.requireRuntimeBlock(block, src);
3301 try sema.requireFunctionBlock(block, src);
32763302 try sema.queueFullTypeResolution(final_elem_ty);
32773303
32783304 // Change it to a normal alloc.
......@@ -3593,7 +3619,7 @@ fn validateUnionInit(
35933619 return;
35943620 }
35953621
3596 try sema.requireRuntimeBlock(block, init_src);
3622 try sema.requireFunctionBlock(block, init_src);
35973623 const new_tag = try sema.addConstant(union_obj.tag_ty, tag_val);
35983624 _ = try block.addBinOp(.set_union_tag, union_ptr, new_tag);
35993625}
......@@ -3859,7 +3885,7 @@ fn zirValidateArrayInit(
38593885 // any ZIR instructions at comptime; we need to do that here.
38603886 if (array_ty.sentinel()) |sentinel_val| {
38613887 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);
38633889 const sentinel = try sema.addConstant(array_ty.childType(), sentinel_val);
38643890 try sema.storePtr2(block, init_src, sentinel_ptr, init_src, sentinel, init_src, .store);
38653891 }
......@@ -4207,10 +4233,8 @@ fn storeToInferredAllocComptime(
42074233 const operand_ty = sema.typeOf(operand);
42084234 // There will be only one store_to_inferred_ptr because we are running at comptime.
42094235 // The alloc will turn into a Decl.
4210 if (try sema.resolveMaybeUndefValAllowVariables(block, src, operand)) |operand_val| {
4211 if (operand_val.tag() == .variable) {
4212 return sema.failWithNeededComptime(block, src);
4213 }
4236 if (try sema.resolveMaybeUndefValAllowVariables(block, src, operand)) |operand_val| store: {
4237 if (operand_val.tag() == .variable) break :store;
42144238 var anon_decl = try block.startAnonDecl(src);
42154239 defer anon_decl.deinit();
42164240 iac.data.decl_index = try anon_decl.finish(
......@@ -4219,15 +4243,15 @@ fn storeToInferredAllocComptime(
42194243 iac.data.alignment,
42204244 );
42214245 return;
4222 } else {
4223 return sema.failWithNeededComptime(block, src);
42244246 }
4247
4248 return sema.failWithNeededComptime(block, src, "value being stored to a comptime variable must be comptime known");
42254249}
42264250
42274251fn zirSetEvalBranchQuota(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
42284252 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
42294253 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"));
42314255 sema.branch_quota = @maximum(sema.branch_quota, quota);
42324256}
42334257
......@@ -4282,7 +4306,7 @@ fn zirParamType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
42824306 var param_index = inst_data.param_index;
42834307
42844308 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);
42864310 const bound_fn = bound_fn_val.castTag(.bound_fn).?.data;
42874311 const fn_ty = sema.typeOf(bound_fn.func_inst);
42884312 param_index += 1;
......@@ -4417,7 +4441,7 @@ fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
44174441 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
44184442 const src = inst_data.src();
44194443 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");
44214445 return sema.fail(block, src, "{s}", .{msg});
44224446}
44234447
......@@ -4466,7 +4490,7 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index, force_comptime: bo
44664490 if (block.is_comptime or force_comptime) {
44674491 return sema.fail(block, src, "encountered @panic at comptime", .{});
44684492 }
4469 try sema.requireRuntimeBlock(block, src);
4493 try sema.requireFunctionBlock(block, src);
44704494 return sema.panicWithMsg(block, src, msg_inst);
44714495}
44724496
......@@ -4854,7 +4878,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
48544878 const src = inst_data.src();
48554879 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
48564880 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");
48584882 const options = try sema.resolveExportOptions(block, options_src, extra.options);
48594883 const decl_index = switch (operand.val.tag()) {
48604884 .function => operand.val.castTag(.function).?.data.owner_decl,
......@@ -4989,7 +5013,7 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
49895013fn zirSetCold(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
49905014 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
49915015 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");
49935017 const func = sema.func orelse return; // does nothing outside a function
49945018 func.is_cold = is_cold;
49955019}
......@@ -4997,7 +5021,7 @@ fn zirSetCold(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
49975021fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
49985022 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
49995023 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");
50015025 switch (float_mode) {
50025026 .Strict => return,
50035027 .Optimized => {
......@@ -5009,7 +5033,7 @@ fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
50095033fn zirSetRuntimeSafety(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
50105034 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
50115035 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");
50135037}
50145038
50155039fn 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
50175041
50185042 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
50195043 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
50225046 if (@enumToInt(order) < @enumToInt(std.builtin.AtomicOrder.Acquire)) {
50235047 return sema.fail(block, order_src, "atomic ordering must be Acquire or stricter", .{});
......@@ -5292,7 +5316,7 @@ fn zirCall(
52925316
52935317 // Desugar bound functions here
52945318 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);
52965320 const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data;
52975321 func = bound_data.func_inst;
52985322 resolved_args = try sema.arena.alloc(Air.Inst.Ref, args.len + 1);
......@@ -5489,7 +5513,8 @@ fn analyzeCall(
54895513 }
54905514
54915515 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");
54935518 const module_fn = switch (func_val.tag()) {
54945519 .decl_ref => mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data,
54955520 .function => func_val.castTag(.function).?.data,
......@@ -5588,82 +5613,39 @@ fn analyzeCall(
55885613 // which means its parameter type expressions must be resolved in order and used
55895614 // to successively coerce the arguments.
55905615 const fn_info = sema.code.getFnInfo(module_fn.zir_body_inst);
5591 const zir_tags = sema.code.instructions.items(.tag);
55925616 var arg_i: usize = 0;
5593 for (fn_info.param_body) |inst| switch (zir_tags[inst]) {
5594 .param, .param_comptime => {
5595 // Evaluate the parameter type expression now that previous ones have
5596 // been mapped, and coerce the corresponding argument to it.
5597 const pl_tok = sema.code.instructions.items(.data)[inst].pl_tok;
5598 const param_src = pl_tok.src();
5599 const extra = sema.code.extraData(Zir.Inst.Param, pl_tok.payload_index);
5600 const param_body = sema.code.extra[extra.end..][0..extra.data.body_len];
5601 const param_ty_inst = try sema.resolveBody(&child_block, param_body, inst);
5602 const param_ty = try sema.analyzeAsType(&child_block, param_src, param_ty_inst);
5603 new_fn_info.param_types[arg_i] = param_ty;
5604 const arg_src = call_src; // TODO: better source location
5605 const casted_arg = try sema.coerce(&child_block, param_ty, uncasted_args[arg_i], arg_src);
5606 try sema.inst_map.putNoClobber(gpa, inst, casted_arg);
5607
5608 if (is_comptime_call) {
5609 const arg_val = try sema.resolveConstMaybeUndefVal(&child_block, arg_src, casted_arg);
5610 switch (arg_val.tag()) {
5611 .generic_poison, .generic_poison_type => {
5612 // This function is currently evaluated as part of an as-of-yet unresolvable
5613 // parameter or return type.
5614 return error.GenericPoison;
5615 },
5616 else => {
5617 // Needed so that lazy values do not trigger
5618 // assertion due to type not being resolved
5619 // when the hash function is called.
5620 try sema.resolveLazyValue(&child_block, arg_src, arg_val);
5621 },
5622 }
5623 should_memoize = should_memoize and !arg_val.canMutateComptimeVarState();
5624 memoized_call_key.args[arg_i] = .{
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 };
5617 for (fn_info.param_body) |inst| {
5618 sema.analyzeInlineCallArg(
5619 &child_block,
5620 .unneeded,
5621 inst,
5622 new_fn_info,
5623 &arg_i,
5624 uncasted_args,
5625 is_comptime_call,
5626 &should_memoize,
5627 memoized_call_key,
5628 ) catch |err| switch (err) {
5629 error.NeededSourceLocation => {
5630 const decl = sema.mod.declPtr(block.src_decl);
5631 try sema.analyzeInlineCallArg(
5632 // Intentionally use the wrong block here since we know it's
5633 // going to fail and `argSrc` is relative to `block.src_decl`.
5634 block,
5635 Module.argSrc(call_src.node_offset.x, sema.gpa, decl, arg_i),
5636 inst,
5637 new_fn_info,
5638 &arg_i,
5639 uncasted_args,
5640 is_comptime_call,
5641 &should_memoize,
5642 memoized_call_key,
5643 );
5644 return error.AnalysisFail;
5645 },
5646 else => |e| return e,
5647 };
5648 }
56675649
56685650 // In case it is a generic function with an expression for the return type that depends
56695651 // on parameters, we must now do the same for the return type as we just did with
......@@ -5719,6 +5701,7 @@ fn analyzeCall(
57195701 if (!is_comptime_call) {
57205702 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);
57225705 for (fn_info.param_body) |param| switch (zir_tags[param]) {
57235706 .param, .param_comptime => {
57245707 const inst_data = sema.code.instructions.items(.data)[param].pl_tok;
......@@ -5764,7 +5747,7 @@ fn analyzeCall(
57645747 }
57655748
57665749 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
57695752 // TODO: check whether any external comptime memory was mutated by the
57705753 // comptime function call. If so, then do not memoize the call here.
......@@ -5795,15 +5778,30 @@ fn analyzeCall(
57955778 break :res res2;
57965779 } else res: {
57975780 assert(!func_ty_info.is_generic);
5798 try sema.requireRuntimeBlock(block, call_src);
5781 try sema.requireFunctionBlock(block, call_src);
57995782
58005783 const args = try sema.arena.alloc(Air.Inst.Ref, uncasted_args.len);
58015784 for (uncasted_args) |uncasted_arg, i| {
5802 const arg_src = call_src; // TODO: better source location
58035785 if (i < fn_params_len) {
58045786 const param_ty = func_ty.fnParamType(i);
5805 try sema.resolveTypeFully(block, arg_src, param_ty);
5806 args[i] = try sema.coerce(block, param_ty, uncasted_arg, arg_src);
5787 args[i] = sema.analyzeCallArg(
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 };
58075805 } else {
58085806 args[i] = uncasted_arg;
58095807 }
......@@ -5835,6 +5833,136 @@ fn analyzeCall(
58355833 return result;
58365834}
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
58385966fn instantiateGenericCall(
58395967 sema: *Sema,
58405968 block: *Block,
......@@ -5849,7 +5977,7 @@ fn instantiateGenericCall(
58495977 const mod = sema.mod;
58505978 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");
58535981 const module_fn = switch (func_val.tag()) {
58545982 .function => func_val.castTag(.function).?.data,
58555983 .decl_ref => mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data,
......@@ -5900,10 +6028,16 @@ fn instantiateGenericCall(
59006028 }
59016029
59026030 if (is_comptime) {
5903 const arg_src = call_src; // TODO better source location
59046031 const arg_ty = sema.typeOf(uncasted_args[i]);
5905 const arg_val = try sema.resolveValue(block, arg_src, uncasted_args[i]);
5906 try sema.resolveLazyValue(block, arg_src, arg_val);
6032 const arg_val = sema.analyzeGenericCallArgVal(block, .unneeded, uncasted_args[i]) catch |err| switch (err) {
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 };
59076041 arg_val.hash(arg_ty, &hasher, mod);
59086042 if (is_anytype) {
59096043 arg_ty.hashWithHasher(&hasher, mod);
......@@ -6059,19 +6193,18 @@ fn instantiateGenericCall(
60596193 },
60606194 else => continue,
60616195 }
6062 const arg_src = call_src; // TODO: better source location
60636196 const arg = uncasted_args[arg_i];
60646197 if (is_comptime) {
6065 if (try sema.resolveMaybeUndefVal(block, arg_src, arg)) |arg_val| {
6198 if (try sema.resolveMaybeUndefVal(block, .unneeded, arg)) |arg_val| {
60666199 const child_arg = try child_sema.addConstant(sema.typeOf(arg), arg_val);
60676200 child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);
60686201 } else {
6069 return sema.failWithNeededComptime(block, arg_src);
6202 return sema.failWithNeededComptime(block, .unneeded, undefined);
60706203 }
60716204 } else if (is_anytype) {
60726205 const arg_ty = sema.typeOf(arg);
6073 if (try sema.typeRequiresComptime(block, arg_src, arg_ty)) {
6074 const arg_val = try sema.resolveConstValue(block, arg_src, arg);
6206 if (try sema.typeRequiresComptime(block, .unneeded, arg_ty)) {
6207 const arg_val = try sema.resolveConstValue(block, .unneeded, arg, undefined);
60756208 const child_arg = try child_sema.addConstant(arg_ty, arg_val);
60766209 child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);
60776210 } else {
......@@ -6093,7 +6226,7 @@ fn instantiateGenericCall(
60936226 }
60946227 return err;
60956228 };
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;
60976230 const new_func = new_func_val.castTag(.function).?.data;
60986231 errdefer new_func.deinit(gpa);
60996232 assert(new_func == new_module_func);
......@@ -6129,8 +6262,7 @@ fn instantiateGenericCall(
61296262 const copied_arg_ty = try child_sema.typeOf(arg).copy(new_decl_arena_allocator);
61306263 anytype_args[arg_i] = is_anytype;
61316264
6132 const arg_src = call_src; // TODO: better source location
6133 if (try sema.typeRequiresComptime(block, arg_src, copied_arg_ty)) {
6265 if (try sema.typeRequiresComptime(block, .unneeded, copied_arg_ty)) {
61346266 is_comptime = true;
61356267 }
61366268
......@@ -6195,7 +6327,7 @@ fn instantiateGenericCall(
61956327 const callee_inst = try sema.analyzeDeclVal(block, func_src, callee.owner_decl);
61966328
61976329 // 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
62006332 const comptime_args = callee.comptime_args.?;
62016333 const new_fn_info = mod.declPtr(callee.owner_decl).ty.fnInfo();
......@@ -6209,18 +6341,30 @@ fn instantiateGenericCall(
62096341 .param_comptime, .param_anytype_comptime, .param, .param_anytype => {},
62106342 else => continue,
62116343 }
6212 const arg_src = call_src; // TODO: better source location
6213 const is_runtime = comptime_args[total_i].val.tag() == .generic_poison and
6214 comptime_args[total_i].ty.hasRuntimeBits() and
6215 !(try sema.typeRequiresComptime(block, arg_src, comptime_args[total_i].ty));
6216 if (is_runtime) {
6217 const param_ty = new_fn_info.param_types[runtime_i];
6218 const uncasted_arg = uncasted_args[total_i];
6219 const casted_arg = try sema.coerce(block, param_ty, uncasted_arg, arg_src);
6220 try sema.queueFullTypeResolution(param_ty);
6221 runtime_args[runtime_i] = casted_arg;
6222 runtime_i += 1;
6223 }
6344 sema.analyzeGenericCallArg(
6345 block,
6346 .unneeded,
6347 uncasted_args[total_i],
6348 comptime_args[total_i],
6349 runtime_args,
6350 new_fn_info,
6351 &runtime_i,
6352 ) catch |err| switch (err) {
6353 error.NeededSourceLocation => {
6354 const decl = sema.mod.declPtr(block.src_decl);
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 };
62246368 total_i += 1;
62256369 }
62266370
......@@ -6314,7 +6458,7 @@ fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
63146458 const elem_type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
63156459 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
63166460 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");
63186462 const elem_type = try sema.resolveType(block, elem_type_src, extra.rhs);
63196463 try sema.checkVectorElemType(block, elem_type_src, elem_type);
63206464 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
63326476 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
63336477 const len_src: LazySrcLoc = .{ .node_offset_array_type_len = inst_data.src_node };
63346478 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");
63366480 const elem_type = try sema.resolveType(block, elem_src, extra.rhs);
63376481 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
63486492 const len_src: LazySrcLoc = .{ .node_offset_array_type_len = inst_data.src_node };
63496493 const sentinel_src: LazySrcLoc = .{ .node_offset_array_type_sentinel = inst_data.src_node };
63506494 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");
63526496 const elem_type = try sema.resolveType(block, elem_src, extra.elem_type);
63536497 const uncasted_sentinel = try sema.resolveInst(extra.sentinel);
63546498 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");
63566500 const array_ty = try Type.array(sema.arena, len, sentinel_val, elem_type, sema.mod);
63576501
63586502 return sema.addType(array_ty);
......@@ -6452,7 +6596,7 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
64526596 }
64536597 }
64546598
6455 try sema.requireRuntimeBlock(block, src);
6599 try sema.requireRuntimeBlock(block, src, operand_src);
64566600 return block.addBitCast(result_ty, operand);
64576601}
64586602
......@@ -6478,7 +6622,7 @@ fn zirIntToError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
64786622 };
64796623 return sema.addConstant(Type.anyerror, Value.initPayload(&payload.base));
64806624 }
6481 try sema.requireRuntimeBlock(block, src);
6625 try sema.requireRuntimeBlock(block, src, operand_src);
64826626 if (block.wantSafety()) {
64836627 const is_lt_len = try block.addUnOp(.cmp_lt_errors_len, operand);
64846628 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
65986742 return sema.addConstant(int_tag_ty, try val.copy(sema.arena));
65996743 }
66006744
6601 try sema.requireRuntimeBlock(block, src);
6745 try sema.requireRuntimeBlock(block, src, operand_src);
66026746 return block.addBitCast(int_tag_ty, enum_tag);
66036747}
66046748
......@@ -6645,7 +6789,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
66456789 return sema.addConstant(dest_ty, int_val);
66466790 }
66476791
6648 try sema.requireRuntimeBlock(block, src);
6792 try sema.requireRuntimeBlock(block, src, operand_src);
66496793 // TODO insert safety check to make sure the value matches an enum value
66506794 return block.addTyOp(.intcast, dest_ty, operand);
66516795}
......@@ -6696,7 +6840,7 @@ fn analyzeOptionalPayloadPtr(
66966840 // If the pointer resulting from this function was stored at comptime,
66976841 // the optional non-null bit would be set that way. But in this case,
66986842 // we need to emit a runtime instruction to do it.
6699 try sema.requireRuntimeBlock(block, src);
6843 try sema.requireFunctionBlock(block, src);
67006844 _ = try block.addTyOp(.optional_payload_ptr_set, child_pointer, optional_ptr);
67016845 }
67026846 return sema.addConstant(
......@@ -6722,7 +6866,7 @@ fn analyzeOptionalPayloadPtr(
67226866 }
67236867 }
67246868
6725 try sema.requireRuntimeBlock(block, src);
6869 try sema.requireRuntimeBlock(block, src, null);
67266870 if (safety_check and block.wantSafety()) {
67276871 const is_non_null = try block.addUnOp(.is_non_null_ptr, optional_ptr);
67286872 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);
......@@ -6778,7 +6922,7 @@ fn zirOptionalPayload(
67786922 return sema.addConstant(result_ty, val);
67796923 }
67806924
6781 try sema.requireRuntimeBlock(block, src);
6925 try sema.requireRuntimeBlock(block, src, null);
67826926 if (safety_check and block.wantSafety()) {
67836927 const is_non_null = try block.addUnOp(.is_non_null, operand);
67846928 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);
......@@ -6827,7 +6971,7 @@ fn analyzeErrUnionPayload(
68276971 return sema.addConstant(payload_ty, data);
68286972 }
68296973
6830 try sema.requireRuntimeBlock(block, src);
6974 try sema.requireRuntimeBlock(block, src, null);
68316975
68326976 // If the error set has no fields then no safety check is needed.
68336977 if (safety_check and block.wantSafety() and
......@@ -6887,7 +7031,7 @@ fn analyzeErrUnionPayloadPtr(
68877031 // If the pointer resulting from this function was stored at comptime,
68887032 // the error union error code would be set that way. But in this case,
68897033 // we need to emit a runtime instruction to do it.
6890 try sema.requireRuntimeBlock(block, src);
7034 try sema.requireRuntimeBlock(block, src, null);
68917035 _ = try block.addTyOp(.errunion_payload_ptr_set, operand_pointer_ty, operand);
68927036 }
68937037 return sema.addConstant(
......@@ -6913,7 +7057,7 @@ fn analyzeErrUnionPayloadPtr(
69137057 }
69147058 }
69157059
6916 try sema.requireRuntimeBlock(block, src);
7060 try sema.requireRuntimeBlock(block, src, null);
69177061
69187062 // If the error set has no fields then no safety check is needed.
69197063 if (safety_check and block.wantSafety() and
......@@ -6951,7 +7095,7 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
69517095 return sema.addConstant(result_ty, val);
69527096 }
69537097
6954 try sema.requireRuntimeBlock(block, src);
7098 try sema.requireRuntimeBlock(block, src, null);
69557099 return block.addTyOp(.unwrap_errunion_err, result_ty, operand);
69567100}
69577101
......@@ -6981,7 +7125,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
69817125 }
69827126 }
69837127
6984 try sema.requireRuntimeBlock(block, src);
7128 try sema.requireRuntimeBlock(block, src, null);
69857129 return block.addTyOp(.unwrap_errunion_err_ptr, result_ty, operand);
69867130}
69877131
......@@ -7037,7 +7181,7 @@ fn zirFunc(
70377181 const ret_ty_body = sema.code.extra[extra_index..][0..extra.data.ret_body_len];
70387182 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");
70417185 var buffer: Value.ToTypeBuffer = undefined;
70427186 break :blk try ret_ty_val.toType(&buffer).copy(sema.arena);
70437187 },
......@@ -7085,6 +7229,7 @@ fn resolveGenericBody(
70857229 body: []const Zir.Inst.Index,
70867230 func_inst: Zir.Inst.Index,
70877231 dest_ty: Type,
7232 reason: []const u8,
70887233) !Value {
70897234 assert(body.len != 0);
70907235
......@@ -7098,7 +7243,7 @@ fn resolveGenericBody(
70987243 }
70997244 const uncasted = sema.resolveBody(block, body, func_inst) catch |err| break :err err;
71007245 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;
71027247 return val;
71037248 };
71047249 switch (err) {
......@@ -7205,6 +7350,7 @@ fn funcCommon(
72057350 opt_lib_name: ?[]const u8,
72067351 noalias_bits: u32,
72077352) CompileError!Air.Inst.Ref {
7353 const fn_src = LazySrcLoc.nodeOffset(src_node_offset);
72087354 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset };
72097355 const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = src_node_offset };
72107356
......@@ -7213,10 +7359,6 @@ fn funcCommon(
72137359 address_space == null or
72147360 section == .generic or
72157361 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
72217363 var destroy_fn_on_error = false;
72227364 const new_func: *Module.Fn = new_func: {
......@@ -7227,7 +7369,10 @@ fn funcCommon(
72277369 break :new_func new_func;
72287370 }
72297371 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;
72317376 };
72327377 errdefer if (destroy_fn_on_error) sema.gpa.destroy(new_func);
72337378
......@@ -7261,18 +7406,47 @@ fn funcCommon(
72617406 }
72627407 }
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
72647418 const param_types = try sema.arena.alloc(Type, block.params.items.len);
72657419 const comptime_params = try sema.arena.alloc(bool, block.params.items.len);
72667420 for (block.params.items) |param, i| {
7267 const param_src = LazySrcLoc.nodeOffset(src_node_offset); // TODO better soruce location
72687421 param_types[i] = param.ty;
7269 comptime_params[i] = param.is_comptime or
7270 try sema.typeRequiresComptime(block, param_src, param.ty);
7271 is_generic = is_generic or comptime_params[i] or param.ty.tag() == .generic_poison;
7272 if (is_extern and is_generic) {
7273 // TODO add note: function is generic because of this parameter
7274 return sema.fail(block, param_src, "extern function cannot be generic", .{});
7275 }
7422 sema.analyzeParameter(
7423 block,
7424 fn_src,
7425 .unneeded,
7426 param,
7427 comptime_params,
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 };
72767450 }
72777451
72787452 const ret_poison = if (!is_generic) rp: {
......@@ -7302,14 +7476,34 @@ fn funcCommon(
73027476 });
73037477 };
73047478
7305 // These locals are pulled out from the init expression below to work around
7306 // a stage1 compiler bug.
7307 // In the case of generic calling convention, or generic alignment, we use
7308 // default values which are only meaningful for the generic function, *not*
7309 // the instantiation, which can depend on comptime parameters.
7310 // Related proposal: https://github.com/ziglang/zig/issues/11834
7311 const cc_workaround = cc orelse .Unspecified;
7312 const align_workaround = alignment orelse 0;
7479 if (!bare_return_type.isValidReturnType()) {
7480 const opaque_str = if (bare_return_type.zigTypeTag() == .Opaque) "opaque " else "";
7481 const msg = msg: {
7482 const msg = try sema.errMsg(block, ret_ty_src, "{s}return type '{}' not allowed", .{
7483 opaque_str, bare_return_type.fmt(sema.mod),
7484 });
7485 errdefer msg.destroy(sema.gpa);
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
73147508 const arch = sema.mod.getTarget().cpu.arch;
73157509 if (switch (cc_workaround) {
......@@ -7442,6 +7636,79 @@ fn funcCommon(
74427636 return sema.addConstant(fn_ty, Value.initPayload(&fn_payload.base));
74437637}
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
74457712fn zirParam(
74467713 sema: *Sema,
74477714 block: *Block,
......@@ -7629,7 +7896,7 @@ fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
76297896 if (try sema.resolveMaybeUndefVal(block, ptr_src, ptr)) |ptr_val| {
76307897 return sema.addConstant(Type.usize, ptr_val);
76317898 }
7632 try sema.requireRuntimeBlock(block, ptr_src);
7899 try sema.requireRuntimeBlock(block, ptr_src, ptr_src);
76337900 return block.addUnOp(.ptrtoint, ptr);
76347901}
76357902
......@@ -7681,7 +7948,7 @@ fn zirFieldValNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
76817948 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
76827949 const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;
76837950 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");
76857952 return sema.fieldVal(block, src, object, field_name, field_name_src);
76867953}
76877954
......@@ -7694,7 +7961,7 @@ fn zirFieldPtrNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
76947961 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
76957962 const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;
76967963 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");
76987965 return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src);
76997966}
77007967
......@@ -7706,7 +7973,7 @@ fn zirFieldCallBindNamed(sema: *Sema, block: *Block, extended: Zir.Inst.Extended
77067973 const src = LazySrcLoc.nodeOffset(extra.node);
77077974 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
77087975 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");
77107977 return sema.fieldCallBind(block, src, object_ptr, field_name, field_name_src);
77117978}
77127979
......@@ -7722,12 +7989,13 @@ fn zirIntCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
77227989 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
77237990 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);
77267993}
77277994
77287995fn intCast(
77297996 sema: *Sema,
77307997 block: *Block,
7998 src: LazySrcLoc,
77317999 dest_ty: Type,
77328000 dest_ty_src: LazySrcLoc,
77338001 operand: Air.Inst.Ref,
......@@ -7750,7 +8018,7 @@ fn intCast(
77508018 if ((try sema.typeHasOnePossibleValue(block, dest_ty_src, dest_ty))) |opv| {
77518019 // requirement: intCast(u0, input) iff input == 0
77528020 if (runtime_safety and block.wantSafety()) {
7753 try sema.requireRuntimeBlock(block, operand_src);
8021 try sema.requireRuntimeBlock(block, src, operand_src);
77548022 const target = sema.mod.getTarget();
77558023 const wanted_info = dest_scalar_ty.intInfo(target);
77568024 const wanted_bits = wanted_info.bits;
......@@ -7765,7 +8033,7 @@ fn intCast(
77658033 return sema.addConstant(dest_ty, opv);
77668034 }
77678035
7768 try sema.requireRuntimeBlock(block, operand_src);
8036 try sema.requireRuntimeBlock(block, src, operand_src);
77698037 if (runtime_safety and block.wantSafety()) {
77708038 const target = sema.mod.getTarget();
77718039 const actual_info = operand_scalar_ty.intInfo(target);
......@@ -7972,7 +8240,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
79728240 if (dst_bits >= src_bits) {
79738241 return sema.coerce(block, dest_ty, operand, operand_src);
79748242 }
7975 try sema.requireRuntimeBlock(block, operand_src);
8243 try sema.requireRuntimeBlock(block, inst_data.src(), operand_src);
79768244 return block.addTyOp(.fptrunc, dest_ty, operand);
79778245}
79788246
......@@ -8096,7 +8364,6 @@ fn zirSwitchCapture(
80968364 const switch_info = zir_datas[capture_info.switch_inst].pl_node;
80978365 const switch_extra = sema.code.extraData(Zir.Inst.SwitchBlock, switch_info.payload_index);
80988366 const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = switch_info.src_node };
8099 const switch_src = switch_info.src();
81008367 const operand_is_ref = switch_extra.data.bits.is_ref;
81018368 const cond_inst = Zir.refToIndex(switch_extra.data.operand).?;
81028369 const cond_info = sema.code.instructions.items(.data)[cond_inst].un_node;
......@@ -8141,24 +8408,30 @@ fn zirSwitchCapture(
81418408
81428409 const first_item = try sema.resolveInst(items[0]);
81438410 // 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
81468413 const first_field_index = @intCast(u32, enum_ty.enumTagFieldIndex(first_item_val, sema.mod).?);
81478414 const first_field = union_obj.fields.values()[first_field_index];
81488415
8149 for (items[1..]) |item| {
8416 for (items[1..]) |item, i| {
81508417 const item_ref = try sema.resolveInst(item);
81518418 // 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
81548421 const field_index = enum_ty.enumTagFieldIndex(item_val, sema.mod).?;
81558422 const field = union_obj.fields.values()[field_index];
81568423 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;
81598424 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", .{});
81618429 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);
81628435 try sema.errNote(block, first_item_src, msg, "type '{}' here", .{first_field.ty.fmt(sema.mod)});
81638436 try sema.errNote(block, item_src, msg, "type '{}' here", .{field.ty.fmt(sema.mod)});
81648437 break :msg msg;
......@@ -8186,7 +8459,7 @@ fn zirSwitchCapture(
81868459 }),
81878460 );
81888461 }
8189 try sema.requireRuntimeBlock(block, operand_src);
8462 try sema.requireRuntimeBlock(block, operand_src, null);
81908463 return block.addStructFieldPtr(operand_ptr, first_field_index, field_ty_ptr);
81918464 }
81928465
......@@ -8196,7 +8469,7 @@ fn zirSwitchCapture(
81968469 operand_val.castTag(.@"union").?.data.val,
81978470 );
81988471 }
8199 try sema.requireRuntimeBlock(block, operand_src);
8472 try sema.requireRuntimeBlock(block, operand_src, null);
82008473 return block.addStructFieldVal(operand, first_field_index, first_field.ty);
82018474 },
82028475 .ErrorSet => {
......@@ -8206,7 +8479,7 @@ fn zirSwitchCapture(
82068479 for (items) |item| {
82078480 const item_ref = try sema.resolveInst(item);
82088481 // 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;
82108483 names.putAssumeCapacityNoClobber(
82118484 item_val.getError().?,
82128485 {},
......@@ -8220,7 +8493,7 @@ fn zirSwitchCapture(
82208493 } else {
82218494 const item_ref = try sema.resolveInst(items[0]);
82228495 // 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
82258498 const item_ty = try Type.Tag.error_set_single.create(sema.arena, item_val.getError().?);
82268499 return sema.bitCast(block, item_ty, operand, operand_src);
......@@ -8247,7 +8520,7 @@ fn zirSwitchCond(
82478520) CompileError!Air.Inst.Ref {
82488521 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
82498522 const src = inst_data.src();
8250 const operand_src = src; // TODO make this point at the switch operand
8523 const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = inst_data.src_node };
82518524 const operand_ptr = try sema.resolveInst(inst_data.operand);
82528525 const operand = if (is_ref)
82538526 try sema.analyzeLoad(block, src, operand_ptr, operand_src)
......@@ -8345,12 +8618,19 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
83458618 },
83468619 };
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
83488628 const operand_ty = sema.typeOf(operand);
83498629
83508630 var else_error_ty: ?Type = null;
83518631
83528632 // 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)) {
83548634 const msg = msg: {
83558635 const msg = try sema.errMsg(
83568636 block,
......@@ -8375,6 +8655,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
83758655
83768656 // Validate for duplicate items, missing else prong, and invalid range.
83778657 switch (operand_ty.zigTypeTag()) {
8658 .Union => unreachable, // handled in zirSwitchCond
83788659 .Enum => {
83798660 var seen_fields = try gpa.alloc(?Module.SwitchProngSrc, operand_ty.enumFieldCount());
83808661 defer gpa.free(seen_fields);
......@@ -8432,60 +8713,53 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
84328713 }
84338714 const all_tags_handled = for (seen_fields) |seen_src| {
84348715 if (seen_src == null) break false;
8435 } else !operand_ty.isNonexhaustiveEnum();
8716 } else true;
84368717
8437 switch (special_prong) {
8438 .none => {
8439 if (!all_tags_handled) {
8440 const msg = msg: {
8441 const msg = try sema.errMsg(
8442 block,
8443 src,
8444 "switch must handle all possibilities",
8445 .{},
8446 );
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(
8718 if (special_prong == .@"else") {
8719 if (all_tags_handled and !operand_ty.isNonexhaustiveEnum()) return sema.fail(
8720 block,
8721 special_prong_src,
8722 "unreachable else prong; all cases already handled",
8723 .{},
8724 );
8725 } else if (!all_tags_handled) {
8726 const msg = msg: {
8727 const msg = try sema.errMsg(
84758728 block,
8476 special_prong_src,
8477 "unreachable '_' prong; all cases already handled",
8729 src,
8730 "switch must handle all possibilities",
84788731 .{},
84798732 );
8480 },
8481 .@"else" => {
8482 if (all_tags_handled) return sema.fail(
8483 block,
8484 special_prong_src,
8485 "unreachable else prong; all cases already handled",
8486 .{},
8733 errdefer msg.destroy(sema.gpa);
8734 for (seen_fields) |seen_src, i| {
8735 if (seen_src != null) continue;
8736
8737 const field_name = operand_ty.enumFieldName(i);
8738 try sema.addFieldErrNote(
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)},
84878752 );
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 );
84898763 }
84908764 },
84918765 .ErrorSet => {
......@@ -8625,7 +8899,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
86258899 else_error_ty = try Type.Tag.error_set_merged.create(sema.arena, names);
86268900 }
86278901 },
8628 .Union => return sema.fail(block, src, "TODO validate switch .Union", .{}),
86298902 .Int, .ComptimeInt => {
86308903 var range_set = RangeSet.init(gpa, sema.mod);
86318904 defer range_set.deinit();
......@@ -8923,7 +9196,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
89239196
89249197 const item = try sema.resolveInst(item_ref);
89259198 // 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;
89279200 if (operand_val.eql(item_val, operand_ty, sema.mod)) {
89289201 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);
89299202 }
......@@ -8945,7 +9218,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
89459218 for (items) |item_ref| {
89469219 const item = try sema.resolveInst(item_ref);
89479220 // 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;
89499222 if (operand_val.eql(item_val, operand_ty, sema.mod)) {
89509223 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);
89519224 }
......@@ -8959,8 +9232,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
89599232 extra_index += 1;
89609233
89619234 // Validation above ensured these will succeed.
8962 const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first) catch unreachable;
8963 const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last) catch unreachable;
9235 const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first, undefined) catch unreachable;
9236 const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last, undefined) catch unreachable;
89649237 if ((try sema.compare(block, src, operand_val, .gte, first_tv.val, operand_ty)) and
89659238 (try sema.compare(block, src, operand_val, .lte, last_tv.val, operand_ty)))
89669239 {
......@@ -8981,7 +9254,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
89819254 return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges);
89829255 }
89839256
8984 try sema.requireRuntimeBlock(block, src);
9257 try sema.requireRuntimeBlock(block, src, operand_src);
89859258
89869259 const estimated_cases_extra = (scalar_cases_len + multi_cases_len) *
89879260 @typeInfo(Air.SwitchBr.Case).Struct.fields.len + 2;
......@@ -9270,14 +9543,14 @@ fn resolveSwitchItemVal(
92709543 // Constructing a LazySrcLoc is costly because we only have the switch AST node.
92719544 // Only if we know for sure we need to report a compile error do we resolve the
92729545 // full source locations.
9273 if (sema.resolveConstValue(block, .unneeded, item)) |val| {
9546 if (sema.resolveConstValue(block, .unneeded, item, undefined)) |val| {
92749547 return TypedValue{ .ty = item_ty, .val = val };
92759548 } else |err| switch (err) {
92769549 error.NeededSourceLocation => {
92779550 const src = switch_prong_src.resolve(sema.gpa, sema.mod.declPtr(block.src_decl), switch_node_offset, range_expand);
92789551 return TypedValue{
92799552 .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"),
92819554 };
92829555 },
92839556 else => |e| return e,
......@@ -9463,7 +9736,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
94639736 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
94649737 const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
94659738 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");
94679740 const ty = try sema.resolveTypeFields(block, ty_src, unresolved_ty);
94689741
94699742 const has_field = hf: {
......@@ -9505,7 +9778,7 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
95059778 const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
95069779 const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
95079780 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
95109783 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
95529825 const mod = sema.mod;
95539826 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
95549827 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
95579830 const embed_file = mod.embedFile(block.getFileScope(), name) catch |err| switch (err) {
95589831 error.ImportOutsidePkgPath => {
......@@ -9706,13 +9979,13 @@ fn zirShl(
97069979 try lhs_ty.maxInt(sema.arena, target),
97079980 );
97089981 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);
97109983 } else {
97119984 break :rhs rhs;
97129985 }
97139986 } else rhs;
97149987
9715 try sema.requireRuntimeBlock(block, runtime_src);
9988 try sema.requireRuntimeBlock(block, src, runtime_src);
97169989 if (block.wantSafety()) {
97179990 const maybe_op_ov: ?Air.Inst.Tag = switch (air_tag) {
97189991 .shl_exact => .shl_with_overflow,
......@@ -9823,7 +10096,7 @@ fn zirShr(
982310096 }
982410097 } else rhs_src;
982510098
9826 try sema.requireRuntimeBlock(block, runtime_src);
10099 try sema.requireRuntimeBlock(block, src, runtime_src);
982710100 return block.addBinOp(air_tag, lhs, rhs);
982810101}
982910102
......@@ -9882,7 +10155,7 @@ fn zirBitwise(
988210155 }
988310156 };
988410157
9885 try sema.requireRuntimeBlock(block, runtime_src);
10158 try sema.requireRuntimeBlock(block, src, runtime_src);
988610159 return block.addBinOp(air_tag, casted_lhs, casted_rhs);
988710160}
988810161
......@@ -9926,7 +10199,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
992610199 }
992710200 }
992810201
9929 try sema.requireRuntimeBlock(block, src);
10202 try sema.requireRuntimeBlock(block, src, null);
993010203 return block.addTyOp(.not, operand_type, operand);
993110204}
993210205
......@@ -9939,6 +10212,7 @@ fn analyzeTupleCat(
993910212) CompileError!Air.Inst.Ref {
994010213 const lhs_ty = sema.typeOf(lhs);
994110214 const rhs_ty = sema.typeOf(rhs);
10215 const src = LazySrcLoc.nodeOffset(src_node);
994210216 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = src_node };
994310217 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = src_node };
994410218
......@@ -9986,7 +10260,7 @@ fn analyzeTupleCat(
998610260 return sema.addConstant(tuple_ty, tuple_val);
998710261 };
998810262
9989 try sema.requireRuntimeBlock(block, runtime_src);
10263 try sema.requireRuntimeBlock(block, src, runtime_src);
999010264
999110265 const element_refs = try sema.arena.alloc(Air.Inst.Ref, final_len);
999210266 for (lhs_tuple.types) |_, i| {
......@@ -10049,8 +10323,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1004910323 const rhs_sent = try sema.addConstant(rhs_info.elem_type, rhs_sent_val);
1005010324 const lhs_sent_casted = try sema.coerce(block, resolved_elem_ty, lhs_sent, lhs_src);
1005110325 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);
10053 const rhs_sent_casted_val = try sema.resolveConstValue(block, rhs_src, rhs_sent_casted);
10326 const lhs_sent_casted_val = try sema.resolveConstValue(block, lhs_src, lhs_sent_casted, "array sentinel value must be comptime known");
10327 const rhs_sent_casted_val = try sema.resolveConstValue(block, rhs_src, rhs_sent_casted, "array sentinel value must be comptime known");
1005410328 if (try sema.valuesEqual(block, src, lhs_sent_casted_val, rhs_sent_casted_val, resolved_elem_ty)) {
1005510329 break :s lhs_sent_casted_val;
1005610330 } else {
......@@ -10058,14 +10332,14 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1005810332 }
1005910333 } else {
1006010334 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");
1006210336 break :s lhs_sent_casted_val;
1006310337 }
1006410338 } else {
1006510339 if (rhs_info.sentinel) |rhs_sent_val| {
1006610340 const rhs_sent = try sema.addConstant(rhs_info.elem_type, rhs_sent_val);
1006710341 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");
1006910343 break :s rhs_sent_casted_val;
1007010344 } else {
1007110345 break :s null;
......@@ -10120,7 +10394,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1012010394 } else break :rs rhs_src;
1012110395 } else lhs_src;
1012210396
10123 try sema.requireRuntimeBlock(block, runtime_src);
10397 try sema.requireRuntimeBlock(block, src, runtime_src);
1012410398
1012510399 if (ptr_addrspace) |ptr_as| {
1012610400 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
1018610460 // has a sentinel, and this code should compute the length based
1018710461 // on the sentinel value.
1018810462 .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");
1019010464 return Type.ArrayInfo{
1019110465 .elem_type = ptr_info.pointee_type,
1019210466 .sentinel = ptr_info.sentinel,
......@@ -10215,6 +10489,7 @@ fn analyzeTupleMul(
1021510489) CompileError!Air.Inst.Ref {
1021610490 const operand_ty = sema.typeOf(operand);
1021710491 const operand_tuple = operand_ty.tupleFields();
10492 const src = LazySrcLoc.nodeOffset(src_node);
1021810493 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = src_node };
1021910494 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = src_node };
1022010495
......@@ -10258,7 +10533,7 @@ fn analyzeTupleMul(
1025810533 return sema.addConstant(tuple_ty, tuple_val);
1025910534 };
1026010535
10261 try sema.requireRuntimeBlock(block, runtime_src);
10536 try sema.requireRuntimeBlock(block, src, runtime_src);
1026210537
1026310538 const element_refs = try sema.arena.alloc(Air.Inst.Ref, final_len);
1026410539 for (operand_tuple.types) |_, i| {
......@@ -10286,7 +10561,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1028610561 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
1028710562
1028810563 // 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
1029110566 if (lhs_ty.isTuple()) {
1029210567 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
1033710612 return sema.addConstantMaybeRef(block, src, result_ty, val, ptr_addrspace != null);
1033810613 }
1033910614
10340 try sema.requireRuntimeBlock(block, lhs_src);
10615 try sema.requireRuntimeBlock(block, src, lhs_src);
1034110616
1034210617 if (ptr_addrspace) |ptr_as| {
1034310618 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.
1041110686 const target = sema.mod.getTarget();
1041210687 return sema.addConstant(rhs_ty, try rhs_val.floatNeg(rhs_ty, sema.arena, target));
1041310688 }
10414 try sema.requireRuntimeBlock(block, rhs_src);
10689 try sema.requireRuntimeBlock(block, src, null);
1041510690 return block.addUnOp(.neg, rhs);
1041610691 }
1041710692
......@@ -10495,7 +10770,7 @@ fn zirOverflowArithmetic(
1049510770 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1049610771 const dest_ty = lhs_ty;
1049710772 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)});
1049910774 }
1050010775
1050110776 const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, lhs);
......@@ -10635,7 +10910,8 @@ fn zirOverflowArithmetic(
1063510910 else => unreachable,
1063610911 };
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
1064010916 const tuple = try block.addInst(.{
1064110917 .tag = air_tag,
......@@ -11542,7 +11818,7 @@ fn analyzeArithmetic(
1154211818 }
1154311819 };
1154411820
11545 try sema.requireRuntimeBlock(block, rs.src);
11821 try sema.requireRuntimeBlock(block, src, rs.src);
1154611822 if (block.wantSafety()) {
1154711823 if (scalar_tag == .Int) {
1154811824 const maybe_op_ov: ?Air.Inst.Tag = switch (rs.air_tag) {
......@@ -11666,7 +11942,7 @@ fn analyzePtrArithmetic(
1166611942 } else break :rs ptr_src;
1166711943 };
1166811944
11669 try sema.requireRuntimeBlock(block, runtime_src);
11945 try sema.requireRuntimeBlock(block, op_src, runtime_src);
1167011946 return block.addInst(.{
1167111947 .tag = air_tag,
1167211948 .data = .{ .ty_pl = .{
......@@ -11685,7 +11961,7 @@ fn zirLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.In
1168511961
1168611962 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1168711963 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
1168911965 const ptr = try sema.resolveInst(inst_data.operand);
1169011966 return sema.analyzeLoad(block, src, ptr, ptr_src);
1169111967}
......@@ -11733,7 +12009,7 @@ fn zirAsm(
1173312009 }
1173412010
1173512011 if (block.is_comptime) {
11736 try sema.requireRuntimeBlock(block, src);
12012 try sema.requireRuntimeBlock(block, src, null);
1173712013 }
1173812014
1173912015 var extra_i = extra.end;
......@@ -11895,10 +12171,10 @@ fn zirCmpEq(
1189512171 }
1189612172
1189712173 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);
1189912175 }
1190012176 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);
1190212178 }
1190312179
1190412180 if (lhs_ty_tag == .ErrorSet and rhs_ty_tag == .ErrorSet) {
......@@ -11925,7 +12201,7 @@ fn zirCmpEq(
1192512201 break :src lhs_src;
1192612202 }
1192712203 };
11928 try sema.requireRuntimeBlock(block, runtime_src);
12204 try sema.requireRuntimeBlock(block, src, runtime_src);
1192912205 return block.addBinOp(air_tag, lhs, rhs);
1193012206 }
1193112207 if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) {
......@@ -11943,6 +12219,7 @@ fn zirCmpEq(
1194312219fn analyzeCmpUnionTag(
1194412220 sema: *Sema,
1194512221 block: *Block,
12222 src: LazySrcLoc,
1194612223 un: Air.Inst.Ref,
1194712224 un_src: LazySrcLoc,
1194812225 tag: Air.Inst.Ref,
......@@ -11964,7 +12241,7 @@ fn analyzeCmpUnionTag(
1196412241 const coerced_tag = try sema.coerce(block, union_tag_ty, tag, tag_src);
1196512242 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);
1196812245}
1196912246
1197012247/// Only called for non-equality operators. See also `zirCmpEq`.
......@@ -12020,7 +12297,7 @@ fn analyzeCmp(
1202012297 }
1202112298 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
1202212299 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);
1202412301}
1202512302
1202612303fn compareOperatorName(comp: std.math.CompareOperator) []const u8 {
......@@ -12037,6 +12314,7 @@ fn compareOperatorName(comp: std.math.CompareOperator) []const u8 {
1203712314fn cmpSelf(
1203812315 sema: *Sema,
1203912316 block: *Block,
12317 src: LazySrcLoc,
1204012318 casted_lhs: Air.Inst.Ref,
1204112319 casted_rhs: Air.Inst.Ref,
1204212320 op: std.math.CompareOperator,
......@@ -12064,7 +12342,7 @@ fn cmpSelf(
1206412342 } else {
1206512343 if (resolved_type.zigTypeTag() == .Bool) {
1206612344 // 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);
1206812346 }
1206912347 break :src rhs_src;
1207012348 }
......@@ -12074,13 +12352,13 @@ fn cmpSelf(
1207412352 if (resolved_type.zigTypeTag() == .Bool) {
1207512353 if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| {
1207612354 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);
1207812356 }
1207912357 }
1208012358 break :src lhs_src;
1208112359 }
1208212360 };
12083 try sema.requireRuntimeBlock(block, runtime_src);
12361 try sema.requireRuntimeBlock(block, src, runtime_src);
1208412362 if (resolved_type.zigTypeTag() == .Vector) {
1208512363 const result_ty = try Type.vector(sema.arena, resolved_type.vectorLen(), Type.@"bool");
1208612364 const result_ty_ref = try sema.addType(result_ty);
......@@ -12097,13 +12375,14 @@ fn cmpSelf(
1209712375fn runtimeBoolCmp(
1209812376 sema: *Sema,
1209912377 block: *Block,
12378 src: LazySrcLoc,
1210012379 op: std.math.CompareOperator,
1210112380 lhs: Air.Inst.Ref,
1210212381 rhs: bool,
1210312382 runtime_src: LazySrcLoc,
1210412383) CompileError!Air.Inst.Ref {
1210512384 if ((op == .neq) == rhs) {
12106 try sema.requireRuntimeBlock(block, runtime_src);
12385 try sema.requireRuntimeBlock(block, src, runtime_src);
1210712386 return block.addTyOp(.not, Type.bool, lhs);
1210812387 } else {
1210912388 return lhs;
......@@ -12225,7 +12504,7 @@ fn zirRetAddr(
1222512504 extended: Zir.Inst.Extended.InstData,
1222612505) CompileError!Air.Inst.Ref {
1222712506 const src = LazySrcLoc.nodeOffset(@bitCast(i32, extended.operand));
12228 try sema.requireRuntimeBlock(block, src);
12507 try sema.requireRuntimeBlock(block, src, null);
1222912508 return try block.addNoOp(.ret_addr);
1223012509}
1223112510
......@@ -12235,7 +12514,7 @@ fn zirFrameAddress(
1223512514 extended: Zir.Inst.Extended.InstData,
1223612515) CompileError!Air.Inst.Ref {
1223712516 const src = LazySrcLoc.nodeOffset(@bitCast(i32, extended.operand));
12238 try sema.requireRuntimeBlock(block, src);
12517 try sema.requireRuntimeBlock(block, src, null);
1223912518 return try block.addNoOp(.frame_addr);
1224012519}
1224112520
......@@ -13304,7 +13583,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1330413583 else
1330513584 Air.Inst.Ref.bool_true;
1330613585 }
13307 try sema.requireRuntimeBlock(block, src);
13586 try sema.requireRuntimeBlock(block, src, null);
1330813587 return block.addTyOp(.not, Type.bool, operand);
1330913588}
1331013589
......@@ -13689,7 +13968,7 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1368913968 if (block.is_comptime or inst_data.force_comptime) {
1369013969 return sema.fail(block, src, "reached unreachable code", .{});
1369113970 }
13692 try sema.requireRuntimeBlock(block, src);
13971 try sema.requireFunctionBlock(block, src);
1369313972 // TODO Add compile error for @optimizeFor occurring too late in a scope.
1369413973 try block.addUnreachable(src, true);
1369513974 return always_noreturn;
......@@ -13751,7 +14030,6 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir
1375114030 const operand = try sema.analyzeLoad(block, src, ret_ptr, src);
1375214031 return sema.analyzeRet(block, operand, src);
1375314032 }
13754 try sema.requireRuntimeBlock(block, src);
1375514033 _ = try block.addUnOp(.ret_load, ret_ptr);
1375614034 return always_noreturn;
1375714035}
......@@ -13834,22 +14112,21 @@ fn floatOpAllowed(tag: Zir.Inst.Tag) bool {
1383414112 };
1383514113}
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 {
1383814116 const tracy = trace(@src());
1383914117 defer tracy.end();
1384014118
13841 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type_simple;
13842 const elem_ty_src = sema.src; // TODO better source location
13843 const elem_type = try sema.resolveType(block, elem_ty_src, inst_data.elem_type);
14119 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
14120 const elem_ty_src = inst_data.src();
14121 const elem_type = try sema.resolveType(block, elem_ty_src, inst_data.operand);
1384414122 const ty = try Type.ptr(sema.arena, sema.mod, .{
1384514123 .pointee_type = elem_type,
1384614124 .@"addrspace" = .generic,
13847 .mutable = inst_data.is_mutable,
13848 .@"allowzero" = inst_data.is_allowzero or inst_data.size == .C,
13849 .@"volatile" = inst_data.is_volatile,
13850 .size = inst_data.size,
14125 .mutable = true,
14126 .@"allowzero" = false,
14127 .@"volatile" = false,
14128 .size = .One,
1385114129 });
13852 try sema.validatePtrTy(block, elem_ty_src, ty);
1385314130 return sema.addType(ty);
1385414131}
1385514132
......@@ -13857,14 +14134,15 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1385714134 const tracy = trace(@src());
1385814135 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
1386614137 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type;
1386714138 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
1386814146 const unresolved_elem_ty = try sema.resolveType(block, elem_ty_src, extra.data.elem_type);
1386914147 const target = sema.mod.getTarget();
1387014148
......@@ -13873,14 +14151,14 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1387314151 const sentinel = if (inst_data.flags.has_sentinel) blk: {
1387414152 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
1387514153 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;
1387714155 } else null;
1387814156
1387914157 const abi_align: u32 = if (inst_data.flags.has_align) blk: {
1388014158 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
1388114159 extra_i += 1;
13882 const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), src);
13883 const val = try sema.resolveConstValue(block, src, coerced);
14160 const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), align_src);
14161 const val = try sema.resolveConstValue(block, align_src, coerced, "pointer alignment must be comptime known");
1388414162 // Check if this happens to be the lazy alignment of our element type, in
1388514163 // which case we can make this 0 without resolving it.
1388614164 if (val.castTag(.lazy_align)) |payload| {
......@@ -13888,8 +14166,9 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1388814166 break :blk 0;
1388914167 }
1389014168 }
13891 const abi_align = (try val.getUnsignedIntAdvanced(target, sema.kit(block, src))).?;
13892 break :blk @intCast(u32, abi_align);
14169 const abi_align = @intCast(u32, (try val.getUnsignedIntAdvanced(target, sema.kit(block, align_src))).?);
14170 try sema.validateAlign(block, align_src, abi_align);
14171 break :blk abi_align;
1389314172 } else 0;
1389414173
1389514174 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
1390114180 const bit_offset = if (inst_data.flags.has_bit_range) blk: {
1390214181 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
1390314182 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");
1390514184 break :blk @intCast(u16, bit_offset);
1390614185 } else 0;
1390714186
1390814187 const host_size: u16 = if (inst_data.flags.has_bit_range) blk: {
1390914188 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
1391014189 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");
1391214191 break :blk @intCast(u16, host_size);
1391314192 } else 0;
1391414193
1391514194 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", .{});
1391714196 }
1391814197
1391914198 const elem_ty = if (abi_align == 0)
......@@ -13923,48 +14202,53 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1392314202 try sema.resolveTypeLayout(block, elem_ty_src, elem_ty);
1392414203 break :t elem_ty;
1392514204 };
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 {
13943 const ptr_info = ty.ptrInfo().data;
13944 const pointee_tag = ptr_info.pointee_type.zigTypeTag();
13945 if (pointee_tag == .NoReturn) {
13946 return sema.fail(block, elem_src, "pointer to noreturn not allowed", .{});
13947 } else if (ptr_info.size == .Many and pointee_tag == .Opaque) {
13948 return sema.fail(block, elem_src, "unknown-length pointer to opaque not allowed", .{});
13949 } else if (ptr_info.size == .C) {
13950 const elem_ty = ptr_info.pointee_type;
14206 if (elem_ty.zigTypeTag() == .NoReturn) {
14207 return sema.fail(block, elem_ty_src, "pointer to noreturn not allowed", .{});
14208 } else if (elem_ty.zigTypeTag() == .Fn) {
14209 if (inst_data.size != .One) {
14210 return sema.fail(block, elem_ty_src, "function pointers must be single pointers", .{});
14211 }
14212 const fn_align = elem_ty.fnInfo().alignment;
14213 if (inst_data.flags.has_align and abi_align != 0 and fn_align != 0 and
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) {
1395114221 if (!(try sema.validateExternType(elem_ty, .other))) {
1395214222 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)});
1395414224 errdefer msg.destroy(sema.gpa);
1395514225
1395614226 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
1395914229 try sema.addDeclaredHereNote(msg, elem_ty);
1396014230 break :msg msg;
1396114231 };
1396214232 return sema.failWithOwnedErrorMsg(block, msg);
1396314233 }
13964 if (pointee_tag == .Opaque) {
13965 return sema.fail(block, elem_src, "C pointers cannot point to opaque types", .{});
14234 if (elem_ty.zigTypeTag() == .Opaque) {
14235 return sema.fail(block, elem_ty_src, "C pointers cannot point to opaque types", .{});
1396614236 }
1396714237 }
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);
1396814252}
1396914253
1397014254fn 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
1401814302 const init_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
1401914303 const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;
1402014304 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");
1402214306 const init = try sema.resolveInst(extra.init);
1402314307 return sema.unionInit(block, init, init_src, union_ty, ty_src, field_name, field_src);
1402414308}
......@@ -14045,7 +14329,7 @@ fn unionInit(
1404514329 }));
1404614330 }
1404714331
14048 try sema.requireRuntimeBlock(block, init_src);
14332 try sema.requireRuntimeBlock(block, init_src, null);
1404914333 _ = union_ty_src;
1405014334 try sema.queueFullTypeResolution(union_ty);
1405114335 return block.addUnionInit(union_ty, field_index, init);
......@@ -14150,7 +14434,7 @@ fn zirStructInit(
1415014434 return alloc;
1415114435 }
1415214436
14153 try sema.requireRuntimeBlock(block, src);
14437 try sema.requireRuntimeBlock(block, src, null);
1415414438 try sema.queueFullTypeResolution(resolved_ty);
1415514439 return block.addUnionInit(resolved_ty, field_index, init_inst);
1415614440 } else if (resolved_ty.isAnonStruct()) {
......@@ -14255,7 +14539,7 @@ fn finishStructInit(
1425514539 return alloc;
1425614540 }
1425714541
14258 try sema.requireRuntimeBlock(block, dest_src);
14542 try sema.requireRuntimeBlock(block, dest_src, null);
1425914543 try sema.queueFullTypeResolution(struct_ty);
1426014544 return block.addAggregateInit(struct_ty, field_inits);
1426114545}
......@@ -14277,13 +14561,23 @@ fn zirStructInitAnon(
1427714561 var runtime_src: ?LazySrcLoc = null;
1427814562 var extra_index = extra.end;
1427914563 for (types) |*field_ty, i| {
14564 const init_src = src; // TODO better source location
1428014565 const item = sema.code.extraData(Zir.Inst.StructInitAnon.Item, extra_index);
1428114566 extra_index = item.end;
1428214567
1428314568 names[i] = sema.code.nullTerminatedString(item.data.field_name);
1428414569 const init = try sema.resolveInst(item.data.init);
1428514570 field_ty.* = sema.typeOf(init);
14286 const init_src = src; // TODO better source location
14571 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 }
1428714581 if (try sema.resolveMaybeUndefVal(block, init_src, init)) |init_val| {
1428814582 values[i] = init_val;
1428914583 } else {
......@@ -14305,7 +14599,7 @@ fn zirStructInitAnon(
1430514599 return sema.addConstantMaybeRef(block, src, tuple_ty, tuple_val, is_ref);
1430614600 };
1430714601
14308 try sema.requireRuntimeBlock(block, runtime_src);
14602 try sema.requireRuntimeBlock(block, src, runtime_src);
1430914603
1431014604 if (is_ref) {
1431114605 const target = sema.mod.getTarget();
......@@ -14397,7 +14691,7 @@ fn zirArrayInit(
1439714691 return sema.addConstantMaybeRef(block, src, array_ty, array_val, is_ref);
1439814692 };
1439914693
14400 try sema.requireRuntimeBlock(block, runtime_src);
14694 try sema.requireRuntimeBlock(block, src, runtime_src);
1440114695 try sema.queueFullTypeResolution(array_ty);
1440214696
1440314697 if (is_ref) {
......@@ -14460,9 +14754,19 @@ fn zirArrayInitAnon(
1446014754 const opt_runtime_src = rs: {
1446114755 var runtime_src: ?LazySrcLoc = null;
1446214756 for (operands) |operand, i| {
14757 const operand_src = src; // TODO better source location
1446314758 const elem = try sema.resolveInst(operand);
1446414759 types[i] = sema.typeOf(elem);
14465 const operand_src = src; // TODO better source location
14760 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 }
1446614770 if (try sema.resolveMaybeUndefVal(block, operand_src, elem)) |val| {
1446714771 values[i] = val;
1446814772 } else {
......@@ -14483,7 +14787,7 @@ fn zirArrayInitAnon(
1448314787 return sema.addConstantMaybeRef(block, src, tuple_ty, tuple_val, is_ref);
1448414788 };
1448514789
14486 try sema.requireRuntimeBlock(block, runtime_src);
14790 try sema.requireRuntimeBlock(block, src, runtime_src);
1448714791
1448814792 if (is_ref) {
1448914793 const target = sema.mod.getTarget();
......@@ -14542,7 +14846,7 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
1454214846 const ty_src = inst_data.src();
1454314847 const field_src = inst_data.src();
1454414848 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");
1454614850 return sema.fieldType(block, aggregate_ty, field_name, field_src, ty_src);
1454714851}
1454814852
......@@ -14732,7 +15036,7 @@ fn zirUnaryMath(
1473215036 );
1473315037 }
1473415038
14735 try sema.requireRuntimeBlock(block, operand_src);
15039 try sema.requireRuntimeBlock(block, operand_src, null);
1473615040 return block.addUnOp(air_tag, operand);
1473715041 },
1473815042 .ComptimeFloat, .Float => {
......@@ -14743,7 +15047,7 @@ fn zirUnaryMath(
1474315047 return sema.addConstant(operand_ty, result_val);
1474415048 }
1474515049
14746 try sema.requireRuntimeBlock(block, operand_src);
15050 try sema.requireRuntimeBlock(block, operand_src, null);
1474715051 return block.addUnOp(air_tag, operand);
1474815052 },
1474915053 else => unreachable,
......@@ -14761,7 +15065,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1476115065 try sema.resolveTypeLayout(block, operand_src, operand_ty);
1476215066 const enum_ty = switch (operand_ty.zigTypeTag()) {
1476315067 .EnumLiteral => {
14764 const val = try sema.resolveConstValue(block, operand_src, operand);
15068 const val = try sema.resolveConstValue(block, .unneeded, operand, undefined);
1476515069 const bytes = val.castTag(.enum_literal).?.data;
1476615070 return sema.addStrLit(block, bytes);
1476715071 },
......@@ -14813,7 +15117,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1481315117 const uncasted_operand = try sema.resolveInst(inst_data.operand);
1481415118 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1481515119 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");
1481715121 const union_val = val.cast(Value.Payload.Union).?.data;
1481815122 const tag_ty = type_info_ty.unionTagType().?;
1481915123 const target = mod.getTarget();
......@@ -15497,10 +15801,10 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1549715801 const result_val = try sema.floatToInt(block, operand_src, val, operand_ty, dest_ty);
1549815802 return sema.addConstant(dest_ty, result_val);
1549915803 } 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");
1550115805 }
1550215806
15503 try sema.requireRuntimeBlock(block, operand_src);
15807 try sema.requireRuntimeBlock(block, inst_data.src(), operand_src);
1550415808 return block.addTyOp(.float_to_int, dest_ty, operand);
1550515809}
1550615810
......@@ -15521,10 +15825,10 @@ fn zirIntToFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1552115825 const result_val = try val.intToFloat(sema.arena, operand_ty, dest_ty, target);
1552215826 return sema.addConstant(dest_ty, result_val);
1552315827 } 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");
1552515829 }
1552615830
15527 try sema.requireRuntimeBlock(block, operand_src);
15831 try sema.requireRuntimeBlock(block, inst_data.src(), operand_src);
1552815832 return block.addTyOp(.int_to_float, dest_ty, operand);
1552915833}
1553015834
......@@ -15560,7 +15864,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1556015864 return sema.addConstant(type_res, Value.initPayload(&val_payload.base));
1556115865 }
1556215866
15563 try sema.requireRuntimeBlock(block, src);
15867 try sema.requireRuntimeBlock(block, src, operand_src);
1556415868 if (block.wantSafety()) {
1556515869 if (!type_res.isAllowzeroPtr()) {
1556615870 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
1565715961 return sema.addConstant(dest_ty, val);
1565815962 }
1565915963
15660 try sema.requireRuntimeBlock(block, src);
15964 try sema.requireRuntimeBlock(block, src, operand_src);
1566115965 if (block.wantSafety() and !dest_ty.isAnyError()) {
1566215966 const err_int_inst = try block.addBitCast(Type.u16, operand);
1566315967 // 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
1581216116 );
1581316117 }
1581416118
15815 try sema.requireRuntimeBlock(block, src);
16119 try sema.requireRuntimeBlock(block, src, operand_src);
1581616120 return block.addTyOp(.trunc, dest_ty, operand);
1581716121}
1581816122
......@@ -15855,6 +16159,7 @@ fn zirBitCount(
1585516159 comptimeOp: fn (val: Value, ty: Type, target: std.Target) u64,
1585616160) CompileError!Air.Inst.Ref {
1585716161 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
16162 const src = inst_data.src();
1585816163 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
1585916164 const operand = try sema.resolveInst(inst_data.operand);
1586016165 const operand_ty = sema.typeOf(operand);
......@@ -15887,7 +16192,7 @@ fn zirBitCount(
1588716192 try Value.Tag.aggregate.create(sema.arena, elems),
1588816193 );
1588916194 } else {
15890 try sema.requireRuntimeBlock(block, operand_src);
16195 try sema.requireRuntimeBlock(block, src, operand_src);
1589116196 return block.addTyOp(air_tag, result_ty, operand);
1589216197 }
1589316198 },
......@@ -15896,7 +16201,7 @@ fn zirBitCount(
1589616201 if (val.isUndef()) return sema.addConstUndef(result_scalar_ty);
1589716202 return sema.addIntUnsigned(result_scalar_ty, comptimeOp(val, operand_ty, target));
1589816203 } else {
15899 try sema.requireRuntimeBlock(block, operand_src);
16204 try sema.requireRuntimeBlock(block, src, operand_src);
1590016205 return block.addTyOp(air_tag, result_scalar_ty, operand);
1590116206 }
1590216207 },
......@@ -15906,6 +16211,7 @@ fn zirBitCount(
1590616211
1590716212fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1590816213 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
16214 const src = inst_data.src();
1590916215 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1591016216 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
1591116217 const operand = try sema.resolveInst(inst_data.operand);
......@@ -15934,7 +16240,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1593416240 return sema.addConstant(operand_ty, result_val);
1593516241 } else operand_src;
1593616242
15937 try sema.requireRuntimeBlock(block, runtime_src);
16243 try sema.requireRuntimeBlock(block, src, runtime_src);
1593816244 return block.addTyOp(.byte_swap, operand_ty, operand);
1593916245 },
1594016246 .Vector => {
......@@ -15955,7 +16261,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1595516261 );
1595616262 } else operand_src;
1595716263
15958 try sema.requireRuntimeBlock(block, runtime_src);
16264 try sema.requireRuntimeBlock(block, src, runtime_src);
1595916265 return block.addTyOp(.byte_swap, operand_ty, operand);
1596016266 },
1596116267 else => unreachable,
......@@ -15964,6 +16270,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1596416270
1596516271fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1596616272 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
16273 const src = inst_data.src();
1596716274 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
1596816275 const operand = try sema.resolveInst(inst_data.operand);
1596916276 const operand_ty = sema.typeOf(operand);
......@@ -15982,7 +16289,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1598216289 return sema.addConstant(operand_ty, result_val);
1598316290 } else operand_src;
1598416291
15985 try sema.requireRuntimeBlock(block, runtime_src);
16292 try sema.requireRuntimeBlock(block, src, runtime_src);
1598616293 return block.addTyOp(.bit_reverse, operand_ty, operand);
1598716294 },
1598816295 .Vector => {
......@@ -16003,7 +16310,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1600316310 );
1600416311 } else operand_src;
1600516312
16006 try sema.requireRuntimeBlock(block, runtime_src);
16313 try sema.requireRuntimeBlock(block, src, runtime_src);
1600716314 return block.addTyOp(.bit_reverse, operand_ty, operand);
1600816315 },
1600916316 else => unreachable,
......@@ -16030,7 +16337,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
1603016337 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
1603116338
1603216339 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");
1603416341 const target = sema.mod.getTarget();
1603516342
1603616343 try sema.resolveTypeLayout(block, lhs_src, ty);
......@@ -16451,19 +16758,19 @@ fn resolveExportOptions(
1645116758 const options = try sema.coerce(block, export_options_ty, air_ref, src);
1645216759
1645316760 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");
1645516762 const name_ty = Type.initTag(.const_slice_u8);
1645616763 const name = try name_val.toAllocatedBytes(name_ty, sema.arena, sema.mod);
1645716764
1645816765 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");
1646016767 const linkage = linkage_val.toEnum(std.builtin.GlobalLinkage);
1646116768
1646216769 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
1646516772 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");
1646716774 const visibility = visibility_val.toEnum(std.builtin.SymbolVisibility);
1646816775
1646916776 if (name.len < 1) {
......@@ -16494,11 +16801,12 @@ fn resolveBuiltinEnum(
1649416801 src: LazySrcLoc,
1649516802 zir_ref: Zir.Inst.Ref,
1649616803 comptime name: []const u8,
16804 reason: []const u8,
1649716805) CompileError!@field(std.builtin, name) {
1649816806 const ty = try sema.getBuiltinType(block, src, name);
1649916807 const air_ref = try sema.resolveInst(zir_ref);
1650016808 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);
1650216810 return val.toEnum(@field(std.builtin, name));
1650316811}
1650416812
......@@ -16507,8 +16815,9 @@ fn resolveAtomicOrder(
1650716815 block: *Block,
1650816816 src: LazySrcLoc,
1650916817 zir_ref: Zir.Inst.Ref,
16818 reason: []const u8,
1651016819) CompileError!std.builtin.AtomicOrder {
16511 return resolveBuiltinEnum(sema, block, src, zir_ref, "AtomicOrder");
16820 return resolveBuiltinEnum(sema, block, src, zir_ref, "AtomicOrder", reason);
1651216821}
1651316822
1651416823fn resolveAtomicRmwOp(
......@@ -16517,7 +16826,7 @@ fn resolveAtomicRmwOp(
1651716826 src: LazySrcLoc,
1651816827 zir_ref: Zir.Inst.Ref,
1651916828) 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");
1652116830}
1652216831
1652316832fn zirCmpxchg(
......@@ -16550,8 +16859,8 @@ fn zirCmpxchg(
1655016859 const uncasted_ptr = try sema.resolveInst(extra.ptr);
1655116860 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false);
1655216861 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);
16554 const failure_order = try sema.resolveAtomicOrder(block, failure_order_src, extra.failure_order);
16862 const success_order = try sema.resolveAtomicOrder(block, success_order_src, extra.success_order, "atomic order of cmpxchg success must be comptime known");
16863 const failure_order = try sema.resolveAtomicOrder(block, failure_order_src, extra.failure_order, "atomic order of cmpxchg failure must be comptime known");
1655516864
1655616865 if (@enumToInt(success_order) < @enumToInt(std.builtin.AtomicOrder.Monotonic)) {
1655716866 return sema.fail(block, success_order_src, "success atomic ordering must be Monotonic or stricter", .{});
......@@ -16596,7 +16905,7 @@ fn zirCmpxchg(
1659616905 const flags: u32 = @as(u32, @enumToInt(success_order)) |
1659716906 (@as(u32, @enumToInt(failure_order)) << 3);
1659816907
16599 try sema.requireRuntimeBlock(block, runtime_src);
16908 try sema.requireRuntimeBlock(block, src, runtime_src);
1660016909 return block.addInst(.{
1660116910 .tag = air_tag,
1660216911 .data = .{ .ty_pl = .{
......@@ -16616,7 +16925,7 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1661616925 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
1661716926 const len_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
1661816927 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"));
1662016929 const scalar = try sema.resolveInst(extra.rhs);
1662116930 const scalar_ty = sema.typeOf(scalar);
1662216931 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
1663316942 );
1663416943 }
1663516944
16636 try sema.requireRuntimeBlock(block, scalar_src);
16945 try sema.requireRuntimeBlock(block, inst_data.src(), scalar_src);
1663716946 return block.addTyOp(.splat, vector_ty, scalar);
1663816947}
1663916948
......@@ -16642,7 +16951,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1664216951 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
1664316952 const op_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1664416953 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");
1664616955 const operand = try sema.resolveInst(extra.rhs);
1664716956 const operand_ty = sema.typeOf(operand);
1664816957 const target = sema.mod.getTarget();
......@@ -16697,7 +17006,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1669717006 return sema.addConstant(scalar_ty, accum);
1669817007 }
1669917008
16700 try sema.requireRuntimeBlock(block, operand_src);
17009 try sema.requireRuntimeBlock(block, inst_data.src(), operand_src);
1670117010 return block.addInst(.{
1670217011 .tag = .reduce,
1670317012 .data = .{ .reduce = .{
......@@ -16729,7 +17038,7 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1672917038 .elem_type = Type.@"i32",
1673017039 });
1673117040 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");
1673317042 return sema.analyzeShuffle(block, inst_data.src_node, elem_ty, a, b, mask_val, @intCast(u32, mask_len));
1673417043}
1673517044
......@@ -16901,6 +17210,7 @@ fn analyzeShuffle(
1690117210fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
1690217211 const extra = sema.code.extraData(Zir.Inst.Select, extended.operand).data;
1690317212
17213 const src = LazySrcLoc.nodeOffset(extra.node);
1690417214 const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
1690517215 const pred_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
1690617216 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
1697217282 break :rs pred_src;
1697317283 };
1697417284
16975 try sema.requireRuntimeBlock(block, runtime_src);
17285 try sema.requireRuntimeBlock(block, src, runtime_src);
1697617286 return block.addInst(.{
1697717287 .tag = .select,
1697817288 .data = .{ .pl_op = .{
......@@ -16996,7 +17306,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1699617306 const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type);
1699717307 const uncasted_ptr = try sema.resolveInst(extra.ptr);
1699817308 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
1700117311 switch (order) {
1700217312 .Release, .AcqRel => {
......@@ -17020,7 +17330,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1702017330 }
1702117331 }
1702217332
17023 try sema.requireRuntimeBlock(block, ptr_src);
17333 try sema.requireRuntimeBlock(block, inst_data.src(), ptr_src);
1702417334 return block.addInst(.{
1702517335 .tag = .atomic_load,
1702617336 .data = .{ .atomic_load = .{
......@@ -17060,7 +17370,7 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1706017370 },
1706117371 else => {},
1706217372 }
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
1706517375 if (order == .Unordered) {
1706617376 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
1710117411
1710217412 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);
1710517415 return block.addInst(.{
1710617416 .tag = .atomic_rmw,
1710717417 .data = .{ .pl_op = .{
......@@ -17128,7 +17438,7 @@ fn zirAtomicStore(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1712817438 const elem_ty = sema.typeOf(operand);
1712917439 const uncasted_ptr = try sema.resolveInst(extra.ptr);
1713017440 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
1713317443 const air_tag: Air.Inst.Tag = switch (order) {
1713417444 .Acquire, .AcqRel => {
......@@ -17200,7 +17510,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1720017510 break :rs mulend1_src;
1720117511 };
1720217512
17203 try sema.requireRuntimeBlock(block, runtime_src);
17513 try sema.requireRuntimeBlock(block, src, runtime_src);
1720417514 return block.addInst(.{
1720517515 .tag = .mul_add,
1720617516 .data = .{ .pl_op = .{
......@@ -17233,10 +17543,10 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1723317543 const coerced_options = try sema.coerce(block, call_options_ty, options, options_src);
1723417544
1723517545 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
1723817548 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
1724117551 if (!stack_val.isNull()) {
1724217552 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
1729717607
1729817608 // Desugar bound functions here
1729917609 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);
1730117611 const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data;
1730217612 func = bound_data.func_inst;
1730317613 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
1732417634 const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
1732517635
1732617636 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");
1732817638 const field_ptr = try sema.resolveInst(extra.field_ptr);
1732917639 const field_ptr_ty = sema.typeOf(field_ptr);
1733017640
......@@ -17389,7 +17699,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
1738917699 return sema.addConstant(result_ptr, payload.data.container_ptr);
1739017700 }
1739117701
17392 try sema.requireRuntimeBlock(block, src);
17702 try sema.requireRuntimeBlock(block, src, ptr_src);
1739317703 return block.addInst(.{
1739417704 .tag = .field_parent_ptr,
1739517705 .data = .{ .ty_pl = .{
......@@ -17470,7 +17780,7 @@ fn analyzeMinMax(
1747017780 break :rs lhs_src;
1747117781 };
1747217782
17473 try sema.requireRuntimeBlock(block, runtime_src);
17783 try sema.requireRuntimeBlock(block, src, runtime_src);
1747417784 return block.addBinOp(air_tag, simd_op.lhs, simd_op.rhs);
1747517785}
1747617786
......@@ -17518,7 +17828,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
1751817828 } else break :rs src_src;
1751917829 } else dest_src;
1752017830
17521 try sema.requireRuntimeBlock(block, runtime_src);
17831 try sema.requireRuntimeBlock(block, src, runtime_src);
1752217832 _ = try block.addInst(.{
1752317833 .tag = .memcpy,
1752417834 .data = .{ .pl_op = .{
......@@ -17560,7 +17870,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
1756017870 } else break :rs len_src;
1756117871 } else dest_src;
1756217872
17563 try sema.requireRuntimeBlock(block, runtime_src);
17873 try sema.requireRuntimeBlock(block, src, runtime_src);
1756417874 _ = try block.addInst(.{
1756517875 .tag = .memset,
1756617876 .data = .{ .pl_op = .{
......@@ -17656,7 +17966,7 @@ fn zirVarExtended(
1765617966 uncasted_init;
1765717967
1765817968 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");
1766017970 } else Value.initTag(.unreachable_value);
1766117971
1766217972 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
1769418004 defer tracy.end();
1769518005
1769618006 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
17697 const src = inst_data.src();
1769818007 const extra = sema.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index);
1769918008 const target = sema.mod.getTarget();
1770018009
17701 const align_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at align
17702 const addrspace_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at addrspace
17703 const section_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at section
18010 const align_src: LazySrcLoc = .{ .node_offset_fn_type_align = inst_data.src_node };
18011 const addrspace_src: LazySrcLoc = .{ .node_offset_fn_type_addrspace = inst_data.src_node };
18012 const section_src: LazySrcLoc = .{ .node_offset_fn_type_section = inst_data.src_node };
1770418013 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 type
18014 const ret_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = inst_data.src_node };
18015 const has_body = extra.data.body_len != 0;
1770618016
1770718017 var extra_index: usize = extra.end;
1770818018
......@@ -17712,17 +18022,25 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1771218022 break :blk lib_name;
1771318023 } 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
1771518032 const @"align": ?u32 = if (extra.data.bits.has_align_body) blk: {
1771618033 const body_len = sema.code.extra[extra_index];
1771718034 extra_index += 1;
1771818035 const body = sema.code.extra[extra_index..][0..body_len];
1771918036 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");
1772218039 if (val.tag() == .generic_poison) {
1772318040 break :blk null;
1772418041 }
1772518042 const alignment = @intCast(u32, val.toUnsignedInt(target));
18043 try sema.validateAlign(block, align_src, alignment);
1772618044 if (alignment == target_util.defaultFunctionAlignment(target)) {
1772718045 break :blk 0;
1772818046 } else {
......@@ -17731,13 +18049,14 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1773118049 } else if (extra.data.bits.has_align_ref) blk: {
1773218050 const align_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
1773318051 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) {
1773518053 error.GenericPoison => {
1773618054 break :blk null;
1773718055 },
1773818056 else => |e| return e,
1773918057 };
1774018058 const alignment = @intCast(u32, align_tv.val.toUnsignedInt(target));
18059 try sema.validateAlign(block, align_src, alignment);
1774118060 if (alignment == target_util.defaultFunctionAlignment(target)) {
1774218061 break :blk 0;
1774318062 } else {
......@@ -17752,7 +18071,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1775218071 extra_index += body.len;
1775318072
1775418073 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");
1775618075 if (val.tag() == .generic_poison) {
1775718076 break :blk null;
1775818077 }
......@@ -17760,7 +18079,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1776018079 } else if (extra.data.bits.has_addrspace_ref) blk: {
1776118080 const addrspace_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
1776218081 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) {
1776418083 error.GenericPoison => {
1776518084 break :blk null;
1776618085 },
......@@ -17775,7 +18094,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1777518094 const body = sema.code.extra[extra_index..][0..body_len];
1777618095 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");
1777918098 if (val.tag() == .generic_poison) {
1778018099 break :blk FuncLinkSection{ .generic = {} };
1778118100 }
......@@ -17784,7 +18103,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1778418103 } else if (extra.data.bits.has_section_ref) blk: {
1778518104 const section_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
1778618105 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) {
1778818107 error.GenericPoison => {
1778918108 break :blk FuncLinkSection{ .generic = {} };
1779018109 },
......@@ -17801,7 +18120,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1780118120 extra_index += body.len;
1780218121
1780318122 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");
1780518124 if (val.tag() == .generic_poison) {
1780618125 break :blk null;
1780718126 }
......@@ -17809,7 +18128,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1780918128 } else if (extra.data.bits.has_cc_ref) blk: {
1781018129 const cc_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
1781118130 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) {
1781318132 error.GenericPoison => {
1781418133 break :blk null;
1781518134 },
......@@ -17824,14 +18143,14 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1782418143 const body = sema.code.extra[extra_index..][0..body_len];
1782518144 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");
1782818147 var buffer: Value.ToTypeBuffer = undefined;
1782918148 const ty = try val.toType(&buffer).copy(sema.arena);
1783018149 break :blk ty;
1783118150 } else if (extra.data.bits.has_ret_ty_ref) blk: {
1783218151 const ret_ty_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
1783318152 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) {
1783518154 error.GenericPoison => {
1783618155 break :blk Type.initTag(.generic_poison);
1783718156 },
......@@ -17849,7 +18168,6 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1784918168 } else 0;
1785018169
1785118170 var src_locs: Zir.Inst.Func.SrcLocs = undefined;
17852 const has_body = extra.data.body_len != 0;
1785318171 if (has_body) {
1785418172 extra_index += extra.data.body_len;
1785518173 src_locs = sema.code.extraData(Zir.Inst.Func.SrcLocs, extra_index).data;
......@@ -17886,7 +18204,7 @@ fn zirCUndef(
1788618204 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
1788718205 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");
1789018208 try block.c_import_buf.?.writer().print("#undefine {s}\n", .{name});
1789118209 return Air.Inst.Ref.void_value;
1789218210}
......@@ -17899,7 +18217,7 @@ fn zirCInclude(
1789918217 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
1790018218 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");
1790318221 try block.c_import_buf.?.writer().print("#include <{s}>\n", .{name});
1790418222 return Air.Inst.Ref.void_value;
1790518223}
......@@ -17913,10 +18231,10 @@ fn zirCDefine(
1791318231 const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
1791418232 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");
1791718235 const rhs = try sema.resolveInst(extra.rhs);
1791818236 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");
1792018238 try block.c_import_buf.?.writer().print("#define {s} {s}\n", .{ name, value });
1792118239 } else {
1792218240 try block.c_import_buf.?.writer().print("#define {s}\n", .{name});
......@@ -17937,8 +18255,8 @@ fn zirWasmMemorySize(
1793718255 return sema.fail(block, builtin_src, "builtin @wasmMemorySize is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});
1793818256 }
1793918257
17940 const index = @intCast(u32, try sema.resolveInt(block, index_src, extra.operand, Type.u32));
17941 try sema.requireRuntimeBlock(block, builtin_src);
18258 const index = @intCast(u32, try sema.resolveInt(block, index_src, extra.operand, Type.u32, "wasm memory size index must be comptime known"));
18259 try sema.requireRuntimeBlock(block, builtin_src, null);
1794218260 return block.addInst(.{
1794318261 .tag = .wasm_memory_size,
1794418262 .data = .{ .pl_op = .{
......@@ -17962,10 +18280,10 @@ fn zirWasmMemoryGrow(
1796218280 return sema.fail(block, builtin_src, "builtin @wasmMemoryGrow is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});
1796318281 }
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"));
1796618284 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);
1796918287 return block.addInst(.{
1797018288 .tag = .wasm_memory_grow,
1797118289 .data = .{ .pl_op = .{
......@@ -17990,15 +18308,15 @@ fn zirPrefetch(
1799018308 const target = sema.mod.getTarget();
1799118309
1799218310 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");
1799418312 const rw_tag = rw_val.toEnum(std.builtin.PrefetchOptions.Rw);
1799518313
1799618314 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");
1799818316 const locality_int = @intCast(u2, locality_val.toUnsignedInt(target));
1799918317
1800018318 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");
1800218320 const cache_tag = cache_val.toEnum(std.builtin.PrefetchOptions.Cache);
1800318321
1800418322 if (!block.is_comptime) {
......@@ -18035,16 +18353,16 @@ fn zirBuiltinExtern(
1803518353 const options = try sema.coerce(block, extern_options_ty, options_inst, options_src);
1803618354
1803718355 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
1804018358 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
1804318361 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
1804618364 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
1804918367 var library_name: ?[]const u8 = null;
1805018368 if (!library_name_val.isNull()) {
......@@ -18121,19 +18439,30 @@ fn zirBuiltinExtern(
1812118439 new_decl.value_arena = arena_state;
1812218440
1812318441 const ref = try sema.analyzeDeclRef(new_decl_index);
18124 try sema.requireRuntimeBlock(block, src);
18442 try sema.requireRuntimeBlock(block, src, null);
1812518443 return block.addBitCast(ty, ref);
1812618444}
1812718445
18446/// Asserts that the block is not comptime.
1812818447fn requireFunctionBlock(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
18448 assert(!block.is_comptime);
1812918449 if (sema.func == null and !block.is_typeof and !block.is_coerce_result_ptr) {
1813018450 return sema.fail(block, src, "instruction illegal outside function body", .{});
1813118451 }
1813218452}
1813318453
18134fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
18454fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc, runtime_src: ?LazySrcLoc) !void {
1813518455 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);
1813718466 }
1813818467 try sema.requireFunctionBlock(block, src);
1813918468}
......@@ -18337,6 +18666,8 @@ const ExternPosition = enum {
1833718666 other,
1833818667};
1833918668
18669/// Returns true if `ty` is allowed in extern types.
18670/// Does *NOT* require `ty` to be resolved in any way.
1834018671fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileError!bool {
1834118672 switch (ty.zigTypeTag()) {
1834218673 .Type,
......@@ -18350,7 +18681,7 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr
1835018681 .BoundFn,
1835118682 .Frame,
1835218683 => return false,
18353 .Void => return position == .union_field,
18684 .Void => return position == .union_field or position == .ret_ty,
1835418685 .NoReturn => return position == .ret_ty,
1835518686 .Opaque,
1835618687 .Bool,
......@@ -18362,7 +18693,7 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr
1836218693 8, 16, 32, 64, 128 => return true,
1836318694 else => return false,
1836418695 },
18365 .Fn => return !ty.fnCallingConventionAllowsZigTypes(),
18696 .Fn => return !Type.fnCallingConventionAllowsZigTypes(ty.fnCallingConvention()),
1836618697 .Enum => {
1836718698 var buf: Type.Payload.Bits = undefined;
1836818699 return sema.validateExternType(ty.intTagType(&buf), position);
......@@ -18433,9 +18764,9 @@ fn explainWhyTypeIsNotExtern(
1843318764 .Union => try mod.errNoteNonLazy(src_loc, msg, "only unions with packed or extern layout are extern compatible", .{}),
1843418765 .Array => {
1843518766 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", .{});
1843718768 } 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", .{});
1843918770 }
1844018771 try sema.explainWhyTypeIsNotExtern(block, src, msg, src_loc, ty.elemType2(), position);
1844118772 },
......@@ -18972,7 +19303,7 @@ fn fieldPtr(
1897219303 }),
1897319304 );
1897419305 }
18975 try sema.requireRuntimeBlock(block, src);
19306 try sema.requireRuntimeBlock(block, src, null);
1897619307
1897719308 return block.addTyOp(.ptr_slice_ptr_ptr, result_ty, inner_ptr);
1897819309 } else if (mem.eql(u8, field_name, "len")) {
......@@ -18992,7 +19323,7 @@ fn fieldPtr(
1899219323 }),
1899319324 );
1899419325 }
18995 try sema.requireRuntimeBlock(block, src);
19326 try sema.requireRuntimeBlock(block, src, null);
1899619327
1899719328 return block.addTyOp(.ptr_slice_len_ptr, result_ty, inner_ptr);
1899819329 } else {
......@@ -19005,7 +19336,7 @@ fn fieldPtr(
1900519336 }
1900619337 },
1900719338 .Type => {
19008 _ = try sema.resolveConstValue(block, object_ptr_src, object_ptr);
19339 _ = try sema.resolveConstValue(block, .unneeded, object_ptr, undefined);
1900919340 const result = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src);
1901019341 const inner = if (is_pointer_to)
1901119342 try sema.analyzeLoad(block, src, result, object_ptr_src)
......@@ -19238,7 +19569,7 @@ fn finishFieldCallBind(
1923819569 return sema.analyzeLoad(block, src, pointer, src);
1923919570 }
1924019571
19241 try sema.requireRuntimeBlock(block, src);
19572 try sema.requireRuntimeBlock(block, src, null);
1924219573 const ptr_inst = try block.addStructFieldPtr(object_ptr, field_index, ptr_field_ty);
1924319574 return sema.analyzeLoad(block, src, ptr_inst, src);
1924419575}
......@@ -19425,7 +19756,7 @@ fn structFieldPtrByIndex(
1942519756 );
1942619757 }
1942719758
19428 try sema.requireRuntimeBlock(block, src);
19759 try sema.requireRuntimeBlock(block, src, null);
1942919760 return block.addStructFieldPtr(struct_ptr, field_index, ptr_field_ty);
1943019761}
1943119762
......@@ -19469,7 +19800,7 @@ fn structFieldVal(
1946919800 return sema.addConstant(field.ty, field_values[field_index]);
1947019801 }
1947119802
19472 try sema.requireRuntimeBlock(block, src);
19803 try sema.requireRuntimeBlock(block, src, null);
1947319804 return block.addStructFieldVal(struct_byval, field_index, field.ty);
1947419805 },
1947519806 else => unreachable,
......@@ -19533,7 +19864,7 @@ fn tupleFieldValByIndex(
1953319864 return sema.addConstant(field_ty, field_values[field_index]);
1953419865 }
1953519866
19536 try sema.requireRuntimeBlock(block, src);
19867 try sema.requireRuntimeBlock(block, src, null);
1953719868 return block.addStructFieldVal(tuple_byval, field_index, field_ty);
1953819869}
1953919870
......@@ -19597,7 +19928,7 @@ fn unionFieldPtr(
1959719928 );
1959819929 }
1959919930
19600 try sema.requireRuntimeBlock(block, src);
19931 try sema.requireRuntimeBlock(block, src, null);
1960119932 return block.addStructFieldPtr(union_ptr, field_index, ptr_field_ty);
1960219933}
1960319934
......@@ -19655,7 +19986,7 @@ fn unionFieldVal(
1965519986 }
1965619987 }
1965719988
19658 try sema.requireRuntimeBlock(block, src);
19989 try sema.requireRuntimeBlock(block, src, null);
1965919990 return block.addStructFieldVal(union_byval, field_index, field.ty);
1966019991}
1966119992
......@@ -19684,7 +20015,7 @@ fn elemPtr(
1968420015 // In all below cases, we have to deref the ptr operand to get the actual indexable pointer.
1968520016 const indexable = try sema.analyzeLoad(block, indexable_ptr_src, indexable_ptr, indexable_ptr_src);
1968620017 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),
1968820019 .Many, .C => {
1968920020 const maybe_ptr_val = try sema.resolveDefinedValue(block, indexable_ptr_src, indexable);
1969020021 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
......@@ -19698,19 +20029,19 @@ fn elemPtr(
1969820029 };
1969920030 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);
1970220033 return block.addPtrElemPtr(indexable, elem_index, result_ty);
1970320034 },
1970420035 .One => {
1970520036 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);
1970720038 },
1970820039 }
1970920040 },
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),
1971120042 .Struct => {
1971220043 // 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");
1971420045 const index = @intCast(u32, index_val.toUnsignedInt(target));
1971520046 return sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index);
1971620047 },
......@@ -19740,7 +20071,7 @@ fn elemVal(
1974020071
1974120072 switch (indexable_ty.zigTypeTag()) {
1974220073 .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),
1974420075 .Many, .C => {
1974520076 const maybe_indexable_val = try sema.resolveDefinedValue(block, indexable_src, indexable);
1974620077 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
......@@ -19756,7 +20087,7 @@ fn elemVal(
1975620087 break :rs indexable_src;
1975720088 };
1975820089
19759 try sema.requireRuntimeBlock(block, runtime_src);
20090 try sema.requireRuntimeBlock(block, src, runtime_src);
1976020091 return block.addBinOp(.ptr_elem_val, indexable, elem_index);
1976120092 },
1976220093 .One => {
......@@ -19765,14 +20096,14 @@ fn elemVal(
1976520096 return sema.analyzeLoad(block, indexable_src, elem_ptr, elem_index_src);
1976620097 },
1976720098 },
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),
1976920100 .Vector => {
1977020101 // 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);
1977220103 },
1977320104 .Struct => {
1977420105 // 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");
1977620107 const index = @intCast(u32, index_val.toUnsignedInt(target));
1977720108 return tupleField(sema, block, indexable_src, indexable, elem_index_src, index);
1977820109 },
......@@ -19850,7 +20181,7 @@ fn tupleFieldPtr(
1985020181
1985120182 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);
1985420185 return block.addStructFieldPtr(tuple_ptr, field_index, ptr_field_ty);
1985520186}
1985620187
......@@ -19890,13 +20221,14 @@ fn tupleField(
1989020221
1989120222 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);
1989420225 return block.addStructFieldVal(tuple, field_index, field_ty);
1989520226}
1989620227
1989720228fn elemValArray(
1989820229 sema: *Sema,
1989920230 block: *Block,
20231 src: LazySrcLoc,
1990020232 array_src: LazySrcLoc,
1990120233 array: Air.Inst.Ref,
1990220234 elem_index_src: LazySrcLoc,
......@@ -19943,7 +20275,7 @@ fn elemValArray(
1994320275 try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ty, array_ty, array_src);
1994420276
1994520277 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);
1994720279 if (block.wantSafety()) {
1994820280 // Runtime check is only needed if unable to comptime check
1994920281 if (maybe_index_val == null) {
......@@ -19958,6 +20290,7 @@ fn elemValArray(
1995820290fn elemPtrArray(
1995920291 sema: *Sema,
1996020292 block: *Block,
20293 src: LazySrcLoc,
1996120294 array_ptr_src: LazySrcLoc,
1996220295 array_ptr: Air.Inst.Ref,
1996320296 elem_index_src: LazySrcLoc,
......@@ -20003,7 +20336,7 @@ fn elemPtrArray(
2000320336 }
2000420337
2000520338 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
2000820341 // Runtime check is only needed if unable to comptime check.
2000920342 if (block.wantSafety() and offset == null) {
......@@ -20018,6 +20351,7 @@ fn elemPtrArray(
2001820351fn elemValSlice(
2001920352 sema: *Sema,
2002020353 block: *Block,
20354 src: LazySrcLoc,
2002120355 slice_src: LazySrcLoc,
2002220356 slice: Air.Inst.Ref,
2002320357 elem_index_src: LazySrcLoc,
......@@ -20057,7 +20391,7 @@ fn elemValSlice(
2005720391
2005820392 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);
2006120395 if (block.wantSafety()) {
2006220396 const len_inst = if (maybe_slice_val) |slice_val|
2006320397 try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(sema.mod))
......@@ -20073,6 +20407,7 @@ fn elemValSlice(
2007320407fn elemPtrSlice(
2007420408 sema: *Sema,
2007520409 block: *Block,
20410 src: LazySrcLoc,
2007620411 slice_src: LazySrcLoc,
2007720412 slice: Air.Inst.Ref,
2007820413 elem_index_src: LazySrcLoc,
......@@ -20113,7 +20448,7 @@ fn elemPtrSlice(
2011320448 try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ptr_ty, slice_ty, slice_src);
2011420449
2011520450 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);
2011720452 if (block.wantSafety()) {
2011820453 const len_inst = len: {
2011920454 if (maybe_undef_slice_val) |slice_val|
......@@ -20177,7 +20512,7 @@ fn coerceExtra(
2017720512 // Keep the comptime Value representation; take the new type.
2017820513 return sema.addConstant(dest_ty, val);
2017920514 }
20180 try sema.requireRuntimeBlock(block, inst_src);
20515 try sema.requireRuntimeBlock(block, inst_src, null);
2018120516 return block.addBitCast(dest_ty, inst);
2018220517 }
2018320518
......@@ -20222,7 +20557,7 @@ fn coerceExtra(
2022220557
2022320558 // Function body to function pointer.
2022420559 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);
2022620561 const fn_decl = fn_val.castTag(.function).?.data.owner_decl;
2022720562 const inst_as_ptr = try sema.analyzeDeclRef(fn_decl);
2022820563 return sema.coerce(block, dest_ty, inst_as_ptr, inst_src);
......@@ -20489,7 +20824,7 @@ fn coerceExtra(
2048920824 // small enough unsigned ints can get casted to large enough signed ints
2049020825 (dst_info.signedness == .signed and dst_info.bits > src_info.bits))
2049120826 {
20492 try sema.requireRuntimeBlock(block, inst_src);
20827 try sema.requireRuntimeBlock(block, inst_src, null);
2049320828 return block.addTyOp(.intcast, dest_ty, inst);
2049420829 }
2049520830 },
......@@ -20500,7 +20835,7 @@ fn coerceExtra(
2050020835 },
2050120836 .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag()) {
2050220837 .ComptimeFloat => {
20503 const val = try sema.resolveConstValue(block, inst_src, inst);
20838 const val = try sema.resolveConstValue(block, .unneeded, inst, undefined);
2050420839 const result_val = try val.floatCast(sema.arena, dest_ty, target);
2050520840 return try sema.addConstant(dest_ty, result_val);
2050620841 },
......@@ -20516,13 +20851,15 @@ fn coerceExtra(
2051620851 );
2051720852 }
2051820853 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");
2051920856 }
2052020857
2052120858 // float widening
2052220859 const src_bits = inst_ty.floatBits(target);
2052320860 const dst_bits = dest_ty.floatBits(target);
2052420861 if (dst_bits >= src_bits) {
20525 try sema.requireRuntimeBlock(block, inst_src);
20862 try sema.requireRuntimeBlock(block, inst_src, null);
2052620863 return block.addTyOp(.fpext, dest_ty, inst);
2052720864 }
2052820865 },
......@@ -20549,7 +20886,7 @@ fn coerceExtra(
2054920886 .Enum => switch (inst_ty.zigTypeTag()) {
2055020887 .EnumLiteral => {
2055120888 // enum literal to enum
20552 const val = try sema.resolveConstValue(block, inst_src, inst);
20889 const val = try sema.resolveConstValue(block, .unneeded, inst, undefined);
2055320890 const bytes = val.castTag(.enum_literal).?.data;
2055420891 const field_index = dest_ty.enumFieldIndex(bytes) orelse {
2055520892 const msg = msg: {
......@@ -20956,17 +21293,17 @@ const InMemoryCoercionResult = union(enum) {
2095621293 }
2095721294 }
2095821295 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});
2096021297 } 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});
2096221299 }
2096321300 break;
2096421301 },
2096521302 .fn_param_comptime => |param| {
2096621303 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});
2096821305 } 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});
2097021307 }
2097121308 break;
2097221309 },
......@@ -21712,7 +22049,12 @@ fn storePtr2(
2171222049 return;
2171322050 }
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);
2171622058 try sema.queueFullTypeResolution(elem_ty);
2171722059 if (is_ret) {
2171822060 _ = try block.addBinOp(.store, ptr, operand);
......@@ -22644,7 +22986,7 @@ fn bitCast(
2264422986 const result_val = try sema.bitCastVal(block, inst_src, val, old_ty, dest_ty, 0);
2264522987 return sema.addConstant(dest_ty, result_val);
2264622988 }
22647 try sema.requireRuntimeBlock(block, inst_src);
22989 try sema.requireRuntimeBlock(block, inst_src, null);
2264822990 return block.addBitCast(dest_ty, inst);
2264922991}
2265022992
......@@ -22727,7 +23069,7 @@ fn coerceArrayPtrToSlice(
2272723069 });
2272823070 return sema.addConstant(dest_ty, slice_val);
2272923071 }
22730 try sema.requireRuntimeBlock(block, inst_src);
23072 try sema.requireRuntimeBlock(block, inst_src, null);
2273123073 return block.addTyOp(.array_to_slice, dest_ty, inst);
2273223074}
2273323075
......@@ -22743,7 +23085,7 @@ fn coerceCompatiblePtrs(
2274323085 // The comptime Value representation is compatible with both types.
2274423086 return sema.addConstant(dest_ty, val);
2274523087 }
22746 try sema.requireRuntimeBlock(block, inst_src);
23088 try sema.requireRuntimeBlock(block, inst_src, null);
2274723089 return sema.bitCast(block, dest_ty, inst, inst_src);
2274823090}
2274923091
......@@ -22807,7 +23149,7 @@ fn coerceEnumToUnion(
2280723149 }));
2280823150 }
2280923151
22810 try sema.requireRuntimeBlock(block, inst_src);
23152 try sema.requireRuntimeBlock(block, inst_src, null);
2281123153
2281223154 if (tag_ty.isNonexhaustiveEnum()) {
2281323155 const msg = msg: {
......@@ -22947,7 +23289,7 @@ fn coerceArrayLike(
2294723289 // These types share the same comptime value representation.
2294823290 return sema.addConstant(dest_ty, inst_val);
2294923291 }
22950 try sema.requireRuntimeBlock(block, inst_src);
23292 try sema.requireRuntimeBlock(block, inst_src, null);
2295123293 return block.addBitCast(dest_ty, inst);
2295223294 }
2295323295
......@@ -22960,8 +23302,9 @@ fn coerceArrayLike(
2296023302 Type.usize,
2296123303 try Value.Tag.int_u64.create(sema.arena, i),
2296223304 );
23305 const src = inst_src; // TODO better source location
2296323306 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);
2296523308 const coerced = try sema.coerce(block, dest_elem_ty, elem_ref, elem_src);
2296623309 element_refs[i] = coerced;
2296723310 if (runtime_src == null) {
......@@ -22974,7 +23317,7 @@ fn coerceArrayLike(
2297423317 }
2297523318
2297623319 if (runtime_src) |rs| {
22977 try sema.requireRuntimeBlock(block, rs);
23320 try sema.requireRuntimeBlock(block, inst_src, rs);
2297823321 return block.addAggregateInit(dest_ty, element_refs);
2297923322 }
2298023323
......@@ -23037,7 +23380,7 @@ fn coerceTupleToArray(
2303723380 }
2303823381
2303923382 if (runtime_src) |rs| {
23040 try sema.requireRuntimeBlock(block, rs);
23383 try sema.requireRuntimeBlock(block, inst_src, rs);
2304123384 return block.addAggregateInit(dest_ty, element_refs);
2304223385 }
2304323386
......@@ -23168,7 +23511,7 @@ fn coerceTupleToStruct(
2316823511 }
2316923512
2317023513 if (runtime_src) |rs| {
23171 try sema.requireRuntimeBlock(block, rs);
23514 try sema.requireRuntimeBlock(block, inst_src, rs);
2317223515 return block.addAggregateInit(struct_ty, field_refs);
2317323516 }
2317423517
......@@ -23282,7 +23625,7 @@ fn analyzeRef(
2328223625 ));
2328323626 }
2328423627
23285 try sema.requireRuntimeBlock(block, src);
23628 try sema.requireRuntimeBlock(block, src, null);
2328623629 const address_space = target_util.defaultAddressSpace(sema.mod.getTarget(), .local);
2328723630 const ptr_type = try Type.ptr(sema.arena, sema.mod, .{
2328823631 .pointee_type = operand_ty,
......@@ -23326,10 +23669,12 @@ fn analyzeLoad(
2332623669 }
2332723670 }
2332823671
23329 const valid_rt = try sema.validateRunTimeType(block, src, elem_ty, false);
23330 if (!valid_rt) return sema.failWithNeededComptime(block, src);
23672 if (block.is_comptime) {
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);
2333323678 return block.addTyOp(.load, elem_ty, ptr);
2333423679}
2333523680
......@@ -23346,7 +23691,7 @@ fn analyzeSlicePtr(
2334623691 if (val.isUndef()) return sema.addConstUndef(result_ty);
2334723692 return sema.addConstant(result_ty, val.slicePtr());
2334823693 }
23349 try sema.requireRuntimeBlock(block, slice_src);
23694 try sema.requireRuntimeBlock(block, slice_src, null);
2335023695 return block.addTyOp(.slice_ptr, result_ty, slice);
2335123696}
2335223697
......@@ -23362,7 +23707,7 @@ fn analyzeSliceLen(
2336223707 }
2336323708 return sema.addIntUnsigned(Type.usize, slice_val.sliceLen(sema.mod));
2336423709 }
23365 try sema.requireRuntimeBlock(block, src);
23710 try sema.requireRuntimeBlock(block, src, null);
2336623711 return block.addTyOp(.slice_len, Type.usize, slice_inst);
2336723712}
2336823713
......@@ -23386,7 +23731,7 @@ fn analyzeIsNull(
2338623731 return Air.Inst.Ref.bool_false;
2338723732 }
2338823733 }
23389 try sema.requireRuntimeBlock(block, src);
23734 try sema.requireRuntimeBlock(block, src, null);
2339023735 const air_tag: Air.Inst.Tag = if (invert_logic) .is_non_null else .is_null;
2339123736 return block.addUnOp(air_tag, operand);
2339223737}
......@@ -23476,7 +23821,7 @@ fn analyzeIsNonErr(
2347623821) CompileError!Air.Inst.Ref {
2347723822 const result = try sema.analyzeIsNonErrComptimeOnly(block, src, operand);
2347823823 if (result == .none) {
23479 try sema.requireRuntimeBlock(block, src);
23824 try sema.requireRuntimeBlock(block, src, null);
2348023825 return block.addUnOp(.is_non_err, operand);
2348123826 } else {
2348223827 return result;
......@@ -23661,7 +24006,7 @@ fn analyzeSlice(
2366124006 const sentinel = s: {
2366224007 if (sentinel_opt != .none) {
2366324008 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");
2366524010 }
2366624011 // If we are slicing to the end of something that is sentinel-terminated
2366724012 // then the resulting slice type is also sentinel-terminated.
......@@ -23738,7 +24083,14 @@ fn analyzeSlice(
2373824083 .size = .Slice,
2373924084 });
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);
2374224094 if (block.wantSafety()) {
2374324095 // requirement: slicing C ptr is non-null
2374424096 if (ptr_ptr_child_ty.isCPtr()) {
......@@ -23846,7 +24198,7 @@ fn cmpNumeric(
2384624198 // a full resolution of their value, for example `@sizeOf(@Frame(function))` is known to
2384724199 // always be nonzero, and we benefit from not forcing the full evaluation and stack frame layout
2384824200 // 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
2385124203 // For floats, emit a float comparison instruction.
2385224204 const lhs_is_float = switch (lhs_ty_tag) {
......@@ -24034,7 +24386,7 @@ fn cmpVector(
2403424386 }
2403524387 };
2403624388
24037 try sema.requireRuntimeBlock(block, runtime_src);
24389 try sema.requireRuntimeBlock(block, src, runtime_src);
2403824390 const result_ty_inst = try sema.addType(result_ty);
2403924391 return block.addCmpVector(lhs, rhs, op, result_ty_inst);
2404024392}
......@@ -24050,7 +24402,7 @@ fn wrapOptional(
2405024402 return sema.addConstant(dest_ty, try Value.Tag.opt_payload.create(sema.arena, val));
2405124403 }
2405224404
24053 try sema.requireRuntimeBlock(block, inst_src);
24405 try sema.requireRuntimeBlock(block, inst_src, null);
2405424406 return block.addTyOp(.wrap_optional, dest_ty, inst);
2405524407}
2405624408
......@@ -24066,7 +24418,7 @@ fn wrapErrorUnionPayload(
2406624418 if (try sema.resolveMaybeUndefVal(block, inst_src, coerced)) |val| {
2406724419 return sema.addConstant(dest_ty, try Value.Tag.eu_payload.create(sema.arena, val));
2406824420 }
24069 try sema.requireRuntimeBlock(block, inst_src);
24421 try sema.requireRuntimeBlock(block, inst_src, null);
2407024422 try sema.queueFullTypeResolution(dest_payload_ty);
2407124423 return block.addTyOp(.wrap_errunion_payload, dest_ty, coerced);
2407224424}
......@@ -24122,7 +24474,7 @@ fn wrapErrorUnionSet(
2412224474 return sema.addConstant(dest_ty, val);
2412324475 }
2412424476
24125 try sema.requireRuntimeBlock(block, inst_src);
24477 try sema.requireRuntimeBlock(block, inst_src, null);
2412624478 const coerced = try sema.coerce(block, dest_err_set_ty, inst, inst_src);
2412724479 return block.addTyOp(.wrap_errunion_err, dest_ty, coerced);
2412824480}
......@@ -24140,7 +24492,7 @@ fn unionToTag(
2414024492 if (try sema.resolveMaybeUndefVal(block, un_src, un)) |un_val| {
2414124493 return sema.addConstant(enum_ty, un_val.unionTag());
2414224494 }
24143 try sema.requireRuntimeBlock(block, un_src);
24495 try sema.requireRuntimeBlock(block, un_src, null);
2414424496 return block.addTyOp(.get_union_tag, enum_ty, un);
2414524497}
2414624498
......@@ -24889,20 +25241,6 @@ fn resolveStructFully(
2488925241 struct_obj.status = .fully_resolved_wip;
2489025242 for (struct_obj.fields.values()) |field| {
2489125243 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 }
2490625244 }
2490725245 struct_obj.status = .fully_resolved;
2490825246 }
......@@ -24936,20 +25274,6 @@ fn resolveUnionFully(
2493625274 union_obj.status = .fully_resolved_wip;
2493725275 for (union_obj.fields.values()) |field| {
2493825276 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 }
2495325277 }
2495425278 union_obj.status = .fully_resolved;
2495525279 }
......@@ -25033,7 +25357,7 @@ fn resolveTypeFieldsUnion(
2503325357 }
2503425358
2503525359 union_obj.status = .field_types_wip;
25036 try semaUnionFields(block, sema.mod, union_obj);
25360 try semaUnionFields(sema.mod, union_obj);
2503725361 union_obj.status = .have_field_types;
2503825362}
2503925363
......@@ -25287,6 +25611,33 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
2528725611 const field = &struct_obj.fields.values()[i];
2528825612 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
2529025641 if (zir_field.align_body_len > 0) {
2529125642 const body = zir.extra[extra_index..][0..zir_field.align_body_len];
2529225643 extra_index += body.len;
......@@ -25311,7 +25662,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
2531125662 const field = &struct_obj.fields.values()[i];
2531225663 const coerced = try sema.coerce(&block_scope, field.ty, init, src);
2531325664 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");
2531525666 field.default_val = try default_val.copy(decl_arena_allocator);
2531625667 }
2531725668 }
......@@ -25320,7 +25671,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
2532025671 struct_obj.have_field_inits = true;
2532125672}
2532225673
25323fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) CompileError!void {
25674fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
2532425675 const tracy = trace(@src());
2532525676 defer tracy.end();
2532625677
......@@ -25425,10 +25776,14 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
2542525776 var enum_value_map: ?*Module.EnumNumbered.ValueMap = null;
2542625777 var tag_ty_field_names: ?Module.EnumFull.NameMap = null;
2542725778 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);
2542925781 if (small.auto_enum_tag) {
2543025782 // The provided type is an integer type and we must construct the enum tag type here.
2543125783 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 }
2543225787 union_obj.tag_ty = try sema.generateUnionTagTypeNumbered(&block_scope, fields_len, provided_ty, union_obj);
2543325788 const enum_obj = union_obj.tag_ty.castTag(.enum_numbered).?.data;
2543425789 enum_field_names = &enum_obj.fields;
......@@ -25437,8 +25792,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
2543725792 // The provided type is the enum tag type.
2543825793 union_obj.tag_ty = try provided_ty.copy(decl_arena_allocator);
2543925794 if (union_obj.tag_ty.zigTypeTag() != .Enum) {
25440 const tag_ty_src = src; // TODO better source location
25441 return sema.fail(block, tag_ty_src, "expected enum tag type, found '{}'", .{union_obj.tag_ty.fmt(sema.mod)});
25795 return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{union_obj.tag_ty.fmt(sema.mod)});
2544225796 }
2544325797 // The fields of the union must match the enum exactly.
2544425798 // 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
2550425858 if (tag_ref != .none) {
2550525859 const tag_src = src; // TODO better source location
2550625860 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");
2550825862 last_tag_val = val;
2550925863
2551025864 // 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
2551625870 });
2551725871 } else {
2551825872 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)
2552025874 else
2552125875 Value.zero;
2552225876 last_tag_val = val;
......@@ -25570,15 +25924,44 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
2557025924 const enum_has_field = names.orderedRemove(field_name);
2557125925 if (!enum_has_field) {
2557225926 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 });
2557425930 errdefer msg.destroy(sema.gpa);
2557525931 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
2557625932 break :msg msg;
2557725933 };
25578 return sema.failWithOwnedErrorMsg(block, msg);
25934 return sema.failWithOwnedErrorMsg(&block_scope, msg);
2557925935 }
2558025936 }
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
2558225965 gop.value_ptr.* = .{
2558325966 .ty = try field_ty.copy(decl_arena_allocator),
2558425967 .abi_align = 0,
......@@ -25597,18 +25980,18 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
2559725980 if (tag_ty_field_names) |names| {
2559825981 if (names.count() > 0) {
2559925982 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", .{});
2560125984 errdefer msg.destroy(sema.gpa);
2560225985
2560325986 const enum_ty = union_obj.tag_ty;
2560425987 for (names.keys()) |field_name| {
2560525988 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});
2560725990 }
2560825991 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
2560925992 break :msg msg;
2561025993 };
25611 return sema.failWithOwnedErrorMsg(block, msg);
25994 return sema.failWithOwnedErrorMsg(&block_scope, msg);
2561225995 }
2561325996 }
2561425997}
......@@ -26247,7 +26630,7 @@ pub fn analyzeAddrspace(
2624726630 zir_ref: Zir.Inst.Ref,
2624826631 ctx: AddressSpaceContext,
2624926632) !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");
2625126634 const address_space = addrspace_tv.val.toEnum(std.builtin.AddressSpace);
2625226635 const target = sema.mod.getTarget();
2625326636 const arch = target.cpu.arch;
src/Zir.zig+7-14
......@@ -534,9 +534,9 @@ pub const Inst = struct {
534534 /// Obtains the return type of the in-scope function.
535535 /// Uses the `node` union field.
536536 ret_type,
537 /// Create a pointer type that does not have a sentinel, alignment, address space, or bit range specified.
538 /// Uses the `ptr_type_simple` union field.
539 ptr_type_simple,
537 /// Create a pointer type for overflow arithmetic.
538 /// TODO remove when doing https://github.com/ziglang/zig/issues/10248
539 overflow_arithmetic_ptr,
540540 /// Create a pointer type which can have a sentinel, alignment, address space, and/or bit range.
541541 /// Uses the `ptr_type` union field.
542542 ptr_type,
......@@ -1121,7 +1121,7 @@ pub const Inst = struct {
11211121 .err_union_code,
11221122 .err_union_code_ptr,
11231123 .ptr_type,
1124 .ptr_type_simple,
1124 .overflow_arithmetic_ptr,
11251125 .ensure_err_payload_void,
11261126 .enum_literal,
11271127 .merge_error_sets,
......@@ -1417,7 +1417,7 @@ pub const Inst = struct {
14171417 .err_union_code,
14181418 .err_union_code_ptr,
14191419 .ptr_type,
1420 .ptr_type_simple,
1420 .overflow_arithmetic_ptr,
14211421 .enum_literal,
14221422 .merge_error_sets,
14231423 .error_union_type,
......@@ -1659,7 +1659,7 @@ pub const Inst = struct {
16591659 .ret_err_value_code = .str_tok,
16601660 .ret_ptr = .node,
16611661 .ret_type = .node,
1662 .ptr_type_simple = .ptr_type_simple,
1662 .overflow_arithmetic_ptr = .un_node,
16631663 .ptr_type = .ptr_type,
16641664 .slice_start = .pl_node,
16651665 .slice_end = .pl_node,
......@@ -2499,13 +2499,6 @@ pub const Inst = struct {
24992499 node: i32,
25002500 int: u64,
25012501 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 },
25092502 ptr_type: struct {
25102503 flags: packed struct {
25112504 is_allowzero: bool,
......@@ -2608,7 +2601,6 @@ pub const Inst = struct {
26082601 node,
26092602 int,
26102603 float,
2611 ptr_type_simple,
26122604 ptr_type,
26132605 int_type,
26142606 bool_br,
......@@ -2869,6 +2861,7 @@ pub const Inst = struct {
28692861 /// 4. host_size: Ref // if `has_bit_range` flag is set
28702862 pub const PtrType = struct {
28712863 elem_type: Ref,
2864 src_node: i32,
28722865 };
28732866
28742867 pub const ArrayTypeSentinel = struct {
src/print_zir.zig+3-20
......@@ -233,6 +233,7 @@ const Writer = struct {
233233 .validate_struct_init_ty,
234234 .make_ptr_const,
235235 .validate_deref,
236 .overflow_arithmetic_ptr,
236237 => try self.writeUnNode(stream, inst),
237238
238239 .ref,
......@@ -247,7 +248,6 @@ const Writer = struct {
247248
248249 .array_type_sentinel => try self.writeArrayTypeSentinel(stream, inst),
249250 .param_type => try self.writeParamType(stream, inst),
250 .ptr_type_simple => try self.writePtrTypeSimple(stream, inst),
251251 .ptr_type => try self.writePtrType(stream, inst),
252252 .int => try self.writeInt(stream, inst),
253253 .int_big => try self.writeIntBig(stream, inst),
......@@ -601,24 +601,6 @@ const Writer = struct {
601601 try stream.print(", {d})", .{inst_data.param_index});
602602 }
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
622604 fn writePtrType(
623605 self: *Writer,
624606 stream: anytype,
......@@ -660,7 +642,8 @@ const Writer = struct {
660642 try self.writeInstRef(stream, @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]));
661643 try stream.writeAll(")");
662644 }
663 try stream.writeAll(")");
645 try stream.writeAll(") ");
646 try self.writeSrc(stream, LazySrcLoc.nodeOffset(extra.data.src_node));
664647 }
665648
666649 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 {
744744 }
745745}
746746
747/// This function returns 1 if function alignment is not observable or settable.
747748pub fn defaultFunctionAlignment(target: std.Target) u32 {
748749 return switch (target.cpu.arch) {
749750 .arm, .armeb => 4,
......@@ -753,3 +754,10 @@ pub fn defaultFunctionAlignment(target: std.Target) u32 {
753754 else => 1,
754755 };
755756}
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 {
46434643 }
46444644
46454645 /// Asserts the type is a function.
4646 pub fn fnCallingConventionAllowsZigTypes(self: Type) bool {
4647 return switch (self.fnCallingConvention()) {
4646 pub fn fnCallingConventionAllowsZigTypes(cc: std.builtin.CallingConvention) bool {
4647 return switch (cc) {
46484648 .Unspecified, .Async, .Inline, .PtxKernel => true,
46494649 else => false,
46504650 };
46514651 }
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
46534667 /// Asserts the type is a function.
46544668 pub fn fnIsVarArgs(self: Type) bool {
46554669 return switch (self.tag()) {
......@@ -5650,6 +5664,10 @@ pub const Type = extern union {
56505664 const union_obj = ty.cast(Payload.Union).?.data;
56515665 return union_obj.srcLoc(mod);
56525666 },
5667 .@"opaque" => {
5668 const opaque_obj = ty.cast(Payload.Opaque).?.data;
5669 return opaque_obj.srcLoc(mod);
5670 },
56535671 .atomic_order,
56545672 .atomic_rmw_op,
56555673 .calling_convention,
test/behavior/align.zig+2-3
......@@ -299,8 +299,7 @@ test "implicitly decreasing fn alignment" {
299299 try testImplicitlyDecreaseFnAlign(alignedBig, 5678);
300300}
301301
302// TODO make it a compile error to put align on the fn proto instead of on the ptr
303fn testImplicitlyDecreaseFnAlign(ptr: *align(1) const fn () i32, answer: i32) !void {
302fn testImplicitlyDecreaseFnAlign(ptr: *const fn () align(1) i32, answer: i32) !void {
304303 try expect(ptr() == answer);
305304}
306305
......@@ -326,7 +325,7 @@ test "@alignCast functions" {
326325fn fnExpectsOnly1(ptr: *const fn () align(1) i32) i32 {
327326 return fnExpects4(@alignCast(4, ptr));
328327}
329fn fnExpects4(ptr: *align(4) const fn () i32) i32 {
328fn fnExpects4(ptr: *const fn () align(4) i32) i32 {
330329 return ptr();
331330}
332331fn simple4() align(4) i32 {
test/behavior/bugs/1310.zig+3-1
......@@ -4,7 +4,7 @@ const builtin = @import("builtin");
44
55pub const VM = ?[*]const struct_InvocationTable_;
66pub const struct_InvocationTable_ = extern struct {
7 GetVM: ?fn (?[*]VM) callconv(.C) c_int,
7 GetVM: ?*const fn (?[*]VM) callconv(.C) c_int,
88};
99
1010pub const struct_VM_ = extern struct {
......@@ -23,5 +23,7 @@ fn agent_callback(_vm: [*]VM, options: [*]u8) callconv(.C) i32 {
2323}
2424
2525test "fixed" {
26 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
27 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2628 try expect(agent_callback(undefined, undefined) == 11);
2729}
test/behavior/union.zig-1
......@@ -1016,7 +1016,6 @@ test "switching on non exhaustive union" {
10161016 switch (a) {
10171017 .a => |val| try expect(val == 2),
10181018 .b => return error.Fail,
1019 _ => return error.Fail,
10201019 }
10211020 }
10221021 };
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 {
1414// backend=llvm
1515// target=native
1616//
17// :6:5: error: unable to resolve comptime value
17// :6:5: error: unable to evalutate comptime expression
1818// :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 {
77// backend=stage2
88// target=native
99//
10// :1:1: 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'
10// :2:16: error: C pointers cannot point to non-C-ABI-compatible type 'void'
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 {
1717// target=native
1818// backend=stage2
1919//
20// :12:18: error: unable to resolve comptime value
20// :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;
77// backend=stage2
88// target=native
99//
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)); }
1818// backend=stage2
1919// target=native
2020//
21// :8:15: 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'
23// :8:15: note: pointer bit offset '3' cannot cast into pointer bit offset '0'
21// :8:16: error: expected type '*const u3', found '*align(0:3:1) const u3'
22// :8:16: note: pointer host size '1' cannot cast into pointer host size '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)); }
77// backend=stage2
88// target=native
99//
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 {
4545// backend=llvm
4646//
4747// :11:22: error: comparison of 'void' with null
48// :25:51: error: unable to resolve comptime value
49// :25:51: error: unable to resolve comptime value
50// :25:51: error: unable to resolve comptime value
51// :25:51: error: unable to resolve comptime value
48// :25:51: error: values of type 'anyopaque' must be comptime known, but operand value is runtime known
49// :25:51: note: opaque type 'anyopaque' has undefined size
50// :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: 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 {
88// backend=stage2
99// target=native
1010//
11// :4:17: 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'
13// :4:17: note: parameter 0 'bool' cannot cast into 'i32'
11// :4:18: error: expected type '*const fn(i32) void', found '*const fn(bool) void'
12// :4:18: note: pointer type child 'fn(bool) void' cannot cast into pointer type child 'fn(i32) void'
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 {
3939// backend=stage2
4040// target=native
4141//
42// :33:8: error: extern structs cannot contain fields of type 'tmp.E'
43// :33:8: note: enum tag type 'u9' is not extern compatible
44// :33:8: note: only integers with power of two bits are extern compatible
42// :31:5: error: extern structs cannot contain fields of type 'tmp.E'
43// :31:5: note: enum tag type 'u9' is not extern compatible
44// :31:5: note: only integers with power of two bits are extern compatible
4545// :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 {
1111// backend=stage2
1212// target=native
1313//
14// :5:8: error: extern structs cannot contain fields of type 'tmp.E'
15// :5:8: note: enum tag type 'u31' is not extern compatible
16// :5:8: note: only integers with power of two bits are extern compatible
14// :3:5: error: extern structs cannot contain fields of type 'tmp.E'
15// :3:5: note: enum tag type 'u31' is not extern compatible
16// :3:5: note: only integers with power of two bits are extern compatible
1717// :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 {
1111// target=native
1212//
1313// :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 {
1212// target=native
1313//
1414// :3:35: error: unable to resolve comptime value
15// :3:35: note: value being casted to 'comptime_int' must be comptime known
1516// :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; }
77// backend=stage2
88// target=native
99//
10// :4:8: error: extern structs cannot contain fields of type '?[*c]u8'
11// :4:8: note: only pointer like optionals are extern compatible
10// :2:5: error: extern structs cannot contain fields of type '?[*c]u8'
11// :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)); }
1414// backend=stage2
1515// target=native
1616//
17// :6:26: error: unable to resolve comptime value
17// :6:26: error: cannot store to runtime value in comptime block
1818// :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 {
2121// backend=stage2
2222// target=native
2323//
24// :3:7: error: unable to resolve comptime value
24// :3:7: error: cannot load runtime value in comptime block
2525// :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"); }
1010// backend=stage2
1111// target=native
1212//
13// :5:25: error: unable to resolve comptime value
13// :5:25: error: cannot load runtime value in comptime block
1414// :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 {
77// backend=stage2
88// target=native
99//
10// :2:19: error: type '[]u8' does not support array initialization syntax
11// :2:19: note: inferred array length is specified with an underscore: '[_]u8'
10// :2:15: error: type '[]u8' does not support array initialization syntax
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 {
1616// error
1717// target=native
1818//
19// :7:1: error: enum field(s) missing in union
19// :7:11: error: enum field(s) missing in union
2020// :4:5: note: field 'c' missing, declared here
2121// :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 {
1616// error
1717// target=native
1818//
19// :6:1: error: enum 'tmp.E' has no field named 'd'
19// :10:5: error: enum 'tmp.E' has no field named 'd'
2020// :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)); }
1919// target=native
2020//
2121// :8:5: error: switch must handle all possibilities
22// :8:5: note: unhandled enumeration value: 'Four'
22// :5:5: note: unhandled enumeration value: 'Four'
2323// :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 {
1010// target=native
1111//
1212// :5:5: error: switch must handle all possibilities
13// :5:5: note: unhandled enumeration value: 'M'
13// :1:20: note: unhandled enumeration value: 'M'
1414// :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 {
1010// backend=stage2
1111// target=native
1212//
13// :6:6: 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'
15// :6:6: note: parameter 0 'u8' cannot cast into '*const u8'
13// :6:7: error: expected type '*const fn(*const u8) void', found '*const fn(u8) void'
14// :6:7: note: pointer type child 'fn(u8) void' cannot cast into pointer type child 'fn(*const u8) void'
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 {
1515// backend=stage2
1616// target=native
1717//
18// :6:1: error: enum field(s) missing in union
18// :6:17: error: enum field(s) missing in union
1919// :4:5: note: field 'C' missing, declared here
2020// :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;
66
77// error
88//
9// :2:15: error: unable to resolve comptime value
9// :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 {
2222// error
2323//
2424// :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 {
1717// error
1818//
1919// :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 {
5151 \\}
5252 \\var y: @import("std").builtin.CallingConvention = .C;
5353 , &.{
54 ":2:22: error: unable to resolve comptime value",
55 ":5:26: error: unable to resolve comptime value",
54 ":2:22: error: cannot load runtime value in comptime block",
55 ":5:26: error: cannot load runtime value in comptime block",
5656 });
5757 }
5858
......@@ -772,7 +772,7 @@ pub fn addCases(ctx: *TestContext) !void {
772772 \\}
773773 , &.{
774774 ":4:5: error: switch must handle all possibilities",
775 ":4:5: note: unhandled enumeration value: 'b'",
775 ":1:21: note: unhandled enumeration value: 'b'",
776776 ":1:11: note: enum 'tmp.E' declared here",
777777 });
778778