Commit 6f6b14621d

Veikka Tuominen <git@vexu.eu>
2022-09-09 14:34:43
value: hash extern functions
Closes #12766
1 parent 930f904
Changed files (2)
src
test
behavior
src/value.zig
@@ -2391,12 +2391,15 @@ pub const Value = extern union {
                 union_obj.val.hash(active_field_ty, hasher, mod);
             },
             .Fn => {
-                const func: *Module.Fn = val.castTag(.function).?.data;
-                // Note that his hashes the *Fn rather than the *Decl. This is
+                // Note that his hashes the *Fn/*ExternFn rather than the *Decl. This is
                 // to differentiate function bodies from function pointers.
                 // This is currently redundant since we already hash the zig type tag
                 // at the top of this function.
-                std.hash.autoHash(hasher, func);
+                if (val.castTag(.function)) |func| {
+                    std.hash.autoHash(hasher, func.data);
+                } else if (val.castTag(.extern_fn)) |func| {
+                    std.hash.autoHash(hasher, func.data);
+                } else unreachable;
             },
             .Frame => {
                 @panic("TODO implement hashing frame values");
test/behavior/generics.zig
@@ -358,3 +358,14 @@ test "nested generic function" {
     try expect(@typeInfo(@TypeOf(S.g)).Fn.is_generic);
     try S.foo(u32, S.bar, 123);
 }
+
+test "extern function used as generic parameter" {
+    const S = struct {
+        extern fn foo() void;
+        extern fn bar() void;
+        inline fn baz(comptime _: anytype) type {
+            return struct {};
+        }
+    };
+    try expect(S.baz(S.foo) != S.baz(S.bar));
+}