Validate swizzles don't mix between rgba and xyzw

Added test.

Bug: tint:79
Change-Id: Ibb17cc2d9198403cdf6a2e456ad29d906deac9f7
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/43460
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/type_determiner.cc b/src/type_determiner.cc
index 8861cdb..af104ca 100644
--- a/src/type_determiner.cc
+++ b/src/type_determiner.cc
@@ -14,6 +14,7 @@
 
 #include "src/type_determiner.h"
 
+#include <algorithm>
 #include <memory>
 #include <utility>
 #include <vector>
@@ -830,6 +831,21 @@
       return false;
     }
 
+    // All characters are valid, check if they're being mixed
+    auto is_rgba = [](char c) {
+      return c == 'r' || c == 'g' || c == 'b' || c == 'a';
+    };
+    auto is_xyzw = [](char c) {
+      return c == 'x' || c == 'y' || c == 'z' || c == 'w';
+    };
+    if (!std::all_of(str.begin(), str.end(), is_rgba) &&
+        !std::all_of(str.begin(), str.end(), is_xyzw)) {
+      diagnostics_.add_error(
+          "invalid mixing of vector swizzle characters rgba with xyzw",
+          expr->member()->source());
+      return false;
+    }
+
     if (size == 1) {
       // A single element swizzle is just the type of the vector.
       ret = vec->type();
diff --git a/src/type_determiner_test.cc b/src/type_determiner_test.cc
index 0c118a2..212da35 100644
--- a/src/type_determiner_test.cc
+++ b/src/type_determiner_test.cc
@@ -1117,6 +1117,22 @@
   EXPECT_EQ(td()->error(), "3:5 error: invalid vector swizzle character");
 }
 
+TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle_MixedChars) {
+  Global("my_vec", ty.vec3<f32>(), ast::StorageClass::kNone);
+
+  auto* ident = create<ast::IdentifierExpression>(
+      Source{{Source::Location{3, 3}, Source::Location{3, 7}}},
+      Symbols().Register("rgyw"));
+
+  auto* mem = MemberAccessor("my_vec", ident);
+  WrapInFunction(mem);
+
+  EXPECT_FALSE(td()->Determine());
+  EXPECT_EQ(
+      td()->error(),
+      "3:3 error: invalid mixing of vector swizzle characters rgba with xyzw");
+}
+
 TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle_BadLength) {
   Global("my_vec", ty.vec3<f32>(), ast::StorageClass::kNone);