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

This commit is contained in:
Meghan Denny
2024-01-19 00:35:45 -08:00
committed by Andrew Kelley
parent d7b6d637df
commit 46d592e485
5 changed files with 36 additions and 51 deletions

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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'