Remove fallthrough from WGSL parser.

This CL removes the `fallthrough` parsing from the WGSL parser. The
`fallthrough` token is left so we can generate a nicer error message
in the case `fallthrough` is used.

Bug: tint:1644
Change-Id: Ifb23d78d1219cba9c64b80c9b098a248bc68e5c5
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/109001
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
diff --git a/src/tint/reader/wgsl/parser_impl.cc b/src/tint/reader/wgsl/parser_impl.cc
index 398c123..6314133 100644
--- a/src/tint/reader/wgsl/parser_impl.cc
+++ b/src/tint/reader/wgsl/parser_impl.cc
@@ -25,7 +25,6 @@
 #include "src/tint/ast/continue_statement.h"
 #include "src/tint/ast/discard_statement.h"
 #include "src/tint/ast/external_texture.h"
-#include "src/tint/ast/fallthrough_statement.h"
 #include "src/tint/ast/id_attribute.h"
 #include "src/tint/ast/if_statement.h"
 #include "src/tint/ast/increment_decrement_statement.h"
@@ -2189,24 +2188,17 @@
 // case_body
 //   :
 //   | statement case_body
-//   | FALLTHROUGH SEMICOLON
 Maybe<const ast::BlockStatement*> ParserImpl::case_body() {
     StatementList stmts;
     while (continue_parsing()) {
         Source source;
         if (match(Token::Type::kFallthrough, &source)) {
-            if (!expect("fallthrough statement", Token::Type::kSemicolon)) {
-                return Failure::kErrored;
-            }
-
-            deprecated(source,
-                       "fallthrough is set to be removed from WGSL. "
-                       "Case can accept multiple selectors if the existing case bodies are empty. "
-                       "(e.g. `case 1, 2, 3:`) "
-                       "`default` is a valid case selector value. (e.g. `case 1, default:`)");
-
-            stmts.Push(create<ast::FallthroughStatement>(source));
-            break;
+            return add_error(
+                source,
+                "fallthrough is not premitted in WGSL. "
+                "Case can accept multiple selectors if the existing case bodies are empty. "
+                "(e.g. `case 1, 2, 3:`) "
+                "`default` is a valid case selector value. (e.g. `case 1, default:`)");
         }
 
         auto stmt = statement();
diff --git a/src/tint/reader/wgsl/parser_impl_case_body_test.cc b/src/tint/reader/wgsl/parser_impl_case_body_test.cc
index c162be3..4d60e23 100644
--- a/src/tint/reader/wgsl/parser_impl_case_body_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_case_body_test.cc
@@ -12,7 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/ast/fallthrough_statement.h"
 #include "src/tint/reader/wgsl/parser_impl_test_helper.h"
 
 namespace tint::reader::wgsl {
@@ -50,25 +49,5 @@
     EXPECT_EQ(e.value, nullptr);
 }
 
-TEST_F(ParserImplTest, CaseBody_Fallthrough) {
-    auto p = parser("fallthrough;");
-    auto e = p->case_body();
-    ASSERT_FALSE(p->has_error()) << p->error();
-    EXPECT_FALSE(e.errored);
-    EXPECT_TRUE(e.matched);
-    ASSERT_EQ(e->statements.Length(), 1u);
-    EXPECT_TRUE(e->statements[0]->Is<ast::FallthroughStatement>());
-}
-
-TEST_F(ParserImplTest, CaseBody_Fallthrough_MissingSemicolon) {
-    auto p = parser("fallthrough");
-    auto e = p->case_body();
-    EXPECT_TRUE(p->has_error());
-    EXPECT_TRUE(e.errored);
-    EXPECT_FALSE(e.matched);
-    EXPECT_EQ(e.value, nullptr);
-    EXPECT_EQ(p->error(), "1:12: expected ';' for fallthrough statement");
-}
-
 }  // namespace
 }  // namespace tint::reader::wgsl
diff --git a/src/tint/reader/wgsl/parser_impl_error_msg_test.cc b/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
index 6c4f14a..822be9b 100644
--- a/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
@@ -1230,14 +1230,6 @@
 )");
 }
 
