authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-08-21 17:27:52+03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-08-21 17:27:52+03:00
log02070ae26b872aa4a1b3da4c1820a4a360c7ee92
treee9271c0fefbbfcba4ea4adb4ce182b378b92acc9
parent4a98385b0aa3808ab05a1ebfbc90fd0bcd97c0d9
parent20d0018d79c25a0def440040eab2970e7a314130
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #12499 from Vexu/explain-why-called-at-comptime

stage2: add note about function call being comptime because of comptime only return type

10 files changed, 190 insertions(+), 32 deletions(-)

src/Sema.zig+94-27
......@@ -3087,7 +3087,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
30873087
30883088 const candidate = block.instructions.items[search_index];
30893089 switch (air_tags[candidate]) {
3090 .dbg_stmt => continue,
3090 .dbg_stmt, .dbg_block_begin, .dbg_block_end => continue,
30913091 .store => break candidate,
30923092 else => break :ct,
30933093 }
......@@ -3099,7 +3099,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
30993099
31003100 const candidate = block.instructions.items[search_index];
31013101 switch (air_tags[candidate]) {
3102 .dbg_stmt => continue,
3102 .dbg_stmt, .dbg_block_begin, .dbg_block_end => continue,
31033103 .alloc => {
31043104 if (Air.indexToRef(candidate) != alloc) break :ct;
31053105 break;
......@@ -3317,7 +3317,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
33173317
33183318 const candidate = block.instructions.items[search_index];
33193319 switch (air_tags[candidate]) {
3320 .dbg_stmt => continue,
3320 .dbg_stmt, .dbg_block_begin, .dbg_block_end => continue,
33213321 .store => break candidate,
33223322 else => break :ct,
33233323 }
......@@ -3329,7 +3329,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
33293329
33303330 const candidate = block.instructions.items[search_index];
33313331 switch (air_tags[candidate]) {
3332 .dbg_stmt => continue,
3332 .dbg_stmt, .dbg_block_begin, .dbg_block_end => continue,
33333333 .bitcast => break candidate,
33343334 else => break :ct,
33353335 }
......@@ -3341,7 +3341,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
33413341
33423342 const candidate = block.instructions.items[search_index];
33433343 switch (air_tags[candidate]) {
3344 .dbg_stmt => continue,
3344 .dbg_stmt, .dbg_block_begin, .dbg_block_end => continue,
33453345 .constant => break candidate,
33463346 else => break :ct,
33473347 }
......@@ -3615,8 +3615,6 @@ fn validateUnionInit(
36153615 union_ptr: Air.Inst.Ref,
36163616 is_comptime: bool,
36173617) CompileError!void {
3618 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
3619
36203618 if (instrs.len != 1) {
36213619 const msg = msg: {
36223620 const msg = try sema.errMsg(
......@@ -3650,7 +3648,8 @@ fn validateUnionInit(
36503648 const field_src: LazySrcLoc = .{ .node_offset_initializer = field_ptr_data.src_node };
36513649 const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data;
36523650 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);
36543653 const air_tags = sema.air_instructions.items(.tag);
36553654 const air_datas = sema.air_instructions.items(.data);
36563655 const field_ptr_air_ref = sema.inst_map.get(field_ptr).?;
......@@ -3709,7 +3708,9 @@ fn validateUnionInit(
37093708 break;
37103709 }
37113710
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);
37133714
37143715 if (init_val) |val| {
37153716 // Our task is to delete all the `field_ptr` and `store` instructions, and insert
......@@ -3726,7 +3727,7 @@ fn validateUnionInit(
37263727 }
37273728
37283729 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);
37303731 _ = try block.addBinOp(.set_union_tag, union_ptr, new_tag);
37313732}
37323733
......@@ -5643,6 +5644,37 @@ const GenericCallAdapter = struct {
56435644 }
56445645};
56455646
5647fn 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
56465678fn analyzeCall(
56475679 sema: *Sema,
56485680 block: *Block,
......@@ -5733,9 +5765,11 @@ fn analyzeCall(
57335765
57345766 var is_generic_call = func_ty_info.is_generic;
57355767 var is_comptime_call = block.is_comptime or modifier == .compile_time;
5768 var comptime_only_ret_ty = false;
57365769 if (!is_comptime_call) {
57375770 if (sema.typeRequiresComptime(block, func_src, func_ty_info.return_type)) |ct| {
57385771 is_comptime_call = ct;
5772 comptime_only_ret_ty = ct;
57395773 } else |err| switch (err) {
57405774 error.GenericPoison => is_generic_call = true,
57415775 else => |e| return e,
......@@ -5764,6 +5798,7 @@ fn analyzeCall(
57645798 error.ComptimeReturn => {
57655799 is_inline_call = true;
57665800 is_comptime_call = true;
5801 comptime_only_ret_ty = true;
57675802 },
57685803 else => |e| return e,
57695804 }
......@@ -5774,8 +5809,12 @@ fn analyzeCall(
57745809 }
57755810
57765811 const result: Air.Inst.Ref = if (is_inline_call) res: {
5777 // TODO explain why function is being called at comptime
5778 const func_val = try sema.resolveConstValue(block, func_src, func, "function being called at comptime must be comptime known");
5812 const func_val = sema.resolveConstValue(block, func_src, func, "function being called at comptime must be comptime known") catch |err| {
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 };
57795818 const module_fn = switch (func_val.tag()) {
57805819 .decl_ref => mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data,
57815820 .function => func_val.castTag(.function).?.data,
......@@ -5887,6 +5926,11 @@ fn analyzeCall(
58875926 is_comptime_call,
58885927 &should_memoize,
58895928 memoized_call_key,
5929 // last 4 arguments are only used when reporting errors
5930 undefined,
5931 undefined,
5932 undefined,
5933 undefined,
58905934 ) catch |err| switch (err) {
58915935 error.NeededSourceLocation => {
58925936 sema.inst_map.clearRetainingCapacity();
......@@ -5904,6 +5948,10 @@ fn analyzeCall(
59045948 is_comptime_call,
59055949 &should_memoize,
59065950 memoized_call_key,
5951 func,
5952 func_src,
5953 func_ty_info.return_type,
5954 comptime_only_ret_ty,
59075955 );
59085956 return error.AnalysisFail;
59095957 },
......@@ -6119,6 +6167,10 @@ fn analyzeInlineCallArg(
61196167 is_comptime_call: bool,
61206168 should_memoize: *bool,
61216169 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,
61226174) !void {
61236175 const zir_tags = sema.code.instructions.items(.tag);
61246176 switch (zir_tags[inst]) {
......@@ -6134,14 +6186,23 @@ fn analyzeInlineCallArg(
61346186 new_fn_info.param_types[arg_i.*] = param_ty;
61356187 const uncasted_arg = uncasted_args[arg_i.*];
61366188 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 };
61386195 }
61396196 const casted_arg = try sema.coerce(arg_block, param_ty, uncasted_arg, arg_src);
61406197 try sema.inst_map.putNoClobber(sema.gpa, inst, casted_arg);
61416198
61426199 if (is_comptime_call) {
6143 // TODO explain why function is being called at comptime
6144 const arg_val = try sema.resolveConstMaybeUndefVal(arg_block, arg_src, casted_arg, "argument to function being called at comptime must be comptime known");
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| {
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 };
61456206 switch (arg_val.tag()) {
61466207 .generic_poison, .generic_poison_type => {
61476208 // This function is currently evaluated as part of an as-of-yet unresolvable
......@@ -6171,8 +6232,12 @@ fn analyzeInlineCallArg(
61716232 try sema.inst_map.putNoClobber(sema.gpa, inst, uncasted_arg);
61726233
61736234 if (is_comptime_call) {
6174 // TODO explain why function is being called at comptime
6175 const arg_val = try sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "argument to function being called at comptime must be comptime known");
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| {
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 };
61766241 switch (arg_val.tag()) {
61776242 .generic_poison, .generic_poison_type => {
61786243 // This function is currently evaluated as part of an as-of-yet unresolvable
......@@ -8774,13 +8839,11 @@ fn zirSwitchCapture(
87748839 switch (operand_ty.zigTypeTag()) {
87758840 .Union => {
87768841 const union_obj = operand_ty.cast(Type.Payload.Union).?.data;
8777 const enum_ty = union_obj.tag_ty;
8778
87798842 const first_item = try sema.resolveInst(items[0]);
87808843 // Previous switch validation ensured this will succeed
87818844 const first_item_val = sema.resolveConstValue(block, .unneeded, first_item, undefined) catch unreachable;
87828845
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).?);
87848847 const first_field = union_obj.fields.values()[first_field_index];
87858848
87868849 for (items[1..]) |item, i| {
......@@ -8788,7 +8851,7 @@ fn zirSwitchCapture(
87888851 // Previous switch validation ensured this will succeed
87898852 const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable;
87908853
8791 const field_index = enum_ty.enumTagFieldIndex(item_val, sema.mod).?;
8854 const field_index = operand_ty.unionTagFieldIndex(item_val, sema.mod).?;
87928855 const field = union_obj.fields.values()[field_index];
87938856 if (!field.ty.eql(first_field.ty, sema.mod)) {
87948857 const msg = msg: {
......@@ -15521,7 +15584,9 @@ fn unionInit(
1552115584 const init = try sema.coerce(block, field.ty, uncasted_init, init_src);
1552215585
1552315586 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);
1552515590 return sema.addConstant(union_ty, try Value.Tag.@"union".create(sema.arena, .{
1552615591 .tag = tag_val,
1552715592 .val = init_val,
......@@ -15619,7 +15684,9 @@ fn zirStructInit(
1561915684 const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data;
1562015685 const field_name = sema.code.nullTerminatedString(field_type_extra.name_start);
1562115686 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);
1562315690
1562415691 const init_inst = try sema.resolveInst(item.data.init);
1562515692 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
1638416451 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);
1638516452 const val = try sema.resolveConstValue(block, operand_src, type_info, "operand to @Type must be comptime known");
1638616453 const union_val = val.cast(Value.Payload.Union).?.data;
16387 const tag_ty = type_info_ty.unionTagType().?;
1638816454 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).?;
1639016456 if (union_val.val.anyUndef()) return sema.failWithUseOfUndef(block, src);
1639116457 switch (@intToEnum(std.builtin.TypeId, tag_index)) {
1639216458 .Type => return Air.Inst.Ref.type_type,
......@@ -25091,8 +25157,7 @@ fn coerceEnumToUnion(
2509125157
2509225158 const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src);
2509325159 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {
25094 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
25095 const field_index = union_obj.tag_ty.enumTagFieldIndex(val, sema.mod) orelse {
25160 const field_index = union_ty.unionTagFieldIndex(val, sema.mod) orelse {
2509625161 const msg = msg: {
2509725162 const msg = try sema.errMsg(block, inst_src, "union '{}' has no tag with value '{}'", .{
2509825163 union_ty.fmt(sema.mod), val.fmtValue(tag_ty, sema.mod),
......@@ -25103,6 +25168,8 @@ fn coerceEnumToUnion(
2510325168 };
2510425169 return sema.failWithOwnedErrorMsg(msg);
2510525170 };
25171
25172 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
2510625173 const field = union_obj.fields.values()[field_index];
2510725174 const field_ty = try sema.resolveTypeFields(block, inst_src, field.ty);
2510825175 if (field_ty.zigTypeTag() == .NoReturn) {
src/codegen.zig+1-1
......@@ -607,7 +607,7 @@ pub fn generateSymbol(
607607
608608 const union_ty = typed_value.ty.cast(Type.Payload.Union).?.data;
609609 const mod = bin_file.options.module.?;
610 const field_index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag, mod).?;
610 const field_index = typed_value.ty.unionTagFieldIndex(union_obj.tag, mod).?;
611611 assert(union_ty.haveFieldTypes());
612612 const field_ty = union_ty.fields.values()[field_index].ty;
613613 if (!field_ty.hasRuntimeBits()) {
src/codegen/c.zig+1-2
......@@ -835,7 +835,6 @@ pub const DeclGen = struct {
835835 },
836836 .Union => {
837837 const union_obj = val.castTag(.@"union").?.data;
838 const union_ty = ty.cast(Type.Payload.Union).?.data;
839838 const layout = ty.unionGetLayout(target);
840839
841840 try writer.writeAll("(");
......@@ -851,7 +850,7 @@ pub const DeclGen = struct {
851850 try writer.writeAll(".payload = {");
852851 }
853852
854 const index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag, dg.module).?;
853 const index = ty.unionTagFieldIndex(union_obj.tag, dg.module).?;
855854 const field_ty = ty.unionFields().values()[index].ty;
856855 const field_name = ty.unionFields().keys()[index];
857856 if (field_ty.hasRuntimeBits()) {
src/codegen/llvm.zig+1-1
......@@ -3502,7 +3502,7 @@ pub const DeclGen = struct {
35023502 });
35033503 }
35043504 const union_obj = tv.ty.cast(Type.Payload.Union).?.data;
3505 const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, dg.module).?;
3505 const field_index = tv.ty.unionTagFieldIndex(tag_and_val.tag, dg.module).?;
35063506 assert(union_obj.haveFieldTypes());
35073507
35083508 // Sometimes we must make an unnamed struct because LLVM does
src/type.zig+8-1
......@@ -4285,11 +4285,18 @@ pub const Type = extern union {
42854285
42864286 pub fn unionFieldType(ty: Type, enum_tag: Value, mod: *Module) Type {
42874287 const union_obj = ty.cast(Payload.Union).?.data;
4288 const index = union_obj.tag_ty.enumTagFieldIndex(enum_tag, mod).?;
4288 const index = ty.unionTagFieldIndex(enum_tag, mod).?;
42894289 assert(union_obj.haveFieldTypes());
42904290 return union_obj.fields.values()[index].ty;
42914291 }
42924292
4293 pub fn unionTagFieldIndex(ty: Type, enum_tag: Value, mod: *Module) ?usize {
4294 const union_obj = ty.cast(Payload.Union).?.data;
4295 const index = union_obj.tag_ty.enumTagFieldIndex(enum_tag, mod) orelse return null;
4296 const name = union_obj.tag_ty.enumFieldName(index);
4297 return union_obj.fields.getIndex(name);
4298 }
4299
42934300 pub fn unionHasAllZeroBitFieldTypes(ty: Type) bool {
42944301 return ty.cast(Payload.Union).?.data.hasAllZeroBitFieldTypes();
42954302 }
test/behavior/eval.zig+15
......@@ -1310,3 +1310,18 @@ test "repeated value is correctly expanded" {
13101310 } }, res);
13111311 }
13121312}
1313
1314test "value in if block is comptime known" {
1315 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
1316
1317 const first = blk: {
1318 const s = if (false) "a" else "b";
1319 break :blk "foo" ++ s;
1320 };
1321 const second = blk: {
1322 const S = struct { str: []const u8 };
1323 const s = if (false) S{ .str = "a" } else S{ .str = "b" };
1324 break :blk "foo" ++ s.str;
1325 };
1326 comptime try expect(std.mem.eql(u8, first, second));
1327}
test/behavior/union.zig+24
......@@ -1301,3 +1301,27 @@ test "noreturn field in union" {
13011301 }
13021302 try expect(count == 5);
13031303}
1304
1305test "union and enum field order doesn't match" {
1306 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
1307 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1308 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1309
1310 const MyTag = enum(u32) {
1311 b = 1337,
1312 a = 1666,
1313 };
1314 const MyUnion = union(MyTag) {
1315 a: f32,
1316 b: void,
1317 };
1318 var x: MyUnion = .{ .a = 666 };
1319 switch (x) {
1320 .a => |my_f32| {
1321 try expect(@TypeOf(my_f32) == f32);
1322 },
1323 .b => unreachable,
1324 }
1325 x = .b;
1326 try expect(x == .b);
1327}
test/cases/compile_errors/explain_why_fn_is_called_at_comptime.zig created+23
......@@ -0,0 +1,23 @@
1const S = struct {
2 fnPtr: fn () void,
3 a: u8,
4};
5fn bar() void {}
6
7fn foo(a: u8) S {
8 return .{ .fnPtr = bar, .a = a };
9}
10pub export fn entry() void {
11 var a: u8 = 1;
12 _ = foo(a);
13}
14
15// error
16// backend=stage2
17// target=native
18//
19// :12:13: error: unable to resolve comptime value
20// :12:13: note: argument to function being called at comptime must be comptime known
21// :7:15: note: function is being called at comptime because it returns a comptime only type 'tmp.S'
22// :2:12: note: struct requires comptime because of this field
23// :2:12: note: use '*const fn() void' for a function pointer type
test/cases/compile_errors/explain_why_generic_fn_is_called_at_comptime.zig created+22
......@@ -0,0 +1,22 @@
1fn S(comptime PtrTy: type) type {
2 return struct {
3 fnPtr: PtrTy,
4 a: u8,
5 };
6}
7fn bar() void {}
8
9fn foo(a: u8, comptime PtrTy: type) S(PtrTy) {
10 return .{ .fnPtr = bar, .a = a };
11}
12pub export fn entry() void {
13 var a: u8 = 1;
14 _ = foo(a, fn () void);
15}
16// error
17// backend=stage2
18// target=native
19//
20// :14:13: error: unable to resolve comptime value
21// :14:13: note: argument to function being called at comptime must be comptime known
22// :9:38: note: generic function is instantiated with a comptime only return type
test/compile_errors.zig+1
......@@ -204,6 +204,7 @@ pub fn addCases(ctx: *TestContext) !void {
204204 , &[_][]const u8{
205205 ":3:12: error: unable to resolve comptime value",
206206 ":3:12: note: argument to function being called at comptime must be comptime known",
207 ":2:55: note: generic function is instantiated with a comptime only return type",
207208 });
208209 }
209210