commit 50754ba336e99ac3db972a8b4e7bc583d77f2892 (tree)
parent 4c87281b5cf0e9268107f6456aeb16d097d1eb76
Author: LemonBoy <thatlemon@gmail.com>
Date: Tue, 14 Jan 2020 12:19:10 +0100
Fix ICE when BoundFn are passed as parameters
Closes #4022
Closes #3699
Diffstat:
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/src/analyze.cpp b/src/analyze.cpp
@@ -5289,7 +5289,10 @@ static uint32_t hash_const_val(ZigValue *const_val) {
case ZigTypeIdAnyFrame:
// TODO better hashing algorithm
return 3747294894;
- case ZigTypeIdBoundFn:
+ case ZigTypeIdBoundFn: {
+ assert(const_val->data.x_bound_fn.fn != nullptr);
+ return 3677364617 ^ hash_ptr(const_val->data.x_bound_fn.fn);
+ }
case ZigTypeIdInvalid:
case ZigTypeIdUnreachable:
zig_unreachable();
diff --git a/test/stage1/behavior/call.zig b/test/stage1/behavior/call.zig
@@ -1,5 +1,6 @@
const std = @import("std");
const expect = std.testing.expect;
+const expectEqual = std.testing.expectEqual;
test "basic invocations" {
const foo = struct {
@@ -53,3 +54,21 @@ test "tuple parameters" {
expect(@call(.{ .modifier = .always_inline }, add, separate_args3) == 46);
}
}
+
+test "comptime call with bound function as parameter" {
+ const S = struct {
+ fn ReturnType(func: var) type {
+ return switch (@typeInfo(@TypeOf(func))) {
+ .BoundFn => |info| info,
+ else => unreachable,
+ }.return_type orelse void;
+ }
+
+ fn call_me_maybe() ?i32 {
+ return 123;
+ }
+ };
+
+ var inst: S = undefined;
+ expectEqual(?i32, S.ReturnType(inst.call_me_maybe));
+}