authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-10-03 12:51:59+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-10-05 17:26:29+03:00
logc0350cf87eaae64ca81e17aef8872e8e55767437
treea65fb350db2a802c678d739cfd6f38c7fe132264
parent3234e8de3a50575195fab625f818a6e5fe141c7b

Sema: avoid passing undefined as reason to `failWithNeededComptime`

Closes #13046

2 files changed, 39 insertions(+), 25 deletions(-)

src/Sema.zig+25-25
...@@ -2469,7 +2469,7 @@ fn createAnonymousDeclTypeNamed(...@@ -2469,7 +2469,7 @@ fn createAnonymousDeclTypeNamed(
2469 const arg = sema.inst_map.get(zir_inst).?;2469 const arg = sema.inst_map.get(zir_inst).?;
2470 // The comptime call code in analyzeCall already did this, so we're2470 // The comptime call code in analyzeCall already did this, so we're
2471 // just repeating it here and it's guaranteed to work.2471 // just repeating it here and it's guaranteed to work.
2472 const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg, undefined) catch unreachable;2472 const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg, "") catch unreachable;
24732473
2474 if (arg_i != 0) try buf.appendSlice(",");2474 if (arg_i != 0) try buf.appendSlice(",");
2475 try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg), sema.mod)});2475 try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg), sema.mod)});
...@@ -5631,7 +5631,7 @@ fn zirCall(...@@ -5631,7 +5631,7 @@ fn zirCall(
5631 var bound_arg_src: ?LazySrcLoc = null;5631 var bound_arg_src: ?LazySrcLoc = null;
5632 if (func_type.tag() == .bound_fn) {5632 if (func_type.tag() == .bound_fn) {
5633 bound_arg_src = func_src;5633 bound_arg_src = func_src;
5634 const bound_func = try sema.resolveValue(block, .unneeded, func, undefined);5634 const bound_func = try sema.resolveValue(block, .unneeded, func, "");
5635 const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data;5635 const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data;
5636 func = bound_data.func_inst;5636 func = bound_data.func_inst;
5637 resolved_args = try sema.arena.alloc(Air.Inst.Ref, args_len + 1);5637 resolved_args = try sema.arena.alloc(Air.Inst.Ref, args_len + 1);
...@@ -6213,7 +6213,7 @@ fn analyzeCall(...@@ -6213,7 +6213,7 @@ fn analyzeCall(
6213 }6213 }
62146214
6215 if (should_memoize and is_comptime_call) {6215 if (should_memoize and is_comptime_call) {
6216 const result_val = try sema.resolveConstMaybeUndefVal(block, .unneeded, result, undefined);6216 const result_val = try sema.resolveConstMaybeUndefVal(block, .unneeded, result, "");
62176217
6218 // TODO: check whether any external comptime memory was mutated by the6218 // TODO: check whether any external comptime memory was mutated by the
6219 // comptime function call. If so, then do not memoize the call here.6219 // comptime function call. If so, then do not memoize the call here.
...@@ -6724,12 +6724,12 @@ fn instantiateGenericCall(...@@ -6724,12 +6724,12 @@ fn instantiateGenericCall(
6724 const child_arg = try child_sema.addConstant(sema.typeOf(arg), arg_val);6724 const child_arg = try child_sema.addConstant(sema.typeOf(arg), arg_val);
6725 child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);6725 child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);
6726 } else {6726 } else {
6727 return sema.failWithNeededComptime(block, .unneeded, undefined);6727 return sema.failWithNeededComptime(block, .unneeded, "");
6728 }6728 }
6729 } else if (is_anytype) {6729 } else if (is_anytype) {
6730 const arg_ty = sema.typeOf(arg);6730 const arg_ty = sema.typeOf(arg);
6731 if (try sema.typeRequiresComptime(arg_ty)) {6731 if (try sema.typeRequiresComptime(arg_ty)) {
6732 const arg_val = try sema.resolveConstValue(block, .unneeded, arg, undefined);6732 const arg_val = try sema.resolveConstValue(block, .unneeded, arg, "");
6733 const child_arg = try child_sema.addConstant(arg_ty, arg_val);6733 const child_arg = try child_sema.addConstant(arg_ty, arg_val);
6734 child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);6734 child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);
6735 } else {6735 } else {
...@@ -6751,7 +6751,7 @@ fn instantiateGenericCall(...@@ -6751,7 +6751,7 @@ fn instantiateGenericCall(
6751 }6751 }
6752 return err;6752 return err;
6753 };6753 };
6754 const new_func_val = child_sema.resolveConstValue(&child_block, .unneeded, new_func_inst, undefined) catch unreachable;6754 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;6755 const new_func = new_func_val.castTag(.function).?.data;
6756 errdefer new_func.deinit(gpa);6756 errdefer new_func.deinit(gpa);
6757 assert(new_func == new_module_func);6757 assert(new_func == new_module_func);
...@@ -9115,7 +9115,7 @@ fn zirSwitchCapture(...@@ -9115,7 +9115,7 @@ fn zirSwitchCapture(
9115 const union_obj = operand_ty.cast(Type.Payload.Union).?.data;9115 const union_obj = operand_ty.cast(Type.Payload.Union).?.data;
9116 const first_item = try sema.resolveInst(items[0]);9116 const first_item = try sema.resolveInst(items[0]);
9117 // Previous switch validation ensured this will succeed9117 // Previous switch validation ensured this will succeed
9118 const first_item_val = sema.resolveConstValue(block, .unneeded, first_item, undefined) catch unreachable;9118 const first_item_val = sema.resolveConstValue(block, .unneeded, first_item, "") catch unreachable;
91199119
9120 const first_field_index = @intCast(u32, operand_ty.unionTagFieldIndex(first_item_val, sema.mod).?);9120 const first_field_index = @intCast(u32, operand_ty.unionTagFieldIndex(first_item_val, sema.mod).?);
9121 const first_field = union_obj.fields.values()[first_field_index];9121 const first_field = union_obj.fields.values()[first_field_index];
...@@ -9123,7 +9123,7 @@ fn zirSwitchCapture(...@@ -9123,7 +9123,7 @@ fn zirSwitchCapture(
9123 for (items[1..]) |item, i| {9123 for (items[1..]) |item, i| {
9124 const item_ref = try sema.resolveInst(item);9124 const item_ref = try sema.resolveInst(item);
9125 // Previous switch validation ensured this will succeed9125 // Previous switch validation ensured this will succeed
9126 const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable;9126 const item_val = sema.resolveConstValue(block, .unneeded, item_ref, "") catch unreachable;
91279127
9128 const field_index = operand_ty.unionTagFieldIndex(item_val, sema.mod).?;9128 const field_index = operand_ty.unionTagFieldIndex(item_val, sema.mod).?;
9129 const field = union_obj.fields.values()[field_index];9129 const field = union_obj.fields.values()[field_index];
...@@ -9184,7 +9184,7 @@ fn zirSwitchCapture(...@@ -9184,7 +9184,7 @@ fn zirSwitchCapture(
9184 for (items) |item| {9184 for (items) |item| {
9185 const item_ref = try sema.resolveInst(item);9185 const item_ref = try sema.resolveInst(item);
9186 // Previous switch validation ensured this will succeed9186 // Previous switch validation ensured this will succeed
9187 const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable;9187 const item_val = sema.resolveConstValue(block, .unneeded, item_ref, "") catch unreachable;
9188 names.putAssumeCapacityNoClobber(9188 names.putAssumeCapacityNoClobber(
9189 item_val.getError().?,9189 item_val.getError().?,
9190 {},9190 {},
...@@ -9198,7 +9198,7 @@ fn zirSwitchCapture(...@@ -9198,7 +9198,7 @@ fn zirSwitchCapture(
9198 } else {9198 } else {
9199 const item_ref = try sema.resolveInst(items[0]);9199 const item_ref = try sema.resolveInst(items[0]);
9200 // Previous switch validation ensured this will succeed9200 // Previous switch validation ensured this will succeed
9201 const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable;9201 const item_val = sema.resolveConstValue(block, .unneeded, item_ref, "") catch unreachable;
92029202
9203 const item_ty = try Type.Tag.error_set_single.create(sema.arena, item_val.getError().?);9203 const item_ty = try Type.Tag.error_set_single.create(sema.arena, item_val.getError().?);
9204 return sema.bitCast(block, item_ty, operand, operand_src);9204 return sema.bitCast(block, item_ty, operand, operand_src);
...@@ -9943,7 +9943,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -9943,7 +9943,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
99439943
9944 const item = try sema.resolveInst(item_ref);9944 const item = try sema.resolveInst(item_ref);
9945 // Validation above ensured these will succeed.9945 // Validation above ensured these will succeed.
9946 const item_val = sema.resolveConstValue(&child_block, .unneeded, item, undefined) catch unreachable;9946 const item_val = sema.resolveConstValue(&child_block, .unneeded, item, "") catch unreachable;
9947 if (operand_val.eql(item_val, operand_ty, sema.mod)) {9947 if (operand_val.eql(item_val, operand_ty, sema.mod)) {
9948 if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand);9948 if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand);
9949 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);9949 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);
...@@ -9966,7 +9966,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -9966,7 +9966,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
9966 for (items) |item_ref| {9966 for (items) |item_ref| {
9967 const item = try sema.resolveInst(item_ref);9967 const item = try sema.resolveInst(item_ref);
9968 // Validation above ensured these will succeed.9968 // Validation above ensured these will succeed.
9969 const item_val = sema.resolveConstValue(&child_block, .unneeded, item, undefined) catch unreachable;9969 const item_val = sema.resolveConstValue(&child_block, .unneeded, item, "") catch unreachable;
9970 if (operand_val.eql(item_val, operand_ty, sema.mod)) {9970 if (operand_val.eql(item_val, operand_ty, sema.mod)) {
9971 if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand);9971 if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand);
9972 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);9972 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);
...@@ -9981,8 +9981,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -9981,8 +9981,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
9981 extra_index += 1;9981 extra_index += 1;
99829982
9983 // Validation above ensured these will succeed.9983 // Validation above ensured these will succeed.
9984 const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first, undefined) catch unreachable;9984 const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first, "") catch unreachable;
9985 const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last, undefined) catch unreachable;9985 const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last, "") catch unreachable;
9986 if ((try sema.compare(block, src, operand_val, .gte, first_tv.val, operand_ty)) and9986 if ((try sema.compare(block, src, operand_val, .gte, first_tv.val, operand_ty)) and
9987 (try sema.compare(block, src, operand_val, .lte, last_tv.val, operand_ty)))9987 (try sema.compare(block, src, operand_val, .lte, last_tv.val, operand_ty)))
9988 {9988 {
...@@ -10048,7 +10048,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10048,7 +10048,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10048 // `item` is already guaranteed to be constant known.10048 // `item` is already guaranteed to be constant known.
1004910049
10050 const analyze_body = if (union_originally) blk: {10050 const analyze_body = if (union_originally) blk: {
10051 const item_val = sema.resolveConstValue(block, .unneeded, item, undefined) catch unreachable;10051 const item_val = sema.resolveConstValue(block, .unneeded, item, "") catch unreachable;
10052 const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod);10052 const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod);
10053 break :blk field_ty.zigTypeTag() != .NoReturn;10053 break :blk field_ty.zigTypeTag() != .NoReturn;
10054 } else true;10054 } else true;
...@@ -10199,7 +10199,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10199,7 +10199,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10199 const analyze_body = if (union_originally)10199 const analyze_body = if (union_originally)
10200 for (items) |item_ref| {10200 for (items) |item_ref| {
10201 const item = try sema.resolveInst(item_ref);10201 const item = try sema.resolveInst(item_ref);
10202 const item_val = sema.resolveConstValue(block, .unneeded, item, undefined) catch unreachable;10202 const item_val = sema.resolveConstValue(block, .unneeded, item, "") catch unreachable;
10203 const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod);10203 const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod);
10204 if (field_ty.zigTypeTag() != .NoReturn) break true;10204 if (field_ty.zigTypeTag() != .NoReturn) break true;
10205 } else false10205 } else false
...@@ -10587,7 +10587,7 @@ fn resolveSwitchItemVal(...@@ -10587,7 +10587,7 @@ fn resolveSwitchItemVal(
10587 // Constructing a LazySrcLoc is costly because we only have the switch AST node.10587 // Constructing a LazySrcLoc is costly because we only have the switch AST node.
10588 // Only if we know for sure we need to report a compile error do we resolve the10588 // Only if we know for sure we need to report a compile error do we resolve the
10589 // full source locations.10589 // full source locations.
10590 if (sema.resolveConstValue(block, .unneeded, item, undefined)) |val| {10590 if (sema.resolveConstValue(block, .unneeded, item, "")) |val| {
10591 return TypedValue{ .ty = item_ty, .val = val };10591 return TypedValue{ .ty = item_ty, .val = val };
10592 } else |err| switch (err) {10592 } else |err| switch (err) {
10593 error.NeededSourceLocation => {10593 error.NeededSourceLocation => {
...@@ -17094,7 +17094,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -17094,7 +17094,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
17094 try sema.resolveTypeLayout(block, operand_src, operand_ty);17094 try sema.resolveTypeLayout(block, operand_src, operand_ty);
17095 const enum_ty = switch (operand_ty.zigTypeTag()) {17095 const enum_ty = switch (operand_ty.zigTypeTag()) {
17096 .EnumLiteral => {17096 .EnumLiteral => {
17097 const val = try sema.resolveConstValue(block, .unneeded, operand, undefined);17097 const val = try sema.resolveConstValue(block, .unneeded, operand, "");
17098 const bytes = val.castTag(.enum_literal).?.data;17098 const bytes = val.castTag(.enum_literal).?.data;
17099 return sema.addStrLit(block, bytes);17099 return sema.addStrLit(block, bytes);
17100 },17100 },
...@@ -20069,7 +20069,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -20069,7 +20069,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
20069 var bound_arg_src: ?LazySrcLoc = null;20069 var bound_arg_src: ?LazySrcLoc = null;
20070 if (sema.typeOf(func).tag() == .bound_fn) {20070 if (sema.typeOf(func).tag() == .bound_fn) {
20071 bound_arg_src = func_src;20071 bound_arg_src = func_src;
20072 const bound_func = try sema.resolveValue(block, .unneeded, func, undefined);20072 const bound_func = try sema.resolveValue(block, .unneeded, func, "");
20073 const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data;20073 const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data;
20074 func = bound_data.func_inst;20074 func = bound_data.func_inst;
20075 resolved_args = try sema.arena.alloc(Air.Inst.Ref, args_ty.structFieldCount() + 1);20075 resolved_args = try sema.arena.alloc(Air.Inst.Ref, args_ty.structFieldCount() + 1);
...@@ -22020,7 +22020,7 @@ fn fieldPtr(...@@ -22020,7 +22020,7 @@ fn fieldPtr(
22020 }22020 }
22021 },22021 },
22022 .Type => {22022 .Type => {
22023 _ = try sema.resolveConstValue(block, .unneeded, object_ptr, undefined);22023 _ = try sema.resolveConstValue(block, .unneeded, object_ptr, "");
22024 const result = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src);22024 const result = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src);
22025 const inner = if (is_pointer_to)22025 const inner = if (is_pointer_to)
22026 try sema.analyzeLoad(block, src, result, object_ptr_src)22026 try sema.analyzeLoad(block, src, result, object_ptr_src)
...@@ -23348,7 +23348,7 @@ fn coerceExtra(...@@ -23348,7 +23348,7 @@ fn coerceExtra(
2334823348
23349 // Function body to function pointer.23349 // Function body to function pointer.
23350 if (inst_ty.zigTypeTag() == .Fn) {23350 if (inst_ty.zigTypeTag() == .Fn) {
23351 const fn_val = try sema.resolveConstValue(block, .unneeded, inst, undefined);23351 const fn_val = try sema.resolveConstValue(block, .unneeded, inst, "");
23352 const fn_decl = fn_val.pointerDecl().?;23352 const fn_decl = fn_val.pointerDecl().?;
23353 const inst_as_ptr = try sema.analyzeDeclRef(fn_decl);23353 const inst_as_ptr = try sema.analyzeDeclRef(fn_decl);
23354 return sema.coerce(block, dest_ty, inst_as_ptr, inst_src);23354 return sema.coerce(block, dest_ty, inst_as_ptr, inst_src);
...@@ -23650,7 +23650,7 @@ fn coerceExtra(...@@ -23650,7 +23650,7 @@ fn coerceExtra(
23650 },23650 },
23651 .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag()) {23651 .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag()) {
23652 .ComptimeFloat => {23652 .ComptimeFloat => {
23653 const val = try sema.resolveConstValue(block, .unneeded, inst, undefined);23653 const val = try sema.resolveConstValue(block, .unneeded, inst, "");
23654 const result_val = try val.floatCast(sema.arena, dest_ty, target);23654 const result_val = try val.floatCast(sema.arena, dest_ty, target);
23655 return try sema.addConstant(dest_ty, result_val);23655 return try sema.addConstant(dest_ty, result_val);
23656 },23656 },
...@@ -23708,7 +23708,7 @@ fn coerceExtra(...@@ -23708,7 +23708,7 @@ fn coerceExtra(
23708 .Enum => switch (inst_ty.zigTypeTag()) {23708 .Enum => switch (inst_ty.zigTypeTag()) {
23709 .EnumLiteral => {23709 .EnumLiteral => {
23710 // enum literal to enum23710 // enum literal to enum
23711 const val = try sema.resolveConstValue(block, .unneeded, inst, undefined);23711 const val = try sema.resolveConstValue(block, .unneeded, inst, "");
23712 const bytes = val.castTag(.enum_literal).?.data;23712 const bytes = val.castTag(.enum_literal).?.data;
23713 const field_index = dest_ty.enumFieldIndex(bytes) orelse {23713 const field_index = dest_ty.enumFieldIndex(bytes) orelse {
23714 const msg = msg: {23714 const msg = msg: {
...@@ -24778,7 +24778,7 @@ fn coerceVarArgParam(...@@ -24778,7 +24778,7 @@ fn coerceVarArgParam(
24778 .{},24778 .{},
24779 ),24779 ),
24780 .Fn => blk: {24780 .Fn => blk: {
24781 const fn_val = try sema.resolveConstValue(block, .unneeded, inst, undefined);24781 const fn_val = try sema.resolveConstValue(block, .unneeded, inst, "");
24782 const fn_decl = fn_val.pointerDecl().?;24782 const fn_decl = fn_val.pointerDecl().?;
24783 break :blk try sema.analyzeDeclRef(fn_decl);24783 break :blk try sema.analyzeDeclRef(fn_decl);
24784 },24784 },
...@@ -27202,7 +27202,7 @@ fn analyzeSlice(...@@ -27202,7 +27202,7 @@ fn analyzeSlice(
27202 if (!end_is_len) {27202 if (!end_is_len) {
27203 break :e try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);27203 break :e try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
27204 }27204 }
27205 return sema.fail(block, end_src, "slice of pointer must include end value", .{});27205 return sema.fail(block, src, "slice of pointer must include end value", .{});
27206 };27206 };
2720727207
27208 const sentinel = s: {27208 const sentinel = s: {
test/cases/compile_errors/stage1/obj/runtime_value_in_switch_prong.zig created+14
...@@ -0,0 +1,14 @@
1pub export fn entry() void {
2 var byte: u8 = 1;
3 switch (byte) {
4 byte => {},
5 else => {},
6 }
7}
8
9// error
10// backend=stage2
11// target=native
12//
13// :4:9: error: unable to resolve comptime value
14// :4:9: note: switch prong values must be comptime known