mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
Also check whether structs contain slices
This commit is contained in:
parent
1df601d581
commit
d9133b9ae0
@ -169,21 +169,31 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn typeContainsSlice(comptime K: type) bool {
|
||||||
|
comptime {
|
||||||
|
if (meta.trait.isSlice(K)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (meta.trait.is(.Struct)(K)) {
|
||||||
|
inline for (@typeInfo(K).Struct.fields) |field| {
|
||||||
|
if (typeContainsSlice(field.field_type)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Provides generic hashing for any eligible type.
|
/// Provides generic hashing for any eligible type.
|
||||||
/// Only hashes `key` itself, pointers are not followed.
|
/// Only hashes `key` itself, pointers are not followed.
|
||||||
/// Slices are rejected to avoid ambiguity on the user's intention.
|
/// Slices and structs containing slices are rejected to avoid ambiguity on the
|
||||||
|
/// user's intention.
|
||||||
pub fn autoHash(hasher: anytype, key: anytype) void {
|
pub fn autoHash(hasher: anytype, key: anytype) void {
|
||||||
const Key = @TypeOf(key);
|
const Key = @TypeOf(key);
|
||||||
if (comptime meta.trait.isSlice(Key)) {
|
if (comptime typeContainsSlice(Key)) {
|
||||||
comptime assert(@hasDecl(std, "StringHashMap")); // detect when the following message needs updated
|
@compileError("std.auto_hash.autoHash does not allow slices or structs containing slices here (" ++ @typeName(Key) ++
|
||||||
const extra_help = if (Key == []const u8)
|
") because the intent is unclear. Consider using std.auto_hash.hash or providing your own hash function instead.");
|
||||||
" Consider std.StringHashMap for hashing the contents of []const u8."
|
|
||||||
else
|
|
||||||
"";
|
|
||||||
|
|
||||||
@compileError("std.auto_hash.autoHash does not allow slices (here " ++ @typeName(Key) ++
|
|
||||||
") because the intent is unclear. Consider using std.auto_hash.hash or providing your own hash function instead." ++
|
|
||||||
extra_help);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hash(hasher, key, .Shallow);
|
hash(hasher, key, .Shallow);
|
||||||
@ -220,6 +230,23 @@ fn testHashDeepRecursive(key: anytype) u64 {
|
|||||||
return hasher.final();
|
return hasher.final();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "typeContainsSlice" {
|
||||||
|
comptime {
|
||||||
|
testing.expect(!typeContainsSlice(@TagType(std.builtin.TypeInfo)));
|
||||||
|
|
||||||
|
testing.expect(typeContainsSlice([]const u8));
|
||||||
|
testing.expect(!typeContainsSlice(u8));
|
||||||
|
const A = struct { x: []const u8 };
|
||||||
|
const B = struct { a: A };
|
||||||
|
const C = struct { b: B };
|
||||||
|
const D = struct { x: u8 };
|
||||||
|
testing.expect(typeContainsSlice(A));
|
||||||
|
testing.expect(typeContainsSlice(B));
|
||||||
|
testing.expect(typeContainsSlice(C));
|
||||||
|
testing.expect(!typeContainsSlice(D));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
test "hash pointer" {
|
test "hash pointer" {
|
||||||
const array = [_]u32{ 123, 123, 123 };
|
const array = [_]u32{ 123, 123, 123 };
|
||||||
const a = &array[0];
|
const a = &array[0];
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user