| author | |
| committer | |
| log | 46d592e485cf8ee4d85854040acd1b05271591b5 |
| tree | 3c6de775a40405360f3ca216e2e4c205851404c4 |
| parent | d7b6d637df5b94ec07cf017fa742e8c34a4b9433 |
5 files changed, 36 insertions(+), 51 deletions(-)
lib/std/comptime_string_map.zig+19| ... | @@ -299,3 +299,22 @@ test "ComptimeStringMap redundant insensitive" { | ... | @@ -299,3 +299,22 @@ test "ComptimeStringMap redundant insensitive" { |
| 299 | 299 | ||
| 300 | try std.testing.expectEqual(TestEnum.A, map.get("theNeedle").?); | 300 | try std.testing.expectEqual(TestEnum.A, map.get("theNeedle").?); |
| 301 | } | 301 | } |
| 302 | |||
| 303 | test "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( | ... | @@ -9302,7 +9302,7 @@ fn funcCommon( |
| 9302 | }; | 9302 | }; |
| 9303 | return sema.failWithOwnedErrorMsg(block, msg); | 9303 | return sema.failWithOwnedErrorMsg(block, msg); |
| 9304 | } | 9304 | } |
| 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) { |
| 9306 | const msg = msg: { | 9306 | const msg = msg: { |
| 9307 | const msg = try sema.errMsg(block, param_src, "parameter of type '{}' must be declared comptime", .{ | 9307 | const msg = try sema.errMsg(block, param_src, "parameter of type '{}' must be declared comptime", .{ |
| 9308 | param_ty.fmt(mod), | 9308 | param_ty.fmt(mod), |
| ... | @@ -9597,7 +9597,7 @@ fn finishFunc( | ... | @@ -9597,7 +9597,7 @@ fn finishFunc( |
| 9597 | 9597 | ||
| 9598 | // If the return type is comptime-only but not dependent on parameters then | 9598 | // If the return type is comptime-only but not dependent on parameters then |
| 9599 | // all parameter types also need to be comptime. | 9599 | // 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: { |
| 9601 | for (block.params.items(.is_comptime)) |is_comptime| { | 9601 | for (block.params.items(.is_comptime)) |is_comptime| { |
| 9602 | if (!is_comptime) break; | 9602 | if (!is_comptime) break; |
| 9603 | } else break :comptime_check; | 9603 | } else break :comptime_check; |
test/behavior/fn.zig+9| ... | @@ -596,3 +596,12 @@ test "pointer to alias behaves same as pointer to function" { | ... | @@ -596,3 +596,12 @@ test "pointer to alias behaves same as pointer to function" { |
| 596 | _ = &a; | 596 | _ = &a; |
| 597 | try std.testing.expect(S.foo() == a()); | 597 | try std.testing.expect(S.foo() == a()); |
| 598 | } | 598 | } |
| 599 | |||
| 600 | test "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 @@ | ||
| 1 | fn f(_: anytype) void {} | ||
| 2 | const T = *const fn (anytype) void; | ||
| 3 | fn g(h: T) void { | ||
| 4 | h({}); | ||
| 5 | } | ||
| 6 | pub export fn entry() void { | ||
| 7 | g(f); | ||
| 8 | } | ||
| 9 | |||
| 10 | pub fn comptimeMod(num: anytype, denom: comptime_int) void { | ||
| 11 | _ = num; | ||
| 12 | _ = denom; | ||
| 13 | } | ||
| 14 | |||
| 15 | pub 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 { | ... | @@ -3,34 +3,16 @@ fn F(val: anytype) type { |
| 3 | return struct {}; | 3 | return struct {}; |
| 4 | } | 4 | } |
| 5 | export fn entry() void { | 5 | export fn entry() void { |
| 6 | _ = F(void{}); | 6 | var x: u32 = 0; |
| 7 | } | 7 | _ = &x; |
| 8 | const S = struct { | 8 | _ = F(x); |
| 9 | foo: fn () void, | ||
| 10 | }; | ||
| 11 | fn bar(_: u32) S { | ||
| 12 | return undefined; | ||
| 13 | } | ||
| 14 | export fn entry1() void { | ||
| 15 | _ = bar(); | ||
| 16 | } | ||
| 17 | // prioritize other return type errors | ||
| 18 | fn foo(a: u32) callconv(.C) comptime_int { | ||
| 19 | return a; | ||
| 20 | } | ||
| 21 | export fn entry2() void { | ||
| 22 | _ = foo(1); | ||
| 23 | } | 9 | } |
| 24 | 10 | ||
| 25 | // error | 11 | // error |
| 26 | // backend=stage2 | 12 | // backend=stage2 |
| 27 | // target=native | 13 | // target=native |
| 28 | // | 14 | // |
| 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' | ||
| 30 | // :1:20: note: types are not available at runtime | 18 | // :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' |