| ... | @@ -1034,8 +1034,8 @@ fn analyzeBodyInner( | ... | @@ -1034,8 +1034,8 @@ fn analyzeBodyInner( |
| 1034 | i += 1; | 1034 | i += 1; |
| 1035 | continue; | 1035 | continue; |
| 1036 | }, | 1036 | }, |
| 1037 | .ensure_err_payload_void => { | 1037 | .ensure_err_union_payload_void => { |
| 1038 | try sema.zirEnsureErrPayloadVoid(block, inst); | 1038 | try sema.zirEnsureErrUnionPayloadVoid(block, inst); |
| 1039 | i += 1; | 1039 | i += 1; |
| 1040 | continue; | 1040 | continue; |
| 1041 | }, | 1041 | }, |
| ... | @@ -1302,17 +1302,28 @@ fn analyzeBodyInner( | ... | @@ -1302,17 +1302,28 @@ fn analyzeBodyInner( |
| 1302 | // current list of parameters and restore it later. | 1302 | // current list of parameters and restore it later. |
| 1303 | // Note: this probably needs to be resolved in a more general manner. | 1303 | // Note: this probably needs to be resolved in a more general manner. |
| 1304 | const prev_params = block.params; | 1304 | const prev_params = block.params; |
| 1305 | const prev_inline_block = block.inline_block; | 1305 | const need_sub_block = tags[inline_body[inline_body.len - 1]] == .repeat_inline; |
| 1306 | if (tags[inline_body[inline_body.len - 1]] == .repeat_inline) { | 1306 | var sub_block = block; |
| 1307 | block.inline_block = inline_body[0]; | 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 | block.params = .{}; | 1316 | block.params = .{}; |
| 1310 | defer { | 1317 | defer { |
| 1311 | block.params.deinit(gpa); | 1318 | block.params.deinit(gpa); |
| 1312 | block.params = prev_params; | 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 | // A runtime conditional branch that needs a post-hoc block to be | 1327 | // A runtime conditional branch that needs a post-hoc block to be |
| 1317 | // emitted communicates this by mapping the block index into the inst map. | 1328 | // emitted communicates this by mapping the block index into the inst map. |
| 1318 | if (map.get(inst)) |new_block_ref| ph: { | 1329 | if (map.get(inst)) |new_block_ref| ph: { |
| ... | @@ -2469,7 +2480,7 @@ fn createAnonymousDeclTypeNamed( | ... | @@ -2469,7 +2480,7 @@ fn createAnonymousDeclTypeNamed( |
| 2469 | const arg = sema.inst_map.get(zir_inst).?; | 2480 | const arg = sema.inst_map.get(zir_inst).?; |
| 2470 | // The comptime call code in analyzeCall already did this, so we're | 2481 | // The comptime call code in analyzeCall already did this, so we're |
| 2471 | // just repeating it here and it's guaranteed to work. | 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 | if (arg_i != 0) try buf.appendSlice(","); | 2485 | if (arg_i != 0) try buf.appendSlice(","); |
| 2475 | try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg), sema.mod)}); | 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,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 | fn zirIndexablePtrLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 3130 | fn zirIndexablePtrLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 3093 | const tracy = trace(@src()); | 3131 | const tracy = trace(@src()); |
| 3094 | defer tracy.end(); | 3132 | defer tracy.end(); |
| ... | @@ -5631,7 +5669,7 @@ fn zirCall( | ... | @@ -5631,7 +5669,7 @@ fn zirCall( |
| 5631 | var bound_arg_src: ?LazySrcLoc = null; | 5669 | var bound_arg_src: ?LazySrcLoc = null; |
| 5632 | if (func_type.tag() == .bound_fn) { | 5670 | if (func_type.tag() == .bound_fn) { |
| 5633 | bound_arg_src = func_src; | 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 | const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data; | 5673 | const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data; |
| 5636 | func = bound_data.func_inst; | 5674 | func = bound_data.func_inst; |
| 5637 | resolved_args = try sema.arena.alloc(Air.Inst.Ref, args_len + 1); | 5675 | resolved_args = try sema.arena.alloc(Air.Inst.Ref, args_len + 1); |
| ... | @@ -6010,6 +6048,7 @@ fn analyzeCall( | ... | @@ -6010,6 +6048,7 @@ fn analyzeCall( |
| 6010 | const parent_inst_map = sema.inst_map; | 6048 | const parent_inst_map = sema.inst_map; |
| 6011 | sema.inst_map = .{}; | 6049 | sema.inst_map = .{}; |
| 6012 | defer { | 6050 | defer { |
| | 6051 | sema.src = call_src; |
| 6013 | sema.inst_map.deinit(gpa); | 6052 | sema.inst_map.deinit(gpa); |
| 6014 | sema.inst_map = parent_inst_map; | 6053 | sema.inst_map = parent_inst_map; |
| 6015 | } | 6054 | } |
| ... | @@ -6213,7 +6252,7 @@ fn analyzeCall( | ... | @@ -6213,7 +6252,7 @@ fn analyzeCall( |
| 6213 | } | 6252 | } |
| 6214 | | 6253 | |
| 6215 | if (should_memoize and is_comptime_call) { | 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 | // TODO: check whether any external comptime memory was mutated by the | 6257 | // TODO: check whether any external comptime memory was mutated by the |
| 6219 | // comptime function call. If so, then do not memoize the call here. | 6258 | // comptime function call. If so, then do not memoize the call here. |
| ... | @@ -6675,6 +6714,8 @@ fn instantiateGenericCall( | ... | @@ -6675,6 +6714,8 @@ fn instantiateGenericCall( |
| 6675 | .comptime_args_fn_inst = module_fn.zir_body_inst, | 6714 | .comptime_args_fn_inst = module_fn.zir_body_inst, |
| 6676 | .preallocated_new_func = new_module_func, | 6715 | .preallocated_new_func = new_module_func, |
| 6677 | .is_generic_instantiation = true, | 6716 | .is_generic_instantiation = true, |
| | 6717 | .branch_quota = sema.branch_quota, |
| | 6718 | .branch_count = sema.branch_count, |
| 6678 | }; | 6719 | }; |
| 6679 | defer child_sema.deinit(); | 6720 | defer child_sema.deinit(); |
| 6680 | | 6721 | |
| ... | @@ -6724,12 +6765,12 @@ fn instantiateGenericCall( | ... | @@ -6724,12 +6765,12 @@ fn instantiateGenericCall( |
| 6724 | const child_arg = try child_sema.addConstant(sema.typeOf(arg), arg_val); | 6765 | const child_arg = try child_sema.addConstant(sema.typeOf(arg), arg_val); |
| 6725 | child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); | 6766 | child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); |
| 6726 | } else { | 6767 | } else { |
| 6727 | return sema.failWithNeededComptime(block, .unneeded, undefined); | 6768 | return sema.failWithNeededComptime(block, .unneeded, ""); |
| 6728 | } | 6769 | } |
| 6729 | } else if (is_anytype) { | 6770 | } else if (is_anytype) { |
| 6730 | const arg_ty = sema.typeOf(arg); | 6771 | const arg_ty = sema.typeOf(arg); |
| 6731 | if (try sema.typeRequiresComptime(arg_ty)) { | 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 | const child_arg = try child_sema.addConstant(arg_ty, arg_val); | 6774 | const child_arg = try child_sema.addConstant(arg_ty, arg_val); |
| 6734 | child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); | 6775 | child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); |
| 6735 | } else { | 6776 | } else { |
| ... | @@ -6751,7 +6792,7 @@ fn instantiateGenericCall( | ... | @@ -6751,7 +6792,7 @@ fn instantiateGenericCall( |
| 6751 | } | 6792 | } |
| 6752 | return err; | 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 | const new_func = new_func_val.castTag(.function).?.data; | 6796 | const new_func = new_func_val.castTag(.function).?.data; |
| 6756 | errdefer new_func.deinit(gpa); | 6797 | errdefer new_func.deinit(gpa); |
| 6757 | assert(new_func == new_module_func); | 6798 | assert(new_func == new_module_func); |
| ... | @@ -7674,24 +7715,6 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE | ... | @@ -7674,24 +7715,6 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 7674 | return block.addTyOp(.unwrap_errunion_err_ptr, result_ty, operand); | 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 | fn zirFunc( | 7718 | fn zirFunc( |
| 7696 | sema: *Sema, | 7719 | sema: *Sema, |
| 7697 | block: *Block, | 7720 | block: *Block, |
| ... | @@ -9119,7 +9142,7 @@ fn zirSwitchCapture( | ... | @@ -9119,7 +9142,7 @@ fn zirSwitchCapture( |
| 9119 | const union_obj = operand_ty.cast(Type.Payload.Union).?.data; | 9142 | const union_obj = operand_ty.cast(Type.Payload.Union).?.data; |
| 9120 | const first_item = try sema.resolveInst(items[0]); | 9143 | const first_item = try sema.resolveInst(items[0]); |
| 9121 | // Previous switch validation ensured this will succeed | 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 | const first_field_index = @intCast(u32, operand_ty.unionTagFieldIndex(first_item_val, sema.mod).?); | 9147 | const first_field_index = @intCast(u32, operand_ty.unionTagFieldIndex(first_item_val, sema.mod).?); |
| 9125 | const first_field = union_obj.fields.values()[first_field_index]; | 9148 | const first_field = union_obj.fields.values()[first_field_index]; |
| ... | @@ -9127,7 +9150,7 @@ fn zirSwitchCapture( | ... | @@ -9127,7 +9150,7 @@ fn zirSwitchCapture( |
| 9127 | for (items[1..]) |item, i| { | 9150 | for (items[1..]) |item, i| { |
| 9128 | const item_ref = try sema.resolveInst(item); | 9151 | const item_ref = try sema.resolveInst(item); |
| 9129 | // Previous switch validation ensured this will succeed | 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 | const field_index = operand_ty.unionTagFieldIndex(item_val, sema.mod).?; | 9155 | const field_index = operand_ty.unionTagFieldIndex(item_val, sema.mod).?; |
| 9133 | const field = union_obj.fields.values()[field_index]; | 9156 | const field = union_obj.fields.values()[field_index]; |
| ... | @@ -9188,7 +9211,7 @@ fn zirSwitchCapture( | ... | @@ -9188,7 +9211,7 @@ fn zirSwitchCapture( |
| 9188 | for (items) |item| { | 9211 | for (items) |item| { |
| 9189 | const item_ref = try sema.resolveInst(item); | 9212 | const item_ref = try sema.resolveInst(item); |
| 9190 | // Previous switch validation ensured this will succeed | 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 | names.putAssumeCapacityNoClobber( | 9215 | names.putAssumeCapacityNoClobber( |
| 9193 | item_val.getError().?, | 9216 | item_val.getError().?, |
| 9194 | {}, | 9217 | {}, |
| ... | @@ -9202,7 +9225,7 @@ fn zirSwitchCapture( | ... | @@ -9202,7 +9225,7 @@ fn zirSwitchCapture( |
| 9202 | } else { | 9225 | } else { |
| 9203 | const item_ref = try sema.resolveInst(items[0]); | 9226 | const item_ref = try sema.resolveInst(items[0]); |
| 9204 | // Previous switch validation ensured this will succeed | 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 | const item_ty = try Type.Tag.error_set_single.create(sema.arena, item_val.getError().?); | 9230 | const item_ty = try Type.Tag.error_set_single.create(sema.arena, item_val.getError().?); |
| 9208 | return sema.bitCast(block, item_ty, operand, operand_src); | 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,14 +9964,17 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9941 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); | 9964 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 9942 | extra_index += 1; | 9965 | extra_index += 1; |
| 9943 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | 9966 | const body_len = @truncate(u31, sema.code.extra[extra_index]); |
| | 9967 | const is_inline = sema.code.extra[extra_index] >> 31 != 0; |
| 9944 | extra_index += 1; | 9968 | extra_index += 1; |
| 9945 | const body = sema.code.extra[extra_index..][0..body_len]; | 9969 | const body = sema.code.extra[extra_index..][0..body_len]; |
| 9946 | extra_index += body_len; | 9970 | extra_index += body_len; |
| 9947 | | 9971 | |
| 9948 | const item = try sema.resolveInst(item_ref); | 9972 | const item = try sema.resolveInst(item_ref); |
| 9949 | // Validation above ensured these will succeed. | 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 | if (operand_val.eql(item_val, operand_ty, sema.mod)) { | 9975 | if (operand_val.eql(item_val, operand_ty, sema.mod)) { |
| | 9976 | if (is_inline) child_block.inline_case_capture = operand; |
| | 9977 | |
| 9952 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); | 9978 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); |
| 9953 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); | 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,6 +9988,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9962 | const ranges_len = sema.code.extra[extra_index]; | 9988 | const ranges_len = sema.code.extra[extra_index]; |
| 9963 | extra_index += 1; | 9989 | extra_index += 1; |
| 9964 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | 9990 | const body_len = @truncate(u31, sema.code.extra[extra_index]); |
| | 9991 | const is_inline = sema.code.extra[extra_index] >> 31 != 0; |
| 9965 | extra_index += 1; | 9992 | extra_index += 1; |
| 9966 | const items = sema.code.refSlice(extra_index, items_len); | 9993 | const items = sema.code.refSlice(extra_index, items_len); |
| 9967 | extra_index += items_len; | 9994 | extra_index += items_len; |
| ... | @@ -9970,8 +9997,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -9970,8 +9997,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9970 | for (items) |item_ref| { | 9997 | for (items) |item_ref| { |
| 9971 | const item = try sema.resolveInst(item_ref); | 9998 | const item = try sema.resolveInst(item_ref); |
| 9972 | // Validation above ensured these will succeed. | 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 | if (operand_val.eql(item_val, operand_ty, sema.mod)) { | 10001 | if (operand_val.eql(item_val, operand_ty, sema.mod)) { |
| | 10002 | if (is_inline) child_block.inline_case_capture = operand; |
| | 10003 | |
| 9975 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); | 10004 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); |
| 9976 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); | 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,11 +10014,12 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9985 | extra_index += 1; | 10014 | extra_index += 1; |
| 9986 | | 10015 | |
| 9987 | // Validation above ensured these will succeed. | 10016 | // Validation above ensured these will succeed. |
| 9988 | const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first, undefined) catch unreachable; | 10017 | const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first, "") catch unreachable; |
| 9989 | const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last, undefined) catch unreachable; | 10018 | const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last, "") catch unreachable; |
| 9990 | if ((try sema.compare(block, src, operand_val, .gte, first_tv.val, operand_ty)) and | 10019 | if ((try sema.compare(block, src, operand_val, .gte, first_tv.val, operand_ty)) and |
| 9991 | (try sema.compare(block, src, operand_val, .lte, last_tv.val, operand_ty))) | 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 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); | 10023 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); |
| 9994 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); | 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,6 +10029,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9999 | } | 10029 | } |
| 10000 | } | 10030 | } |
| 10001 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, special.body, operand); | 10031 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, special.body, operand); |
| | 10032 | if (special.is_inline) child_block.inline_case_capture = operand; |
| 10002 | return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges); | 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,7 +10091,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10060 | // `item` is already guaranteed to be constant known. | 10091 | // `item` is already guaranteed to be constant known. |
| 10061 | | 10092 | |
| 10062 | const analyze_body = if (union_originally) blk: { | 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 | const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod); | 10095 | const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod); |
| 10065 | break :blk field_ty.zigTypeTag() != .NoReturn; | 10096 | break :blk field_ty.zigTypeTag() != .NoReturn; |
| 10066 | } else true; | 10097 | } else true; |
| ... | @@ -10211,7 +10242,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10211,7 +10242,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10211 | const analyze_body = if (union_originally) | 10242 | const analyze_body = if (union_originally) |
| 10212 | for (items) |item_ref| { | 10243 | for (items) |item_ref| { |
| 10213 | const item = try sema.resolveInst(item_ref); | 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 | const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod); | 10246 | const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod); |
| 10216 | if (field_ty.zigTypeTag() != .NoReturn) break true; | 10247 | if (field_ty.zigTypeTag() != .NoReturn) break true; |
| 10217 | } else false | 10248 | } else false |
| ... | @@ -10606,7 +10637,7 @@ fn resolveSwitchItemVal( | ... | @@ -10606,7 +10637,7 @@ fn resolveSwitchItemVal( |
| 10606 | // Constructing a LazySrcLoc is costly because we only have the switch AST node. | 10637 | // Constructing a LazySrcLoc is costly because we only have the switch AST node. |
| 10607 | // Only if we know for sure we need to report a compile error do we resolve the | 10638 | // Only if we know for sure we need to report a compile error do we resolve the |
| 10608 | // full source locations. | 10639 | // full source locations. |
| 10609 | if (sema.resolveConstValue(block, .unneeded, item, undefined)) |val| { | 10640 | if (sema.resolveConstValue(block, .unneeded, item, "")) |val| { |
| 10610 | return TypedValue{ .ty = item_ty, .val = val }; | 10641 | return TypedValue{ .ty = item_ty, .val = val }; |
| 10611 | } else |err| switch (err) { | 10642 | } else |err| switch (err) { |
| 10612 | error.NeededSourceLocation => { | 10643 | error.NeededSourceLocation => { |
| ... | @@ -14291,6 +14322,38 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -14291,6 +14322,38 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 14291 | const src = inst_data.src(); | 14322 | const src = inst_data.src(); |
| 14292 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | 14323 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 14293 | const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand); | 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 | const target = sema.mod.getTarget(); | 14357 | const target = sema.mod.getTarget(); |
| 14295 | const bit_size = try operand_ty.bitSizeAdvanced(target, sema.kit(block, src)); | 14358 | const bit_size = try operand_ty.bitSizeAdvanced(target, sema.kit(block, src)); |
| 14296 | return sema.addIntUnsigned(Type.comptime_int, bit_size); | 14359 | return sema.addIntUnsigned(Type.comptime_int, bit_size); |
| ... | @@ -14321,7 +14384,7 @@ fn zirClosureCapture( | ... | @@ -14321,7 +14384,7 @@ fn zirClosureCapture( |
| 14321 | // value only. In such case we preserve the type and use a dummy runtime value. | 14384 | // value only. In such case we preserve the type and use a dummy runtime value. |
| 14322 | const operand = try sema.resolveInst(inst_data.operand); | 14385 | const operand = try sema.resolveInst(inst_data.operand); |
| 14323 | const val = (try sema.resolveMaybeUndefValAllowVariables(block, src, operand)) orelse | 14386 | const val = (try sema.resolveMaybeUndefValAllowVariables(block, src, operand)) orelse |
| 14324 | Value.initTag(.generic_poison); | 14387 | Value.initTag(.unreachable_value); |
| 14325 | | 14388 | |
| 14326 | try block.wip_capture_scope.captures.putNoClobber(sema.gpa, inst, .{ | 14389 | try block.wip_capture_scope.captures.putNoClobber(sema.gpa, inst, .{ |
| 14327 | .ty = try sema.typeOf(operand).copy(sema.perm_arena), | 14390 | .ty = try sema.typeOf(operand).copy(sema.perm_arena), |
| ... | @@ -14358,7 +14421,35 @@ fn zirClosureGet( | ... | @@ -14358,7 +14421,35 @@ fn zirClosureGet( |
| 14358 | scope = scope.parent.?; | 14421 | scope = scope.parent.?; |
| 14359 | } else unreachable; | 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 | const msg = msg: { | 14453 | const msg = msg: { |
| 14363 | const name = name: { | 14454 | const name = name: { |
| 14364 | const file = sema.owner_decl.getFileScope(); | 14455 | const file = sema.owner_decl.getFileScope(); |
| ... | @@ -17121,7 +17212,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -17121,7 +17212,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 17121 | try sema.resolveTypeLayout(block, operand_src, operand_ty); | 17212 | try sema.resolveTypeLayout(block, operand_src, operand_ty); |
| 17122 | const enum_ty = switch (operand_ty.zigTypeTag()) { | 17213 | const enum_ty = switch (operand_ty.zigTypeTag()) { |
| 17123 | .EnumLiteral => { | 17214 | .EnumLiteral => { |
| 17124 | const val = try sema.resolveConstValue(block, .unneeded, operand, undefined); | 17215 | const val = try sema.resolveConstValue(block, .unneeded, operand, ""); |
| 17125 | const bytes = val.castTag(.enum_literal).?.data; | 17216 | const bytes = val.castTag(.enum_literal).?.data; |
| 17126 | return sema.addStrLit(block, bytes); | 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,7 +18470,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 18379 | return sema.failWithOwnedErrorMsg(msg); | 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 | if (!dest_ty.ptrAllowsZero() and operand_val.isUndef()) { | 18474 | if (!dest_ty.ptrAllowsZero() and operand_val.isUndef()) { |
| 18384 | return sema.failWithUseOfUndef(block, operand_src); | 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,6 +18847,10 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 |
| 18756 | break :blk try sema.tupleFieldIndex(block, ty, field_name, rhs_src); | 18847 | break :blk try sema.tupleFieldIndex(block, ty, field_name, rhs_src); |
| 18757 | } else try sema.structFieldIndex(block, ty, field_name, rhs_src); | 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 | switch (ty.containerLayout()) { | 18854 | switch (ty.containerLayout()) { |
| 18760 | .Packed => { | 18855 | .Packed => { |
| 18761 | var bit_sum: u64 = 0; | 18856 | var bit_sum: u64 = 0; |
| ... | @@ -20096,7 +20191,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -20096,7 +20191,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 20096 | var bound_arg_src: ?LazySrcLoc = null; | 20191 | var bound_arg_src: ?LazySrcLoc = null; |
| 20097 | if (sema.typeOf(func).tag() == .bound_fn) { | 20192 | if (sema.typeOf(func).tag() == .bound_fn) { |
| 20098 | bound_arg_src = func_src; | 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 | const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data; | 20195 | const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data; |
| 20101 | func = bound_data.func_inst; | 20196 | func = bound_data.func_inst; |
| 20102 | resolved_args = try sema.arena.alloc(Air.Inst.Ref, args_ty.structFieldCount() + 1); | 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,6 +20234,10 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 20139 | break :blk try sema.tupleFieldIndex(block, struct_ty, field_name, name_src); | 20234 | break :blk try sema.tupleFieldIndex(block, struct_ty, field_name, name_src); |
| 20140 | } else try sema.structFieldIndex(block, struct_ty, field_name, name_src); | 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 | try sema.checkPtrOperand(block, ptr_src, field_ptr_ty); | 20241 | try sema.checkPtrOperand(block, ptr_src, field_ptr_ty); |
| 20143 | const field_ptr_ty_info = field_ptr_ty.ptrInfo().data; | 20242 | const field_ptr_ty_info = field_ptr_ty.ptrInfo().data; |
| 20144 | | 20243 | |
| ... | @@ -21197,6 +21296,8 @@ const ExternPosition = enum { | ... | @@ -21197,6 +21296,8 @@ const ExternPosition = enum { |
| 21197 | ret_ty, | 21296 | ret_ty, |
| 21198 | param_ty, | 21297 | param_ty, |
| 21199 | union_field, | 21298 | union_field, |
| | 21299 | struct_field, |
| | 21300 | element, |
| 21200 | other, | 21301 | other, |
| 21201 | }; | 21302 | }; |
| 21202 | | 21303 | |
| ... | @@ -21234,7 +21335,10 @@ fn validateExternType( | ... | @@ -21234,7 +21335,10 @@ fn validateExternType( |
| 21234 | 8, 16, 32, 64, 128 => return true, | 21335 | 8, 16, 32, 64, 128 => return true, |
| 21235 | else => return false, | 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 | .Enum => { | 21342 | .Enum => { |
| 21239 | var buf: Type.Payload.Bits = undefined; | 21343 | var buf: Type.Payload.Bits = undefined; |
| 21240 | return sema.validateExternType(block, src, ty.intTagType(&buf), position); | 21344 | return sema.validateExternType(block, src, ty.intTagType(&buf), position); |
| ... | @@ -21253,9 +21357,9 @@ fn validateExternType( | ... | @@ -21253,9 +21357,9 @@ fn validateExternType( |
| 21253 | }, | 21357 | }, |
| 21254 | .Array => { | 21358 | .Array => { |
| 21255 | if (position == .ret_ty or position == .param_ty) return false; | 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 | .Optional => return ty.isPtrLikeOptional(), | 21363 | .Optional => return ty.isPtrLikeOptional(), |
| 21260 | } | 21364 | } |
| 21261 | } | 21365 | } |
| ... | @@ -21295,11 +21399,18 @@ fn explainWhyTypeIsNotExtern( | ... | @@ -21295,11 +21399,18 @@ fn explainWhyTypeIsNotExtern( |
| 21295 | } else { | 21399 | } else { |
| 21296 | try mod.errNoteNonLazy(src_loc, msg, "only integers with power of two bits are extern compatible", .{}); | 21400 | try mod.errNoteNonLazy(src_loc, msg, "only integers with power of two bits are extern compatible", .{}); |
| 21297 | }, | 21401 | }, |
| 21298 | .Fn => switch (ty.fnCallingConvention()) { | 21402 | .Fn => { |
| 21299 | .Unspecified => try mod.errNoteNonLazy(src_loc, msg, "extern function must specify calling convention", .{}), | 21403 | if (position != .other) { |
| 21300 | .Async => try mod.errNoteNonLazy(src_loc, msg, "async function cannot be extern", .{}), | 21404 | try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{}); |
| 21301 | .Inline => try mod.errNoteNonLazy(src_loc, msg, "inline function cannot be extern", .{}), | 21405 | try mod.errNoteNonLazy(src_loc, msg, "use '*const ' to make a function pointer type", .{}); |
| 21302 | else => return, | 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 | .Enum => { | 21415 | .Enum => { |
| 21305 | var buf: Type.Payload.Bits = undefined; | 21416 | var buf: Type.Payload.Bits = undefined; |
| ... | @@ -21315,9 +21426,9 @@ fn explainWhyTypeIsNotExtern( | ... | @@ -21315,9 +21426,9 @@ fn explainWhyTypeIsNotExtern( |
| 21315 | } else if (position == .param_ty) { | 21426 | } else if (position == .param_ty) { |
| 21316 | return mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a parameter type", .{}); | 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 | .Optional => try mod.errNoteNonLazy(src_loc, msg, "only pointer like optionals are extern compatible", .{}), | 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,7 +22158,7 @@ fn fieldPtr( |
| 22047 | } | 22158 | } |
| 22048 | }, | 22159 | }, |
| 22049 | .Type => { | 22160 | .Type => { |
| 22050 | _ = try sema.resolveConstValue(block, .unneeded, object_ptr, undefined); | 22161 | _ = try sema.resolveConstValue(block, .unneeded, object_ptr, ""); |
| 22051 | const result = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src); | 22162 | const result = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src); |
| 22052 | const inner = if (is_pointer_to) | 22163 | const inner = if (is_pointer_to) |
| 22053 | try sema.analyzeLoad(block, src, result, object_ptr_src) | 22164 | try sema.analyzeLoad(block, src, result, object_ptr_src) |
| ... | @@ -23375,7 +23486,7 @@ fn coerceExtra( | ... | @@ -23375,7 +23486,7 @@ fn coerceExtra( |
| 23375 | | 23486 | |
| 23376 | // Function body to function pointer. | 23487 | // Function body to function pointer. |
| 23377 | if (inst_ty.zigTypeTag() == .Fn) { | 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 | const fn_decl = fn_val.pointerDecl().?; | 23490 | const fn_decl = fn_val.pointerDecl().?; |
| 23380 | const inst_as_ptr = try sema.analyzeDeclRef(fn_decl); | 23491 | const inst_as_ptr = try sema.analyzeDeclRef(fn_decl); |
| 23381 | return sema.coerce(block, dest_ty, inst_as_ptr, inst_src); | 23492 | return sema.coerce(block, dest_ty, inst_as_ptr, inst_src); |
| ... | @@ -23677,7 +23788,7 @@ fn coerceExtra( | ... | @@ -23677,7 +23788,7 @@ fn coerceExtra( |
| 23677 | }, | 23788 | }, |
| 23678 | .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag()) { | 23789 | .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag()) { |
| 23679 | .ComptimeFloat => { | 23790 | .ComptimeFloat => { |
| 23680 | const val = try sema.resolveConstValue(block, .unneeded, inst, undefined); | 23791 | const val = try sema.resolveConstValue(block, .unneeded, inst, ""); |
| 23681 | const result_val = try val.floatCast(sema.arena, dest_ty, target); | 23792 | const result_val = try val.floatCast(sema.arena, dest_ty, target); |
| 23682 | return try sema.addConstant(dest_ty, result_val); | 23793 | return try sema.addConstant(dest_ty, result_val); |
| 23683 | }, | 23794 | }, |
| ... | @@ -23735,7 +23846,7 @@ fn coerceExtra( | ... | @@ -23735,7 +23846,7 @@ fn coerceExtra( |
| 23735 | .Enum => switch (inst_ty.zigTypeTag()) { | 23846 | .Enum => switch (inst_ty.zigTypeTag()) { |
| 23736 | .EnumLiteral => { | 23847 | .EnumLiteral => { |
| 23737 | // enum literal to enum | 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 | const bytes = val.castTag(.enum_literal).?.data; | 23850 | const bytes = val.castTag(.enum_literal).?.data; |
| 23740 | const field_index = dest_ty.enumFieldIndex(bytes) orelse { | 23851 | const field_index = dest_ty.enumFieldIndex(bytes) orelse { |
| 23741 | const msg = msg: { | 23852 | const msg = msg: { |
| ... | @@ -24805,7 +24916,7 @@ fn coerceVarArgParam( | ... | @@ -24805,7 +24916,7 @@ fn coerceVarArgParam( |
| 24805 | .{}, | 24916 | .{}, |
| 24806 | ), | 24917 | ), |
| 24807 | .Fn => blk: { | 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 | const fn_decl = fn_val.pointerDecl().?; | 24920 | const fn_decl = fn_val.pointerDecl().?; |
| 24810 | break :blk try sema.analyzeDeclRef(fn_decl); | 24921 | break :blk try sema.analyzeDeclRef(fn_decl); |
| 24811 | }, | 24922 | }, |
| ... | @@ -24814,13 +24925,13 @@ fn coerceVarArgParam( | ... | @@ -24814,13 +24925,13 @@ fn coerceVarArgParam( |
| 24814 | }; | 24925 | }; |
| 24815 | | 24926 | |
| 24816 | const coerced_ty = sema.typeOf(coerced); | 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 | const msg = msg: { | 24929 | const msg = msg: { |
| 24819 | const msg = try sema.errMsg(block, inst_src, "cannot pass '{}' to variadic function", .{coerced_ty.fmt(sema.mod)}); | 24930 | const msg = try sema.errMsg(block, inst_src, "cannot pass '{}' to variadic function", .{coerced_ty.fmt(sema.mod)}); |
| 24820 | errdefer msg.destroy(sema.gpa); | 24931 | errdefer msg.destroy(sema.gpa); |
| 24821 | | 24932 | |
| 24822 | const src_decl = sema.mod.declPtr(block.src_decl); | 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 | try sema.addDeclaredHereNote(msg, coerced_ty); | 24936 | try sema.addDeclaredHereNote(msg, coerced_ty); |
| 24826 | break :msg msg; | 24937 | break :msg msg; |
| ... | @@ -26904,10 +27015,14 @@ fn analyzeIsNull( | ... | @@ -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 | const operand_ty = sema.typeOf(operand); | 27019 | const operand_ty = sema.typeOf(operand); |
| 26908 | var buf: Type.Payload.ElemType = undefined; | 27020 | var buf: Type.Payload.ElemType = undefined; |
| 26909 | if (operand_ty.zigTypeTag() == .Optional and operand_ty.optionalChild(&buf).zigTypeTag() == .NoReturn) { | 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 | try sema.requireRuntimeBlock(block, src, null); | 27027 | try sema.requireRuntimeBlock(block, src, null); |
| 26913 | const air_tag: Air.Inst.Tag = if (invert_logic) .is_non_null else .is_null; | 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,14 +29220,14 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 29105 | }; | 29220 | }; |
| 29106 | return sema.failWithOwnedErrorMsg(msg); | 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 | const msg = msg: { | 29224 | const msg = msg: { |
| 29110 | const tree = try sema.getAstTree(&block_scope); | 29225 | const tree = try sema.getAstTree(&block_scope); |
| 29111 | const fields_src = enumFieldSrcLoc(decl, tree.*, 0, i); | 29226 | const fields_src = enumFieldSrcLoc(decl, tree.*, 0, i); |
| 29112 | const msg = try sema.errMsg(&block_scope, fields_src, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); | 29227 | const msg = try sema.errMsg(&block_scope, fields_src, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); |
| 29113 | errdefer msg.destroy(sema.gpa); | 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 | try sema.addDeclaredHereNote(msg, field.ty); | 29232 | try sema.addDeclaredHereNote(msg, field.ty); |
| 29118 | break :msg msg; | 29233 | break :msg msg; |