Commit 46d592e485

Meghan Denny <hello@nektro.net>
2024-01-19 09:35:45
do not enforce function parameters to be marked comptime if only called at comptime
1 parent d7b6d63
lib/std/comptime_string_map.zig
@@ -299,3 +299,22 @@ test "ComptimeStringMap redundant insensitive" {
 
     try std.testing.expectEqual(TestEnum.A, map.get("theNeedle").?);
 }
+
+test "ComptimeStringMap comptime-only value" {
+    const map = std.ComptimeStringMap(type, .{
+        .{ "a", struct {
+            pub const foo = 1;
+        } },
+        .{ "b", struct {
+            pub const foo = 2;
+        } },
+        .{ "c", struct {
+            pub const foo = 3;
+        } },
+    });
+
+    try std.testing.expect(map.get("a").?.foo == 1);
+    try std.testing.expect(map.get("b").?.foo == 2);
+    try std.testing.expect(map.get("c").?.foo == 3);
+    try std.testing.expect(map.get("d") == null);
+}
src/Sema.zig
@@ -9302,7 +9302,7 @@ fn funcCommon(
             };
             return sema.failWithOwnedErrorMsg(block, msg);
         }
-        if (is_source_decl and requires_comptime and !param_is_comptime and has_body) {
+        if (is_source_decl and requires_comptime and !param_is_comptime and has_body and !block.is_comptime) {
             const msg = msg: {
                 const msg = try sema.errMsg(block, param_src, "parameter of type '{}' must be declared comptime", .{
                     param_ty.fmt(mod),
@@ -9597,7 +9597,7 @@ fn finishFunc(
 
     // If the return type is comptime-only but not dependent on parameters then
     // all parameter types also need to be comptime.
-    if (is_source_decl and opt_func_index != .none and ret_ty_requires_comptime) comptime_check: {
+    if (is_source_decl and opt_func_index != .none and ret_ty_requires_comptime and !block.is_comptime) comptime_check: {
         for (block.params.items(.is_comptime)) |is_comptime| {
             if (!is_comptime) break;
         } else break :comptime_check;
test/behavior/fn.zig
@@ -596,3 +596,12 @@ test "pointer to alias behaves same as pointer to function" {
     _ = &a;
     try std.testing.expect(S.foo() == a());
 }
+
+test "comptime parameters don't have to be marked comptime if only called at comptime" {
+    const S = struct {
+        fn foo(x: comptime_int, y: comptime_int) u32 {
+            return x + y;
+        }
+    };
+    comptime std.debug.assert(S.foo(5, 6) == 11);
+}
test/cases/compile_errors/comptime_parameter_not_declared_as_such.zig
@@ -1,25 +0,0 @@
-fn f(_: anytype) void {}
-const T = *const fn (anytype) void;
-fn g(h: T) void {
-    h({});
-}
-pub export fn entry() void {
-    g(f);
-}
-
-pub fn comptimeMod(num: anytype, denom: comptime_int) void {
-    _ = num;
-    _ = denom;
-}
-
-pub export fn entry1() void {
-    _ = comptimeMod(1, 2);
-}
-
-// error
-// backend=stage2
-// target=native
-//
-// :3:6: error: parameter of type '*const fn (anytype) void' must be declared comptime
-// :3:6: note: function is generic
-// :10:34: error: parameter of type 'comptime_int' must be declared comptime
test/cases/compile_errors/non_comptime_param_in_comptime_function.zig
@@ -3,34 +3,16 @@ fn F(val: anytype) type {
     return struct {};
 }
 export fn entry() void {
-    _ = F(void{});
-}
-const S = struct {
-    foo: fn () void,
-};
-fn bar(_: u32) S {
-    return undefined;
-}
-export fn entry1() void {
-    _ = bar();
-}
-// prioritize other return type errors
-fn foo(a: u32) callconv(.C) comptime_int {
-    return a;
-}
-export fn entry2() void {
-    _ = foo(1);
+    var x: u32 = 0;
+    _ = &x;
+    _ = F(x);
 }
 
 // error
 // backend=stage2
 // target=native
 //
-// :1:20: error: function with comptime-only return type 'type' requires all parameters to be comptime
+// :8:11: error: unable to resolve comptime value
+// :8:11: note: argument to function being called at comptime must be comptime-known
+// :1:20: note: expression is evaluated at comptime because the function returns a comptime-only type 'type'
 // :1:20: note: types are not available at runtime
-// :1:6: note: param 'val' is required to be comptime
-// :11:16: error: function with comptime-only return type 'tmp.S' requires all parameters to be comptime
-// :9:10: note: struct requires comptime because of this field
-// :9:10: note: use '*const fn () void' for a function pointer type
-// :11:8: note: param is required to be comptime
-// :18:29: error: return type 'comptime_int' not allowed in function with calling convention 'C'