tint: improve compile error when calling builder::Val with the wrong
type

Now that Val() creates a Vecor of Scalar, we get horrible template spew
if the input value is of the wrong type.

Bug: tint:1581
Change-Id: I464d369e25f6374d3ffce0ee4dc21723b7e533a9
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/112323
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/tint/resolver/resolver_test_helper.h b/src/tint/resolver/resolver_test_helper.h
index 68a7017..fe33c26 100644
--- a/src/tint/resolver/resolver_test_helper.h
+++ b/src/tint/resolver/resolver_test_helper.h
@@ -31,6 +31,7 @@
 #include "src/tint/sem/expression.h"
 #include "src/tint/sem/statement.h"
 #include "src/tint/sem/variable.h"
+#include "src/tint/traits.h"
 #include "src/tint/utils/vector.h"
 
 namespace tint::resolver {
@@ -793,6 +794,7 @@
 /// Creates a Value of DataType<T> from a scalar `v`
 template <typename T>
 Value Val(T v) {
+    static_assert(traits::IsTypeIn<T, Scalar>, "v must be a Number of bool");
     return Value::Create<T>(utils::Vector<Scalar, 1>{v});
 }
 
diff --git a/src/tint/traits.h b/src/tint/traits.h
index 8dcc65b..441067e 100644
--- a/src/tint/traits.h
+++ b/src/tint/traits.h
@@ -160,6 +160,22 @@
 using SliceTuple =
     std::remove_pointer_t<decltype(detail::SwizzlePtrTy<TUPLE>(Range<OFFSET, COUNT>()))>;
 
+namespace detail {
+/// Base template for IsTypeIn
+template <class T, class TypeList>
+struct IsTypeIn;
+
+/// Specialization for IsTypeIn
+template <class T, template <class...> class TypeContainer, class... Ts>
+struct IsTypeIn<T, TypeContainer<Ts...>> : std::disjunction<std::is_same<T, Ts>...> {};
+}  // namespace detail
+
+/// Evaluates to true if T is one of the types in the TypeContainer's template arguments.
+/// Works for std::variant, std::tuple, std::pair, or any class template where all parameters are
+/// types.
+template <typename T, typename TypeContainer>
+static constexpr bool IsTypeIn = detail::IsTypeIn<T, TypeContainer>::value;
+
 }  // namespace tint::traits
 
 #endif  // SRC_TINT_TRAITS_H_