authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-02-12 20:37:28+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-03-10 10:26:12+00:00
log986a4f1445e3ed1a6227a24d78b2154239ccdb31
tree488f38252e6285432dedd3b00e9a5c5fa3c71ffd
parentb27c56fe5087872800f6b340ec3d1fc219d0d77b
signaturelock-open Commit is signed but in an unrecognized format.

Sema: fix illegal comparison to undefined


1 files changed, 24 insertions(+), 28 deletions(-)

src/Sema.zig+24-28
......@@ -10374,7 +10374,7 @@ fn analyzeSwitchBlock(
1037410374 assert(case.range_infos.len == 0);
1037510375 for (case.item_infos, item_refs) |item_info, item_ref| {
1037610376 if (item_info.bodyLen()) |body_len| extra_index += body_len;
10377 if (sema.wantSwitchProngBodyAnalysis(block, item_ref, operand_ty, false, true, prong_info.is_comptime_unreach)) {
10377 if (sema.wantSwitchProngBodyAnalysis(item_ref, operand_ty, false, true, prong_info.is_comptime_unreach)) {
1037810378 break :skip_case;
1037910379 }
1038010380 }
......@@ -10390,7 +10390,7 @@ fn analyzeSwitchBlock(
1039010390 unreachable; // malformed validated switch
1039110391 };
1039210392
10393 const analyze_body = sema.wantSwitchProngBodyAnalysis(block, .fromValue(item_opv), operand_ty, union_originally, err_set, false);
10393 const analyze_body = sema.wantSwitchProngBodyAnalysis(.fromValue(item_opv), operand_ty, union_originally, err_set, false);
1039410394 if (!analyze_body) return .unreachable_value;
1039510395
1039610396 if (!(err_set and
......@@ -10648,7 +10648,7 @@ fn finishSwitchBr(
1064810648 if (item_ref == .none) is_under_prong = true;
1064910649 if (item_info.bodyLen()) |body_len| extra_index += body_len;
1065010650
10651 const analyze_body = sema.wantSwitchProngBodyAnalysis(block, item_ref, operand_ty, union_originally, err_set, prong_info.is_comptime_unreach);
10651 const analyze_body = sema.wantSwitchProngBodyAnalysis(item_ref, operand_ty, union_originally, err_set, prong_info.is_comptime_unreach);
1065210652 if (analyze_body) any_analyze_body = true;
1065310653
1065410654 if (prong_info.is_inline) {
......@@ -10708,8 +10708,8 @@ fn finishSwitchBr(
1070810708 any_analyze_body = true; // always an integer range, always needs analysis
1070910709
1071010710 if (prong_info.is_inline) {
10711 var item = sema.resolveConstDefinedValue(block, .unneeded, range_ref[0], undefined) catch unreachable;
10712 const item_last = sema.resolveConstDefinedValue(block, .unneeded, range_ref[1], undefined) catch unreachable;
10711 var item = sema.resolveValue(range_ref[0]).?;
10712 const item_last = sema.resolveValue(range_ref[1]).?;
1071310713
1071410714 if (item.getUnsignedInt(zcu)) |first_int| {
1071510715 if (item_last.getUnsignedInt(zcu)) |last_int| {
......@@ -10887,7 +10887,7 @@ fn finishSwitchBr(
1088710887
1088810888 const item_ref: Air.Inst.Ref = .fromValue(item_val);
1088910889
10890 const analyze_body = sema.wantSwitchProngBodyAnalysis(block, item_ref, operand_ty, union_originally, err_set, false);
10890 const analyze_body = sema.wantSwitchProngBodyAnalysis(item_ref, operand_ty, union_originally, err_set, false);
1089110891
1089210892 if (emit_bb) try sema.emitBackwardBranch(block, else_prong_src);
1089310893 emit_bb = true;
......@@ -11820,7 +11820,7 @@ fn resolveSwitchBlock(
1182011820 };
1182111821 continue;
1182211822 }
11823 const item_val = sema.resolveConstDefinedValue(child_block, .unneeded, item_ref, undefined) catch unreachable;
11823 const item_val = sema.resolveValue(item_ref).?;
1182411824 if (cond_val.eql(item_val, item_ty, zcu)) {
1182511825 if (err_set) try sema.maybeErrorUnwrapComptime(child_block, prong_body, cond_ref);
1182611826 if (union_originally and operand_ty.unionFieldType(item_val, zcu).?.isNoReturn(zcu)) {
......@@ -11853,8 +11853,8 @@ fn resolveSwitchBlock(
1185311853 }
1185411854 }
1185511855 for (range_refs) |range_ref| {
11856 const first_val = sema.resolveConstDefinedValue(child_block, .unneeded, range_ref[0], undefined) catch unreachable;
11857 const last_val = sema.resolveConstDefinedValue(child_block, .unneeded, range_ref[1], undefined) catch unreachable;
11856 const first_val = sema.resolveValue(range_ref[0]).?;
11857 const last_val = sema.resolveValue(range_ref[1]).?;
1185811858 if ((try sema.compareAll(cond_val, .gte, first_val, item_ty)) and
1185911859 (try sema.compareAll(cond_val, .lte, last_val, item_ty)))
1186011860 {
......@@ -12063,7 +12063,6 @@ fn resolveSwitchProng(
1206312063
1206412064fn wantSwitchProngBodyAnalysis(
1206512065 sema: *Sema,
12066 block: *Block,
1206712066 item_ref: Air.Inst.Ref,
1206812067 operand_ty: Type,
1206912068 union_originally: bool,
......@@ -12072,12 +12071,12 @@ fn wantSwitchProngBodyAnalysis(
1207212071) bool {
1207312072 const zcu = sema.pt.zcu;
1207412073 if (union_originally) {
12075 const item_val = sema.resolveConstDefinedValue(block, .unneeded, item_ref, undefined) catch unreachable;
12074 const item_val = sema.resolveValue(item_ref).?;
1207612075 const field_ty = operand_ty.unionFieldType(item_val, zcu).?;
1207712076 if (field_ty.isNoReturn(zcu)) return false;
1207812077 }
1207912078 if (err_set and prong_is_comptime_unreach) {
12080 const item_val = sema.resolveConstDefinedValue(block, .unneeded, item_ref, undefined) catch unreachable;
12079 const item_val = sema.resolveValue(item_ref).?;
1208112080 const err_name = item_val.getErrorName(zcu).unwrap().?;
1208212081 if (!operand_ty.errorSetHasField(err_name, zcu)) return false;
1208312082 }
......@@ -12252,7 +12251,7 @@ fn analyzeSwitchPayloadCapture(
1225212251 const switch_node_offset = operand_src.offset.node_offset_switch_operand;
1225312252
1225412253 if (kind == .inline_ref) {
12255 const item_val = sema.resolveConstDefinedValue(case_block, .unneeded, kind.inline_ref, undefined) catch unreachable;
12254 const item_val = sema.resolveValue(kind.inline_ref).?;
1225612255 if (operand_ty.zigTypeTag(zcu) == .@"union") {
1225712256 const field_index: u32 = @intCast(operand_ty.unionTagFieldIndex(item_val, zcu).?);
1225812257 const union_obj = zcu.typeToUnion(operand_ty).?;
......@@ -12303,14 +12302,14 @@ fn analyzeSwitchPayloadCapture(
1230312302 const case_vals = kind.item_refs;
1230412303
1230512304 const union_obj = zcu.typeToUnion(operand_ty).?;
12306 const first_item_val = sema.resolveConstDefinedValue(case_block, .unneeded, case_vals[0], undefined) catch unreachable;
12305 const first_item_val = sema.resolveValue(case_vals[0]).?;
1230712306
1230812307 const first_field_index: u32 = zcu.unionTagFieldIndex(union_obj, first_item_val).?;
1230912308 const first_field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[first_field_index]);
1231012309
1231112310 const field_indices = try sema.arena.alloc(u32, case_vals.len);
1231212311 for (case_vals, field_indices) |item, *field_idx| {
12313 const item_val = sema.resolveConstDefinedValue(case_block, .unneeded, item, undefined) catch unreachable;
12312 const item_val = sema.resolveValue(item).?;
1231412313 field_idx.* = zcu.unionTagFieldIndex(union_obj, item_val).?;
1231512314 }
1231612315
......@@ -12592,7 +12591,7 @@ fn analyzeSwitchPayloadCapture(
1259212591
1259312592 const case_vals = kind.item_refs;
1259412593 if (case_vals.len == 1) {
12595 const item_val = sema.resolveConstDefinedValue(case_block, .unneeded, case_vals[0], undefined) catch unreachable;
12594 const item_val = sema.resolveValue(case_vals[0]).?;
1259612595 const item_ty = try pt.singleErrorSetType(item_val.getErrorName(zcu).unwrap().?);
1259712596 return sema.bitCast(case_block, item_ty, .fromValue(item_val), operand_src, null);
1259812597 }
......@@ -12600,7 +12599,7 @@ fn analyzeSwitchPayloadCapture(
1260012599 var names: InferredErrorSet.NameMap = .{};
1260112600 try names.ensureUnusedCapacity(sema.arena, case_vals.len);
1260212601 for (case_vals) |err| {
12603 const err_val = sema.resolveConstDefinedValue(case_block, .unneeded, err, undefined) catch unreachable;
12602 const err_val = sema.resolveValue(err).?;
1260412603 names.putAssumeCapacityNoClobber(err_val.getErrorName(zcu).unwrap().?, {});
1260512604 }
1260612605 const error_ty = try pt.errorSetFromUnsortedNames(names.keys());
......@@ -13731,26 +13730,24 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1373113730 const lhs_elem_i = elem_i;
1373213731 const elem_default_val: ?Value = if (lhs_is_tuple) lhs_ty.structFieldDefaultValue(lhs_elem_i, zcu) else null;
1373313732 const elem_val = elem_default_val orelse try lhs_sub_val.elemValue(pt, lhs_elem_i);
13734 const elem_val_inst = Air.internedToRef(elem_val.toIntern());
1373513733 const operand_src = block.src(.{ .array_cat_lhs = .{
1373613734 .array_cat_offset = inst_data.src_node,
1373713735 .elem_index = elem_i,
1373813736 } });
13739 const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, operand_src);
13740 const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined);
13737 const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, .fromValue(elem_val), operand_src);
13738 const coerced_elem_val = sema.resolveValue(coerced_elem_val_inst).?;
1374113739 element_vals[elem_i] = coerced_elem_val.toIntern();
1374213740 }
1374313741 while (elem_i < result_len) : (elem_i += 1) {
1374413742 const rhs_elem_i = elem_i - lhs_len;
1374513743 const elem_default_val: ?Value = if (rhs_is_tuple) rhs_ty.structFieldDefaultValue(rhs_elem_i, zcu) else null;
1374613744 const elem_val = elem_default_val orelse try rhs_sub_val.elemValue(pt, rhs_elem_i);
13747 const elem_val_inst = Air.internedToRef(elem_val.toIntern());
1374813745 const operand_src = block.src(.{ .array_cat_rhs = .{
1374913746 .array_cat_offset = inst_data.src_node,
1375013747 .elem_index = @intCast(rhs_elem_i),
1375113748 } });
13752 const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, operand_src);
13753 const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined);
13749 const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, .fromValue(elem_val), operand_src);
13750 const coerced_elem_val = sema.resolveValue(coerced_elem_val_inst).?;
1375413751 element_vals[elem_i] = coerced_elem_val.toIntern();
1375513752 }
1375613753 return sema.addConstantMaybeRef(
......@@ -25886,7 +25883,6 @@ fn fieldPtr(
2588625883 }
2588725884 },
2588825885 .type => {
25889 _ = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, object_ptr, undefined);
2589025886 const result = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src);
2589125887 const inner = if (is_pointer_to)
2589225888 try sema.analyzeLoad(block, src, result, object_ptr_src)
......@@ -27361,7 +27357,7 @@ fn coerceExtra(
2736127357
2736227358 // Function body to function pointer.
2736327359 if (inst_ty.zigTypeTag(zcu) == .@"fn") {
27364 const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
27360 const fn_val = sema.resolveValue(inst).?;
2736527361 const fn_nav = switch (zcu.intern_pool.indexToKey(fn_val.toIntern())) {
2736627362 .func => |f| f.owner_nav,
2736727363 .@"extern" => |e| e.owner_nav,
......@@ -27667,7 +27663,7 @@ fn coerceExtra(
2766727663 },
2766827664 .float, .comptime_float => switch (inst_ty.zigTypeTag(zcu)) {
2766927665 .comptime_float => {
27670 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
27666 const val = sema.resolveValue(inst).?;
2767127667 const result_val = try val.floatCast(dest_ty, pt);
2767227668 return Air.internedToRef(result_val.toIntern());
2767327669 },
......@@ -27753,7 +27749,7 @@ fn coerceExtra(
2775327749 .@"enum" => switch (inst_ty.zigTypeTag(zcu)) {
2775427750 .enum_literal => {
2775527751 // enum literal to enum
27756 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
27752 const val = sema.resolveValue(inst).?;
2775727753 const string = zcu.intern_pool.indexToKey(val.toIntern()).enum_literal;
2775827754 const field_index = dest_ty.enumFieldIndex(string, zcu) orelse {
2775927755 return sema.fail(block, inst_src, "no field named '{f}' in enum '{f}'", .{
......@@ -28965,7 +28961,7 @@ fn coerceVarArgParam(
2896528961 .{},
2896628962 ),
2896728963 .@"fn" => fn_ptr: {
28968 const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
28964 const fn_val = sema.resolveValue(inst).?;
2896928965 const fn_nav = zcu.funcInfo(fn_val.toIntern()).owner_nav;
2897028966 break :fn_ptr try sema.analyzeNavRef(block, inst_src, fn_nav);
2897128967 },