-TEST_F(ParserImplErrorTest, SwitchStmtCaseFallthroughMissingSemicolon) {
-    EXPECT("fn f() { switch(1) { case 1: { fallthrough } case 2: {} } }",
-           R"(test.wgsl:1:44 error: expected ';' for fallthrough statement
-fn f() { switch(1) { case 1: { fallthrough } case 2: {} } }
-                                           ^
-)");
-}
-
 TEST_F(ParserImplErrorTest, VarStmtMissingSemicolon) {
     EXPECT("fn f() { var a : u32 }",
            R"(test.wgsl:1:22 error: expected ';' for variable declaration
diff --git a/src/tint/resolver/uniformity_test.cc b/src/tint/resolver/uniformity_test.cc
index c7fd1f6..fd632df 100644
--- a/src/tint/resolver/uniformity_test.cc
+++ b/src/tint/resolver/uniformity_test.cc
@@ -3013,49 +3013,6 @@
     RunTest(src, true);
 }
 
-TEST_F(UniformityAnalysisTest, Switch_NonUniformBreakInDifferentCase_Fallthrough) {
-    std::string src = R"(
-@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
-@group(0) @binding(0) var<uniform> condition : i32;
-
-fn foo() {
-  switch (condition) {
-    case 0: {
-      if (non_uniform == 42) {
-        break;
-      }
-      fallthrough;
-    }
-    case 42: {
-      workgroupBarrier();
-    }
-    default: {
-    }
-  }
-}
-)";
-
-    RunTest(src, false);
-    EXPECT_EQ(
-        error_,
-        R"(test:11:7 warning: use of deprecated language feature: fallthrough is set to be removed from WGSL. Case can accept multiple selectors if the existing case bodies are empty. (e.g. `case 1, 2, 3:`) `default` is a valid case selector value. (e.g. `case 1, default:`)
-      fallthrough;
-      ^^^^^^^^^^^
-
-test:14:7 warning: 'workgroupBarrier' must only be called from uniform control flow
-      workgroupBarrier();
-      ^^^^^^^^^^^^^^^^
-
-test:8:7 note: control flow depends on non-uniform value
-      if (non_uniform == 42) {
-      ^^
-
-test:8:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
-      if (non_uniform == 42) {
-          ^^^^^^^^^^^
-)");
-}
-
 TEST_F(UniformityAnalysisTest, Switch_VarBecomesNonUniformInDifferentCase_WithBreak) {
     std::string src = R"(
 @group(0) @binding(0) var<storage, read_write> non_uniform : i32;
@@ -3082,50 +3039,6 @@
     RunTest(src, true);
 }
 
-TEST_F(UniformityAnalysisTest, Switch_VarBecomesNonUniformInDifferentCase_WithFallthrough) {
-    std::string src = R"(
-@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
-@group(0) @binding(0) var<uniform> condition : i32;
-
-fn foo() {
-  var x = 0;
-  switch (condition) {
-    case 0: {
-      x = non_uniform;
-      fallthrough;
-    }
-    case 42: {
-      if (x == 0) {
-        workgroupBarrier();
-      }
-    }
-    default: {
-    }
-  }
-}
-)";
-
-    RunTest(src, false);
-    EXPECT_EQ(
-        error_,
-        R"(test:10:7 warning: use of deprecated language feature: fallthrough is set to be removed from WGSL. Case can accept multiple selectors if the existing case bodies are empty. (e.g. `case 1, 2, 3:`) `default` is a valid case selector value. (e.g. `case 1, default:`)
-      fallthrough;
-      ^^^^^^^^^^^
-
-test:14:9 warning: 'workgroupBarrier' must only be called from uniform control flow
-        workgroupBarrier();
-        ^^^^^^^^^^^^^^^^
-
-test:13:7 note: control flow depends on non-uniform value
-      if (x == 0) {
-      ^^
-
-test:9:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
-      x = non_uniform;
-          ^^^^^^^^^^^
-)");
-}
-
 TEST_F(UniformityAnalysisTest, Switch_VarBecomesUniformInDifferentCase_WithBreak) {
     std::string src = R"(
 @group(0) @binding(0) var<storage, read_write> non_uniform : i32;
diff --git a/src/tint/transform/merge_return_test.cc b/src/tint/transform/merge_return_test.cc
index fb2377d..02a565c 100644
--- a/src/tint/transform/merge_return_test.cc
+++ b/src/tint/transform/merge_return_test.cc
@@ -688,7 +688,6 @@
         return 1;
       }
       bar = 6;
-      fallthrough;
     }
     case 2 {
       bar = 5;
@@ -726,7 +725,6 @@
         }
       }
       bar = 6;
-      fallthrough;
     }
     case 2: {
       bar = 5;