Commit 46d592e485
Changed files (5)
lib
src
test
behavior
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'