| ... | ... | @@ -487,20 +487,23 @@ pub fn deinit(sema: *Sema) void { |
| 487 | 487 | /// Returns only the result from the body that is specified. |
| 488 | 488 | /// Only appropriate to call when it is determined at comptime that this body |
| 489 | 489 | /// has no peers. |
| 490 | | fn resolveBody(sema: *Sema, block: *Block, body: []const Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 490 | fn resolveBody( |
| 491 | sema: *Sema, |
| 492 | block: *Block, |
| 493 | body: []const Zir.Inst.Index, |
| 494 | /// This is the instruction that a break instruction within `body` can |
| 495 | /// use to return from the body. |
| 496 | body_inst: Zir.Inst.Index, |
| 497 | ) CompileError!Air.Inst.Ref { |
| 491 | 498 | const break_inst = try sema.analyzeBody(block, body); |
| 492 | 499 | const break_data = sema.code.instructions.items(.data)[break_inst].@"break"; |
| 493 | 500 | // For comptime control flow, we need to detect when `analyzeBody` reports |
| 494 | 501 | // that we need to break from an outer block. In such case we |
| 495 | 502 | // use Zig's error mechanism to send control flow up the stack until |
| 496 | 503 | // we find the corresponding block to this break. |
| 497 | | if (block.is_comptime) { |
| 498 | | if (block.label) |label| { |
| 499 | | if (label.zir_block != break_data.block_inst) { |
| 500 | | sema.comptime_break_inst = break_inst; |
| 501 | | return error.ComptimeBreak; |
| 502 | | } |
| 503 | | } |
| 504 | if (block.is_comptime and break_data.block_inst != body_inst) { |
| 505 | sema.comptime_break_inst = break_inst; |
| 506 | return error.ComptimeBreak; |
| 504 | 507 | } |
| 505 | 508 | return sema.resolveInst(break_data.operand); |
| 506 | 509 | } |
| ... | ... | @@ -3508,10 +3511,13 @@ fn resolveBlockBody( |
| 3508 | 3511 | src: LazySrcLoc, |
| 3509 | 3512 | child_block: *Block, |
| 3510 | 3513 | body: []const Zir.Inst.Index, |
| 3514 | /// This is the instruction that a break instruction within `body` can |
| 3515 | /// use to return from the body. |
| 3516 | body_inst: Zir.Inst.Index, |
| 3511 | 3517 | merges: *Block.Merges, |
| 3512 | 3518 | ) CompileError!Air.Inst.Ref { |
| 3513 | 3519 | if (child_block.is_comptime) { |
| 3514 | | return sema.resolveBody(child_block, body); |
| 3520 | return sema.resolveBody(child_block, body, body_inst); |
| 3515 | 3521 | } else { |
| 3516 | 3522 | _ = try sema.analyzeBody(child_block, body); |
| 3517 | 3523 | return sema.analyzeBlockBody(parent_block, src, child_block, merges); |
| ... | ... | @@ -4251,7 +4257,7 @@ fn analyzeCall( |
| 4251 | 4257 | const param_src = pl_tok.src(); |
| 4252 | 4258 | const extra = sema.code.extraData(Zir.Inst.Param, pl_tok.payload_index); |
| 4253 | 4259 | const param_body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| 4254 | | const param_ty_inst = try sema.resolveBody(&child_block, param_body); |
| 4260 | const param_ty_inst = try sema.resolveBody(&child_block, param_body, inst); |
| 4255 | 4261 | const param_ty = try sema.analyzeAsType(&child_block, param_src, param_ty_inst); |
| 4256 | 4262 | const arg_src = call_src; // TODO: better source location |
| 4257 | 4263 | const casted_arg = try sema.coerce(&child_block, param_ty, uncasted_args[arg_i], arg_src); |
| ... | ... | @@ -4308,7 +4314,7 @@ fn analyzeCall( |
| 4308 | 4314 | // on parameters, we must now do the same for the return type as we just did with |
| 4309 | 4315 | // each of the parameters, resolving the return type and providing it to the child |
| 4310 | 4316 | // `Sema` so that it can be used for the `ret_ptr` instruction. |
| 4311 | | const ret_ty_inst = try sema.resolveBody(&child_block, fn_info.ret_ty_body); |
| 4317 | const ret_ty_inst = try sema.resolveBody(&child_block, fn_info.ret_ty_body, module_fn.zir_body_inst); |
| 4312 | 4318 | const ret_ty_src = func_src; // TODO better source location |
| 4313 | 4319 | const bare_return_type = try sema.analyzeAsType(&child_block, ret_ty_src, ret_ty_inst); |
| 4314 | 4320 | // Create a fresh inferred error set type for inline/comptime calls. |
| ... | ... | @@ -4589,7 +4595,7 @@ fn analyzeCall( |
| 4589 | 4595 | } |
| 4590 | 4596 | arg_i += 1; |
| 4591 | 4597 | } |
| 4592 | | const new_func_inst = child_sema.resolveBody(&child_block, fn_info.param_body) catch |err| { |
| 4598 | const new_func_inst = child_sema.resolveBody(&child_block, fn_info.param_body, fn_info.param_body_inst) catch |err| { |
| 4593 | 4599 | // TODO look up the compile error that happened here and attach a note to it |
| 4594 | 4600 | // pointing here, at the generic instantiation callsite. |
| 4595 | 4601 | if (sema.owner_func) |owner_func| { |
| ... | ... | @@ -5388,10 +5394,9 @@ fn zirFunc( |
| 5388 | 5394 | const ret_ty_body = sema.code.extra[extra_index..][0..extra.data.ret_body_len]; |
| 5389 | 5395 | extra_index += ret_ty_body.len; |
| 5390 | 5396 | |
| 5391 | | var body_inst: Zir.Inst.Index = 0; |
| 5392 | 5397 | var src_locs: Zir.Inst.Func.SrcLocs = undefined; |
| 5393 | | if (extra.data.body_len != 0) { |
| 5394 | | body_inst = inst; |
| 5398 | const has_body = extra.data.body_len != 0; |
| 5399 | if (has_body) { |
| 5395 | 5400 | extra_index += extra.data.body_len; |
| 5396 | 5401 | src_locs = sema.code.extraData(Zir.Inst.Func.SrcLocs, extra_index).data; |
| 5397 | 5402 | } |
| ... | ... | @@ -5404,13 +5409,14 @@ fn zirFunc( |
| 5404 | 5409 | return sema.funcCommon( |
| 5405 | 5410 | block, |
| 5406 | 5411 | inst_data.src_node, |
| 5407 | | body_inst, |
| 5412 | inst, |
| 5408 | 5413 | ret_ty_body, |
| 5409 | 5414 | cc, |
| 5410 | 5415 | Value.@"null", |
| 5411 | 5416 | false, |
| 5412 | 5417 | inferred_error_set, |
| 5413 | 5418 | false, |
| 5419 | has_body, |
| 5414 | 5420 | src_locs, |
| 5415 | 5421 | null, |
| 5416 | 5422 | ); |
| ... | ... | @@ -5420,13 +5426,14 @@ fn funcCommon( |
| 5420 | 5426 | sema: *Sema, |
| 5421 | 5427 | block: *Block, |
| 5422 | 5428 | src_node_offset: i32, |
| 5423 | | body_inst: Zir.Inst.Index, |
| 5429 | func_inst: Zir.Inst.Index, |
| 5424 | 5430 | ret_ty_body: []const Zir.Inst.Index, |
| 5425 | 5431 | cc: std.builtin.CallingConvention, |
| 5426 | 5432 | align_val: Value, |
| 5427 | 5433 | var_args: bool, |
| 5428 | 5434 | inferred_error_set: bool, |
| 5429 | 5435 | is_extern: bool, |
| 5436 | has_body: bool, |
| 5430 | 5437 | src_locs: Zir.Inst.Func.SrcLocs, |
| 5431 | 5438 | opt_lib_name: ?[]const u8, |
| 5432 | 5439 | ) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -5447,7 +5454,7 @@ fn funcCommon( |
| 5447 | 5454 | block.params.deinit(sema.gpa); |
| 5448 | 5455 | block.params = prev_params; |
| 5449 | 5456 | } |
| 5450 | | if (sema.resolveBody(block, ret_ty_body)) |ret_ty_inst| { |
| 5457 | if (sema.resolveBody(block, ret_ty_body, func_inst)) |ret_ty_inst| { |
| 5451 | 5458 | if (sema.analyzeAsType(block, ret_ty_src, ret_ty_inst)) |ret_ty| { |
| 5452 | 5459 | break :ret_ty ret_ty; |
| 5453 | 5460 | } else |err| break :err err; |
| ... | ... | @@ -5466,15 +5473,15 @@ fn funcCommon( |
| 5466 | 5473 | const mod = sema.mod; |
| 5467 | 5474 | |
| 5468 | 5475 | const new_func: *Module.Fn = new_func: { |
| 5469 | | if (body_inst == 0) break :new_func undefined; |
| 5470 | | if (sema.comptime_args_fn_inst == body_inst) { |
| 5476 | if (!has_body) break :new_func undefined; |
| 5477 | if (sema.comptime_args_fn_inst == func_inst) { |
| 5471 | 5478 | const new_func = sema.preallocated_new_func.?; |
| 5472 | 5479 | sema.preallocated_new_func = null; // take ownership |
| 5473 | 5480 | break :new_func new_func; |
| 5474 | 5481 | } |
| 5475 | 5482 | break :new_func try sema.gpa.create(Module.Fn); |
| 5476 | 5483 | }; |
| 5477 | | errdefer if (body_inst != 0) sema.gpa.destroy(new_func); |
| 5484 | errdefer if (has_body) sema.gpa.destroy(new_func); |
| 5478 | 5485 | |
| 5479 | 5486 | var maybe_inferred_error_set_node: ?*Module.Fn.InferredErrorSetListNode = null; |
| 5480 | 5487 | errdefer if (maybe_inferred_error_set_node) |node| sema.gpa.destroy(node); |
| ... | ... | @@ -5599,21 +5606,21 @@ fn funcCommon( |
| 5599 | 5606 | ); |
| 5600 | 5607 | } |
| 5601 | 5608 | |
| 5602 | | if (body_inst == 0) { |
| 5609 | if (!has_body) { |
| 5603 | 5610 | return sema.addType(fn_ty); |
| 5604 | 5611 | } |
| 5605 | 5612 | |
| 5606 | 5613 | const is_inline = fn_ty.fnCallingConvention() == .Inline; |
| 5607 | 5614 | const anal_state: Module.Fn.Analysis = if (is_inline) .inline_only else .queued; |
| 5608 | 5615 | |
| 5609 | | const comptime_args: ?[*]TypedValue = if (sema.comptime_args_fn_inst == body_inst) blk: { |
| 5616 | const comptime_args: ?[*]TypedValue = if (sema.comptime_args_fn_inst == func_inst) blk: { |
| 5610 | 5617 | break :blk if (sema.comptime_args.len == 0) null else sema.comptime_args.ptr; |
| 5611 | 5618 | } else null; |
| 5612 | 5619 | |
| 5613 | 5620 | const fn_payload = try sema.arena.create(Value.Payload.Function); |
| 5614 | 5621 | new_func.* = .{ |
| 5615 | 5622 | .state = anal_state, |
| 5616 | | .zir_body_inst = body_inst, |
| 5623 | .zir_body_inst = func_inst, |
| 5617 | 5624 | .owner_decl = sema.owner_decl, |
| 5618 | 5625 | .comptime_args = comptime_args, |
| 5619 | 5626 | .lbrace_line = src_locs.lbrace_line, |
| ... | ... | @@ -5660,7 +5667,7 @@ fn zirParam( |
| 5660 | 5667 | block.params = prev_params; |
| 5661 | 5668 | } |
| 5662 | 5669 | |
| 5663 | | if (sema.resolveBody(block, body)) |param_ty_inst| { |
| 5670 | if (sema.resolveBody(block, body, inst)) |param_ty_inst| { |
| 5664 | 5671 | if (sema.analyzeAsType(block, src, param_ty_inst)) |param_ty| { |
| 5665 | 5672 | break :param_ty param_ty; |
| 5666 | 5673 | } else |err| break :err err; |
| ... | ... | @@ -6809,7 +6816,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 6809 | 6816 | // Validation above ensured these will succeed. |
| 6810 | 6817 | const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable; |
| 6811 | 6818 | if (operand_val.eql(item_val, operand_ty)) { |
| 6812 | | return sema.resolveBlockBody(block, src, &child_block, body, merges); |
| 6819 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); |
| 6813 | 6820 | } |
| 6814 | 6821 | } |
| 6815 | 6822 | } |
| ... | ... | @@ -6831,7 +6838,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 6831 | 6838 | // Validation above ensured these will succeed. |
| 6832 | 6839 | const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable; |
| 6833 | 6840 | if (operand_val.eql(item_val, operand_ty)) { |
| 6834 | | return sema.resolveBlockBody(block, src, &child_block, body, merges); |
| 6841 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); |
| 6835 | 6842 | } |
| 6836 | 6843 | } |
| 6837 | 6844 | |
| ... | ... | @@ -6848,18 +6855,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 6848 | 6855 | if (Value.compare(operand_val, .gte, first_tv.val, operand_ty) and |
| 6849 | 6856 | Value.compare(operand_val, .lte, last_tv.val, operand_ty)) |
| 6850 | 6857 | { |
| 6851 | | return sema.resolveBlockBody(block, src, &child_block, body, merges); |
| 6858 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); |
| 6852 | 6859 | } |
| 6853 | 6860 | } |
| 6854 | 6861 | |
| 6855 | 6862 | extra_index += body_len; |
| 6856 | 6863 | } |
| 6857 | 6864 | } |
| 6858 | | return sema.resolveBlockBody(block, src, &child_block, special.body, merges); |
| 6865 | return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges); |
| 6859 | 6866 | } |
| 6860 | 6867 | |
| 6861 | 6868 | if (scalar_cases_len + multi_cases_len == 0) { |
| 6862 | | return sema.resolveBlockBody(block, src, &child_block, special.body, merges); |
| 6869 | return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges); |
| 6863 | 6870 | } |
| 6864 | 6871 | |
| 6865 | 6872 | try sema.requireRuntimeBlock(block, src); |
| ... | ... | @@ -10038,7 +10045,7 @@ fn zirBoolBr( |
| 10038 | 10045 | // comptime-known left-hand side. No need for a block here; the result |
| 10039 | 10046 | // is simply the rhs expression. Here we rely on there only being 1 |
| 10040 | 10047 | // break instruction (`break_inline`). |
| 10041 | | return sema.resolveBody(parent_block, body); |
| 10048 | return sema.resolveBody(parent_block, body, inst); |
| 10042 | 10049 | } |
| 10043 | 10050 | |
| 10044 | 10051 | const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len); |
| ... | ... | @@ -10068,7 +10075,7 @@ fn zirBoolBr( |
| 10068 | 10075 | const lhs_result: Air.Inst.Ref = if (is_bool_or) .bool_true else .bool_false; |
| 10069 | 10076 | _ = try lhs_block.addBr(block_inst, lhs_result); |
| 10070 | 10077 | |
| 10071 | | const rhs_result = try sema.resolveBody(rhs_block, body); |
| 10078 | const rhs_result = try sema.resolveBody(rhs_block, body, inst); |
| 10072 | 10079 | _ = try rhs_block.addBr(block_inst, rhs_result); |
| 10073 | 10080 | |
| 10074 | 10081 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).Struct.fields.len + |
| ... | ... | @@ -12419,10 +12426,9 @@ fn zirFuncExtended( |
| 12419 | 12426 | const ret_ty_body = sema.code.extra[extra_index..][0..extra.data.ret_body_len]; |
| 12420 | 12427 | extra_index += ret_ty_body.len; |
| 12421 | 12428 | |
| 12422 | | var body_inst: Zir.Inst.Index = 0; |
| 12423 | 12429 | var src_locs: Zir.Inst.Func.SrcLocs = undefined; |
| 12424 | | if (extra.data.body_len != 0) { |
| 12425 | | body_inst = inst; |
| 12430 | const has_body = extra.data.body_len != 0; |
| 12431 | if (has_body) { |
| 12426 | 12432 | extra_index += extra.data.body_len; |
| 12427 | 12433 | src_locs = sema.code.extraData(Zir.Inst.Func.SrcLocs, extra_index).data; |
| 12428 | 12434 | } |
| ... | ... | @@ -12434,13 +12440,14 @@ fn zirFuncExtended( |
| 12434 | 12440 | return sema.funcCommon( |
| 12435 | 12441 | block, |
| 12436 | 12442 | extra.data.src_node, |
| 12437 | | body_inst, |
| 12443 | inst, |
| 12438 | 12444 | ret_ty_body, |
| 12439 | 12445 | cc, |
| 12440 | 12446 | align_val, |
| 12441 | 12447 | is_var_args, |
| 12442 | 12448 | is_inferred_error, |
| 12443 | 12449 | is_extern, |
| 12450 | has_body, |
| 12444 | 12451 | src_locs, |
| 12445 | 12452 | lib_name, |
| 12446 | 12453 | ); |