[tint] Reduce all hash codes to 32 bits
Change-Id: Iab9c324b928265d094336e0ca7f68fd4ed135e6e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/172541
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Auto-Submit: Ben Clayton <bclayton@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/api/common/binding_point.h b/src/tint/api/common/binding_point.h
index b602c81..2c6baa5 100644
--- a/src/tint/api/common/binding_point.h
+++ b/src/tint/api/common/binding_point.h
@@ -48,6 +48,9 @@
/// Reflect the fields of this class so that it can be used by tint::ForeachField()
TINT_REFLECT(BindingPoint, group, binding);
+ /// @returns the hash code of the BindingPoint
+ tint::HashCode HashCode() const { return tint::Hash(group, binding); }
+
/// Equality operator
/// @param rhs the BindingPoint to compare against
/// @returns true if this BindingPoint is equal to `rhs`
@@ -97,8 +100,9 @@
public:
/// @param binding_point the binding point to create a hash for
/// @return the hash value
- inline std::size_t operator()(const tint::BindingPoint& binding_point) const {
- return tint::Hash(binding_point.group, binding_point.binding);
+ inline size_t operator()(const tint::BindingPoint& binding_point) const {
+ return static_cast<size_t>(binding_point.group) << 16 |
+ static_cast<size_t>(binding_point.binding);
}
};
diff --git a/src/tint/api/common/override_id.h b/src/tint/api/common/override_id.h
index f7a6837..99e9d6a 100644
--- a/src/tint/api/common/override_id.h
+++ b/src/tint/api/common/override_id.h
@@ -31,6 +31,7 @@
#include <stdint.h>
#include <functional>
+#include "src/tint/utils/math/hash.h"
#include "src/tint/utils/reflection/reflection.h"
namespace tint {
@@ -42,6 +43,9 @@
/// Reflect the fields of this struct so that it can be used by tint::ForeachField()
TINT_REFLECT(OverrideId, value);
+
+ /// @returns the hash code of the OverrideId
+ tint::HashCode HashCode() const { return Hash(value); }
};
/// Ensure that all the fields of OverrideId are reflected.
@@ -73,7 +77,7 @@
public:
/// @param id the override identifier
/// @return the hash of the override identifier
- inline std::size_t operator()(tint::OverrideId id) const {
+ inline size_t operator()(tint::OverrideId id) const {
return std::hash<decltype(tint::OverrideId::value)>()(id.value);
}
};
diff --git a/src/tint/fuzzers/random_generator.cc b/src/tint/fuzzers/random_generator.cc
index 3965b1c..5bcf4cd 100644
--- a/src/tint/fuzzers/random_generator.cc
+++ b/src/tint/fuzzers/random_generator.cc
@@ -33,7 +33,6 @@
#include "src/tint/fuzzers/mersenne_twister_engine.h"
#include "src/tint/fuzzers/random_generator_engine.h"
-#include "src/tint/utils/math/hash.h"
namespace tint::fuzzers {
@@ -47,9 +46,9 @@
/// @param size - number of elements in buffer
/// @returns hash of the data in the buffer
size_t HashBuffer(const uint8_t* data, const size_t size) {
- size_t hash = Hash(size);
+ size_t hash = std::hash<size_t>{}(size);
for (size_t i = 0; i < size; i++) {
- hash = HashCombine(hash, data[i]);
+ hash ^= (static_cast<uint64_t>(data[i]) * 31) + (0x7f4a7c16 ^ (hash >> 2));
}
return hash;
}
diff --git a/src/tint/lang/core/constant/composite.h b/src/tint/lang/core/constant/composite.h
index 5844d96..1b359fe 100644
--- a/src/tint/lang/core/constant/composite.h
+++ b/src/tint/lang/core/constant/composite.h
@@ -69,7 +69,7 @@
bool AnyZero() const override { return any_zero; }
/// @copydoc Value::Hash()
- size_t Hash() const override { return hash; }
+ HashCode Hash() const override { return hash; }
/// Clones the constant into the provided context
/// @param ctx the clone context
@@ -85,14 +85,14 @@
/// True if any element is zero
const bool any_zero;
/// The hash of the composite
- const size_t hash;
+ const HashCode hash;
protected:
/// @copydoc Value::InternalValue()
std::variant<std::monostate, AInt, AFloat> InternalValue() const override { return {}; }
private:
- size_t CalcHash() {
+ HashCode CalcHash() {
auto h = tint::Hash(type, all_zero, any_zero);
for (auto* el : elements) {
h = HashCombine(h, el->Hash());
diff --git a/src/tint/lang/core/constant/manager.h b/src/tint/lang/core/constant/manager.h
index 9fdfac8..993a388 100644
--- a/src/tint/lang/core/constant/manager.h
+++ b/src/tint/lang/core/constant/manager.h
@@ -155,7 +155,7 @@
struct Hasher {
/// @param value the value to hash
/// @returns a hash of the value
- size_t operator()(const constant::Value& value) const { return value.Hash(); }
+ HashCode operator()(const constant::Value& value) const { return value.Hash(); }
};
/// An equality helper for constant::Value
diff --git a/src/tint/lang/core/constant/scalar.h b/src/tint/lang/core/constant/scalar.h
index bd9724e..29a3c69 100644
--- a/src/tint/lang/core/constant/scalar.h
+++ b/src/tint/lang/core/constant/scalar.h
@@ -77,7 +77,7 @@
bool AnyZero() const override { return IsZero(); }
/// @copydoc Value::Hash()
- size_t Hash() const override { return tint::Hash(type, ValueOf()); }
+ HashCode Hash() const override { return tint::Hash(type, ValueOf()); }
/// Clones the constant into the provided context
/// @param ctx the clone context
diff --git a/src/tint/lang/core/constant/splat.h b/src/tint/lang/core/constant/splat.h
index a65ea83..bf7a0c4 100644
--- a/src/tint/lang/core/constant/splat.h
+++ b/src/tint/lang/core/constant/splat.h
@@ -65,7 +65,7 @@
bool AnyZero() const override { return el->AnyZero(); }
/// @returns the hash for the splat
- size_t Hash() const override { return tint::Hash(type, el->Hash(), count); }
+ HashCode Hash() const override { return tint::Hash(type, el->Hash(), count); }
/// Clones the constant into the provided context
/// @param ctx the clone context
diff --git a/src/tint/lang/core/constant/value.h b/src/tint/lang/core/constant/value.h
index 98c7bcb..c0ce056 100644
--- a/src/tint/lang/core/constant/value.h
+++ b/src/tint/lang/core/constant/value.h
@@ -70,7 +70,7 @@
virtual bool AnyZero() const = 0;
/// @returns a hash of the value.
- virtual size_t Hash() const = 0;
+ virtual HashCode Hash() const = 0;
/// @returns the value as the given scalar or abstract value.
template <typename T>
diff --git a/src/tint/lang/core/intrinsic/table.h b/src/tint/lang/core/intrinsic/table.h
index 32f60fc..c1cbfcc 100644
--- a/src/tint/lang/core/intrinsic/table.h
+++ b/src/tint/lang/core/intrinsic/table.h
@@ -295,8 +295,8 @@
struct Hasher<core::intrinsic::Overload> {
/// @param i the core::intrinsic::Overload to create a hash for
/// @return the hash value
- inline std::size_t operator()(const core::intrinsic::Overload& i) const {
- size_t hash = Hash(i.parameters.Length());
+ inline HashCode operator()(const core::intrinsic::Overload& i) const {
+ HashCode hash = Hash(i.parameters.Length());
for (auto& p : i.parameters) {
hash = HashCombine(hash, p.type, p.usage);
}
diff --git a/src/tint/lang/core/ir/disassembler.h b/src/tint/lang/core/ir/disassembler.h
index c585fc4..d22b8a1 100644
--- a/src/tint/lang/core/ir/disassembler.h
+++ b/src/tint/lang/core/ir/disassembler.h
@@ -64,7 +64,7 @@
size_t index = 0u;
/// @returns the hash code of the IndexedValue
- size_t HashCode() const { return Hash(instruction, index); }
+ tint::HashCode HashCode() const { return Hash(instruction, index); }
/// An equality helper for IndexedValue.
/// @param other the IndexedValue to compare against
diff --git a/src/tint/lang/core/ir/transform/direct_variable_access.cc b/src/tint/lang/core/ir/transform/direct_variable_access.cc
index 5297c81..ca89b39 100644
--- a/src/tint/lang/core/ir/transform/direct_variable_access.cc
+++ b/src/tint/lang/core/ir/transform/direct_variable_access.cc
@@ -53,7 +53,7 @@
Var* var = nullptr;
/// @return a hash value for this object
- size_t HashCode() const { return Hash(var); }
+ tint::HashCode HashCode() const { return Hash(var); }
/// Inequality operator
bool operator!=(const RootModuleScopeVar& other) const { return var != other.var; }
@@ -66,7 +66,7 @@
const type::Pointer* type = nullptr;
/// @return a hash value for this object
- size_t HashCode() const { return Hash(type); }
+ tint::HashCode HashCode() const { return Hash(type); }
/// Inequality operator
bool operator!=(const RootPtrParameter& other) const { return type != other.type; }
@@ -81,7 +81,7 @@
const type::StructMember* member;
/// @return a hash member for this object
- size_t HashCode() const { return Hash(member); }
+ tint::HashCode HashCode() const { return Hash(member); }
/// Inequality operator
bool operator!=(const MemberAccess& other) const { return member != other.member; }
@@ -91,7 +91,7 @@
/// The ordered list of indices is passed by parameter.
struct IndexAccess {
/// @return a hash value for this object
- size_t HashCode() const { return 42; }
+ tint::HashCode HashCode() const { return 42; }
/// Inequality operator
bool operator!=(const IndexAccess&) const { return false; }
@@ -166,7 +166,7 @@
}
/// @return a hash value for this object
- size_t HashCode() const { return Hash(root, ops); }
+ tint::HashCode HashCode() const { return Hash(root, ops); }
/// Inequality operator
bool operator!=(const AccessShape& other) const {
diff --git a/src/tint/lang/core/ir/value.h b/src/tint/lang/core/ir/value.h
index e2819bc..0603e87 100644
--- a/src/tint/lang/core/ir/value.h
+++ b/src/tint/lang/core/ir/value.h
@@ -48,7 +48,7 @@
size_t operand_index = 0u;
/// @returns the hash code of the Usage
- size_t HashCode() const { return Hash(instruction, operand_index); }
+ tint::HashCode HashCode() const { return Hash(instruction, operand_index); }
/// An equality helper for Usage.
/// @param other the usage to compare against
diff --git a/src/tint/lang/spirv/reader/ast_parser/type.cc b/src/tint/lang/spirv/reader/ast_parser/type.cc
index 2c29979..5c62f29 100644
--- a/src/tint/lang/spirv/reader/ast_parser/type.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/type.cc
@@ -70,55 +70,57 @@
namespace {
struct PointerHasher {
- size_t operator()(const Pointer& t) const { return Hash(t.address_space, t.type, t.access); }
+ HashCode operator()(const Pointer& t) const { return Hash(t.address_space, t.type, t.access); }
};
struct ReferenceHasher {
- size_t operator()(const Reference& t) const { return Hash(t.address_space, t.type, t.access); }
+ HashCode operator()(const Reference& t) const {
+ return Hash(t.address_space, t.type, t.access);
+ }
};
struct VectorHasher {
- size_t operator()(const Vector& t) const { return Hash(t.type, t.size); }
+ HashCode operator()(const Vector& t) const { return Hash(t.type, t.size); }
};
struct MatrixHasher {
- size_t operator()(const Matrix& t) const { return Hash(t.type, t.columns, t.rows); }
+ HashCode operator()(const Matrix& t) const { return Hash(t.type, t.columns, t.rows); }
};
struct ArrayHasher {
- size_t operator()(const Array& t) const { return Hash(t.type, t.size, t.stride); }
+ HashCode operator()(const Array& t) const { return Hash(t.type, t.size, t.stride); }
};
struct AliasHasher {
- size_t operator()(const Alias& t) const { return Hash(t.name); }
+ HashCode operator()(const Alias& t) const { return Hash(t.name); }
};
struct StructHasher {
- size_t operator()(const Struct& t) const { return Hash(t.name); }
+ HashCode operator()(const Struct& t) const { return Hash(t.name); }
};
struct SamplerHasher {
- size_t operator()(const Sampler& s) const { return Hash(s.kind); }
+ HashCode operator()(const Sampler& s) const { return Hash(s.kind); }
};
struct DepthTextureHasher {
- size_t operator()(const DepthTexture& t) const { return Hash(t.dims); }
+ HashCode operator()(const DepthTexture& t) const { return Hash(t.dims); }
};
struct DepthMultisampledTextureHasher {
- size_t operator()(const DepthMultisampledTexture& t) const { return Hash(t.dims); }
+ HashCode operator()(const DepthMultisampledTexture& t) const { return Hash(t.dims); }
};
struct MultisampledTextureHasher {
- size_t operator()(const MultisampledTexture& t) const { return Hash(t.dims, t.type); }
+ HashCode operator()(const MultisampledTexture& t) const { return Hash(t.dims, t.type); }
};
struct SampledTextureHasher {
- size_t operator()(const SampledTexture& t) const { return Hash(t.dims, t.type); }
+ HashCode operator()(const SampledTexture& t) const { return Hash(t.dims, t.type); }
};
struct StorageTextureHasher {
- size_t operator()(const StorageTexture& t) const { return Hash(t.dims, t.format, t.access); }
+ HashCode operator()(const StorageTexture& t) const { return Hash(t.dims, t.format, t.access); }
};
} // namespace
diff --git a/src/tint/lang/spirv/reader/parser/parser.cc b/src/tint/lang/spirv/reader/parser/parser.cc
index 1976c38..6023194 100644
--- a/src/tint/lang/spirv/reader/parser/parser.cc
+++ b/src/tint/lang/spirv/reader/parser/parser.cc
@@ -669,14 +669,8 @@
return type == other.type && access_mode == other.access_mode;
}
- /// Hasher provides a hash function for the TypeKey.
- struct Hasher {
- /// @param tk the TypeKey to create a hash for
- /// @return the hash value
- inline std::size_t operator()(const TypeKey& tk) const {
- return HashCombine(Hash(tk.type), tk.access_mode);
- }
- };
+ /// @returns the hash code of the TypeKey
+ tint::HashCode HashCode() const { return Hash(type, access_mode); }
};
/// The generated IR module.
@@ -691,7 +685,7 @@
/// The Tint IR block that is currently being emitted.
core::ir::Block* current_block_ = nullptr;
/// A map from a SPIR-V type declaration to the corresponding Tint type object.
- Hashmap<TypeKey, const core::type::Type*, 16, TypeKey::Hasher> types_;
+ Hashmap<TypeKey, const core::type::Type*, 16> types_;
/// A map from a SPIR-V function definition result ID to the corresponding Tint function object.
Hashmap<uint32_t, core::ir::Function*, 8> functions_;
/// A map from a SPIR-V result ID to the corresponding Tint value object.
diff --git a/src/tint/lang/spirv/writer/ast_printer/builder.cc b/src/tint/lang/spirv/writer/ast_printer/builder.cc
index bcd175e..eb393ca 100644
--- a/src/tint/lang/spirv/writer/ast_printer/builder.cc
+++ b/src/tint/lang/spirv/writer/ast_printer/builder.cc
@@ -622,7 +622,7 @@
}
uint32_t Builder::GenerateFunctionTypeIfNeeded(const sem::Function* func) {
- return tint::GetOrAdd(func_sig_to_id_, func->Signature(), [&]() -> uint32_t {
+ return func_sig_to_id_.GetOrAdd(func->Signature(), [&]() -> uint32_t {
auto func_op = result_op();
auto func_type_id = std::get<uint32_t>(func_op);
diff --git a/src/tint/lang/spirv/writer/ast_printer/builder.h b/src/tint/lang/spirv/writer/ast_printer/builder.h
index bd74c08..1e39a34 100644
--- a/src/tint/lang/spirv/writer/ast_printer/builder.h
+++ b/src/tint/lang/spirv/writer/ast_printer/builder.h
@@ -549,7 +549,7 @@
std::unordered_map<uint32_t, const sem::Variable*> id_to_var_;
std::unordered_map<std::string, uint32_t> import_name_to_id_;
std::unordered_map<Symbol, uint32_t> func_symbol_to_id_;
- std::unordered_map<sem::CallTargetSignature, uint32_t> func_sig_to_id_;
+ Hashmap<sem::CallTargetSignature, uint32_t, 4> func_sig_to_id_;
std::unordered_map<const core::type::Type*, uint32_t> type_to_id_;
std::unordered_map<ScalarConstant, uint32_t> const_to_id_;
std::unordered_map<const core::type::Type*, uint32_t> const_null_to_id_;
diff --git a/src/tint/lang/spirv/writer/printer/printer.cc b/src/tint/lang/spirv/writer/printer/printer.cc
index 9f243f4..ef41faf 100644
--- a/src/tint/lang/spirv/writer/printer/printer.cc
+++ b/src/tint/lang/spirv/writer/printer/printer.cc
@@ -225,18 +225,14 @@
uint32_t return_type_id;
Vector<uint32_t, 4> param_type_ids;
- /// Hasher provides a hash function for the FunctionType.
- struct Hasher {
- /// @param ft the FunctionType to create a hash for
- /// @return the hash value
- inline std::size_t operator()(const FunctionType& ft) const {
- size_t hash = Hash(ft.return_type_id);
- for (auto& p : ft.param_type_ids) {
- hash = HashCombine(hash, p);
- }
- return hash;
+ /// @returns the hash code of the FunctionType
+ tint::HashCode HashCode() const {
+ auto hash = Hash(return_type_id);
+ for (auto& p : param_type_ids) {
+ hash = HashCombine(hash, p);
}
- };
+ return hash;
+ }
/// Equality operator for FunctionType.
bool operator==(const FunctionType& other) const {
@@ -249,7 +245,7 @@
Hashmap<const core::type::Type*, uint32_t, 8> types_;
/// The map of function types to their result IDs.
- Hashmap<FunctionType, uint32_t, 8, FunctionType::Hasher> function_types_;
+ Hashmap<FunctionType, uint32_t, 8> function_types_;
/// The map of constants to their result IDs.
Hashmap<const core::constant::Value*, uint32_t, 16> constants_;
diff --git a/src/tint/lang/spirv/writer/raise/var_for_dynamic_index.cc b/src/tint/lang/spirv/writer/raise/var_for_dynamic_index.cc
index 19037f7..cd41b6e 100644
--- a/src/tint/lang/spirv/writer/raise/var_for_dynamic_index.cc
+++ b/src/tint/lang/spirv/writer/raise/var_for_dynamic_index.cc
@@ -65,12 +65,8 @@
// The list of constant indices to get from the base to the source object.
Vector<core::ir::Value*, 4> indices;
- // A specialization of Hasher for PartialAccess.
- struct Hasher {
- inline std::size_t operator()(const PartialAccess& src) const {
- return Hash(src.base, src.indices);
- }
- };
+ /// @returns the hash code of the PartialAccess
+ tint::HashCode HashCode() const { return Hash(base, indices); }
// An equality helper for PartialAccess.
bool operator==(const PartialAccess& other) const {
@@ -139,7 +135,7 @@
// Replace each access instruction that we recorded.
Hashmap<core::ir::Value*, core::ir::Value*, 4> object_to_local;
- Hashmap<PartialAccess, core::ir::Value*, 4, PartialAccess::Hasher> source_object_to_value;
+ Hashmap<PartialAccess, core::ir::Value*, 4> source_object_to_value;
for (const auto& to_replace : worklist) {
auto* access = to_replace.access;
auto* source_object = access->Object();
diff --git a/src/tint/lang/wgsl/ast/transform/direct_variable_access.cc b/src/tint/lang/wgsl/ast/transform/direct_variable_access.cc
index 7cdee65..d92bfb0 100644
--- a/src/tint/lang/wgsl/ast/transform/direct_variable_access.cc
+++ b/src/tint/lang/wgsl/ast/transform/direct_variable_access.cc
@@ -73,7 +73,7 @@
tint::core::AddressSpace address_space = tint::core::AddressSpace::kUndefined;
/// @return a hash code for this object
- size_t HashCode() const { return Hash(type, variable); }
+ tint::HashCode HashCode() const { return Hash(type, variable); }
};
/// Inequality operator for AccessRoot
@@ -85,7 +85,7 @@
/// vector index.
struct DynamicIndex {
/// @return a hash code for this object
- size_t HashCode() const { return 42 /* empty struct: any number will do */; }
+ tint::HashCode HashCode() const { return 42 /* empty struct: any number will do */; }
};
/// Inequality operator for DynamicIndex
@@ -160,7 +160,7 @@
}
/// @return a hash code for this object
- size_t HashCode() const { return Hash(root, ops); }
+ tint::HashCode HashCode() const { return Hash(root, ops); }
};
/// Equality operator for AccessShape
diff --git a/src/tint/lang/wgsl/ast/transform/std140.cc b/src/tint/lang/wgsl/ast/transform/std140.cc
index 037d716..9dc49b5 100644
--- a/src/tint/lang/wgsl/ast/transform/std140.cc
+++ b/src/tint/lang/wgsl/ast/transform/std140.cc
@@ -57,7 +57,7 @@
/// UniformVariable is used by Std140::State::AccessIndex to indicate the root uniform variable
struct UniformVariable {
/// @returns a hash code for this object
- size_t HashCode() const { return 0; }
+ tint::HashCode HashCode() const { return 0; }
};
/// Inequality operator for UniformVariable
@@ -70,7 +70,7 @@
size_t slot; // The index of the expression in Std140::State::AccessChain::dynamic_indices
/// @returns a hash code for this object
- size_t HashCode() const { return Hash(slot); }
+ tint::HashCode HashCode() const { return Hash(slot); }
};
/// Inequality operator for DynamicIndex
@@ -193,12 +193,8 @@
/// The chain of accesses indices.
AccessIndices indices;
- /// Hash function for LoadFnKey.
- struct Hasher {
- /// @param fn the LoadFnKey to hash
- /// @return the hash for the given LoadFnKey
- size_t operator()(const LoadFnKey& fn) const { return Hash(fn.var, fn.indices); }
- };
+ /// @returns the hash code for the LoadFnKey
+ tint::HashCode HashCode() const { return Hash(var, indices); }
/// Equality operator
bool operator==(const LoadFnKey& other) const {
@@ -218,7 +214,7 @@
const SymbolTable& sym = src.Symbols();
/// Map of load function signature, to the generated function
- Hashmap<LoadFnKey, Symbol, 8, LoadFnKey::Hasher> load_fns;
+ Hashmap<LoadFnKey, Symbol, 8> load_fns;
/// Map of std140-forked type to converter function name
Hashmap<const core::type::Type*, Symbol, 8> conv_fns;
diff --git a/src/tint/lang/wgsl/ast/transform/zero_init_workgroup_memory.cc b/src/tint/lang/wgsl/ast/transform/zero_init_workgroup_memory.cc
index d0b303e..e394520 100644
--- a/src/tint/lang/wgsl/ast/transform/zero_init_workgroup_memory.cc
+++ b/src/tint/lang/wgsl/ast/transform/zero_init_workgroup_memory.cc
@@ -94,23 +94,19 @@
/// The RHS of the division part of the expression
uint32_t division = 1;
+ /// @returns the hash code of the ArrayIndex
+ tint::HashCode HashCode() const { return Hash(modulo, division); }
+
/// Equality operator
/// @param i the ArrayIndex to compare to this ArrayIndex
/// @returns true if `i` and this ArrayIndex are equal
bool operator==(const ArrayIndex& i) const {
return modulo == i.modulo && division == i.division;
}
-
- /// Hash function for the ArrayIndex type
- struct Hasher {
- /// @param i the ArrayIndex to calculate a hash for
- /// @returns the hash value for the ArrayIndex `i`
- size_t operator()(const ArrayIndex& i) const { return Hash(i.modulo, i.division); }
- };
};
/// A list of unique ArrayIndex
- using ArrayIndices = UniqueVector<ArrayIndex, 4, ArrayIndex::Hasher>;
+ using ArrayIndices = UniqueVector<ArrayIndex, 4>;
/// Expression holds information about an expression that is being built for a
/// statement will zero workgroup values.
@@ -142,7 +138,7 @@
/// A map of ArrayIndex to the name reserved for the `let` declaration of that
/// index.
- std::unordered_map<ArrayIndex, Symbol, ArrayIndex::Hasher> array_index_names;
+ Hashmap<ArrayIndex, Symbol, 4> array_index_names;
/// Constructor
/// @param c the program::CloneContext used for the transform
@@ -397,8 +393,8 @@
}
auto array_indices = a.array_indices;
array_indices.Add(ArrayIndex{modulo, division});
- auto index = tint::GetOrAdd(array_index_names, ArrayIndex{modulo, division},
- [&] { return b.Symbols().New("i"); });
+ auto index = array_index_names.GetOrAdd(ArrayIndex{modulo, division},
+ [&] { return b.Symbols().New("i"); });
return Expression{b.IndexAccessor(a.expr, index), a.num_iterations, array_indices};
};
return BuildZeroingStatements(arr->ElemType(), get_el);
@@ -422,13 +418,13 @@
StatementList stmts;
std::map<Symbol, ArrayIndex> indices_by_name;
for (auto index : array_indices) {
- auto name = array_index_names.at(index);
+ auto name = array_index_names.Get(index);
auto* mod = (num_iterations > index.modulo)
? b.create<BinaryExpression>(core::BinaryOp::kModulo, iteration(),
b.Expr(u32(index.modulo)))
: iteration();
auto* div = (index.division != 1u) ? b.Div(mod, u32(index.division)) : mod;
- auto* decl = b.Decl(b.Let(name, b.ty.u32(), div));
+ auto* decl = b.Decl(b.Let(*name, b.ty.u32(), div));
stmts.Push(decl);
}
return stmts;
diff --git a/src/tint/lang/wgsl/resolver/dependency_graph.cc b/src/tint/lang/wgsl/resolver/dependency_graph.cc
index 438acef..cb666d5 100644
--- a/src/tint/lang/wgsl/resolver/dependency_graph.cc
+++ b/src/tint/lang/wgsl/resolver/dependency_graph.cc
@@ -107,22 +107,16 @@
const Global* from;
/// The Global that is depended on by #from
const Global* to;
-};
-/// DependencyEdgeCmp implements the contracts of std::equal_to<DependencyEdge>
-/// and std::hash<DependencyEdge>.
-struct DependencyEdgeCmp {
+ /// @returns the hash code of the DependencyEdge
+ tint::HashCode HashCode() const { return Hash(from, to); }
+
/// Equality operator
- bool operator()(const DependencyEdge& lhs, const DependencyEdge& rhs) const {
- return lhs.from == rhs.from && lhs.to == rhs.to;
- }
- /// Hashing operator
- inline std::size_t operator()(const DependencyEdge& d) const { return Hash(d.from, d.to); }
+ bool operator==(const DependencyEdge& rhs) const { return from == rhs.from && to == rhs.to; }
};
/// A map of DependencyEdge to DependencyInfo
-using DependencyEdges =
- Hashmap<DependencyEdge, DependencyInfo, 64, DependencyEdgeCmp, DependencyEdgeCmp>;
+using DependencyEdges = Hashmap<DependencyEdge, DependencyInfo, 64>;
/// Global describes a module-scope variable, type or function.
struct Global {
diff --git a/src/tint/lang/wgsl/resolver/validator.h b/src/tint/lang/wgsl/resolver/validator.h
index 4834073..92ccf7c 100644
--- a/src/tint/lang/wgsl/resolver/validator.h
+++ b/src/tint/lang/wgsl/resolver/validator.h
@@ -98,7 +98,7 @@
}
/// @returns the hash value of this object
- std::size_t HashCode() const { return Hash(type, address_space); }
+ tint::HashCode HashCode() const { return Hash(type, address_space); }
};
/// DiagnosticFilterStack is a scoped stack of diagnostic filters.
diff --git a/src/tint/lang/wgsl/sem/builtin_fn.h b/src/tint/lang/wgsl/sem/builtin_fn.h
index 7c5d12c..bcac245 100644
--- a/src/tint/lang/wgsl/sem/builtin_fn.h
+++ b/src/tint/lang/wgsl/sem/builtin_fn.h
@@ -123,7 +123,7 @@
wgsl::LanguageFeature RequiredLanguageFeature() const;
/// @return the hash code for this object
- std::size_t HashCode() const {
+ tint::HashCode HashCode() const {
return Hash(Fn(), SupportedStages(), ReturnType(), Parameters(), IsDeprecated());
}
diff --git a/src/tint/lang/wgsl/sem/call_target.cc b/src/tint/lang/wgsl/sem/call_target.cc
index 37098f5..1298301 100644
--- a/src/tint/lang/wgsl/sem/call_target.cc
+++ b/src/tint/lang/wgsl/sem/call_target.cc
@@ -71,6 +71,14 @@
return -1;
}
+tint::HashCode CallTargetSignature::HashCode() const {
+ auto hash = tint::Hash(parameters.Length());
+ for (auto* p : parameters) {
+ hash = HashCombine(hash, p->Type(), p->Usage());
+ }
+ return Hash(hash, return_type);
+}
+
bool CallTargetSignature::operator==(const CallTargetSignature& other) const {
if (return_type != other.return_type || parameters.Length() != other.parameters.Length()) {
return false;
@@ -86,16 +94,3 @@
}
} // namespace tint::sem
-
-namespace std {
-
-std::size_t hash<tint::sem::CallTargetSignature>::operator()(
- const tint::sem::CallTargetSignature& sig) const {
- size_t hash = tint::Hash(sig.parameters.Length());
- for (auto* p : sig.parameters) {
- hash = HashCombine(hash, p->Type(), p->Usage());
- }
- return Hash(hash, sig.return_type);
-}
-
-} // namespace std
diff --git a/src/tint/lang/wgsl/sem/call_target.h b/src/tint/lang/wgsl/sem/call_target.h
index cdf7141..24ed2ae 100644
--- a/src/tint/lang/wgsl/sem/call_target.h
+++ b/src/tint/lang/wgsl/sem/call_target.h
@@ -54,10 +54,8 @@
/// Destructor
~CallTargetSignature();
- /// The type of the call target return value
- const core::type::Type* return_type = nullptr;
- /// The parameters of the call target
- tint::Vector<const sem::Parameter*, 8> parameters;
+ /// @returns the hash code of the CallTargetSignature
+ tint::HashCode HashCode() const;
/// Equality operator
/// @param other the signature to compare this to
@@ -76,6 +74,12 @@
auto idx = IndexOf(usage);
return (idx >= 0) ? parameters[static_cast<size_t>(idx)] : nullptr;
}
+
+ /// The type of the call target return value
+ const core::type::Type* return_type = nullptr;
+
+ /// The parameters of the call target
+ tint::Vector<const sem::Parameter*, 8> parameters;
};
/// CallTarget is the base for callable functions, builtins, value constructors and value
@@ -140,19 +144,4 @@
} // namespace tint::sem
-namespace std {
-
-/// Custom std::hash specialization for tint::sem::CallTargetSignature so
-/// CallTargetSignature can be used as keys for std::unordered_map and
-/// std::unordered_set.
-template <>
-class hash<tint::sem::CallTargetSignature> {
- public:
- /// @param sig the CallTargetSignature to hash
- /// @return the hash value
- std::size_t operator()(const tint::sem::CallTargetSignature& sig) const;
-};
-
-} // namespace std
-
#endif // SRC_TINT_LANG_WGSL_SEM_CALL_TARGET_H_
diff --git a/src/tint/lang/wgsl/sem/value_expression_test.cc b/src/tint/lang/wgsl/sem/value_expression_test.cc
index c3ced06..de31e95 100644
--- a/src/tint/lang/wgsl/sem/value_expression_test.cc
+++ b/src/tint/lang/wgsl/sem/value_expression_test.cc
@@ -46,7 +46,7 @@
size_t NumElements() const override { return 0; }
bool AllZero() const override { return {}; }
bool AnyZero() const override { return {}; }
- size_t Hash() const override { return 0; }
+ HashCode Hash() const override { return 0; }
MockConstant* Clone(core::constant::CloneContext&) const override { return nullptr; }
protected:
diff --git a/src/tint/utils/containers/enum_set.h b/src/tint/utils/containers/enum_set.h
index 611a314..5736c13 100644
--- a/src/tint/utils/containers/enum_set.h
+++ b/src/tint/utils/containers/enum_set.h
@@ -33,6 +33,7 @@
#include <type_traits>
#include <utility>
+#include "src/tint/utils/math/hash.h"
#include "src/tint/utils/traits/traits.h"
namespace tint {
@@ -148,7 +149,7 @@
inline bool Empty() const { return set == 0; }
/// @return the hash value of this object
- inline size_t HashCode() const { return std::hash<uint64_t>()(Value()); }
+ tint::HashCode HashCode() const { return Hash(Value()); }
/// Equality operator
/// @param rhs the other EnumSet to compare this to
diff --git a/src/tint/utils/containers/hashmap.h b/src/tint/utils/containers/hashmap.h
index 58f653d..69790f3 100644
--- a/src/tint/utils/containers/hashmap.h
+++ b/src/tint/utils/containers/hashmap.h
@@ -331,7 +331,7 @@
struct Hasher<Hashmap<K, V, N, HASH, EQUAL>> {
/// @param map the Hashmap to hash
/// @returns a hash of the map
- size_t operator()(const Hashmap<K, V, N, HASH, EQUAL>& map) const {
+ HashCode operator()(const Hashmap<K, V, N, HASH, EQUAL>& map) const {
auto hash = Hash(map.Count());
for (auto it : map) {
// Use an XOR to ensure that the non-deterministic ordering of the map still produces
diff --git a/src/tint/utils/containers/hashmap_base.h b/src/tint/utils/containers/hashmap_base.h
index 1697959..2a86e3a 100644
--- a/src/tint/utils/containers/hashmap_base.h
+++ b/src/tint/utils/containers/hashmap_base.h
@@ -75,12 +75,12 @@
/// Constructor using pre-computed hash and copied value.
/// @param hash_ the precomputed hash of @p value
/// @param value the key value
- HashmapKey(size_t hash_, const T& value) : value_(value), hash(hash_) {}
+ HashmapKey(HashCode hash_, const T& value) : value_(value), hash(hash_) {}
/// Constructor using pre-computed hash and moved value.
/// @param hash_ the precomputed hash of @p value
/// @param value the key value
- HashmapKey(size_t hash_, T&& value) : value_(std::forward<T>(value)), hash(hash_) {}
+ HashmapKey(HashCode hash_, T&& value) : value_(std::forward<T>(value)), hash(hash_) {}
/// Copy constructor
HashmapKey(const HashmapKey&) = default;
@@ -145,7 +145,7 @@
}
/// The hash of value
- const size_t hash;
+ const HashCode hash;
};
/// Writes the HashmapKey to the stream.
@@ -298,7 +298,7 @@
/// the map is cleared, or the map is destructed.
template <typename K>
Entry* GetEntry(K&& key) {
- size_t hash = Hash{}(key);
+ HashCode hash = Hash{}(key);
auto& slot = slots_[hash % slots_.Length()];
return slot.Find(hash, key);
}
@@ -310,7 +310,7 @@
/// the map is cleared, or the map is destructed.
template <typename K>
const Entry* GetEntry(K&& key) const {
- size_t hash = Hash{}(key);
+ HashCode hash = Hash{}(key);
auto& slot = slots_[hash % slots_.Length()];
return slot.Find(hash, key);
}
@@ -327,7 +327,7 @@
/// @param key the key to look for.
template <typename K = Key>
bool Remove(K&& key) {
- size_t hash = Hash{}(key);
+ HashCode hash = Hash{}(key);
auto& slot = slots_[hash % slots_.Length()];
Node** edge = &slot.nodes;
for (auto* node = *edge; node; node = node->next) {
@@ -442,7 +442,7 @@
/// @returns true if the Entry's hash is equal to @p hash, and the Entry's key is equal to
/// @p value.
template <typename T>
- bool Equals(size_t hash, T&& value) const {
+ bool Equals(HashCode hash, T&& value) const {
auto& key = Key();
return key.hash == hash && HashmapBase::Equal{}(key.Value(), value);
}
@@ -497,7 +497,7 @@
/// The slot that will hold the edit.
Slot& slot;
/// The hash of the key, passed to EditAt().
- size_t hash;
+ HashCode hash;
/// The resolved node entry, or nullptr if EditAt() did not resolve to an existing entry.
Entry* entry = nullptr;
@@ -540,7 +540,7 @@
capacity_ += capacity_;
Rehash();
}
- size_t hash = Hash{}(key);
+ HashCode hash = Hash{}(key);
auto& slot = slots_[hash % slots_.Length()];
auto* entry = slot.Find(hash, key);
return {*this, slot, hash, entry};
@@ -582,7 +582,7 @@
/// @param hash the key hash to search for.
/// @param key the key value to search for.
template <typename K>
- const Entry* Find(size_t hash, K&& key) const {
+ const Entry* Find(HashCode hash, K&& key) const {
for (auto* node = nodes; node; node = node->next) {
if (node->Equals(hash, key)) {
return &node->Entry();
@@ -595,7 +595,7 @@
/// @param hash the key hash to search for.
/// @param key the key value to search for.
template <typename K>
- Entry* Find(size_t hash, K&& key) {
+ Entry* Find(HashCode hash, K&& key) {
for (auto* node = nodes; node; node = node->next) {
if (node->Equals(hash, key)) {
return &node->Entry();
diff --git a/src/tint/utils/containers/unique_allocator.h b/src/tint/utils/containers/unique_allocator.h
index 8d88623..b6d7224 100644
--- a/src/tint/utils/containers/unique_allocator.h
+++ b/src/tint/utils/containers/unique_allocator.h
@@ -37,7 +37,7 @@
namespace tint {
/// UniqueAllocator is used to allocate unique instances of the template type `T`.
-template <typename T, typename HASH = std::hash<T>, typename EQUAL = std::equal_to<T>>
+template <typename T, typename HASH = Hasher<T>, typename EQUAL = std::equal_to<T>>
class UniqueAllocator {
public:
/// Iterator is the type returned by begin() and end()
@@ -90,7 +90,7 @@
/// Hashing function
/// @param e the entry
/// @returns the hash of the entry
- size_t operator()(T* e) const { return HASH{}(*e); }
+ HashCode operator()(T* e) const { return HASH{}(*e); }
};
/// Equality is the equality function used by the Hashset
diff --git a/src/tint/utils/containers/unique_vector.h b/src/tint/utils/containers/unique_vector.h
index bf59b06..38e4714 100644
--- a/src/tint/utils/containers/unique_vector.h
+++ b/src/tint/utils/containers/unique_vector.h
@@ -41,7 +41,7 @@
/// UniqueVector is an ordered container that only contains unique items.
/// Attempting to add a duplicate is a no-op.
-template <typename T, size_t N, typename HASH = std::hash<T>, typename EQUAL = std::equal_to<T>>
+template <typename T, size_t N, typename HASH = Hasher<T>, typename EQUAL = std::equal_to<T>>
struct UniqueVector {
/// STL-friendly alias to T. Used by gmock.
using value_type = T;
diff --git a/src/tint/utils/containers/vector.h b/src/tint/utils/containers/vector.h
index 663e310..c7edd0e 100644
--- a/src/tint/utils/containers/vector.h
+++ b/src/tint/utils/containers/vector.h
@@ -777,7 +777,7 @@
#endif
/// @returns a hash code for this Vector
- size_t HashCode() const {
+ tint::HashCode HashCode() const {
auto hash = Hash(Length());
for (auto& el : *this) {
hash = HashCombine(hash, el);
@@ -1160,7 +1160,7 @@
auto rend() const { return slice_.rend(); }
/// @returns a hash code of the Vector
- size_t HashCode() const {
+ tint::HashCode HashCode() const {
auto hash = Hash(Length());
for (auto& el : *this) {
hash = HashCombine(hash, el);
diff --git a/src/tint/utils/math/hash.h b/src/tint/utils/math/hash.h
index 43c97f4..a148f2c 100644
--- a/src/tint/utils/math/hash.h
+++ b/src/tint/utils/math/hash.h
@@ -40,39 +40,9 @@
#include "src/tint/utils/math/crc32.h"
namespace tint {
+
namespace detail {
-/// Helper for obtaining a seed bias value for HashCombine with a bit-width
-/// dependent on the size of size_t.
-template <int SIZE_OF_SIZE_T>
-struct HashCombineOffset {};
-
-/// Specialization of HashCombineOffset for size_t == 4.
-template <>
-struct HashCombineOffset<4> {
- /// @returns the seed bias value for HashCombine()
- static constexpr inline uint32_t value() {
- constexpr uint32_t base = 0x7f4a7c16;
-#ifdef TINT_HASH_SEED
- return base ^ static_cast<uint32_t>(TINT_HASH_SEED);
-#endif
- return base;
- }
-};
-
-/// Specialization of HashCombineOffset for size_t == 8.
-template <>
-struct HashCombineOffset<8> {
- /// @returns the seed bias value for HashCombine()
- static constexpr inline uint64_t value() {
- constexpr uint64_t base = 0x9e3779b97f4a7c16;
-#ifdef TINT_HASH_SEED
- return base ^ static_cast<uint64_t>(TINT_HASH_SEED);
-#endif
- return base;
- }
-};
-
template <typename T, typename = void>
struct HasHashCodeMember : std::false_type {};
@@ -84,49 +54,53 @@
} // namespace detail
+/// The type of a hash code
+using HashCode = uint32_t;
+
/// Forward declarations (see below)
template <typename... ARGS>
-size_t Hash(const ARGS&... values);
+HashCode Hash(const ARGS&... values);
template <typename... ARGS>
-size_t HashCombine(size_t hash, const ARGS&... values);
+HashCode HashCombine(HashCode hash, const ARGS&... values);
/// A STL-compatible hasher that does a more thorough job than most implementations of std::hash.
/// Hasher has been optimized for a better quality hash at the expense of increased computation
/// costs.
/// Hasher is specialized for various core Tint data types. The default implementation will use a
-/// `size_t HashCode()` method on the `T` type, and will fallback to `std::hash<T>` if
+/// `HashCode HashCode()` method on the `T` type, and will fallback to `std::hash<T>` if
/// `T::HashCode` is missing.
template <typename T>
struct Hasher {
/// @param value the value to hash
/// @returns a hash of the value
- size_t operator()(const T& value) const {
+ HashCode operator()(const T& value) const {
if constexpr (detail::HasHashCodeMember<T>::value) {
auto hash = value.HashCode();
- static_assert(std::is_same_v<decltype(hash), size_t>,
- "T::HashCode() must return size_t");
+ static_assert(std::is_same_v<decltype(hash), HashCode>,
+ "T::HashCode() must return HashCode");
return hash;
} else {
- return std::hash<T>()(value);
+ return static_cast<HashCode>(std::hash<T>()(value));
}
}
};
/// Hasher specialization for pointers
-/// std::hash<T*> typically uses a reinterpret of the pointer to a size_t.
-/// As most pointers a 4 or 16 byte aligned, this usually results in the LSBs of the hash being 0,
-/// resulting in bad hashes for hashtables. This implementation mixes up those LSBs.
template <typename T>
struct Hasher<T*> {
/// @param ptr the pointer to hash
/// @returns a hash of the pointer
- size_t operator()(T* ptr) const {
- auto hash = static_cast<size_t>(reinterpret_cast<uintptr_t>(ptr));
+ HashCode operator()(T* ptr) const {
+ auto hash = reinterpret_cast<uintptr_t>(ptr);
#ifdef TINT_HASH_SEED
hash ^= static_cast<uint32_t>(TINT_HASH_SEED);
#endif
- return hash >> 4;
+ if constexpr (sizeof(hash) > 4) {
+ return static_cast<HashCode>(hash >> 4 | hash >> 32);
+ } else {
+ return static_cast<HashCode>(hash >> 4);
+ }
}
};
@@ -135,7 +109,7 @@
struct Hasher<std::vector<T>> {
/// @param vector the vector to hash
/// @returns a hash of the vector
- size_t operator()(const std::vector<T>& vector) const {
+ HashCode operator()(const std::vector<T>& vector) const {
auto hash = Hash(vector.size());
for (auto& el : vector) {
hash = HashCombine(hash, el);
@@ -149,7 +123,7 @@
struct Hasher<std::tuple<TYPES...>> {
/// @param tuple the tuple to hash
/// @returns a hash of the tuple
- size_t operator()(const std::tuple<TYPES...>& tuple) const {
+ HashCode operator()(const std::tuple<TYPES...>& tuple) const {
return std::apply(Hash<TYPES...>, tuple);
}
};
@@ -159,7 +133,9 @@
struct Hasher<std::pair<A, B>> {
/// @param tuple the tuple to hash
/// @returns a hash of the tuple
- size_t operator()(const std::pair<A, B>& tuple) const { return std::apply(Hash<A, B>, tuple); }
+ HashCode operator()(const std::pair<A, B>& tuple) const {
+ return std::apply(Hash<A, B>, tuple);
+ }
};
/// Hasher specialization for std::variant
@@ -167,7 +143,7 @@
struct Hasher<std::variant<TYPES...>> {
/// @param variant the variant to hash
/// @returns a hash of the tuple
- size_t operator()(const std::variant<TYPES...>& variant) const {
+ HashCode operator()(const std::variant<TYPES...>& variant) const {
return std::visit([](auto&& val) { return Hash(val); }, variant);
}
};
@@ -178,20 +154,20 @@
struct Hasher<std::string> {
/// @param str the string to hash
/// @returns a hash of the string
- size_t operator()(const std::string& str) const {
- return std::hash<std::string_view>()(std::string_view(str));
+ HashCode operator()(const std::string& str) const {
+ return static_cast<HashCode>(std::hash<std::string_view>()(std::string_view(str)));
}
/// @param str the string to hash
/// @returns a hash of the string
- size_t operator()(const char* str) const {
- return std::hash<std::string_view>()(std::string_view(str));
+ HashCode operator()(const char* str) const {
+ return static_cast<HashCode>(std::hash<std::string_view>()(std::string_view(str)));
}
/// @param str the string to hash
/// @returns a hash of the string
- size_t operator()(const std::string_view& str) const {
- return std::hash<std::string_view>()(str);
+ HashCode operator()(const std::string_view& str) const {
+ return static_cast<HashCode>(std::hash<std::string_view>()(str));
}
};
@@ -199,14 +175,14 @@
/// @returns a hash of the variadic list of arguments.
/// The returned hash is dependent on the order of the arguments.
template <typename... ARGS>
-size_t Hash(const ARGS&... args) {
+HashCode Hash(const ARGS&... args) {
if constexpr (sizeof...(ARGS) == 0) {
return 0;
} else if constexpr (sizeof...(ARGS) == 1) {
using T = std::tuple_element_t<0, std::tuple<ARGS...>>;
return Hasher<T>()(args...);
} else {
- size_t hash = 102931; // seed with an arbitrary prime
+ HashCode hash = 102931; // seed with an arbitrary prime
return HashCombine(hash, args...);
}
}
@@ -216,8 +192,13 @@
/// @returns a hash of the variadic list of arguments.
/// The returned hash is dependent on the order of the arguments.
template <typename... ARGS>
-size_t HashCombine(size_t hash, const ARGS&... values) {
- constexpr size_t offset = tint::detail::HashCombineOffset<sizeof(size_t)>::value();
+HashCode HashCombine(HashCode hash, const ARGS&... values) {
+#ifdef TINT_HASH_SEED
+ constexpr uint32_t offset = 0x7f4a7c16 ^ static_cast<uint32_t>(TINT_HASH_SEED);
+#else
+ constexpr uint32_t offset = 0x7f4a7c16;
+#endif
+
((hash ^= Hash(values) + (offset ^ (hash >> 2))), ...);
return hash;
}
@@ -270,7 +251,7 @@
/// The wrapped value
T value;
/// The hash of value
- size_t hash;
+ HashCode hash;
/// Constructor
/// @param v the value to wrap
diff --git a/src/tint/utils/rtti/castable.h b/src/tint/utils/rtti/castable.h
index 0683254..c944074 100644
--- a/src/tint/utils/rtti/castable.h
+++ b/src/tint/utils/rtti/castable.h
@@ -34,7 +34,9 @@
#include <type_traits>
#include <utility>
+#include "src/tint/utils/macros/compiler.h"
#include "src/tint/utils/math/crc32.h"
+#include "src/tint/utils/math/hash.h"
#include "src/tint/utils/rtti/ignore.h"
#include "src/tint/utils/traits/traits.h"
@@ -43,15 +45,15 @@
#define TINT_CASTABLE_PUSH_DISABLE_WARNINGS() \
_Pragma("clang diagnostic push") /**/ \
_Pragma("clang diagnostic ignored \"-Wundefined-var-template\"") /**/ \
- static_assert(true, "require extra semicolon")
+ TINT_REQUIRE_SEMICOLON
/// Restore disabled warnings
#define TINT_CASTABLE_POP_DISABLE_WARNINGS() \
_Pragma("clang diagnostic pop") /**/ \
- static_assert(true, "require extra semicolon")
+ TINT_REQUIRE_SEMICOLON
#else
-#define TINT_CASTABLE_PUSH_DISABLE_WARNINGS() static_assert(true, "require extra semicolon")
-#define TINT_CASTABLE_POP_DISABLE_WARNINGS() static_assert(true, "require extra semicolon")
+#define TINT_CASTABLE_PUSH_DISABLE_WARNINGS() TINT_REQUIRE_SEMICOLON
+#define TINT_CASTABLE_POP_DISABLE_WARNINGS() TINT_REQUIRE_SEMICOLON
#endif
TINT_CASTABLE_PUSH_DISABLE_WARNINGS();