| ... | @@ -4109,6 +4109,8 @@ fn validateUnionInit( | ... | @@ -4109,6 +4109,8 @@ fn validateUnionInit( |
| 4109 | const union_init = try sema.addConstant(union_ty, union_val); | 4109 | const union_init = try sema.addConstant(union_ty, union_val); |
| 4110 | try sema.storePtr2(block, init_src, union_ptr, init_src, union_init, init_src, .store); | 4110 | try sema.storePtr2(block, init_src, union_ptr, init_src, union_init, init_src, .store); |
| 4111 | return; | 4111 | return; |
| | 4112 | } else if (try sema.typeRequiresComptime(union_ty)) { |
| | 4113 | return sema.failWithNeededComptime(block, field_ptr_data.src(), "initializer of comptime only union must be comptime-known"); |
| 4112 | } | 4114 | } |
| 4113 | | 4115 | |
| 4114 | const new_tag = try sema.addConstant(tag_ty, tag_val); | 4116 | const new_tag = try sema.addConstant(tag_ty, tag_val); |
| ... | @@ -4226,6 +4228,7 @@ fn validateStructInit( | ... | @@ -4226,6 +4228,7 @@ fn validateStructInit( |
| 4226 | var first_block_index = block.instructions.items.len; | 4228 | var first_block_index = block.instructions.items.len; |
| 4227 | var make_runtime = false; | 4229 | var make_runtime = false; |
| 4228 | | 4230 | |
| | 4231 | const require_comptime = try sema.typeRequiresComptime(struct_ty); |
| 4229 | const air_tags = sema.air_instructions.items(.tag); | 4232 | const air_tags = sema.air_instructions.items(.tag); |
| 4230 | const air_datas = sema.air_instructions.items(.data); | 4233 | const air_datas = sema.air_instructions.items(.data); |
| 4231 | | 4234 | |
| ... | @@ -4301,6 +4304,9 @@ fn validateStructInit( | ... | @@ -4301,6 +4304,9 @@ fn validateStructInit( |
| 4301 | } | 4304 | } |
| 4302 | if (try sema.resolveMaybeUndefValAllowVariablesMaybeRuntime(bin_op.rhs, &make_runtime)) |val| { | 4305 | if (try sema.resolveMaybeUndefValAllowVariablesMaybeRuntime(bin_op.rhs, &make_runtime)) |val| { |
| 4303 | field_values[i] = val; | 4306 | field_values[i] = val; |
| | 4307 | } else if (require_comptime) { |
| | 4308 | const field_ptr_data = sema.code.instructions.items(.data)[field_ptr].pl_node; |
| | 4309 | return sema.failWithNeededComptime(block, field_ptr_data.src(), "initializer of comptime only struct must be comptime-known"); |
| 4304 | } else { | 4310 | } else { |
| 4305 | struct_is_comptime = false; | 4311 | struct_is_comptime = false; |
| 4306 | } | 4312 | } |
| ... | @@ -5402,7 +5408,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -5402,7 +5408,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 5402 | const options = sema.resolveExportOptions(block, .unneeded, extra.options) catch |err| switch (err) { | 5408 | const options = sema.resolveExportOptions(block, .unneeded, extra.options) catch |err| switch (err) { |
| 5403 | error.NeededSourceLocation => { | 5409 | error.NeededSourceLocation => { |
| 5404 | _ = try sema.resolveExportOptions(block, options_src, extra.options); | 5410 | _ = try sema.resolveExportOptions(block, options_src, extra.options); |
| 5405 | return error.AnalysisFail; | 5411 | unreachable; |
| 5406 | }, | 5412 | }, |
| 5407 | else => |e| return e, | 5413 | else => |e| return e, |
| 5408 | }; | 5414 | }; |
| ... | @@ -5429,7 +5435,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -5429,7 +5435,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 5429 | const options = sema.resolveExportOptions(block, .unneeded, extra.options) catch |err| switch (err) { | 5435 | const options = sema.resolveExportOptions(block, .unneeded, extra.options) catch |err| switch (err) { |
| 5430 | error.NeededSourceLocation => { | 5436 | error.NeededSourceLocation => { |
| 5431 | _ = try sema.resolveExportOptions(block, options_src, extra.options); | 5437 | _ = try sema.resolveExportOptions(block, options_src, extra.options); |
| 5432 | return error.AnalysisFail; | 5438 | unreachable; |
| 5433 | }, | 5439 | }, |
| 5434 | else => |e| return e, | 5440 | else => |e| return e, |
| 5435 | }; | 5441 | }; |
| ... | @@ -6512,7 +6518,7 @@ fn analyzeCall( | ... | @@ -6512,7 +6518,7 @@ fn analyzeCall( |
| 6512 | func_ty_info.param_types, | 6518 | func_ty_info.param_types, |
| 6513 | func, | 6519 | func, |
| 6514 | ); | 6520 | ); |
| 6515 | return error.AnalysisFail; | 6521 | unreachable; |
| 6516 | }, | 6522 | }, |
| 6517 | else => |e| return e, | 6523 | else => |e| return e, |
| 6518 | }; | 6524 | }; |
| ... | @@ -6674,7 +6680,7 @@ fn analyzeCall( | ... | @@ -6674,7 +6680,7 @@ fn analyzeCall( |
| 6674 | uncasted_arg, | 6680 | uncasted_arg, |
| 6675 | opts, | 6681 | opts, |
| 6676 | ); | 6682 | ); |
| 6677 | return error.AnalysisFail; | 6683 | unreachable; |
| 6678 | }, | 6684 | }, |
| 6679 | else => |e| return e, | 6685 | else => |e| return e, |
| 6680 | }; | 6686 | }; |
| ... | @@ -6687,7 +6693,7 @@ fn analyzeCall( | ... | @@ -6687,7 +6693,7 @@ fn analyzeCall( |
| 6687 | uncasted_arg, | 6693 | uncasted_arg, |
| 6688 | Module.argSrc(call_src.node_offset.x, sema.gpa, decl, i, bound_arg_src), | 6694 | Module.argSrc(call_src.node_offset.x, sema.gpa, decl, i, bound_arg_src), |
| 6689 | ); | 6695 | ); |
| 6690 | return error.AnalysisFail; | 6696 | unreachable; |
| 6691 | }, | 6697 | }, |
| 6692 | else => |e| return e, | 6698 | else => |e| return e, |
| 6693 | }; | 6699 | }; |
| ... | @@ -6991,7 +6997,7 @@ fn instantiateGenericCall( | ... | @@ -6991,7 +6997,7 @@ fn instantiateGenericCall( |
| 6991 | const decl = sema.mod.declPtr(block.src_decl); | 6997 | const decl = sema.mod.declPtr(block.src_decl); |
| 6992 | const arg_src = Module.argSrc(call_src.node_offset.x, sema.gpa, decl, i, bound_arg_src); | 6998 | const arg_src = Module.argSrc(call_src.node_offset.x, sema.gpa, decl, i, bound_arg_src); |
| 6993 | _ = try sema.analyzeGenericCallArgVal(block, arg_src, uncasted_args[i]); | 6999 | _ = try sema.analyzeGenericCallArgVal(block, arg_src, uncasted_args[i]); |
| 6994 | return error.AnalysisFail; | 7000 | unreachable; |
| 6995 | }, | 7001 | }, |
| 6996 | else => |e| return e, | 7002 | else => |e| return e, |
| 6997 | }; | 7003 | }; |
| ... | @@ -7174,7 +7180,7 @@ fn instantiateGenericCall( | ... | @@ -7174,7 +7180,7 @@ fn instantiateGenericCall( |
| 7174 | const decl = sema.mod.declPtr(block.src_decl); | 7180 | const decl = sema.mod.declPtr(block.src_decl); |
| 7175 | const arg_src = Module.argSrc(call_src.node_offset.x, sema.gpa, decl, arg_i, bound_arg_src); | 7181 | const arg_src = Module.argSrc(call_src.node_offset.x, sema.gpa, decl, arg_i, bound_arg_src); |
| 7176 | _ = try sema.resolveConstValue(block, arg_src, arg, "argument to parameter with comptime-only type must be comptime-known"); | 7182 | _ = try sema.resolveConstValue(block, arg_src, arg, "argument to parameter with comptime-only type must be comptime-known"); |
| 7177 | return error.AnalysisFail; | 7183 | unreachable; |
| 7178 | }, | 7184 | }, |
| 7179 | else => |e| return e, | 7185 | else => |e| return e, |
| 7180 | }; | 7186 | }; |
| ... | @@ -7330,7 +7336,7 @@ fn instantiateGenericCall( | ... | @@ -7330,7 +7336,7 @@ fn instantiateGenericCall( |
| 7330 | new_fn_info, | 7336 | new_fn_info, |
| 7331 | &runtime_i, | 7337 | &runtime_i, |
| 7332 | ); | 7338 | ); |
| 7333 | return error.AnalysisFail; | 7339 | unreachable; |
| 7334 | }, | 7340 | }, |
| 7335 | else => |e| return e, | 7341 | else => |e| return e, |
| 7336 | }; | 7342 | }; |
| ... | @@ -8417,6 +8423,10 @@ fn funcCommon( | ... | @@ -8417,6 +8423,10 @@ fn funcCommon( |
| 8417 | const param_types = try sema.arena.alloc(Type, block.params.items.len); | 8423 | const param_types = try sema.arena.alloc(Type, block.params.items.len); |
| 8418 | const comptime_params = try sema.arena.alloc(bool, block.params.items.len); | 8424 | const comptime_params = try sema.arena.alloc(bool, block.params.items.len); |
| 8419 | for (block.params.items) |param, i| { | 8425 | for (block.params.items) |param, i| { |
| | 8426 | const is_noalias = blk: { |
| | 8427 | const index = std.math.cast(u5, i) orelse break :blk false; |
| | 8428 | break :blk @truncate(u1, noalias_bits >> index) != 0; |
| | 8429 | }; |
| 8420 | param_types[i] = param.ty; | 8430 | param_types[i] = param.ty; |
| 8421 | sema.analyzeParameter( | 8431 | sema.analyzeParameter( |
| 8422 | block, | 8432 | block, |
| ... | @@ -8427,6 +8437,7 @@ fn funcCommon( | ... | @@ -8427,6 +8437,7 @@ fn funcCommon( |
| 8427 | &is_generic, | 8437 | &is_generic, |
| 8428 | cc_resolved, | 8438 | cc_resolved, |
| 8429 | has_body, | 8439 | has_body, |
| | 8440 | is_noalias, |
| 8430 | ) catch |err| switch (err) { | 8441 | ) catch |err| switch (err) { |
| 8431 | error.NeededSourceLocation => { | 8442 | error.NeededSourceLocation => { |
| 8432 | const decl = sema.mod.declPtr(block.src_decl); | 8443 | const decl = sema.mod.declPtr(block.src_decl); |
| ... | @@ -8439,8 +8450,9 @@ fn funcCommon( | ... | @@ -8439,8 +8450,9 @@ fn funcCommon( |
| 8439 | &is_generic, | 8450 | &is_generic, |
| 8440 | cc_resolved, | 8451 | cc_resolved, |
| 8441 | has_body, | 8452 | has_body, |
| | 8453 | is_noalias, |
| 8442 | ); | 8454 | ); |
| 8443 | return error.AnalysisFail; | 8455 | unreachable; |
| 8444 | }, | 8456 | }, |
| 8445 | else => |e| return e, | 8457 | else => |e| return e, |
| 8446 | }; | 8458 | }; |
| ... | @@ -8689,6 +8701,7 @@ fn analyzeParameter( | ... | @@ -8689,6 +8701,7 @@ fn analyzeParameter( |
| 8689 | is_generic: *bool, | 8701 | is_generic: *bool, |
| 8690 | cc: std.builtin.CallingConvention, | 8702 | cc: std.builtin.CallingConvention, |
| 8691 | has_body: bool, | 8703 | has_body: bool, |
| | 8704 | is_noalias: bool, |
| 8692 | ) !void { | 8705 | ) !void { |
| 8693 | const requires_comptime = try sema.typeRequiresComptime(param.ty); | 8706 | const requires_comptime = try sema.typeRequiresComptime(param.ty); |
| 8694 | comptime_params[i] = param.is_comptime or requires_comptime; | 8707 | comptime_params[i] = param.is_comptime or requires_comptime; |
| ... | @@ -8743,6 +8756,9 @@ fn analyzeParameter( | ... | @@ -8743,6 +8756,9 @@ fn analyzeParameter( |
| 8743 | }; | 8756 | }; |
| 8744 | return sema.failWithOwnedErrorMsg(msg); | 8757 | return sema.failWithOwnedErrorMsg(msg); |
| 8745 | } | 8758 | } |
| | 8759 | if (!this_generic and is_noalias and !param.ty.isPtrAtRuntime()) { |
| | 8760 | return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{}); |
| | 8761 | } |
| 8746 | } | 8762 | } |
| 8747 | | 8763 | |
| 8748 | fn zirParam( | 8764 | fn zirParam( |
| ... | @@ -10633,7 +10649,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10633,7 +10649,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10633 | const case_src = Module.SwitchProngSrc{ .range = .{ .prong = multi_i, .item = range_i } }; | 10649 | const case_src = Module.SwitchProngSrc{ .range = .{ .prong = multi_i, .item = range_i } }; |
| 10634 | const decl = sema.mod.declPtr(case_block.src_decl); | 10650 | const decl = sema.mod.declPtr(case_block.src_decl); |
| 10635 | try sema.emitBackwardBranch(block, case_src.resolve(sema.gpa, decl, src_node_offset, .none)); | 10651 | try sema.emitBackwardBranch(block, case_src.resolve(sema.gpa, decl, src_node_offset, .none)); |
| 10636 | return error.AnalysisFail; | 10652 | unreachable; |
| 10637 | }, | 10653 | }, |
| 10638 | else => return err, | 10654 | else => return err, |
| 10639 | }; | 10655 | }; |
| ... | @@ -10669,7 +10685,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10669,7 +10685,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10669 | const case_src = Module.SwitchProngSrc{ .multi = .{ .prong = multi_i, .item = @intCast(u32, item_i) } }; | 10685 | const case_src = Module.SwitchProngSrc{ .multi = .{ .prong = multi_i, .item = @intCast(u32, item_i) } }; |
| 10670 | const decl = sema.mod.declPtr(case_block.src_decl); | 10686 | const decl = sema.mod.declPtr(case_block.src_decl); |
| 10671 | try sema.emitBackwardBranch(block, case_src.resolve(sema.gpa, decl, src_node_offset, .none)); | 10687 | try sema.emitBackwardBranch(block, case_src.resolve(sema.gpa, decl, src_node_offset, .none)); |
| 10672 | return error.AnalysisFail; | 10688 | unreachable; |
| 10673 | }, | 10689 | }, |
| 10674 | else => return err, | 10690 | else => return err, |
| 10675 | }; | 10691 | }; |
| ... | @@ -11101,10 +11117,8 @@ fn resolveSwitchItemVal( | ... | @@ -11101,10 +11117,8 @@ fn resolveSwitchItemVal( |
| 11101 | } else |err| switch (err) { | 11117 | } else |err| switch (err) { |
| 11102 | error.NeededSourceLocation => { | 11118 | error.NeededSourceLocation => { |
| 11103 | const src = switch_prong_src.resolve(sema.gpa, sema.mod.declPtr(block.src_decl), switch_node_offset, range_expand); | 11119 | const src = switch_prong_src.resolve(sema.gpa, sema.mod.declPtr(block.src_decl), switch_node_offset, range_expand); |
| 11104 | return TypedValue{ | 11120 | _ = try sema.resolveConstValue(block, src, item, "switch prong values must be comptime-known"); |
| 11105 | .ty = item_ty, | 11121 | unreachable; |
| 11106 | .val = try sema.resolveConstValue(block, src, item, "switch prong values must be comptime-known"), | | |
| 11107 | }; | | |
| 11108 | }, | 11122 | }, |
| 11109 | else => |e| return e, | 11123 | else => |e| return e, |
| 11110 | } | 11124 | } |
| ... | @@ -11618,6 +11632,21 @@ fn zirShl( | ... | @@ -11618,6 +11632,21 @@ fn zirShl( |
| 11618 | }); | 11632 | }); |
| 11619 | } | 11633 | } |
| 11620 | } | 11634 | } |
| | 11635 | if (rhs_ty.zigTypeTag() == .Vector) { |
| | 11636 | var i: usize = 0; |
| | 11637 | while (i < rhs_ty.vectorLen()) : (i += 1) { |
| | 11638 | if (rhs_val.indexVectorlike(i).compareHetero(.lt, Value.zero, target)) { |
| | 11639 | return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ |
| | 11640 | rhs_val.indexVectorlike(i).fmtValue(scalar_ty, sema.mod), |
| | 11641 | i, |
| | 11642 | }); |
| | 11643 | } |
| | 11644 | } |
| | 11645 | } else if (rhs_val.compareHetero(.lt, Value.zero, target)) { |
| | 11646 | return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ |
| | 11647 | rhs_val.fmtValue(scalar_ty, sema.mod), |
| | 11648 | }); |
| | 11649 | } |
| 11621 | } | 11650 | } |
| 11622 | | 11651 | |
| 11623 | const runtime_src = if (maybe_lhs_val) |lhs_val| rs: { | 11652 | const runtime_src = if (maybe_lhs_val) |lhs_val| rs: { |
| ... | @@ -11787,6 +11816,21 @@ fn zirShr( | ... | @@ -11787,6 +11816,21 @@ fn zirShr( |
| 11787 | }); | 11816 | }); |
| 11788 | } | 11817 | } |
| 11789 | } | 11818 | } |
| | 11819 | if (rhs_ty.zigTypeTag() == .Vector) { |
| | 11820 | var i: usize = 0; |
| | 11821 | while (i < rhs_ty.vectorLen()) : (i += 1) { |
| | 11822 | if (rhs_val.indexVectorlike(i).compareHetero(.lt, Value.zero, target)) { |
| | 11823 | return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ |
| | 11824 | rhs_val.indexVectorlike(i).fmtValue(scalar_ty, sema.mod), |
| | 11825 | i, |
| | 11826 | }); |
| | 11827 | } |
| | 11828 | } |
| | 11829 | } else if (rhs_val.compareHetero(.lt, Value.zero, target)) { |
| | 11830 | return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ |
| | 11831 | rhs_val.fmtValue(scalar_ty, sema.mod), |
| | 11832 | }); |
| | 11833 | } |
| 11790 | if (maybe_lhs_val) |lhs_val| { | 11834 | if (maybe_lhs_val) |lhs_val| { |
| 11791 | if (lhs_val.isUndef()) { | 11835 | if (lhs_val.isUndef()) { |
| 11792 | return sema.addConstUndef(lhs_ty); | 11836 | return sema.addConstUndef(lhs_ty); |
| ... | @@ -14721,7 +14765,9 @@ fn analyzeCmp( | ... | @@ -14721,7 +14765,9 @@ fn analyzeCmp( |
| 14721 | ) CompileError!Air.Inst.Ref { | 14765 | ) CompileError!Air.Inst.Ref { |
| 14722 | const lhs_ty = sema.typeOf(lhs); | 14766 | const lhs_ty = sema.typeOf(lhs); |
| 14723 | const rhs_ty = sema.typeOf(rhs); | 14767 | const rhs_ty = sema.typeOf(rhs); |
| 14724 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); | 14768 | if (lhs_ty.zigTypeTag() != .Optional and rhs_ty.zigTypeTag() != .Optional) { |
| | 14769 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| | 14770 | } |
| 14725 | | 14771 | |
| 14726 | if (lhs_ty.zigTypeTag() == .Vector and rhs_ty.zigTypeTag() == .Vector) { | 14772 | if (lhs_ty.zigTypeTag() == .Vector and rhs_ty.zigTypeTag() == .Vector) { |
| 14727 | return sema.cmpVector(block, src, lhs, rhs, op, lhs_src, rhs_src); | 14773 | return sema.cmpVector(block, src, lhs, rhs, op, lhs_src, rhs_src); |
| ... | @@ -15217,12 +15263,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15217,12 +15263,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15217 | try Value.Tag.ty.create(params_anon_decl.arena(), try param_ty.copy(params_anon_decl.arena())), | 15263 | try Value.Tag.ty.create(params_anon_decl.arena(), try param_ty.copy(params_anon_decl.arena())), |
| 15218 | ); | 15264 | ); |
| 15219 | | 15265 | |
| | 15266 | const is_noalias = blk: { |
| | 15267 | const index = std.math.cast(u5, i) orelse break :blk false; |
| | 15268 | break :blk @truncate(u1, info.noalias_bits >> index) != 0; |
| | 15269 | }; |
| | 15270 | |
| 15220 | const param_fields = try params_anon_decl.arena().create([3]Value); | 15271 | const param_fields = try params_anon_decl.arena().create([3]Value); |
| 15221 | param_fields.* = .{ | 15272 | param_fields.* = .{ |
| 15222 | // is_generic: bool, | 15273 | // is_generic: bool, |
| 15223 | Value.makeBool(is_generic), | 15274 | Value.makeBool(is_generic), |
| 15224 | // is_noalias: bool, | 15275 | // is_noalias: bool, |
| 15225 | Value.false, // TODO | 15276 | Value.makeBool(is_noalias), |
| 15226 | // arg_type: ?type, | 15277 | // arg_type: ?type, |
| 15227 | param_ty_val, | 15278 | param_ty_val, |
| 15228 | }; | 15279 | }; |
| ... | @@ -17409,7 +17460,7 @@ fn zirStructInitAnon( | ... | @@ -17409,7 +17460,7 @@ fn zirStructInitAnon( |
| 17409 | const decl = sema.mod.declPtr(block.src_decl); | 17460 | const decl = sema.mod.declPtr(block.src_decl); |
| 17410 | const field_src = Module.initSrc(src.node_offset.x, sema.gpa, decl, runtime_index); | 17461 | const field_src = Module.initSrc(src.node_offset.x, sema.gpa, decl, runtime_index); |
| 17411 | try sema.requireRuntimeBlock(block, src, field_src); | 17462 | try sema.requireRuntimeBlock(block, src, field_src); |
| 17412 | return error.AnalysisFail; | 17463 | unreachable; |
| 17413 | }, | 17464 | }, |
| 17414 | else => |e| return e, | 17465 | else => |e| return e, |
| 17415 | }; | 17466 | }; |
| ... | @@ -17474,25 +17525,31 @@ fn zirArrayInit( | ... | @@ -17474,25 +17525,31 @@ fn zirArrayInit( |
| 17474 | defer gpa.free(resolved_args); | 17525 | defer gpa.free(resolved_args); |
| 17475 | for (args[1..]) |arg, i| { | 17526 | for (args[1..]) |arg, i| { |
| 17476 | const resolved_arg = try sema.resolveInst(arg); | 17527 | const resolved_arg = try sema.resolveInst(arg); |
| 17477 | const arg_src = src; // TODO better source location | | |
| 17478 | const elem_ty = if (array_ty.zigTypeTag() == .Struct) | 17528 | const elem_ty = if (array_ty.zigTypeTag() == .Struct) |
| 17479 | array_ty.structFieldType(i) | 17529 | array_ty.structFieldType(i) |
| 17480 | else | 17530 | else |
| 17481 | array_ty.elemType2(); | 17531 | array_ty.elemType2(); |
| 17482 | resolved_args[i] = try sema.coerce(block, elem_ty, resolved_arg, arg_src); | 17532 | resolved_args[i] = sema.coerce(block, elem_ty, resolved_arg, .unneeded) catch |err| switch (err) { |
| | 17533 | error.NeededSourceLocation => { |
| | 17534 | const decl = sema.mod.declPtr(block.src_decl); |
| | 17535 | const elem_src = Module.initSrc(src.node_offset.x, sema.gpa, decl, i); |
| | 17536 | _ = try sema.coerce(block, elem_ty, resolved_arg, elem_src); |
| | 17537 | unreachable; |
| | 17538 | }, |
| | 17539 | else => return err, |
| | 17540 | }; |
| 17483 | } | 17541 | } |
| 17484 | | 17542 | |
| 17485 | if (sentinel_val) |some| { | 17543 | if (sentinel_val) |some| { |
| 17486 | resolved_args[resolved_args.len - 1] = try sema.addConstant(array_ty.elemType2(), some); | 17544 | resolved_args[resolved_args.len - 1] = try sema.addConstant(array_ty.elemType2(), some); |
| 17487 | } | 17545 | } |
| 17488 | | 17546 | |
| 17489 | const opt_runtime_src: ?LazySrcLoc = for (resolved_args) |arg| { | 17547 | const opt_runtime_index: ?u32 = for (resolved_args) |arg, i| { |
| 17490 | const arg_src = src; // TODO better source location | | |
| 17491 | const comptime_known = try sema.isComptimeKnown(arg); | 17548 | const comptime_known = try sema.isComptimeKnown(arg); |
| 17492 | if (!comptime_known) break arg_src; | 17549 | if (!comptime_known) break @intCast(u32, i); |
| 17493 | } else null; | 17550 | } else null; |
| 17494 | | 17551 | |
| 17495 | const runtime_src = opt_runtime_src orelse { | 17552 | const runtime_index = opt_runtime_index orelse { |
| 17496 | const elem_vals = try sema.arena.alloc(Value, resolved_args.len); | 17553 | const elem_vals = try sema.arena.alloc(Value, resolved_args.len); |
| 17497 | | 17554 | |
| 17498 | for (resolved_args) |arg, i| { | 17555 | for (resolved_args) |arg, i| { |
| ... | @@ -17504,7 +17561,15 @@ fn zirArrayInit( | ... | @@ -17504,7 +17561,15 @@ fn zirArrayInit( |
| 17504 | return sema.addConstantMaybeRef(block, array_ty, array_val, is_ref); | 17561 | return sema.addConstantMaybeRef(block, array_ty, array_val, is_ref); |
| 17505 | }; | 17562 | }; |
| 17506 | | 17563 | |
| 17507 | try sema.requireRuntimeBlock(block, src, runtime_src); | 17564 | sema.requireRuntimeBlock(block, src, .unneeded) catch |err| switch (err) { |
| | 17565 | error.NeededSourceLocation => { |
| | 17566 | const decl = sema.mod.declPtr(block.src_decl); |
| | 17567 | const elem_src = Module.initSrc(src.node_offset.x, sema.gpa, decl, runtime_index); |
| | 17568 | try sema.requireRuntimeBlock(block, src, elem_src); |
| | 17569 | unreachable; |
| | 17570 | }, |
| | 17571 | else => return err, |
| | 17572 | }; |
| 17508 | try sema.queueFullTypeResolution(array_ty); | 17573 | try sema.queueFullTypeResolution(array_ty); |
| 17509 | | 17574 | |
| 17510 | if (is_ref) { | 17575 | if (is_ref) { |
| ... | @@ -18502,10 +18567,47 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in | ... | @@ -18502,10 +18567,47 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in |
| 18502 | } | 18567 | } |
| 18503 | | 18568 | |
| 18504 | var buffer: Value.ToTypeBuffer = undefined; | 18569 | var buffer: Value.ToTypeBuffer = undefined; |
| | 18570 | const field_ty = try field_type_val.toType(&buffer).copy(new_decl_arena_allocator); |
| 18505 | gop.value_ptr.* = .{ | 18571 | gop.value_ptr.* = .{ |
| 18506 | .ty = try field_type_val.toType(&buffer).copy(new_decl_arena_allocator), | 18572 | .ty = field_ty, |
| 18507 | .abi_align = @intCast(u32, (try alignment_val.getUnsignedIntAdvanced(target, sema)).?), | 18573 | .abi_align = @intCast(u32, (try alignment_val.getUnsignedIntAdvanced(target, sema)).?), |
| 18508 | }; | 18574 | }; |
| | 18575 | |
| | 18576 | if (field_ty.zigTypeTag() == .Opaque) { |
| | 18577 | const msg = msg: { |
| | 18578 | const msg = try sema.errMsg(block, src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{}); |
| | 18579 | errdefer msg.destroy(sema.gpa); |
| | 18580 | |
| | 18581 | try sema.addDeclaredHereNote(msg, field_ty); |
| | 18582 | break :msg msg; |
| | 18583 | }; |
| | 18584 | return sema.failWithOwnedErrorMsg(msg); |
| | 18585 | } |
| | 18586 | if (union_obj.layout == .Extern and !try sema.validateExternType(field_ty, .union_field)) { |
| | 18587 | const msg = msg: { |
| | 18588 | const msg = try sema.errMsg(block, src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); |
| | 18589 | errdefer msg.destroy(sema.gpa); |
| | 18590 | |
| | 18591 | const src_decl = sema.mod.declPtr(block.src_decl); |
| | 18592 | try sema.explainWhyTypeIsNotExtern(msg, src.toSrcLoc(src_decl), field_ty, .union_field); |
| | 18593 | |
| | 18594 | try sema.addDeclaredHereNote(msg, field_ty); |
| | 18595 | break :msg msg; |
| | 18596 | }; |
| | 18597 | return sema.failWithOwnedErrorMsg(msg); |
| | 18598 | } else if (union_obj.layout == .Packed and !(validatePackedType(field_ty))) { |
| | 18599 | const msg = msg: { |
| | 18600 | const msg = try sema.errMsg(block, src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); |
| | 18601 | errdefer msg.destroy(sema.gpa); |
| | 18602 | |
| | 18603 | const src_decl = sema.mod.declPtr(block.src_decl); |
| | 18604 | try sema.explainWhyTypeIsNotPacked(msg, src.toSrcLoc(src_decl), field_ty); |
| | 18605 | |
| | 18606 | try sema.addDeclaredHereNote(msg, field_ty); |
| | 18607 | break :msg msg; |
| | 18608 | }; |
| | 18609 | return sema.failWithOwnedErrorMsg(msg); |
| | 18610 | } |
| 18509 | } | 18611 | } |
| 18510 | | 18612 | |
| 18511 | if (tag_ty_field_names) |names| { | 18613 | if (tag_ty_field_names) |names| { |
| ... | @@ -18587,21 +18689,25 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in | ... | @@ -18587,21 +18689,25 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in |
| 18587 | // is_noalias: bool, | 18689 | // is_noalias: bool, |
| 18588 | const arg_is_noalias = arg_val[1].toBool(); | 18690 | const arg_is_noalias = arg_val[1].toBool(); |
| 18589 | // arg_type: ?type, | 18691 | // arg_type: ?type, |
| 18590 | const param_type_val = arg_val[2]; | 18692 | const param_type_opt_val = arg_val[2]; |
| 18591 | | 18693 | |
| 18592 | if (arg_is_generic) { | 18694 | if (arg_is_generic) { |
| 18593 | return sema.fail(block, src, "Type.Fn.Param.is_generic must be false for @Type", .{}); | 18695 | return sema.fail(block, src, "Type.Fn.Param.is_generic must be false for @Type", .{}); |
| 18594 | } | 18696 | } |
| 18595 | | 18697 | |
| | 18698 | const param_type_val = param_type_opt_val.optionalValue() orelse |
| | 18699 | return sema.fail(block, src, "Type.Fn.Param.arg_type must be non-null for @Type", .{}); |
| | 18700 | const param_type = try param_type_val.toType(&buf).copy(sema.arena); |
| | 18701 | |
| 18596 | if (arg_is_noalias) { | 18702 | if (arg_is_noalias) { |
| 18597 | noalias_bits = @as(u32, 1) << (std.math.cast(u5, i) orelse | 18703 | if (!param_type.isPtrAtRuntime()) { |
| | 18704 | return sema.fail(block, src, "non-pointer parameter declared noalias", .{}); |
| | 18705 | } |
| | 18706 | noalias_bits |= @as(u32, 1) << (std.math.cast(u5, i) orelse |
| 18598 | return sema.fail(block, src, "this compiler implementation only supports 'noalias' on the first 32 parameters", .{})); | 18707 | return sema.fail(block, src, "this compiler implementation only supports 'noalias' on the first 32 parameters", .{})); |
| 18599 | } | 18708 | } |
| 18600 | | 18709 | |
| 18601 | const param_type = param_type_val.optionalValue() orelse | 18710 | param_types[i] = param_type; |
| 18602 | return sema.fail(block, src, "Type.Fn.Param.arg_type must be non-null for @Type", .{}); | | |
| 18603 | | | |
| 18604 | param_types[i] = try param_type.toType(&buf).copy(sema.arena); | | |
| 18605 | comptime_params[i] = false; | 18711 | comptime_params[i] = false; |
| 18606 | } | 18712 | } |
| 18607 | | 18713 | |
| ... | @@ -18745,13 +18851,60 @@ fn reifyStruct( | ... | @@ -18745,13 +18851,60 @@ fn reifyStruct( |
| 18745 | } | 18851 | } |
| 18746 | | 18852 | |
| 18747 | var buffer: Value.ToTypeBuffer = undefined; | 18853 | var buffer: Value.ToTypeBuffer = undefined; |
| | 18854 | const field_ty = try field_type_val.toType(&buffer).copy(new_decl_arena_allocator); |
| 18748 | gop.value_ptr.* = .{ | 18855 | gop.value_ptr.* = .{ |
| 18749 | .ty = try field_type_val.toType(&buffer).copy(new_decl_arena_allocator), | 18856 | .ty = field_ty, |
| 18750 | .abi_align = abi_align, | 18857 | .abi_align = abi_align, |
| 18751 | .default_val = default_val, | 18858 | .default_val = default_val, |
| 18752 | .is_comptime = is_comptime_val.toBool(), | 18859 | .is_comptime = is_comptime_val.toBool(), |
| 18753 | .offset = undefined, | 18860 | .offset = undefined, |
| 18754 | }; | 18861 | }; |
| | 18862 | |
| | 18863 | if (field_ty.zigTypeTag() == .Opaque) { |
| | 18864 | const msg = msg: { |
| | 18865 | const msg = try sema.errMsg(block, src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); |
| | 18866 | errdefer msg.destroy(sema.gpa); |
| | 18867 | |
| | 18868 | try sema.addDeclaredHereNote(msg, field_ty); |
| | 18869 | break :msg msg; |
| | 18870 | }; |
| | 18871 | return sema.failWithOwnedErrorMsg(msg); |
| | 18872 | } |
| | 18873 | if (field_ty.zigTypeTag() == .NoReturn) { |
| | 18874 | const msg = msg: { |
| | 18875 | const msg = try sema.errMsg(block, src, "struct fields cannot be 'noreturn'", .{}); |
| | 18876 | errdefer msg.destroy(sema.gpa); |
| | 18877 | |
| | 18878 | try sema.addDeclaredHereNote(msg, field_ty); |
| | 18879 | break :msg msg; |
| | 18880 | }; |
| | 18881 | return sema.failWithOwnedErrorMsg(msg); |
| | 18882 | } |
| | 18883 | if (struct_obj.layout == .Extern and !try sema.validateExternType(field_ty, .struct_field)) { |
| | 18884 | const msg = msg: { |
| | 18885 | const msg = try sema.errMsg(block, src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); |
| | 18886 | errdefer msg.destroy(sema.gpa); |
| | 18887 | |
| | 18888 | const src_decl = sema.mod.declPtr(block.src_decl); |
| | 18889 | try sema.explainWhyTypeIsNotExtern(msg, src.toSrcLoc(src_decl), field_ty, .struct_field); |
| | 18890 | |
| | 18891 | try sema.addDeclaredHereNote(msg, field_ty); |
| | 18892 | break :msg msg; |
| | 18893 | }; |
| | 18894 | return sema.failWithOwnedErrorMsg(msg); |
| | 18895 | } else if (struct_obj.layout == .Packed and !(validatePackedType(field_ty))) { |
| | 18896 | const msg = msg: { |
| | 18897 | const msg = try sema.errMsg(block, src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); |
| | 18898 | errdefer msg.destroy(sema.gpa); |
| | 18899 | |
| | 18900 | const src_decl = sema.mod.declPtr(block.src_decl); |
| | 18901 | try sema.explainWhyTypeIsNotPacked(msg, src.toSrcLoc(src_decl), field_ty); |
| | 18902 | |
| | 18903 | try sema.addDeclaredHereNote(msg, field_ty); |
| | 18904 | break :msg msg; |
| | 18905 | }; |
| | 18906 | return sema.failWithOwnedErrorMsg(msg); |
| | 18907 | } |
| 18755 | } | 18908 | } |
| 18756 | | 18909 | |
| 18757 | if (layout == .Packed) { | 18910 | if (layout == .Packed) { |
| ... | @@ -21544,7 +21697,7 @@ fn zirPrefetch( | ... | @@ -21544,7 +21697,7 @@ fn zirPrefetch( |
| 21544 | const options = sema.resolvePrefetchOptions(block, .unneeded, extra.rhs) catch |err| switch (err) { | 21697 | const options = sema.resolvePrefetchOptions(block, .unneeded, extra.rhs) catch |err| switch (err) { |
| 21545 | error.NeededSourceLocation => { | 21698 | error.NeededSourceLocation => { |
| 21546 | _ = try sema.resolvePrefetchOptions(block, opts_src, extra.rhs); | 21699 | _ = try sema.resolvePrefetchOptions(block, opts_src, extra.rhs); |
| 21547 | return error.AnalysisFail; | 21700 | unreachable; |
| 21548 | }, | 21701 | }, |
| 21549 | else => |e| return e, | 21702 | else => |e| return e, |
| 21550 | }; | 21703 | }; |
| ... | @@ -21637,7 +21790,7 @@ fn zirBuiltinExtern( | ... | @@ -21637,7 +21790,7 @@ fn zirBuiltinExtern( |
| 21637 | const options = sema.resolveExternOptions(block, .unneeded, extra.rhs) catch |err| switch (err) { | 21790 | const options = sema.resolveExternOptions(block, .unneeded, extra.rhs) catch |err| switch (err) { |
| 21638 | error.NeededSourceLocation => { | 21791 | error.NeededSourceLocation => { |
| 21639 | _ = try sema.resolveExternOptions(block, options_src, extra.rhs); | 21792 | _ = try sema.resolveExternOptions(block, options_src, extra.rhs); |
| 21640 | return error.AnalysisFail; | 21793 | unreachable; |
| 21641 | }, | 21794 | }, |
| 21642 | else => |e| return e, | 21795 | else => |e| return e, |
| 21643 | }; | 21796 | }; |
| ... | @@ -24493,7 +24646,7 @@ fn coerceExtra( | ... | @@ -24493,7 +24646,7 @@ fn coerceExtra( |
| 24493 | } | 24646 | } |
| 24494 | if (try sema.resolveMaybeUndefVal(inst)) |val| { | 24647 | if (try sema.resolveMaybeUndefVal(inst)) |val| { |
| 24495 | const result_val = try val.floatCast(sema.arena, dest_ty, target); | 24648 | const result_val = try val.floatCast(sema.arena, dest_ty, target); |
| 24496 | if (!val.eql(result_val, dest_ty, sema.mod)) { | 24649 | if (!val.eql(result_val, inst_ty, sema.mod)) { |
| 24497 | return sema.fail( | 24650 | return sema.fail( |
| 24498 | block, | 24651 | block, |
| 24499 | inst_src, | 24652 | inst_src, |
| ... | @@ -24987,7 +25140,7 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -24987,7 +25140,7 @@ const InMemoryCoercionResult = union(enum) { |
| 24987 | cur = param.child; | 25140 | cur = param.child; |
| 24988 | }, | 25141 | }, |
| 24989 | .fn_cc => |cc| { | 25142 | .fn_cc => |cc| { |
| 24990 | try sema.errNote(block, src, msg, "calling convention {s} cannot cast into calling convention {s}", .{ @tagName(cc.actual), @tagName(cc.wanted) }); | 25143 | try sema.errNote(block, src, msg, "calling convention '{s}' cannot cast into calling convention '{s}'", .{ @tagName(cc.actual), @tagName(cc.wanted) }); |
| 24991 | break; | 25144 | break; |
| 24992 | }, | 25145 | }, |
| 24993 | .fn_return_type => |pair| { | 25146 | .fn_return_type => |pair| { |
| ... | @@ -26842,6 +26995,9 @@ fn coerceCompatiblePtrs( | ... | @@ -26842,6 +26995,9 @@ fn coerceCompatiblePtrs( |
| 26842 | ) !Air.Inst.Ref { | 26995 | ) !Air.Inst.Ref { |
| 26843 | const inst_ty = sema.typeOf(inst); | 26996 | const inst_ty = sema.typeOf(inst); |
| 26844 | if (try sema.resolveMaybeUndefVal(inst)) |val| { | 26997 | if (try sema.resolveMaybeUndefVal(inst)) |val| { |
| | 26998 | if (!val.isUndef() and val.isNull() and !dest_ty.isAllowzeroPtr()) { |
| | 26999 | return sema.fail(block, inst_src, "null pointer casted to type '{}'", .{dest_ty.fmt(sema.mod)}); |
| | 27000 | } |
| 26845 | // The comptime Value representation is compatible with both types. | 27001 | // The comptime Value representation is compatible with both types. |
| 26846 | return sema.addConstant(dest_ty, val); | 27002 | return sema.addConstant(dest_ty, val); |
| 26847 | } | 27003 | } |
| ... | @@ -30177,7 +30333,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void | ... | @@ -30177,7 +30333,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 30177 | const tree = try sema.getAstTree(&block_scope); | 30333 | const tree = try sema.getAstTree(&block_scope); |
| 30178 | const init_src = containerFieldInitSrcLoc(decl, tree.*, 0, i); | 30334 | const init_src = containerFieldInitSrcLoc(decl, tree.*, 0, i); |
| 30179 | _ = try sema.coerce(&block_scope, field.ty, init, init_src); | 30335 | _ = try sema.coerce(&block_scope, field.ty, init, init_src); |
| 30180 | return error.AnalysisFail; | 30336 | unreachable; |
| 30181 | }, | 30337 | }, |
| 30182 | else => |e| return e, | 30338 | else => |e| return e, |
| 30183 | }; | 30339 | }; |
| ... | @@ -30304,6 +30460,25 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -30304,6 +30460,25 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 30304 | if (int_tag_ty.zigTypeTag() != .Int and int_tag_ty.zigTypeTag() != .ComptimeInt) { | 30460 | if (int_tag_ty.zigTypeTag() != .Int and int_tag_ty.zigTypeTag() != .ComptimeInt) { |
| 30305 | return sema.fail(&block_scope, tag_ty_src, "expected integer tag type, found '{}'", .{int_tag_ty.fmt(sema.mod)}); | 30461 | return sema.fail(&block_scope, tag_ty_src, "expected integer tag type, found '{}'", .{int_tag_ty.fmt(sema.mod)}); |
| 30306 | } | 30462 | } |
| | 30463 | |
| | 30464 | if (fields_len > 0) { |
| | 30465 | var field_count_val: Value.Payload.U64 = .{ |
| | 30466 | .base = .{ .tag = .int_u64 }, |
| | 30467 | .data = fields_len - 1, |
| | 30468 | }; |
| | 30469 | if (!(try sema.intFitsInType(Value.initPayload(&field_count_val.base), int_tag_ty, null))) { |
| | 30470 | const msg = msg: { |
| | 30471 | const msg = try sema.errMsg(&block_scope, tag_ty_src, "specified integer tag type cannot represent every field", .{}); |
| | 30472 | errdefer msg.destroy(sema.gpa); |
| | 30473 | try sema.errNote(&block_scope, tag_ty_src, msg, "type '{}' cannot fit values in range 0...{d}", .{ |
| | 30474 | int_tag_ty.fmt(sema.mod), |
| | 30475 | fields_len - 1, |
| | 30476 | }); |
| | 30477 | break :msg msg; |
| | 30478 | }; |
| | 30479 | return sema.failWithOwnedErrorMsg(msg); |
| | 30480 | } |
| | 30481 | } |
| 30307 | union_obj.tag_ty = try sema.generateUnionTagTypeNumbered(&block_scope, fields_len, provided_ty, union_obj); | 30482 | union_obj.tag_ty = try sema.generateUnionTagTypeNumbered(&block_scope, fields_len, provided_ty, union_obj); |
| 30308 | const enum_obj = union_obj.tag_ty.castTag(.enum_numbered).?.data; | 30483 | const enum_obj = union_obj.tag_ty.castTag(.enum_numbered).?.data; |
| 30309 | enum_field_names = &enum_obj.fields; | 30484 | enum_field_names = &enum_obj.fields; |
| ... | @@ -30379,7 +30554,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -30379,7 +30554,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 30379 | } else .none; | 30554 | } else .none; |
| 30380 | | 30555 | |
| 30381 | if (enum_value_map) |map| { | 30556 | if (enum_value_map) |map| { |
| 30382 | if (tag_ref != .none) { | 30557 | const copied_val = if (tag_ref != .none) blk: { |
| 30383 | const tag_src = src; // TODO better source location | 30558 | const tag_src = src; // TODO better source location |
| 30384 | const coerced = try sema.coerce(&block_scope, int_tag_ty, tag_ref, tag_src); | 30559 | const coerced = try sema.coerce(&block_scope, int_tag_ty, tag_ref, tag_src); |
| 30385 | const val = try sema.resolveConstValue(&block_scope, tag_src, coerced, "enum tag value must be comptime-known"); | 30560 | const val = try sema.resolveConstValue(&block_scope, tag_src, coerced, "enum tag value must be comptime-known"); |
| ... | @@ -30387,23 +30562,31 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -30387,23 +30562,31 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 30387 | | 30562 | |
| 30388 | // This puts the memory into the union arena, not the enum arena, but | 30563 | // This puts the memory into the union arena, not the enum arena, but |
| 30389 | // it is OK since they share the same lifetime. | 30564 | // it is OK since they share the same lifetime. |
| 30390 | const copied_val = try val.copy(decl_arena_allocator); | 30565 | break :blk try val.copy(decl_arena_allocator); |
| 30391 | map.putAssumeCapacityContext(copied_val, {}, .{ | 30566 | } else blk: { |
| 30392 | .ty = int_tag_ty, | | |
| 30393 | .mod = mod, | | |
| 30394 | }); | | |
| 30395 | } else { | | |
| 30396 | const val = if (last_tag_val) |val| | 30567 | const val = if (last_tag_val) |val| |
| 30397 | try sema.intAdd(val, Value.one, int_tag_ty) | 30568 | try sema.intAdd(val, Value.one, int_tag_ty) |
| 30398 | else | 30569 | else |
| 30399 | Value.zero; | 30570 | Value.zero; |
| 30400 | last_tag_val = val; | 30571 | last_tag_val = val; |
| 30401 | | 30572 | |
| 30402 | const copied_val = try val.copy(decl_arena_allocator); | 30573 | break :blk try val.copy(decl_arena_allocator); |
| 30403 | map.putAssumeCapacityContext(copied_val, {}, .{ | 30574 | }; |
| 30404 | .ty = int_tag_ty, | 30575 | const gop = map.getOrPutAssumeCapacityContext(copied_val, .{ |
| 30405 | .mod = mod, | 30576 | .ty = int_tag_ty, |
| 30406 | }); | 30577 | .mod = mod, |
| | 30578 | }); |
| | 30579 | if (gop.found_existing) { |
| | 30580 | const tree = try sema.getAstTree(&block_scope); |
| | 30581 | const field_src = enumFieldSrcLoc(sema.mod.declPtr(block_scope.src_decl), tree.*, src.node_offset.x, field_i); |
| | 30582 | const other_field_src = enumFieldSrcLoc(sema.mod.declPtr(block_scope.src_decl), tree.*, src.node_offset.x, gop.index); |
| | 30583 | const msg = msg: { |
| | 30584 | const msg = try sema.errMsg(&block_scope, field_src, "enum tag value {} already taken", .{copied_val.fmtValue(int_tag_ty, sema.mod)}); |
| | 30585 | errdefer msg.destroy(gpa); |
| | 30586 | try sema.errNote(&block_scope, other_field_src, msg, "other occurrence here", .{}); |
| | 30587 | break :msg msg; |
| | 30588 | }; |
| | 30589 | return sema.failWithOwnedErrorMsg(msg); |
| 30407 | } | 30590 | } |
| 30408 | } | 30591 | } |
| 30409 | | 30592 | |