| ... | @@ -3087,7 +3087,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -3087,7 +3087,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 3087 | | 3087 | |
| 3088 | const candidate = block.instructions.items[search_index]; | 3088 | const candidate = block.instructions.items[search_index]; |
| 3089 | switch (air_tags[candidate]) { | 3089 | switch (air_tags[candidate]) { |
| 3090 | .dbg_stmt => continue, | 3090 | .dbg_stmt, .dbg_block_begin, .dbg_block_end => continue, |
| 3091 | .store => break candidate, | 3091 | .store => break candidate, |
| 3092 | else => break :ct, | 3092 | else => break :ct, |
| 3093 | } | 3093 | } |
| ... | @@ -3099,7 +3099,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -3099,7 +3099,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 3099 | | 3099 | |
| 3100 | const candidate = block.instructions.items[search_index]; | 3100 | const candidate = block.instructions.items[search_index]; |
| 3101 | switch (air_tags[candidate]) { | 3101 | switch (air_tags[candidate]) { |
| 3102 | .dbg_stmt => continue, | 3102 | .dbg_stmt, .dbg_block_begin, .dbg_block_end => continue, |
| 3103 | .alloc => { | 3103 | .alloc => { |
| 3104 | if (Air.indexToRef(candidate) != alloc) break :ct; | 3104 | if (Air.indexToRef(candidate) != alloc) break :ct; |
| 3105 | break; | 3105 | break; |
| ... | @@ -3317,7 +3317,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -3317,7 +3317,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3317 | | 3317 | |
| 3318 | const candidate = block.instructions.items[search_index]; | 3318 | const candidate = block.instructions.items[search_index]; |
| 3319 | switch (air_tags[candidate]) { | 3319 | switch (air_tags[candidate]) { |
| 3320 | .dbg_stmt => continue, | 3320 | .dbg_stmt, .dbg_block_begin, .dbg_block_end => continue, |
| 3321 | .store => break candidate, | 3321 | .store => break candidate, |
| 3322 | else => break :ct, | 3322 | else => break :ct, |
| 3323 | } | 3323 | } |
| ... | @@ -3329,7 +3329,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -3329,7 +3329,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3329 | | 3329 | |
| 3330 | const candidate = block.instructions.items[search_index]; | 3330 | const candidate = block.instructions.items[search_index]; |
| 3331 | switch (air_tags[candidate]) { | 3331 | switch (air_tags[candidate]) { |
| 3332 | .dbg_stmt => continue, | 3332 | .dbg_stmt, .dbg_block_begin, .dbg_block_end => continue, |
| 3333 | .bitcast => break candidate, | 3333 | .bitcast => break candidate, |
| 3334 | else => break :ct, | 3334 | else => break :ct, |
| 3335 | } | 3335 | } |
| ... | @@ -3341,7 +3341,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -3341,7 +3341,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3341 | | 3341 | |
| 3342 | const candidate = block.instructions.items[search_index]; | 3342 | const candidate = block.instructions.items[search_index]; |
| 3343 | switch (air_tags[candidate]) { | 3343 | switch (air_tags[candidate]) { |
| 3344 | .dbg_stmt => continue, | 3344 | .dbg_stmt, .dbg_block_begin, .dbg_block_end => continue, |
| 3345 | .constant => break candidate, | 3345 | .constant => break candidate, |
| 3346 | else => break :ct, | 3346 | else => break :ct, |
| 3347 | } | 3347 | } |
| ... | @@ -3615,8 +3615,6 @@ fn validateUnionInit( | ... | @@ -3615,8 +3615,6 @@ fn validateUnionInit( |
| 3615 | union_ptr: Air.Inst.Ref, | 3615 | union_ptr: Air.Inst.Ref, |
| 3616 | is_comptime: bool, | 3616 | is_comptime: bool, |
| 3617 | ) CompileError!void { | 3617 | ) CompileError!void { |
| 3618 | const union_obj = union_ty.cast(Type.Payload.Union).?.data; | | |
| 3619 | | | |
| 3620 | if (instrs.len != 1) { | 3618 | if (instrs.len != 1) { |
| 3621 | const msg = msg: { | 3619 | const msg = msg: { |
| 3622 | const msg = try sema.errMsg( | 3620 | const msg = try sema.errMsg( |
| ... | @@ -3650,7 +3648,8 @@ fn validateUnionInit( | ... | @@ -3650,7 +3648,8 @@ fn validateUnionInit( |
| 3650 | const field_src: LazySrcLoc = .{ .node_offset_initializer = field_ptr_data.src_node }; | 3648 | const field_src: LazySrcLoc = .{ .node_offset_initializer = field_ptr_data.src_node }; |
| 3651 | const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data; | 3649 | const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data; |
| 3652 | const field_name = sema.code.nullTerminatedString(field_ptr_extra.field_name_start); | 3650 | const field_name = sema.code.nullTerminatedString(field_ptr_extra.field_name_start); |
| 3653 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_src); | 3651 | // Validate the field access but ignore the index since we want the tag enum field index. |
| | 3652 | _ = try sema.unionFieldIndex(block, union_ty, field_name, field_src); |
| 3654 | const air_tags = sema.air_instructions.items(.tag); | 3653 | const air_tags = sema.air_instructions.items(.tag); |
| 3655 | const air_datas = sema.air_instructions.items(.data); | 3654 | const air_datas = sema.air_instructions.items(.data); |
| 3656 | const field_ptr_air_ref = sema.inst_map.get(field_ptr).?; | 3655 | const field_ptr_air_ref = sema.inst_map.get(field_ptr).?; |
| ... | @@ -3709,7 +3708,9 @@ fn validateUnionInit( | ... | @@ -3709,7 +3708,9 @@ fn validateUnionInit( |
| 3709 | break; | 3708 | break; |
| 3710 | } | 3709 | } |
| 3711 | | 3710 | |
| 3712 | const tag_val = try Value.Tag.enum_field_index.create(sema.arena, field_index); | 3711 | const tag_ty = union_ty.unionTagTypeHypothetical(); |
| | 3712 | const enum_field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name).?); |
| | 3713 | const tag_val = try Value.Tag.enum_field_index.create(sema.arena, enum_field_index); |
| 3713 | | 3714 | |
| 3714 | if (init_val) |val| { | 3715 | if (init_val) |val| { |
| 3715 | // Our task is to delete all the `field_ptr` and `store` instructions, and insert | 3716 | // Our task is to delete all the `field_ptr` and `store` instructions, and insert |
| ... | @@ -3726,7 +3727,7 @@ fn validateUnionInit( | ... | @@ -3726,7 +3727,7 @@ fn validateUnionInit( |
| 3726 | } | 3727 | } |
| 3727 | | 3728 | |
| 3728 | try sema.requireFunctionBlock(block, init_src); | 3729 | try sema.requireFunctionBlock(block, init_src); |
| 3729 | const new_tag = try sema.addConstant(union_obj.tag_ty, tag_val); | 3730 | const new_tag = try sema.addConstant(tag_ty, tag_val); |
| 3730 | _ = try block.addBinOp(.set_union_tag, union_ptr, new_tag); | 3731 | _ = try block.addBinOp(.set_union_tag, union_ptr, new_tag); |
| 3731 | } | 3732 | } |
| 3732 | | 3733 | |
| ... | @@ -5643,6 +5644,37 @@ const GenericCallAdapter = struct { | ... | @@ -5643,6 +5644,37 @@ const GenericCallAdapter = struct { |
| 5643 | } | 5644 | } |
| 5644 | }; | 5645 | }; |
| 5645 | | 5646 | |
| | 5647 | fn addComptimeReturnTypeNote( |
| | 5648 | sema: *Sema, |
| | 5649 | block: *Block, |
| | 5650 | func: Air.Inst.Ref, |
| | 5651 | func_src: LazySrcLoc, |
| | 5652 | return_ty: Type, |
| | 5653 | parent: *Module.ErrorMsg, |
| | 5654 | requires_comptime: bool, |
| | 5655 | ) !void { |
| | 5656 | if (!requires_comptime) return; |
| | 5657 | |
| | 5658 | const src_loc = if (try sema.funcDeclSrc(block, func_src, func)) |capture| blk: { |
| | 5659 | var src_loc = capture; |
| | 5660 | src_loc.lazy = .{ .node_offset_fn_type_ret_ty = 0 }; |
| | 5661 | break :blk src_loc; |
| | 5662 | } else blk: { |
| | 5663 | const src_decl = sema.mod.declPtr(block.src_decl); |
| | 5664 | break :blk func_src.toSrcLoc(src_decl); |
| | 5665 | }; |
| | 5666 | if (return_ty.tag() == .generic_poison) { |
| | 5667 | return sema.mod.errNoteNonLazy(src_loc, parent, "generic function is instantiated with a comptime only return type", .{}); |
| | 5668 | } |
| | 5669 | try sema.mod.errNoteNonLazy( |
| | 5670 | src_loc, |
| | 5671 | parent, |
| | 5672 | "function is being called at comptime because it returns a comptime only type '{}'", |
| | 5673 | .{return_ty.fmt(sema.mod)}, |
| | 5674 | ); |
| | 5675 | try sema.explainWhyTypeIsComptime(block, func_src, parent, src_loc, return_ty); |
| | 5676 | } |
| | 5677 | |
| 5646 | fn analyzeCall( | 5678 | fn analyzeCall( |
| 5647 | sema: *Sema, | 5679 | sema: *Sema, |
| 5648 | block: *Block, | 5680 | block: *Block, |
| ... | @@ -5733,9 +5765,11 @@ fn analyzeCall( | ... | @@ -5733,9 +5765,11 @@ fn analyzeCall( |
| 5733 | | 5765 | |
| 5734 | var is_generic_call = func_ty_info.is_generic; | 5766 | var is_generic_call = func_ty_info.is_generic; |
| 5735 | var is_comptime_call = block.is_comptime or modifier == .compile_time; | 5767 | var is_comptime_call = block.is_comptime or modifier == .compile_time; |
| | 5768 | var comptime_only_ret_ty = false; |
| 5736 | if (!is_comptime_call) { | 5769 | if (!is_comptime_call) { |
| 5737 | if (sema.typeRequiresComptime(block, func_src, func_ty_info.return_type)) |ct| { | 5770 | if (sema.typeRequiresComptime(block, func_src, func_ty_info.return_type)) |ct| { |
| 5738 | is_comptime_call = ct; | 5771 | is_comptime_call = ct; |
| | 5772 | comptime_only_ret_ty = ct; |
| 5739 | } else |err| switch (err) { | 5773 | } else |err| switch (err) { |
| 5740 | error.GenericPoison => is_generic_call = true, | 5774 | error.GenericPoison => is_generic_call = true, |
| 5741 | else => |e| return e, | 5775 | else => |e| return e, |
| ... | @@ -5764,6 +5798,7 @@ fn analyzeCall( | ... | @@ -5764,6 +5798,7 @@ fn analyzeCall( |
| 5764 | error.ComptimeReturn => { | 5798 | error.ComptimeReturn => { |
| 5765 | is_inline_call = true; | 5799 | is_inline_call = true; |
| 5766 | is_comptime_call = true; | 5800 | is_comptime_call = true; |
| | 5801 | comptime_only_ret_ty = true; |
| 5767 | }, | 5802 | }, |
| 5768 | else => |e| return e, | 5803 | else => |e| return e, |
| 5769 | } | 5804 | } |
| ... | @@ -5774,8 +5809,12 @@ fn analyzeCall( | ... | @@ -5774,8 +5809,12 @@ fn analyzeCall( |
| 5774 | } | 5809 | } |
| 5775 | | 5810 | |
| 5776 | const result: Air.Inst.Ref = if (is_inline_call) res: { | 5811 | const result: Air.Inst.Ref = if (is_inline_call) res: { |
| 5777 | // TODO explain why function is being called at comptime | 5812 | const func_val = sema.resolveConstValue(block, func_src, func, "function being called at comptime must be comptime known") catch |err| { |
| 5778 | const func_val = try sema.resolveConstValue(block, func_src, func, "function being called at comptime must be comptime known"); | 5813 | if (err == error.AnalysisFail and sema.err != null) { |
| | 5814 | try sema.addComptimeReturnTypeNote(block, func, func_src, func_ty_info.return_type, sema.err.?, comptime_only_ret_ty); |
| | 5815 | } |
| | 5816 | return err; |
| | 5817 | }; |
| 5779 | const module_fn = switch (func_val.tag()) { | 5818 | const module_fn = switch (func_val.tag()) { |
| 5780 | .decl_ref => mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data, | 5819 | .decl_ref => mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data, |
| 5781 | .function => func_val.castTag(.function).?.data, | 5820 | .function => func_val.castTag(.function).?.data, |
| ... | @@ -5887,6 +5926,11 @@ fn analyzeCall( | ... | @@ -5887,6 +5926,11 @@ fn analyzeCall( |
| 5887 | is_comptime_call, | 5926 | is_comptime_call, |
| 5888 | &should_memoize, | 5927 | &should_memoize, |
| 5889 | memoized_call_key, | 5928 | memoized_call_key, |
| | 5929 | // last 4 arguments are only used when reporting errors |
| | 5930 | undefined, |
| | 5931 | undefined, |
| | 5932 | undefined, |
| | 5933 | undefined, |
| 5890 | ) catch |err| switch (err) { | 5934 | ) catch |err| switch (err) { |
| 5891 | error.NeededSourceLocation => { | 5935 | error.NeededSourceLocation => { |
| 5892 | sema.inst_map.clearRetainingCapacity(); | 5936 | sema.inst_map.clearRetainingCapacity(); |
| ... | @@ -5904,6 +5948,10 @@ fn analyzeCall( | ... | @@ -5904,6 +5948,10 @@ fn analyzeCall( |
| 5904 | is_comptime_call, | 5948 | is_comptime_call, |
| 5905 | &should_memoize, | 5949 | &should_memoize, |
| 5906 | memoized_call_key, | 5950 | memoized_call_key, |
| | 5951 | func, |
| | 5952 | func_src, |
| | 5953 | func_ty_info.return_type, |
| | 5954 | comptime_only_ret_ty, |
| 5907 | ); | 5955 | ); |
| 5908 | return error.AnalysisFail; | 5956 | return error.AnalysisFail; |
| 5909 | }, | 5957 | }, |
| ... | @@ -6119,6 +6167,10 @@ fn analyzeInlineCallArg( | ... | @@ -6119,6 +6167,10 @@ fn analyzeInlineCallArg( |
| 6119 | is_comptime_call: bool, | 6167 | is_comptime_call: bool, |
| 6120 | should_memoize: *bool, | 6168 | should_memoize: *bool, |
| 6121 | memoized_call_key: Module.MemoizedCall.Key, | 6169 | memoized_call_key: Module.MemoizedCall.Key, |
| | 6170 | func: Air.Inst.Ref, |
| | 6171 | func_src: LazySrcLoc, |
| | 6172 | ret_ty: Type, |
| | 6173 | comptime_only_ret_ty: bool, |
| 6122 | ) !void { | 6174 | ) !void { |
| 6123 | const zir_tags = sema.code.instructions.items(.tag); | 6175 | const zir_tags = sema.code.instructions.items(.tag); |
| 6124 | switch (zir_tags[inst]) { | 6176 | switch (zir_tags[inst]) { |
| ... | @@ -6134,14 +6186,23 @@ fn analyzeInlineCallArg( | ... | @@ -6134,14 +6186,23 @@ fn analyzeInlineCallArg( |
| 6134 | new_fn_info.param_types[arg_i.*] = param_ty; | 6186 | new_fn_info.param_types[arg_i.*] = param_ty; |
| 6135 | const uncasted_arg = uncasted_args[arg_i.*]; | 6187 | const uncasted_arg = uncasted_args[arg_i.*]; |
| 6136 | if (try sema.typeRequiresComptime(arg_block, arg_src, param_ty)) { | 6188 | if (try sema.typeRequiresComptime(arg_block, arg_src, param_ty)) { |
| 6137 | _ = try sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "argument to parameter with comptime only type must be comptime known"); | 6189 | _ = sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "argument to parameter with comptime only type must be comptime known") catch |err| { |
| | 6190 | if (err == error.AnalysisFail and sema.err != null) { |
| | 6191 | try sema.addComptimeReturnTypeNote(arg_block, func, func_src, ret_ty, sema.err.?, comptime_only_ret_ty); |
| | 6192 | } |
| | 6193 | return err; |
| | 6194 | }; |
| 6138 | } | 6195 | } |
| 6139 | const casted_arg = try sema.coerce(arg_block, param_ty, uncasted_arg, arg_src); | 6196 | const casted_arg = try sema.coerce(arg_block, param_ty, uncasted_arg, arg_src); |
| 6140 | try sema.inst_map.putNoClobber(sema.gpa, inst, casted_arg); | 6197 | try sema.inst_map.putNoClobber(sema.gpa, inst, casted_arg); |
| 6141 | | 6198 | |
| 6142 | if (is_comptime_call) { | 6199 | if (is_comptime_call) { |
| 6143 | // TODO explain why function is being called at comptime | 6200 | const arg_val = sema.resolveConstMaybeUndefVal(arg_block, arg_src, casted_arg, "argument to function being called at comptime must be comptime known") catch |err| { |
| 6144 | const arg_val = try sema.resolveConstMaybeUndefVal(arg_block, arg_src, casted_arg, "argument to function being called at comptime must be comptime known"); | 6201 | if (err == error.AnalysisFail and sema.err != null) { |
| | 6202 | try sema.addComptimeReturnTypeNote(arg_block, func, func_src, ret_ty, sema.err.?, comptime_only_ret_ty); |
| | 6203 | } |
| | 6204 | return err; |
| | 6205 | }; |
| 6145 | switch (arg_val.tag()) { | 6206 | switch (arg_val.tag()) { |
| 6146 | .generic_poison, .generic_poison_type => { | 6207 | .generic_poison, .generic_poison_type => { |
| 6147 | // This function is currently evaluated as part of an as-of-yet unresolvable | 6208 | // This function is currently evaluated as part of an as-of-yet unresolvable |
| ... | @@ -6171,8 +6232,12 @@ fn analyzeInlineCallArg( | ... | @@ -6171,8 +6232,12 @@ fn analyzeInlineCallArg( |
| 6171 | try sema.inst_map.putNoClobber(sema.gpa, inst, uncasted_arg); | 6232 | try sema.inst_map.putNoClobber(sema.gpa, inst, uncasted_arg); |
| 6172 | | 6233 | |
| 6173 | if (is_comptime_call) { | 6234 | if (is_comptime_call) { |
| 6174 | // TODO explain why function is being called at comptime | 6235 | const arg_val = sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "argument to function being called at comptime must be comptime known") catch |err| { |
| 6175 | const arg_val = try sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "argument to function being called at comptime must be comptime known"); | 6236 | if (err == error.AnalysisFail and sema.err != null) { |
| | 6237 | try sema.addComptimeReturnTypeNote(arg_block, func, func_src, ret_ty, sema.err.?, comptime_only_ret_ty); |
| | 6238 | } |
| | 6239 | return err; |
| | 6240 | }; |
| 6176 | switch (arg_val.tag()) { | 6241 | switch (arg_val.tag()) { |
| 6177 | .generic_poison, .generic_poison_type => { | 6242 | .generic_poison, .generic_poison_type => { |
| 6178 | // This function is currently evaluated as part of an as-of-yet unresolvable | 6243 | // This function is currently evaluated as part of an as-of-yet unresolvable |
| ... | @@ -8774,13 +8839,11 @@ fn zirSwitchCapture( | ... | @@ -8774,13 +8839,11 @@ fn zirSwitchCapture( |
| 8774 | switch (operand_ty.zigTypeTag()) { | 8839 | switch (operand_ty.zigTypeTag()) { |
| 8775 | .Union => { | 8840 | .Union => { |
| 8776 | const union_obj = operand_ty.cast(Type.Payload.Union).?.data; | 8841 | const union_obj = operand_ty.cast(Type.Payload.Union).?.data; |
| 8777 | const enum_ty = union_obj.tag_ty; | | |
| 8778 | | | |
| 8779 | const first_item = try sema.resolveInst(items[0]); | 8842 | const first_item = try sema.resolveInst(items[0]); |
| 8780 | // Previous switch validation ensured this will succeed | 8843 | // Previous switch validation ensured this will succeed |
| 8781 | const first_item_val = sema.resolveConstValue(block, .unneeded, first_item, undefined) catch unreachable; | 8844 | const first_item_val = sema.resolveConstValue(block, .unneeded, first_item, undefined) catch unreachable; |
| 8782 | | 8845 | |
| 8783 | const first_field_index = @intCast(u32, enum_ty.enumTagFieldIndex(first_item_val, sema.mod).?); | 8846 | const first_field_index = @intCast(u32, operand_ty.unionTagFieldIndex(first_item_val, sema.mod).?); |
| 8784 | const first_field = union_obj.fields.values()[first_field_index]; | 8847 | const first_field = union_obj.fields.values()[first_field_index]; |
| 8785 | | 8848 | |
| 8786 | for (items[1..]) |item, i| { | 8849 | for (items[1..]) |item, i| { |
| ... | @@ -8788,7 +8851,7 @@ fn zirSwitchCapture( | ... | @@ -8788,7 +8851,7 @@ fn zirSwitchCapture( |
| 8788 | // Previous switch validation ensured this will succeed | 8851 | // Previous switch validation ensured this will succeed |
| 8789 | const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable; | 8852 | const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable; |
| 8790 | | 8853 | |
| 8791 | const field_index = enum_ty.enumTagFieldIndex(item_val, sema.mod).?; | 8854 | const field_index = operand_ty.unionTagFieldIndex(item_val, sema.mod).?; |
| 8792 | const field = union_obj.fields.values()[field_index]; | 8855 | const field = union_obj.fields.values()[field_index]; |
| 8793 | if (!field.ty.eql(first_field.ty, sema.mod)) { | 8856 | if (!field.ty.eql(first_field.ty, sema.mod)) { |
| 8794 | const msg = msg: { | 8857 | const msg = msg: { |
| ... | @@ -15521,7 +15584,9 @@ fn unionInit( | ... | @@ -15521,7 +15584,9 @@ fn unionInit( |
| 15521 | const init = try sema.coerce(block, field.ty, uncasted_init, init_src); | 15584 | const init = try sema.coerce(block, field.ty, uncasted_init, init_src); |
| 15522 | | 15585 | |
| 15523 | if (try sema.resolveMaybeUndefVal(block, init_src, init)) |init_val| { | 15586 | if (try sema.resolveMaybeUndefVal(block, init_src, init)) |init_val| { |
| 15524 | const tag_val = try Value.Tag.enum_field_index.create(sema.arena, field_index); | 15587 | const tag_ty = union_ty.unionTagTypeHypothetical(); |
| | 15588 | const enum_field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name).?); |
| | 15589 | const tag_val = try Value.Tag.enum_field_index.create(sema.arena, enum_field_index); |
| 15525 | return sema.addConstant(union_ty, try Value.Tag.@"union".create(sema.arena, .{ | 15590 | return sema.addConstant(union_ty, try Value.Tag.@"union".create(sema.arena, .{ |
| 15526 | .tag = tag_val, | 15591 | .tag = tag_val, |
| 15527 | .val = init_val, | 15592 | .val = init_val, |
| ... | @@ -15619,7 +15684,9 @@ fn zirStructInit( | ... | @@ -15619,7 +15684,9 @@ fn zirStructInit( |
| 15619 | const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data; | 15684 | const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data; |
| 15620 | const field_name = sema.code.nullTerminatedString(field_type_extra.name_start); | 15685 | const field_name = sema.code.nullTerminatedString(field_type_extra.name_start); |
| 15621 | const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src); | 15686 | const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src); |
| 15622 | const tag_val = try Value.Tag.enum_field_index.create(sema.arena, field_index); | 15687 | const tag_ty = resolved_ty.unionTagTypeHypothetical(); |
| | 15688 | const enum_field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name).?); |
| | 15689 | const tag_val = try Value.Tag.enum_field_index.create(sema.arena, enum_field_index); |
| 15623 | | 15690 | |
| 15624 | const init_inst = try sema.resolveInst(item.data.init); | 15691 | const init_inst = try sema.resolveInst(item.data.init); |
| 15625 | if (try sema.resolveMaybeUndefVal(block, field_src, init_inst)) |val| { | 15692 | if (try sema.resolveMaybeUndefVal(block, field_src, init_inst)) |val| { |
| ... | @@ -16384,9 +16451,8 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in | ... | @@ -16384,9 +16451,8 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in |
| 16384 | const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src); | 16451 | const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src); |
| 16385 | const val = try sema.resolveConstValue(block, operand_src, type_info, "operand to @Type must be comptime known"); | 16452 | const val = try sema.resolveConstValue(block, operand_src, type_info, "operand to @Type must be comptime known"); |
| 16386 | const union_val = val.cast(Value.Payload.Union).?.data; | 16453 | const union_val = val.cast(Value.Payload.Union).?.data; |
| 16387 | const tag_ty = type_info_ty.unionTagType().?; | | |
| 16388 | const target = mod.getTarget(); | 16454 | const target = mod.getTarget(); |
| 16389 | const tag_index = tag_ty.enumTagFieldIndex(union_val.tag, mod).?; | 16455 | const tag_index = type_info_ty.unionTagFieldIndex(union_val.tag, mod).?; |
| 16390 | if (union_val.val.anyUndef()) return sema.failWithUseOfUndef(block, src); | 16456 | if (union_val.val.anyUndef()) return sema.failWithUseOfUndef(block, src); |
| 16391 | switch (@intToEnum(std.builtin.TypeId, tag_index)) { | 16457 | switch (@intToEnum(std.builtin.TypeId, tag_index)) { |
| 16392 | .Type => return Air.Inst.Ref.type_type, | 16458 | .Type => return Air.Inst.Ref.type_type, |
| ... | @@ -25091,8 +25157,7 @@ fn coerceEnumToUnion( | ... | @@ -25091,8 +25157,7 @@ fn coerceEnumToUnion( |
| 25091 | | 25157 | |
| 25092 | const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src); | 25158 | const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src); |
| 25093 | if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| { | 25159 | if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| { |
| 25094 | const union_obj = union_ty.cast(Type.Payload.Union).?.data; | 25160 | const field_index = union_ty.unionTagFieldIndex(val, sema.mod) orelse { |
| 25095 | const field_index = union_obj.tag_ty.enumTagFieldIndex(val, sema.mod) orelse { | | |
| 25096 | const msg = msg: { | 25161 | const msg = msg: { |
| 25097 | const msg = try sema.errMsg(block, inst_src, "union '{}' has no tag with value '{}'", .{ | 25162 | const msg = try sema.errMsg(block, inst_src, "union '{}' has no tag with value '{}'", .{ |
| 25098 | union_ty.fmt(sema.mod), val.fmtValue(tag_ty, sema.mod), | 25163 | union_ty.fmt(sema.mod), val.fmtValue(tag_ty, sema.mod), |
| ... | @@ -25103,6 +25168,8 @@ fn coerceEnumToUnion( | ... | @@ -25103,6 +25168,8 @@ fn coerceEnumToUnion( |
| 25103 | }; | 25168 | }; |
| 25104 | return sema.failWithOwnedErrorMsg(msg); | 25169 | return sema.failWithOwnedErrorMsg(msg); |
| 25105 | }; | 25170 | }; |
| | 25171 | |
| | 25172 | const union_obj = union_ty.cast(Type.Payload.Union).?.data; |
| 25106 | const field = union_obj.fields.values()[field_index]; | 25173 | const field = union_obj.fields.values()[field_index]; |
| 25107 | const field_ty = try sema.resolveTypeFields(block, inst_src, field.ty); | 25174 | const field_ty = try sema.resolveTypeFields(block, inst_src, field.ty); |
| 25108 | if (field_ty.zigTypeTag() == .NoReturn) { | 25175 | if (field_ty.zigTypeTag() == .NoReturn) { |