| ... | ... | @@ -1034,8 +1034,8 @@ fn analyzeBodyInner( |
| 1034 | 1034 | i += 1; |
| 1035 | 1035 | continue; |
| 1036 | 1036 | }, |
| 1037 | | .ensure_err_payload_void => { |
| 1038 | | try sema.zirEnsureErrPayloadVoid(block, inst); |
| 1037 | .ensure_err_union_payload_void => { |
| 1038 | try sema.zirEnsureErrUnionPayloadVoid(block, inst); |
| 1039 | 1039 | i += 1; |
| 1040 | 1040 | continue; |
| 1041 | 1041 | }, |
| ... | ... | @@ -1302,17 +1302,28 @@ fn analyzeBodyInner( |
| 1302 | 1302 | // current list of parameters and restore it later. |
| 1303 | 1303 | // Note: this probably needs to be resolved in a more general manner. |
| 1304 | 1304 | const prev_params = block.params; |
| 1305 | | const prev_inline_block = block.inline_block; |
| 1306 | | if (tags[inline_body[inline_body.len - 1]] == .repeat_inline) { |
| 1307 | | block.inline_block = inline_body[0]; |
| 1305 | const need_sub_block = tags[inline_body[inline_body.len - 1]] == .repeat_inline; |
| 1306 | var sub_block = block; |
| 1307 | var block_space: Block = undefined; |
| 1308 | // NOTE: this has to be done like this because branching in |
| 1309 | // defers here breaks stage1. |
| 1310 | block_space.instructions = .{}; |
| 1311 | if (need_sub_block) { |
| 1312 | block_space = block.makeSubBlock(); |
| 1313 | block_space.inline_block = inline_body[0]; |
| 1314 | sub_block = &block_space; |
| 1308 | 1315 | } |
| 1309 | 1316 | block.params = .{}; |
| 1310 | 1317 | defer { |
| 1311 | 1318 | block.params.deinit(gpa); |
| 1312 | 1319 | block.params = prev_params; |
| 1313 | | block.inline_block = prev_inline_block; |
| 1320 | block_space.instructions.deinit(gpa); |
| 1314 | 1321 | } |
| 1315 | | const opt_break_data = try sema.analyzeBodyBreak(block, inline_body); |
| 1322 | const opt_break_data = try sema.analyzeBodyBreak(sub_block, inline_body); |
| 1323 | if (need_sub_block) { |
| 1324 | try block.instructions.appendSlice(gpa, block_space.instructions.items); |
| 1325 | } |
| 1326 | |
| 1316 | 1327 | // A runtime conditional branch that needs a post-hoc block to be |
| 1317 | 1328 | // emitted communicates this by mapping the block index into the inst map. |
| 1318 | 1329 | if (map.get(inst)) |new_block_ref| ph: { |
| ... | ... | @@ -2469,7 +2480,7 @@ fn createAnonymousDeclTypeNamed( |
| 2469 | 2480 | const arg = sema.inst_map.get(zir_inst).?; |
| 2470 | 2481 | // The comptime call code in analyzeCall already did this, so we're |
| 2471 | 2482 | // just repeating it here and it's guaranteed to work. |
| 2472 | | const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg, undefined) catch unreachable; |
| 2483 | const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg, "") catch unreachable; |
| 2473 | 2484 | |
| 2474 | 2485 | if (arg_i != 0) try buf.appendSlice(","); |
| 2475 | 2486 | try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg), sema.mod)}); |
| ... | ... | @@ -3089,6 +3100,33 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3089 | 3100 | } |
| 3090 | 3101 | } |
| 3091 | 3102 | |
| 3103 | fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 3104 | const tracy = trace(@src()); |
| 3105 | defer tracy.end(); |
| 3106 | |
| 3107 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 3108 | const src = inst_data.src(); |
| 3109 | const operand = try sema.resolveInst(inst_data.operand); |
| 3110 | const operand_ty = sema.typeOf(operand); |
| 3111 | const err_union_ty = if (operand_ty.zigTypeTag() == .Pointer) |
| 3112 | operand_ty.childType() |
| 3113 | else |
| 3114 | operand_ty; |
| 3115 | // TODO this should be validated in a more generic instruction that is |
| 3116 | // emitted for all ifs and whiles with an error union condition. |
| 3117 | if (err_union_ty.zigTypeTag() != .ErrorUnion) return; |
| 3118 | const payload_ty = err_union_ty.errorUnionPayload().zigTypeTag(); |
| 3119 | if (payload_ty != .Void and payload_ty != .NoReturn) { |
| 3120 | const msg = msg: { |
| 3121 | const msg = try sema.errMsg(block, src, "error union payload is ignored", .{}); |
| 3122 | errdefer msg.destroy(sema.gpa); |
| 3123 | try sema.errNote(block, src, msg, "payload value can be explicitly ignored with '|_|'", .{}); |
| 3124 | break :msg msg; |
| 3125 | }; |
| 3126 | return sema.failWithOwnedErrorMsg(msg); |
| 3127 | } |
| 3128 | } |
| 3129 | |
| 3092 | 3130 | fn zirIndexablePtrLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 3093 | 3131 | const tracy = trace(@src()); |
| 3094 | 3132 | defer tracy.end(); |
| ... | ... | @@ -5631,7 +5669,7 @@ fn zirCall( |
| 5631 | 5669 | var bound_arg_src: ?LazySrcLoc = null; |
| 5632 | 5670 | if (func_type.tag() == .bound_fn) { |
| 5633 | 5671 | bound_arg_src = func_src; |
| 5634 | | const bound_func = try sema.resolveValue(block, .unneeded, func, undefined); |
| 5672 | const bound_func = try sema.resolveValue(block, .unneeded, func, ""); |
| 5635 | 5673 | const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data; |
| 5636 | 5674 | func = bound_data.func_inst; |
| 5637 | 5675 | resolved_args = try sema.arena.alloc(Air.Inst.Ref, args_len + 1); |
| ... | ... | @@ -6010,6 +6048,7 @@ fn analyzeCall( |
| 6010 | 6048 | const parent_inst_map = sema.inst_map; |
| 6011 | 6049 | sema.inst_map = .{}; |
| 6012 | 6050 | defer { |
| 6051 | sema.src = call_src; |
| 6013 | 6052 | sema.inst_map.deinit(gpa); |
| 6014 | 6053 | sema.inst_map = parent_inst_map; |
| 6015 | 6054 | } |
| ... | ... | @@ -6213,7 +6252,7 @@ fn analyzeCall( |
| 6213 | 6252 | } |
| 6214 | 6253 | |
| 6215 | 6254 | if (should_memoize and is_comptime_call) { |
| 6216 | | const result_val = try sema.resolveConstMaybeUndefVal(block, .unneeded, result, undefined); |
| 6255 | const result_val = try sema.resolveConstMaybeUndefVal(block, .unneeded, result, ""); |
| 6217 | 6256 | |
| 6218 | 6257 | // TODO: check whether any external comptime memory was mutated by the |
| 6219 | 6258 | // comptime function call. If so, then do not memoize the call here. |
| ... | ... | @@ -6675,6 +6714,8 @@ fn instantiateGenericCall( |
| 6675 | 6714 | .comptime_args_fn_inst = module_fn.zir_body_inst, |
| 6676 | 6715 | .preallocated_new_func = new_module_func, |
| 6677 | 6716 | .is_generic_instantiation = true, |
| 6717 | .branch_quota = sema.branch_quota, |
| 6718 | .branch_count = sema.branch_count, |
| 6678 | 6719 | }; |
| 6679 | 6720 | defer child_sema.deinit(); |
| 6680 | 6721 | |
| ... | ... | @@ -6724,12 +6765,12 @@ fn instantiateGenericCall( |
| 6724 | 6765 | const child_arg = try child_sema.addConstant(sema.typeOf(arg), arg_val); |
| 6725 | 6766 | child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); |
| 6726 | 6767 | } else { |
| 6727 | | return sema.failWithNeededComptime(block, .unneeded, undefined); |
| 6768 | return sema.failWithNeededComptime(block, .unneeded, ""); |
| 6728 | 6769 | } |
| 6729 | 6770 | } else if (is_anytype) { |
| 6730 | 6771 | const arg_ty = sema.typeOf(arg); |
| 6731 | 6772 | if (try sema.typeRequiresComptime(arg_ty)) { |
| 6732 | | const arg_val = try sema.resolveConstValue(block, .unneeded, arg, undefined); |
| 6773 | const arg_val = try sema.resolveConstValue(block, .unneeded, arg, ""); |
| 6733 | 6774 | const child_arg = try child_sema.addConstant(arg_ty, arg_val); |
| 6734 | 6775 | child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); |
| 6735 | 6776 | } else { |
| ... | ... | @@ -6751,7 +6792,7 @@ fn instantiateGenericCall( |
| 6751 | 6792 | } |
| 6752 | 6793 | return err; |
| 6753 | 6794 | }; |
| 6754 | | const new_func_val = child_sema.resolveConstValue(&child_block, .unneeded, new_func_inst, undefined) catch unreachable; |
| 6795 | const new_func_val = child_sema.resolveConstValue(&child_block, .unneeded, new_func_inst, "") catch unreachable; |
| 6755 | 6796 | const new_func = new_func_val.castTag(.function).?.data; |
| 6756 | 6797 | errdefer new_func.deinit(gpa); |
| 6757 | 6798 | assert(new_func == new_module_func); |
| ... | ... | @@ -7674,24 +7715,6 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 7674 | 7715 | return block.addTyOp(.unwrap_errunion_err_ptr, result_ty, operand); |
| 7675 | 7716 | } |
| 7676 | 7717 | |
| 7677 | | fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 7678 | | const tracy = trace(@src()); |
| 7679 | | defer tracy.end(); |
| 7680 | | |
| 7681 | | const inst_data = sema.code.instructions.items(.data)[inst].un_tok; |
| 7682 | | const src = inst_data.src(); |
| 7683 | | const operand = try sema.resolveInst(inst_data.operand); |
| 7684 | | const operand_ty = sema.typeOf(operand); |
| 7685 | | if (operand_ty.zigTypeTag() != .ErrorUnion) { |
| 7686 | | return sema.fail(block, src, "expected error union type, found '{}'", .{ |
| 7687 | | operand_ty.fmt(sema.mod), |
| 7688 | | }); |
| 7689 | | } |
| 7690 | | if (operand_ty.errorUnionPayload().zigTypeTag() != .Void) { |
| 7691 | | return sema.fail(block, src, "expression value is ignored", .{}); |
| 7692 | | } |
| 7693 | | } |
| 7694 | | |
| 7695 | 7718 | fn zirFunc( |
| 7696 | 7719 | sema: *Sema, |
| 7697 | 7720 | block: *Block, |
| ... | ... | @@ -9119,7 +9142,7 @@ fn zirSwitchCapture( |
| 9119 | 9142 | const union_obj = operand_ty.cast(Type.Payload.Union).?.data; |
| 9120 | 9143 | const first_item = try sema.resolveInst(items[0]); |
| 9121 | 9144 | // Previous switch validation ensured this will succeed |
| 9122 | | const first_item_val = sema.resolveConstValue(block, .unneeded, first_item, undefined) catch unreachable; |
| 9145 | const first_item_val = sema.resolveConstValue(block, .unneeded, first_item, "") catch unreachable; |
| 9123 | 9146 | |
| 9124 | 9147 | const first_field_index = @intCast(u32, operand_ty.unionTagFieldIndex(first_item_val, sema.mod).?); |
| 9125 | 9148 | const first_field = union_obj.fields.values()[first_field_index]; |
| ... | ... | @@ -9127,7 +9150,7 @@ fn zirSwitchCapture( |
| 9127 | 9150 | for (items[1..]) |item, i| { |
| 9128 | 9151 | const item_ref = try sema.resolveInst(item); |
| 9129 | 9152 | // Previous switch validation ensured this will succeed |
| 9130 | | const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable; |
| 9153 | const item_val = sema.resolveConstValue(block, .unneeded, item_ref, "") catch unreachable; |
| 9131 | 9154 | |
| 9132 | 9155 | const field_index = operand_ty.unionTagFieldIndex(item_val, sema.mod).?; |
| 9133 | 9156 | const field = union_obj.fields.values()[field_index]; |
| ... | ... | @@ -9188,7 +9211,7 @@ fn zirSwitchCapture( |
| 9188 | 9211 | for (items) |item| { |
| 9189 | 9212 | const item_ref = try sema.resolveInst(item); |
| 9190 | 9213 | // Previous switch validation ensured this will succeed |
| 9191 | | const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable; |
| 9214 | const item_val = sema.resolveConstValue(block, .unneeded, item_ref, "") catch unreachable; |
| 9192 | 9215 | names.putAssumeCapacityNoClobber( |
| 9193 | 9216 | item_val.getError().?, |
| 9194 | 9217 | {}, |
| ... | ... | @@ -9202,7 +9225,7 @@ fn zirSwitchCapture( |
| 9202 | 9225 | } else { |
| 9203 | 9226 | const item_ref = try sema.resolveInst(items[0]); |
| 9204 | 9227 | // Previous switch validation ensured this will succeed |
| 9205 | | const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable; |
| 9228 | const item_val = sema.resolveConstValue(block, .unneeded, item_ref, "") catch unreachable; |
| 9206 | 9229 | |
| 9207 | 9230 | const item_ty = try Type.Tag.error_set_single.create(sema.arena, item_val.getError().?); |
| 9208 | 9231 | return sema.bitCast(block, item_ty, operand, operand_src); |
| ... | ... | @@ -9941,14 +9964,17 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9941 | 9964 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 9942 | 9965 | extra_index += 1; |
| 9943 | 9966 | const body_len = @truncate(u31, sema.code.extra[extra_index]); |
| 9967 | const is_inline = sema.code.extra[extra_index] >> 31 != 0; |
| 9944 | 9968 | extra_index += 1; |
| 9945 | 9969 | const body = sema.code.extra[extra_index..][0..body_len]; |
| 9946 | 9970 | extra_index += body_len; |
| 9947 | 9971 | |
| 9948 | 9972 | const item = try sema.resolveInst(item_ref); |
| 9949 | 9973 | // Validation above ensured these will succeed. |
| 9950 | | const item_val = sema.resolveConstValue(&child_block, .unneeded, item, undefined) catch unreachable; |
| 9974 | const item_val = sema.resolveConstValue(&child_block, .unneeded, item, "") catch unreachable; |
| 9951 | 9975 | if (operand_val.eql(item_val, operand_ty, sema.mod)) { |
| 9976 | if (is_inline) child_block.inline_case_capture = operand; |
| 9977 | |
| 9952 | 9978 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); |
| 9953 | 9979 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); |
| 9954 | 9980 | } |
| ... | ... | @@ -9962,6 +9988,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9962 | 9988 | const ranges_len = sema.code.extra[extra_index]; |
| 9963 | 9989 | extra_index += 1; |
| 9964 | 9990 | const body_len = @truncate(u31, sema.code.extra[extra_index]); |
| 9991 | const is_inline = sema.code.extra[extra_index] >> 31 != 0; |
| 9965 | 9992 | extra_index += 1; |
| 9966 | 9993 | const items = sema.code.refSlice(extra_index, items_len); |
| 9967 | 9994 | extra_index += items_len; |
| ... | ... | @@ -9970,8 +9997,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9970 | 9997 | for (items) |item_ref| { |
| 9971 | 9998 | const item = try sema.resolveInst(item_ref); |
| 9972 | 9999 | // Validation above ensured these will succeed. |
| 9973 | | const item_val = sema.resolveConstValue(&child_block, .unneeded, item, undefined) catch unreachable; |
| 10000 | const item_val = sema.resolveConstValue(&child_block, .unneeded, item, "") catch unreachable; |
| 9974 | 10001 | if (operand_val.eql(item_val, operand_ty, sema.mod)) { |
| 10002 | if (is_inline) child_block.inline_case_capture = operand; |
| 10003 | |
| 9975 | 10004 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); |
| 9976 | 10005 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); |
| 9977 | 10006 | } |
| ... | ... | @@ -9985,11 +10014,12 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9985 | 10014 | extra_index += 1; |
| 9986 | 10015 | |
| 9987 | 10016 | // Validation above ensured these will succeed. |
| 9988 | | const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first, undefined) catch unreachable; |
| 9989 | | const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last, undefined) catch unreachable; |
| 10017 | const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first, "") catch unreachable; |
| 10018 | const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last, "") catch unreachable; |
| 9990 | 10019 | if ((try sema.compare(block, src, operand_val, .gte, first_tv.val, operand_ty)) and |
| 9991 | 10020 | (try sema.compare(block, src, operand_val, .lte, last_tv.val, operand_ty))) |
| 9992 | 10021 | { |
| 10022 | if (is_inline) child_block.inline_case_capture = operand; |
| 9993 | 10023 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); |
| 9994 | 10024 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); |
| 9995 | 10025 | } |
| ... | ... | @@ -9999,6 +10029,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9999 | 10029 | } |
| 10000 | 10030 | } |
| 10001 | 10031 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, special.body, operand); |
| 10032 | if (special.is_inline) child_block.inline_case_capture = operand; |
| 10002 | 10033 | return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges); |
| 10003 | 10034 | } |
| 10004 | 10035 | |
| ... | ... | @@ -10060,7 +10091,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10060 | 10091 | // `item` is already guaranteed to be constant known. |
| 10061 | 10092 | |
| 10062 | 10093 | const analyze_body = if (union_originally) blk: { |
| 10063 | | const item_val = sema.resolveConstValue(block, .unneeded, item, undefined) catch unreachable; |
| 10094 | const item_val = sema.resolveConstValue(block, .unneeded, item, "") catch unreachable; |
| 10064 | 10095 | const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod); |
| 10065 | 10096 | break :blk field_ty.zigTypeTag() != .NoReturn; |
| 10066 | 10097 | } else true; |
| ... | ... | @@ -10211,7 +10242,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10211 | 10242 | const analyze_body = if (union_originally) |
| 10212 | 10243 | for (items) |item_ref| { |
| 10213 | 10244 | const item = try sema.resolveInst(item_ref); |
| 10214 | | const item_val = sema.resolveConstValue(block, .unneeded, item, undefined) catch unreachable; |
| 10245 | const item_val = sema.resolveConstValue(block, .unneeded, item, "") catch unreachable; |
| 10215 | 10246 | const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod); |
| 10216 | 10247 | if (field_ty.zigTypeTag() != .NoReturn) break true; |
| 10217 | 10248 | } else false |
| ... | ... | @@ -10606,7 +10637,7 @@ fn resolveSwitchItemVal( |
| 10606 | 10637 | // Constructing a LazySrcLoc is costly because we only have the switch AST node. |
| 10607 | 10638 | // Only if we know for sure we need to report a compile error do we resolve the |
| 10608 | 10639 | // full source locations. |
| 10609 | | if (sema.resolveConstValue(block, .unneeded, item, undefined)) |val| { |
| 10640 | if (sema.resolveConstValue(block, .unneeded, item, "")) |val| { |
| 10610 | 10641 | return TypedValue{ .ty = item_ty, .val = val }; |
| 10611 | 10642 | } else |err| switch (err) { |
| 10612 | 10643 | error.NeededSourceLocation => { |
| ... | ... | @@ -14291,6 +14322,38 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 14291 | 14322 | const src = inst_data.src(); |
| 14292 | 14323 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 14293 | 14324 | const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand); |
| 14325 | switch (operand_ty.zigTypeTag()) { |
| 14326 | .Fn, |
| 14327 | .NoReturn, |
| 14328 | .Undefined, |
| 14329 | .Null, |
| 14330 | .BoundFn, |
| 14331 | .Opaque, |
| 14332 | => return sema.fail(block, operand_src, "no size available for type '{}'", .{operand_ty.fmt(sema.mod)}), |
| 14333 | |
| 14334 | .Type, |
| 14335 | .EnumLiteral, |
| 14336 | .ComptimeFloat, |
| 14337 | .ComptimeInt, |
| 14338 | .Void, |
| 14339 | => return sema.addIntUnsigned(Type.comptime_int, 0), |
| 14340 | |
| 14341 | .Bool, |
| 14342 | .Int, |
| 14343 | .Float, |
| 14344 | .Pointer, |
| 14345 | .Array, |
| 14346 | .Struct, |
| 14347 | .Optional, |
| 14348 | .ErrorUnion, |
| 14349 | .ErrorSet, |
| 14350 | .Enum, |
| 14351 | .Union, |
| 14352 | .Vector, |
| 14353 | .Frame, |
| 14354 | .AnyFrame, |
| 14355 | => {}, |
| 14356 | } |
| 14294 | 14357 | const target = sema.mod.getTarget(); |
| 14295 | 14358 | const bit_size = try operand_ty.bitSizeAdvanced(target, sema.kit(block, src)); |
| 14296 | 14359 | return sema.addIntUnsigned(Type.comptime_int, bit_size); |
| ... | ... | @@ -14321,7 +14384,7 @@ fn zirClosureCapture( |
| 14321 | 14384 | // value only. In such case we preserve the type and use a dummy runtime value. |
| 14322 | 14385 | const operand = try sema.resolveInst(inst_data.operand); |
| 14323 | 14386 | const val = (try sema.resolveMaybeUndefValAllowVariables(block, src, operand)) orelse |
| 14324 | | Value.initTag(.generic_poison); |
| 14387 | Value.initTag(.unreachable_value); |
| 14325 | 14388 | |
| 14326 | 14389 | try block.wip_capture_scope.captures.putNoClobber(sema.gpa, inst, .{ |
| 14327 | 14390 | .ty = try sema.typeOf(operand).copy(sema.perm_arena), |
| ... | ... | @@ -14358,7 +14421,35 @@ fn zirClosureGet( |
| 14358 | 14421 | scope = scope.parent.?; |
| 14359 | 14422 | } else unreachable; |
| 14360 | 14423 | |
| 14361 | | if (tv.val.tag() == .generic_poison and !block.is_typeof and !block.is_comptime and sema.func != null) { |
| 14424 | if (tv.val.tag() == .unreachable_value and !block.is_typeof and sema.func == null) { |
| 14425 | const msg = msg: { |
| 14426 | const name = name: { |
| 14427 | const file = sema.owner_decl.getFileScope(); |
| 14428 | const tree = file.getTree(sema.mod.gpa) catch |err| { |
| 14429 | // In this case we emit a warning + a less precise source location. |
| 14430 | log.warn("unable to load {s}: {s}", .{ |
| 14431 | file.sub_file_path, @errorName(err), |
| 14432 | }); |
| 14433 | break :name null; |
| 14434 | }; |
| 14435 | const node = sema.owner_decl.relativeToNodeIndex(inst_data.src_node); |
| 14436 | const token = tree.nodes.items(.main_token)[node]; |
| 14437 | break :name tree.tokenSlice(token); |
| 14438 | }; |
| 14439 | |
| 14440 | const msg = if (name) |some| |
| 14441 | try sema.errMsg(block, inst_data.src(), "'{s}' not accessible outside function scope", .{some}) |
| 14442 | else |
| 14443 | try sema.errMsg(block, inst_data.src(), "variable not accessible outside function scope", .{}); |
| 14444 | errdefer msg.destroy(sema.gpa); |
| 14445 | |
| 14446 | // TODO add "declared here" note |
| 14447 | break :msg msg; |
| 14448 | }; |
| 14449 | return sema.failWithOwnedErrorMsg(msg); |
| 14450 | } |
| 14451 | |
| 14452 | if (tv.val.tag() == .unreachable_value and !block.is_typeof and !block.is_comptime and sema.func != null) { |
| 14362 | 14453 | const msg = msg: { |
| 14363 | 14454 | const name = name: { |
| 14364 | 14455 | const file = sema.owner_decl.getFileScope(); |
| ... | ... | @@ -17121,7 +17212,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 17121 | 17212 | try sema.resolveTypeLayout(block, operand_src, operand_ty); |
| 17122 | 17213 | const enum_ty = switch (operand_ty.zigTypeTag()) { |
| 17123 | 17214 | .EnumLiteral => { |
| 17124 | | const val = try sema.resolveConstValue(block, .unneeded, operand, undefined); |
| 17215 | const val = try sema.resolveConstValue(block, .unneeded, operand, ""); |
| 17125 | 17216 | const bytes = val.castTag(.enum_literal).?.data; |
| 17126 | 17217 | return sema.addStrLit(block, bytes); |
| 17127 | 17218 | }, |
| ... | ... | @@ -18379,7 +18470,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 18379 | 18470 | return sema.failWithOwnedErrorMsg(msg); |
| 18380 | 18471 | } |
| 18381 | 18472 | |
| 18382 | | if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |operand_val| { |
| 18473 | if (try sema.resolveMaybeUndefVal(block, operand_src, ptr)) |operand_val| { |
| 18383 | 18474 | if (!dest_ty.ptrAllowsZero() and operand_val.isUndef()) { |
| 18384 | 18475 | return sema.failWithUseOfUndef(block, operand_src); |
| 18385 | 18476 | } |
| ... | ... | @@ -18756,6 +18847,10 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 |
| 18756 | 18847 | break :blk try sema.tupleFieldIndex(block, ty, field_name, rhs_src); |
| 18757 | 18848 | } else try sema.structFieldIndex(block, ty, field_name, rhs_src); |
| 18758 | 18849 | |
| 18850 | if (ty.structFieldIsComptime(field_index)) { |
| 18851 | return sema.fail(block, src, "no offset available for comptime field", .{}); |
| 18852 | } |
| 18853 | |
| 18759 | 18854 | switch (ty.containerLayout()) { |
| 18760 | 18855 | .Packed => { |
| 18761 | 18856 | var bit_sum: u64 = 0; |
| ... | ... | @@ -20096,7 +20191,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 20096 | 20191 | var bound_arg_src: ?LazySrcLoc = null; |
| 20097 | 20192 | if (sema.typeOf(func).tag() == .bound_fn) { |
| 20098 | 20193 | bound_arg_src = func_src; |
| 20099 | | const bound_func = try sema.resolveValue(block, .unneeded, func, undefined); |
| 20194 | const bound_func = try sema.resolveValue(block, .unneeded, func, ""); |
| 20100 | 20195 | const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data; |
| 20101 | 20196 | func = bound_data.func_inst; |
| 20102 | 20197 | resolved_args = try sema.arena.alloc(Air.Inst.Ref, args_ty.structFieldCount() + 1); |
| ... | ... | @@ -20139,6 +20234,10 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 20139 | 20234 | break :blk try sema.tupleFieldIndex(block, struct_ty, field_name, name_src); |
| 20140 | 20235 | } else try sema.structFieldIndex(block, struct_ty, field_name, name_src); |
| 20141 | 20236 | |
| 20237 | if (struct_ty.structFieldIsComptime(field_index)) { |
| 20238 | return sema.fail(block, src, "cannot get @fieldParentPtr of a comptime field", .{}); |
| 20239 | } |
| 20240 | |
| 20142 | 20241 | try sema.checkPtrOperand(block, ptr_src, field_ptr_ty); |
| 20143 | 20242 | const field_ptr_ty_info = field_ptr_ty.ptrInfo().data; |
| 20144 | 20243 | |
| ... | ... | @@ -21197,6 +21296,8 @@ const ExternPosition = enum { |
| 21197 | 21296 | ret_ty, |
| 21198 | 21297 | param_ty, |
| 21199 | 21298 | union_field, |
| 21299 | struct_field, |
| 21300 | element, |
| 21200 | 21301 | other, |
| 21201 | 21302 | }; |
| 21202 | 21303 | |
| ... | ... | @@ -21234,7 +21335,10 @@ fn validateExternType( |
| 21234 | 21335 | 8, 16, 32, 64, 128 => return true, |
| 21235 | 21336 | else => return false, |
| 21236 | 21337 | }, |
| 21237 | | .Fn => return !Type.fnCallingConventionAllowsZigTypes(ty.fnCallingConvention()), |
| 21338 | .Fn => { |
| 21339 | if (position != .other) return false; |
| 21340 | return !Type.fnCallingConventionAllowsZigTypes(ty.fnCallingConvention()); |
| 21341 | }, |
| 21238 | 21342 | .Enum => { |
| 21239 | 21343 | var buf: Type.Payload.Bits = undefined; |
| 21240 | 21344 | return sema.validateExternType(block, src, ty.intTagType(&buf), position); |
| ... | ... | @@ -21253,9 +21357,9 @@ fn validateExternType( |
| 21253 | 21357 | }, |
| 21254 | 21358 | .Array => { |
| 21255 | 21359 | if (position == .ret_ty or position == .param_ty) return false; |
| 21256 | | return sema.validateExternType(block, src, ty.elemType2(), .other); |
| 21360 | return sema.validateExternType(block, src, ty.elemType2(), .element); |
| 21257 | 21361 | }, |
| 21258 | | .Vector => return sema.validateExternType(block, src, ty.elemType2(), .other), |
| 21362 | .Vector => return sema.validateExternType(block, src, ty.elemType2(), .element), |
| 21259 | 21363 | .Optional => return ty.isPtrLikeOptional(), |
| 21260 | 21364 | } |
| 21261 | 21365 | } |
| ... | ... | @@ -21295,11 +21399,18 @@ fn explainWhyTypeIsNotExtern( |
| 21295 | 21399 | } else { |
| 21296 | 21400 | try mod.errNoteNonLazy(src_loc, msg, "only integers with power of two bits are extern compatible", .{}); |
| 21297 | 21401 | }, |
| 21298 | | .Fn => switch (ty.fnCallingConvention()) { |
| 21299 | | .Unspecified => try mod.errNoteNonLazy(src_loc, msg, "extern function must specify calling convention", .{}), |
| 21300 | | .Async => try mod.errNoteNonLazy(src_loc, msg, "async function cannot be extern", .{}), |
| 21301 | | .Inline => try mod.errNoteNonLazy(src_loc, msg, "inline function cannot be extern", .{}), |
| 21302 | | else => return, |
| 21402 | .Fn => { |
| 21403 | if (position != .other) { |
| 21404 | try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{}); |
| 21405 | try mod.errNoteNonLazy(src_loc, msg, "use '*const ' to make a function pointer type", .{}); |
| 21406 | return; |
| 21407 | } |
| 21408 | switch (ty.fnCallingConvention()) { |
| 21409 | .Unspecified => try mod.errNoteNonLazy(src_loc, msg, "extern function must specify calling convention", .{}), |
| 21410 | .Async => try mod.errNoteNonLazy(src_loc, msg, "async function cannot be extern", .{}), |
| 21411 | .Inline => try mod.errNoteNonLazy(src_loc, msg, "inline function cannot be extern", .{}), |
| 21412 | else => return, |
| 21413 | } |
| 21303 | 21414 | }, |
| 21304 | 21415 | .Enum => { |
| 21305 | 21416 | var buf: Type.Payload.Bits = undefined; |
| ... | ... | @@ -21315,9 +21426,9 @@ fn explainWhyTypeIsNotExtern( |
| 21315 | 21426 | } else if (position == .param_ty) { |
| 21316 | 21427 | return mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a parameter type", .{}); |
| 21317 | 21428 | } |
| 21318 | | try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(), position); |
| 21429 | try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(), .element); |
| 21319 | 21430 | }, |
| 21320 | | .Vector => try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(), position), |
| 21431 | .Vector => try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(), .element), |
| 21321 | 21432 | .Optional => try mod.errNoteNonLazy(src_loc, msg, "only pointer like optionals are extern compatible", .{}), |
| 21322 | 21433 | } |
| 21323 | 21434 | } |
| ... | ... | @@ -22047,7 +22158,7 @@ fn fieldPtr( |
| 22047 | 22158 | } |
| 22048 | 22159 | }, |
| 22049 | 22160 | .Type => { |
| 22050 | | _ = try sema.resolveConstValue(block, .unneeded, object_ptr, undefined); |
| 22161 | _ = try sema.resolveConstValue(block, .unneeded, object_ptr, ""); |
| 22051 | 22162 | const result = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src); |
| 22052 | 22163 | const inner = if (is_pointer_to) |
| 22053 | 22164 | try sema.analyzeLoad(block, src, result, object_ptr_src) |
| ... | ... | @@ -23375,7 +23486,7 @@ fn coerceExtra( |
| 23375 | 23486 | |
| 23376 | 23487 | // Function body to function pointer. |
| 23377 | 23488 | if (inst_ty.zigTypeTag() == .Fn) { |
| 23378 | | const fn_val = try sema.resolveConstValue(block, .unneeded, inst, undefined); |
| 23489 | const fn_val = try sema.resolveConstValue(block, .unneeded, inst, ""); |
| 23379 | 23490 | const fn_decl = fn_val.pointerDecl().?; |
| 23380 | 23491 | const inst_as_ptr = try sema.analyzeDeclRef(fn_decl); |
| 23381 | 23492 | return sema.coerce(block, dest_ty, inst_as_ptr, inst_src); |
| ... | ... | @@ -23677,7 +23788,7 @@ fn coerceExtra( |
| 23677 | 23788 | }, |
| 23678 | 23789 | .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag()) { |
| 23679 | 23790 | .ComptimeFloat => { |
| 23680 | | const val = try sema.resolveConstValue(block, .unneeded, inst, undefined); |
| 23791 | const val = try sema.resolveConstValue(block, .unneeded, inst, ""); |
| 23681 | 23792 | const result_val = try val.floatCast(sema.arena, dest_ty, target); |
| 23682 | 23793 | return try sema.addConstant(dest_ty, result_val); |
| 23683 | 23794 | }, |
| ... | ... | @@ -23735,7 +23846,7 @@ fn coerceExtra( |
| 23735 | 23846 | .Enum => switch (inst_ty.zigTypeTag()) { |
| 23736 | 23847 | .EnumLiteral => { |
| 23737 | 23848 | // enum literal to enum |
| 23738 | | const val = try sema.resolveConstValue(block, .unneeded, inst, undefined); |
| 23849 | const val = try sema.resolveConstValue(block, .unneeded, inst, ""); |
| 23739 | 23850 | const bytes = val.castTag(.enum_literal).?.data; |
| 23740 | 23851 | const field_index = dest_ty.enumFieldIndex(bytes) orelse { |
| 23741 | 23852 | const msg = msg: { |
| ... | ... | @@ -24805,7 +24916,7 @@ fn coerceVarArgParam( |
| 24805 | 24916 | .{}, |
| 24806 | 24917 | ), |
| 24807 | 24918 | .Fn => blk: { |
| 24808 | | const fn_val = try sema.resolveConstValue(block, .unneeded, inst, undefined); |
| 24919 | const fn_val = try sema.resolveConstValue(block, .unneeded, inst, ""); |
| 24809 | 24920 | const fn_decl = fn_val.pointerDecl().?; |
| 24810 | 24921 | break :blk try sema.analyzeDeclRef(fn_decl); |
| 24811 | 24922 | }, |
| ... | ... | @@ -24814,13 +24925,13 @@ fn coerceVarArgParam( |
| 24814 | 24925 | }; |
| 24815 | 24926 | |
| 24816 | 24927 | const coerced_ty = sema.typeOf(coerced); |
| 24817 | | if (!try sema.validateExternType(block, inst_src, coerced_ty, .other)) { |
| 24928 | if (!try sema.validateExternType(block, inst_src, coerced_ty, .param_ty)) { |
| 24818 | 24929 | const msg = msg: { |
| 24819 | 24930 | const msg = try sema.errMsg(block, inst_src, "cannot pass '{}' to variadic function", .{coerced_ty.fmt(sema.mod)}); |
| 24820 | 24931 | errdefer msg.destroy(sema.gpa); |
| 24821 | 24932 | |
| 24822 | 24933 | const src_decl = sema.mod.declPtr(block.src_decl); |
| 24823 | | try sema.explainWhyTypeIsNotExtern(msg, inst_src.toSrcLoc(src_decl), coerced_ty, .other); |
| 24934 | try sema.explainWhyTypeIsNotExtern(msg, inst_src.toSrcLoc(src_decl), coerced_ty, .param_ty); |
| 24824 | 24935 | |
| 24825 | 24936 | try sema.addDeclaredHereNote(msg, coerced_ty); |
| 24826 | 24937 | break :msg msg; |
| ... | ... | @@ -26904,10 +27015,14 @@ fn analyzeIsNull( |
| 26904 | 27015 | } |
| 26905 | 27016 | } |
| 26906 | 27017 | |
| 27018 | const inverted_non_null_res = if (invert_logic) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false; |
| 26907 | 27019 | const operand_ty = sema.typeOf(operand); |
| 26908 | 27020 | var buf: Type.Payload.ElemType = undefined; |
| 26909 | 27021 | if (operand_ty.zigTypeTag() == .Optional and operand_ty.optionalChild(&buf).zigTypeTag() == .NoReturn) { |
| 26910 | | return Air.Inst.Ref.bool_true; |
| 27022 | return inverted_non_null_res; |
| 27023 | } |
| 27024 | if (operand_ty.zigTypeTag() != .Optional and !operand_ty.isPtrLikeOptional()) { |
| 27025 | return inverted_non_null_res; |
| 26911 | 27026 | } |
| 26912 | 27027 | try sema.requireRuntimeBlock(block, src, null); |
| 26913 | 27028 | const air_tag: Air.Inst.Tag = if (invert_logic) .is_non_null else .is_null; |
| ... | ... | @@ -29105,14 +29220,14 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 29105 | 29220 | }; |
| 29106 | 29221 | return sema.failWithOwnedErrorMsg(msg); |
| 29107 | 29222 | } |
| 29108 | | if (struct_obj.layout == .Extern and !try sema.validateExternType(&block_scope, src, field.ty, .other)) { |
| 29223 | if (struct_obj.layout == .Extern and !try sema.validateExternType(&block_scope, src, field.ty, .struct_field)) { |
| 29109 | 29224 | const msg = msg: { |
| 29110 | 29225 | const tree = try sema.getAstTree(&block_scope); |
| 29111 | 29226 | const fields_src = enumFieldSrcLoc(decl, tree.*, 0, i); |
| 29112 | 29227 | const msg = try sema.errMsg(&block_scope, fields_src, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); |
| 29113 | 29228 | errdefer msg.destroy(sema.gpa); |
| 29114 | 29229 | |
| 29115 | | try sema.explainWhyTypeIsNotExtern(msg, fields_src.toSrcLoc(decl), field.ty, .other); |
| 29230 | try sema.explainWhyTypeIsNotExtern(msg, fields_src.toSrcLoc(decl), field.ty, .struct_field); |
| 29116 | 29231 | |
| 29117 | 29232 | try sema.addDeclaredHereNote(msg, field.ty); |
| 29118 | 29233 | break :msg msg; |