authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2024-01-19 00:35:45-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-19 15:31:18-08:00
log46d592e485cf8ee4d85854040acd1b05271591b5
tree3c6de775a40405360f3ca216e2e4c205851404c4
parentd7b6d637df5b94ec07cf017fa742e8c34a4b9433

do not enforce function parameters to be marked comptime if only called at comptime


5 files changed, 36 insertions(+), 51 deletions(-)

lib/std/comptime_string_map.zig+19
......@@ -299,3 +299,22 @@ test "ComptimeStringMap redundant insensitive" {
299299
300300 try std.testing.expectEqual(TestEnum.A, map.get("theNeedle").?);
301301}
302
303test "ComptimeStringMap comptime-only value" {
304 const map = std.ComptimeStringMap(type, .{
305 .{ "a", struct {
306 pub const foo = 1;
307 } },
308 .{ "b", struct {
309 pub const foo = 2;
310 } },
311 .{ "c", struct {
312 pub const foo = 3;
313 } },
314 });
315
316 try std.testing.expect(map.get("a").?.foo == 1);
317 try std.testing.expect(map.get("b").?.foo == 2);
318 try std.testing.expect(map.get("c").?.foo == 3);
319 try std.testing.expect(map.get("d") == null);
320}
src/Sema.zig+2-2
......@@ -9302,7 +9302,7 @@ fn funcCommon(
93029302 };
93039303 return sema.failWithOwnedErrorMsg(block, msg);
93049304 }
9305 if (is_source_decl and requires_comptime and !param_is_comptime and has_body) {
9305 if (is_source_decl and requires_comptime and !param_is_comptime and has_body and !block.is_comptime) {
93069306 const msg = msg: {
93079307 const msg = try sema.errMsg(block, param_src, "parameter of type '{}' must be declared comptime", .{
93089308 param_ty.fmt(mod),
......@@ -9597,7 +9597,7 @@ fn finishFunc(
95979597
95989598 // If the return type is comptime-only but not dependent on parameters then
95999599 // all parameter types also need to be comptime.
9600 if (is_source_decl and opt_func_index != .none and ret_ty_requires_comptime) comptime_check: {
9600 if (is_source_decl and opt_func_index != .none and ret_ty_requires_comptime and !block.is_comptime) comptime_check: {
96019601 for (block.params.items(.is_comptime)) |is_comptime| {
96029602 if (!is_comptime) break;
96039603 } else break :comptime_check;
test/behavior/fn.zig+9
......@@ -596,3 +596,12 @@ test "pointer to alias behaves same as pointer to function" {
596596 _ = &a;
597597 try std.testing.expect(S.foo() == a());
598598}
599
600test "comptime parameters don't have to be marked comptime if only called at comptime" {
601 const S = struct {
602 fn foo(x: comptime_int, y: comptime_int) u32 {
603 return x + y;
604 }
605 };
606 comptime std.debug.assert(S.foo(5, 6) == 11);
607}
test/cases/compile_errors/comptime_parameter_not_declared_as_such.zig deleted-25
......@@ -1,25 +0,0 @@
1fn f(_: anytype) void {}
2const T = *const fn (anytype) void;
3fn g(h: T) void {
4 h({});
5}
6pub export fn entry() void {
7 g(f);
8}
9
10pub fn comptimeMod(num: anytype, denom: comptime_int) void {
11 _ = num;
12 _ = denom;
13}
14
15pub export fn entry1() void {
16 _ = comptimeMod(1, 2);
17}
18
19// error
20// backend=stage2
21// target=native
22//
23// :3:6: error: parameter of type '*const fn (anytype) void' must be declared comptime
24// :3:6: note: function is generic
25// :10:34: error: parameter of type 'comptime_int' must be declared comptime
test/cases/compile_errors/non_comptime_param_in_comptime_function.zig+6-24
......@@ -3,34 +3,16 @@ fn F(val: anytype) type {
33 return struct {};
44}
55export fn entry() void {
6 _ = F(void{});
7}
8const S = struct {
9 foo: fn () void,
10};
11fn bar(_: u32) S {
12 return undefined;
13}
14export fn entry1() void {
15 _ = bar();
16}
17// prioritize other return type errors
18fn foo(a: u32) callconv(.C) comptime_int {
19 return a;
20}
21export fn entry2() void {
22 _ = foo(1);
6 var x: u32 = 0;
7 _ = &x;
8 _ = F(x);
239}
2410
2511// error
2612// backend=stage2
2713// target=native
2814//
29// :1:20: error: function with comptime-only return type 'type' requires all parameters to be comptime
15// :8:11: error: unable to resolve comptime value
16// :8:11: note: argument to function being called at comptime must be comptime-known
17// :1:20: note: expression is evaluated at comptime because the function returns a comptime-only type 'type'
3018// :1:20: note: types are not available at runtime
31// :1:6: note: param 'val' is required to be comptime
32// :11:16: error: function with comptime-only return type 'tmp.S' requires all parameters to be comptime
33// :9:10: note: struct requires comptime because of this field
34// :9:10: note: use '*const fn () void' for a function pointer type
35// :11:8: note: param is required to be comptime
36// :18:29: error: return type 'comptime_int' not allowed in function with calling convention 'C'