Remove unless_stmt

The `unless` statement was removed from the WGSL grammar so remove it
from Tint.

Change-Id: I31a185f5c5e3e88b667caea1c9a88aee80c0b810
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/22581
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index 162f7a1..6c7a192 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -324,8 +324,6 @@
     "src/ast/unary_op.h",
     "src/ast/unary_op_expression.cc",
     "src/ast/unary_op_expression.h",
-    "src/ast/unless_statement.cc",
-    "src/ast/unless_statement.h",
     "src/ast/variable.cc",
     "src/ast/variable.h",
     "src/ast/variable_decl_statement.cc",
@@ -615,7 +613,6 @@
     "src/ast/type_constructor_expression_test.cc",
     "src/ast/uint_literal_test.cc",
     "src/ast/unary_op_expression_test.cc",
-    "src/ast/unless_statement_test.cc",
     "src/ast/variable_decl_statement_test.cc",
     "src/ast/variable_test.cc",
     "src/scope_stack_test.cc",
@@ -771,7 +768,6 @@
     "src/reader/wgsl/parser_impl_type_alias_test.cc",
     "src/reader/wgsl/parser_impl_type_decl_test.cc",
     "src/reader/wgsl/parser_impl_unary_expression_test.cc",
-    "src/reader/wgsl/parser_impl_unless_stmt_test.cc",
     "src/reader/wgsl/parser_impl_variable_decl_test.cc",
     "src/reader/wgsl/parser_impl_variable_decoration_list_test.cc",
     "src/reader/wgsl/parser_impl_variable_decoration_test.cc",
@@ -822,7 +818,6 @@
     "src/writer/wgsl/generator_impl_type_test.cc",
     "src/writer/wgsl/generator_impl_unary_method_test.cc",
     "src/writer/wgsl/generator_impl_unary_op_test.cc",
-    "src/writer/wgsl/generator_impl_unless_test.cc",
     "src/writer/wgsl/generator_impl_variable_decl_statement_test.cc",
     "src/writer/wgsl/generator_impl_variable_test.cc",
   ]
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e848119..b18b1d4 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -161,8 +161,6 @@
   ast/unary_op.h
   ast/unary_op_expression.cc
   ast/unary_op_expression.h
-  ast/unless_statement.cc
-  ast/unless_statement.h
   ast/variable.cc
   ast/variable.h
   ast/variable_decoration.cc
@@ -295,7 +293,6 @@
   ast/type_constructor_expression_test.cc
   ast/uint_literal_test.cc
   ast/unary_op_expression_test.cc
-  ast/unless_statement_test.cc
   ast/variable_decl_statement_test.cc
   ast/variable_test.cc
   scope_stack_test.cc
@@ -400,7 +397,6 @@
     reader/wgsl/parser_impl_type_alias_test.cc
     reader/wgsl/parser_impl_type_decl_test.cc
     reader/wgsl/parser_impl_unary_expression_test.cc
-    reader/wgsl/parser_impl_unless_stmt_test.cc
     reader/wgsl/parser_impl_variable_decl_test.cc
     reader/wgsl/parser_impl_variable_decoration_list_test.cc
     reader/wgsl/parser_impl_variable_decoration_test.cc
@@ -469,7 +465,6 @@
     writer/wgsl/generator_impl_switch_test.cc
     writer/wgsl/generator_impl_type_test.cc
     writer/wgsl/generator_impl_unary_op_test.cc
-    writer/wgsl/generator_impl_unless_test.cc
     writer/wgsl/generator_impl_variable_decl_statement_test.cc
     writer/wgsl/generator_impl_variable_test.cc
   )
diff --git a/src/ast/statement.cc b/src/ast/statement.cc
index 6aa1380..3ff8941 100644
--- a/src/ast/statement.cc
+++ b/src/ast/statement.cc
@@ -27,7 +27,6 @@
 #include "src/ast/loop_statement.h"
 #include "src/ast/return_statement.h"
 #include "src/ast/switch_statement.h"
-#include "src/ast/unless_statement.h"
 #include "src/ast/variable_decl_statement.h"
 
 namespace tint {
@@ -85,10 +84,6 @@
   return false;
 }
 
-bool Statement::IsUnless() const {
-  return false;
-}
-
 bool Statement::IsVariableDecl() const {
   return false;
 }
@@ -148,11 +143,6 @@
   return static_cast<const SwitchStatement*>(this);
 }
 
-const UnlessStatement* Statement::AsUnless() const {
-  assert(IsUnless());
-  return static_cast<const UnlessStatement*>(this);
-}
-
 const VariableDeclStatement* Statement::AsVariableDecl() const {
   assert(IsVariableDecl());
   return static_cast<const VariableDeclStatement*>(this);
@@ -213,11 +203,6 @@
   return static_cast<SwitchStatement*>(this);
 }
 
-UnlessStatement* Statement::AsUnless() {
-  assert(IsUnless());
-  return static_cast<UnlessStatement*>(this);
-}
-
 VariableDeclStatement* Statement::AsVariableDecl() {
   assert(IsVariableDecl());
   return static_cast<VariableDeclStatement*>(this);
diff --git a/src/ast/statement.h b/src/ast/statement.h
index a813818..1dd56b3 100644
--- a/src/ast/statement.h
+++ b/src/ast/statement.h
@@ -34,7 +34,6 @@
 class LoopStatement;
 class ReturnStatement;
 class SwitchStatement;
-class UnlessStatement;
 class VariableDeclStatement;
 
 /// Base statement class
@@ -64,8 +63,6 @@
   virtual bool IsReturn() const;
   /// @returns true if this is a switch statement
   virtual bool IsSwitch() const;
-  /// @returns true if this is an unless statement
-  virtual bool IsUnless() const;
   /// @returns true if this is an variable statement
   virtual bool IsVariableDecl() const;
 
@@ -91,8 +88,6 @@
   const ReturnStatement* AsReturn() const;
   /// @returns the statement as a const switch statement
   const SwitchStatement* AsSwitch() const;
-  /// @returns the statement as a const unless statement
-  const UnlessStatement* AsUnless() const;
   /// @returns the statement as a const variable statement
   const VariableDeclStatement* AsVariableDecl() const;
 
@@ -118,8 +113,6 @@
   ReturnStatement* AsReturn();
   /// @returns the statement as a switch statement
   SwitchStatement* AsSwitch();
-  /// @returns the statement as an unless statement
-  UnlessStatement* AsUnless();
   /// @returns the statement as an variable statement
   VariableDeclStatement* AsVariableDecl();
 
diff --git a/src/ast/unless_statement.cc b/src/ast/unless_statement.cc
deleted file mode 100644
index 0cfc8d5..0000000
--- a/src/ast/unless_statement.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2020 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/ast/unless_statement.h"
-
-namespace tint {
-namespace ast {
-
-UnlessStatement::UnlessStatement() : Statement() {}
-
-UnlessStatement::UnlessStatement(std::unique_ptr<Expression> condition,
-                                 StatementList body)
-    : Statement(), condition_(std::move(condition)), body_(std::move(body)) {}
-
-UnlessStatement::UnlessStatement(const Source& source,
-                                 std::unique_ptr<Expression> condition,
-                                 StatementList body)
-    : Statement(source),
-      condition_(std::move(condition)),
-      body_(std::move(body)) {}
-
-UnlessStatement::UnlessStatement(UnlessStatement&&) = default;
-
-UnlessStatement::~UnlessStatement() = default;
-
-bool UnlessStatement::IsUnless() const {
-  return true;
-}
-
-bool UnlessStatement::IsValid() const {
-  if (condition_ == nullptr || !condition_->IsValid()) {
-    return false;
-  }
-  for (const auto& stmt : body_) {
-    if (stmt == nullptr || !stmt->IsValid()) {
-      return false;
-    }
-  }
-  return true;
-}
-
-void UnlessStatement::to_str(std::ostream& out, size_t indent) const {
-  make_indent(out, indent);
-  out << "Unless{" << std::endl;
-
-  make_indent(out, indent + 2);
-  out << "(" << std::endl;
-
-  condition_->to_str(out, indent + 4);
-
-  make_indent(out, indent + 2);
-  out << ")" << std::endl;
-
-  make_indent(out, indent + 2);
-  out << "{" << std::endl;
-
-  for (const auto& stmt : body_)
-    stmt->to_str(out, indent + 4);
-
-  make_indent(out, indent + 2);
-  out << "}" << std::endl;
-
-  make_indent(out, indent);
-  out << "}" << std::endl;
-}
-
-}  // namespace ast
-}  // namespace tint
diff --git a/src/ast/unless_statement.h b/src/ast/unless_statement.h
deleted file mode 100644
index 1113686..0000000
--- a/src/ast/unless_statement.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2020 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef SRC_AST_UNLESS_STATEMENT_H_
-#define SRC_AST_UNLESS_STATEMENT_H_
-
-#include <memory>
-#include <utility>
-
-#include "src/ast/expression.h"
-#include "src/ast/statement.h"
-
-namespace tint {
-namespace ast {
-
-/// A unless statement
-class UnlessStatement : public Statement {
- public:
-  /// Constructor
-  UnlessStatement();
-  /// Constructor
-  /// @param condition the condition expression
-  /// @param body the body statements
-  UnlessStatement(std::unique_ptr<Expression> condition, StatementList body);
-  /// Constructor
-  /// @param source the unless statement source
-  /// @param condition the condition expression
-  /// @param body the body statements
-  UnlessStatement(const Source& source,
-                  std::unique_ptr<Expression> condition,
-                  StatementList body);
-  /// Move constructor
-  UnlessStatement(UnlessStatement&&);
-  ~UnlessStatement() override;
-
-  /// Sets the condition expression
-  /// @param condition the condition expression
-  void set_condition(std::unique_ptr<Expression> condition) {
-    condition_ = std::move(condition);
-  }
-  /// @returns the condition statements
-  Expression* condition() const { return condition_.get(); }
-
-  /// Sets the body statements
-  /// @param body the body statements
-  void set_body(StatementList body) { body_ = std::move(body); }
-  /// @returns the body statements
-  const StatementList& body() const { return body_; }
-
-  /// @returns true if this is an unless statement
-  bool IsUnless() const override;
-
-  /// @returns true if the node is valid
-  bool IsValid() const override;
-
-  /// Writes a representation of the node to the output stream
-  /// @param out the stream to write to
-  /// @param indent number of spaces to indent the node when writing
-  void to_str(std::ostream& out, size_t indent) const override;
-
- private:
-  UnlessStatement(const UnlessStatement&) = delete;
-
-  std::unique_ptr<Expression> condition_;
-  StatementList body_;
-};
-
-}  // namespace ast
-}  // namespace tint
-
-#endif  // SRC_AST_UNLESS_STATEMENT_H_
diff --git a/src/ast/unless_statement_test.cc b/src/ast/unless_statement_test.cc
deleted file mode 100644
index b3c1ae9..0000000
--- a/src/ast/unless_statement_test.cc
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2020 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/ast/unless_statement.h"
-
-#include "gtest/gtest.h"
-#include "src/ast/identifier_expression.h"
-#include "src/ast/if_statement.h"
-#include "src/ast/kill_statement.h"
-
-namespace tint {
-namespace ast {
-namespace {
-
-using UnlessStatementTest = testing::Test;
-
-TEST_F(UnlessStatementTest, Creation) {
-  auto ident = std::make_unique<IdentifierExpression>("ident");
-  StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
-
-  auto* ident_ptr = ident.get();
-  auto* kill_ptr = body[0].get();
-
-  UnlessStatement u(std::move(ident), std::move(body));
-  EXPECT_EQ(u.condition(), ident_ptr);
-  ASSERT_EQ(u.body().size(), 1u);
-  EXPECT_EQ(u.body()[0].get(), kill_ptr);
-}
-
-TEST_F(UnlessStatementTest, Creation_WithSource) {
-  auto ident = std::make_unique<IdentifierExpression>("ident");
-  StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
-
-  UnlessStatement u(Source{20, 2}, std::move(ident), std::move(body));
-  auto src = u.source();
-  EXPECT_EQ(src.line, 20u);
-  EXPECT_EQ(src.column, 2u);
-}
-
-TEST_F(UnlessStatementTest, IsUnless) {
-  UnlessStatement stmt;
-  EXPECT_TRUE(stmt.IsUnless());
-}
-
-TEST_F(UnlessStatementTest, IsValid) {
-  auto ident = std::make_unique<IdentifierExpression>("ident");
-  StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
-
-  UnlessStatement u(std::move(ident), std::move(body));
-  EXPECT_TRUE(u.IsValid());
-}
-
-TEST_F(UnlessStatementTest, IsValid_NullCondition) {
-  StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
-
-  UnlessStatement u;
-  u.set_body(std::move(body));
-  EXPECT_FALSE(u.IsValid());
-}
-
-TEST_F(UnlessStatementTest, IsValid_InvalidCondition) {
-  auto ident = std::make_unique<IdentifierExpression>("");
-  StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
-
-  UnlessStatement u(std::move(ident), std::move(body));
-  EXPECT_FALSE(u.IsValid());
-}
-
-TEST_F(UnlessStatementTest, IsValid_NullBodyStatement) {
-  auto ident = std::make_unique<IdentifierExpression>("ident");
-  StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
-  body.push_back(nullptr);
-
-  UnlessStatement u(std::move(ident), std::move(body));
-  EXPECT_FALSE(u.IsValid());
-}
-
-TEST_F(UnlessStatementTest, IsValid_InvalidBodyStatement) {
-  auto ident = std::make_unique<IdentifierExpression>("ident");
-  StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
-  body.push_back(std::make_unique<IfStatement>());
-
-  UnlessStatement u(std::move(ident), std::move(body));
-  EXPECT_FALSE(u.IsValid());
-}
-
-TEST_F(UnlessStatementTest, ToStr) {
-  auto ident = std::make_unique<IdentifierExpression>("ident");
-  StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
-
-  UnlessStatement u(std::move(ident), std::move(body));
-  std::ostringstream out;
-  u.to_str(out, 2);
-  EXPECT_EQ(out.str(), R"(  Unless{
-    (
-      Identifier{ident}
-    )
-    {
-      Kill{}
-    }
-  }
-)");
-}
-
-}  // namespace
-}  // namespace ast
-}  // namespace tint
diff --git a/src/reader/wgsl/lexer.cc b/src/reader/wgsl/lexer.cc
index ae3e67f..632aa1f 100644
--- a/src/reader/wgsl/lexer.cc
+++ b/src/reader/wgsl/lexer.cc
@@ -576,8 +576,6 @@
     return {Token::Type::kUniform, source, "uniform"};
   if (str == "uniform_constant")
     return {Token::Type::kUniformConstant, source, "uniform_constant"};
-  if (str == "unless")
-    return {Token::Type::kUnless, source, "unless"};
   if (str == "var")
     return {Token::Type::kVar, source, "var"};
   if (str == "vec2")
@@ -621,6 +619,8 @@
     return {Token::Type::kReservedKeyword, source, "let"};
   if (str == "premerge")
     return {Token::Type::kReservedKeyword, source, "premerge"};
+  if (str == "regardless")
+    return {Token::Type::kReservedKeyword, source, "regardless"};
   if (str == "typedef")
     return {Token::Type::kReservedKeyword, source, "typedef"};
   if (str == "u8")
@@ -629,8 +629,8 @@
     return {Token::Type::kReservedKeyword, source, "u16"};
   if (str == "u64")
     return {Token::Type::kReservedKeyword, source, "u64"};
-  if (str == "regardless")
-    return {Token::Type::kReservedKeyword, source, "regardless"};
+  if (str == "unless")
+    return {Token::Type::kReservedKeyword, source, "unless"};
   return {};
 }
 
diff --git a/src/reader/wgsl/lexer_test.cc b/src/reader/wgsl/lexer_test.cc
index 9bed255..9953443 100644
--- a/src/reader/wgsl/lexer_test.cc
+++ b/src/reader/wgsl/lexer_test.cc
@@ -463,7 +463,6 @@
                     TokenData{"uniform", Token::Type::kUniform},
                     TokenData{"uniform_constant",
                               Token::Type::kUniformConstant},
-                    TokenData{"unless", Token::Type::kUnless},
                     TokenData{"var", Token::Type::kVar},
                     TokenData{"vec2", Token::Type::kVec2},
                     TokenData{"vec3", Token::Type::kVec3},
@@ -499,6 +498,7 @@
                                          "u8",
                                          "u16",
                                          "u64",
+                                         "unless",
                                          "regardless"));
 
 }  // namespace
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index eebea01..1367bce 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -1420,7 +1420,6 @@
 //   : SEMICOLON
 //   | return_stmt SEMICOLON
 //   | if_stmt
-//   | unless_stmt
 //   | switch_stmt
 //   | loop_stmt
 //   | variable_stmt SEMICOLON
@@ -1453,12 +1452,6 @@
   if (stmt_if != nullptr)
     return stmt_if;
 
-  auto unless = unless_stmt();
-  if (has_error())
-    return nullptr;
-  if (unless != nullptr)
-    return unless;
-
   auto sw = switch_stmt();
   if (has_error())
     return nullptr;
@@ -1728,32 +1721,6 @@
   return std::make_unique<ast::ElseStatement>(source, std::move(body));
 }
 
-// unless_stmt
-//   : UNLESS paren_rhs_stmt body_stmt
-std::unique_ptr<ast::UnlessStatement> ParserImpl::unless_stmt() {
-  auto t = peek();
-  if (!t.IsUnless())
-    return nullptr;
-
-  auto source = t.source();
-  next();  // Consume the peek
-
-  auto condition = paren_rhs_stmt();
-  if (has_error())
-    return nullptr;
-  if (condition == nullptr) {
-    set_error(peek(), "unable to parse unless condition");
-    return nullptr;
-  }
-
-  auto body = body_stmt();
-  if (has_error())
-    return nullptr;
-
-  return std::make_unique<ast::UnlessStatement>(source, std::move(condition),
-                                                std::move(body));
-}
-
 // switch_stmt
 //   : SWITCH paren_rhs_stmt BRACKET_LEFT switch_body+ BRACKET_RIGHT
 std::unique_ptr<ast::SwitchStatement> ParserImpl::switch_stmt() {
diff --git a/src/reader/wgsl/parser_impl.h b/src/reader/wgsl/parser_impl.h
index 718f3c2..38f8cbf 100644
--- a/src/reader/wgsl/parser_impl.h
+++ b/src/reader/wgsl/parser_impl.h
@@ -40,7 +40,6 @@
 #include "src/ast/struct_member.h"
 #include "src/ast/struct_member_decoration.h"
 #include "src/ast/type/type.h"
-#include "src/ast/unless_statement.h"
 #include "src/ast/variable.h"
 #include "src/ast/variable_decoration.h"
 #include "src/context.h"
@@ -208,9 +207,6 @@
   /// Parses a `else_stmt` grammar element
   /// @returns the parsed statement or nullptr
   std::unique_ptr<ast::ElseStatement> else_stmt();
-  /// Parses a `unless_stmt` grammar element
-  /// @returns the parsed element or nullptr
-  std::unique_ptr<ast::UnlessStatement> unless_stmt();
   /// Parses a `switch_stmt` grammar element
   /// @returns the parsed statement or nullptr
   std::unique_ptr<ast::SwitchStatement> switch_stmt();
diff --git a/src/reader/wgsl/parser_impl_statement_test.cc b/src/reader/wgsl/parser_impl_statement_test.cc
index 5fc9339..9df6b49 100644
--- a/src/reader/wgsl/parser_impl_statement_test.cc
+++ b/src/reader/wgsl/parser_impl_statement_test.cc
@@ -93,22 +93,6 @@
   EXPECT_EQ(p->error(), "1:10: missing }");
 }
 
-TEST_F(ParserImplTest, Statement_Unless) {
-  auto* p = parser("unless (a) {}");
-  auto e = p->statement();
-  ASSERT_FALSE(p->has_error()) << p->error();
-  ASSERT_NE(e, nullptr);
-  ASSERT_TRUE(e->IsUnless());
-}
-
-TEST_F(ParserImplTest, Statement_Unless_Invalid) {
-  auto* p = parser("unless () {}");
-  auto e = p->statement();
-  ASSERT_TRUE(p->has_error());
-  ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:9: unable to parse expression");
-}
-
 TEST_F(ParserImplTest, Statement_Variable) {
   auto* p = parser("var a : i32 = 1;");
   auto e = p->statement();
diff --git a/src/reader/wgsl/parser_impl_unless_stmt_test.cc b/src/reader/wgsl/parser_impl_unless_stmt_test.cc
deleted file mode 100644
index 4557c7c..0000000
--- a/src/reader/wgsl/parser_impl_unless_stmt_test.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2020 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "gtest/gtest.h"
-#include "src/reader/wgsl/parser_impl.h"
-#include "src/reader/wgsl/parser_impl_test_helper.h"
-
-namespace tint {
-namespace reader {
-namespace wgsl {
-namespace {
-
-TEST_F(ParserImplTest, UnlessStmt) {
-  auto* p = parser("unless (a) { kill; }");
-  auto e = p->unless_stmt();
-  ASSERT_FALSE(p->has_error()) << p->error();
-  ASSERT_NE(e, nullptr);
-  ASSERT_TRUE(e->IsUnless());
-  ASSERT_NE(e->condition(), nullptr);
-  EXPECT_TRUE(e->condition()->IsIdentifier());
-  ASSERT_EQ(e->body().size(), 1u);
-  EXPECT_TRUE(e->body()[0]->IsKill());
-}
-
-TEST_F(ParserImplTest, UnlessStmt_InvalidCondition) {
-  auto* p = parser("unless(if(a){}) {}");
-  auto e = p->unless_stmt();
-  ASSERT_TRUE(p->has_error());
-  ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:8: unable to parse expression");
-}
-
-TEST_F(ParserImplTest, UnlessStmt_EmptyCondition) {
-  auto* p = parser("unless() {}");
-  auto e = p->unless_stmt();
-  ASSERT_TRUE(p->has_error());
-  ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:8: unable to parse expression");
-}
-
-TEST_F(ParserImplTest, UnlessStmt_InvalidBody) {
-  auto* p = parser("unless(a + 2 - 5 == true) { kill }");
-  auto e = p->unless_stmt();
-  ASSERT_TRUE(p->has_error());
-  ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:34: missing ;");
-}
-
-}  // namespace
-}  // namespace wgsl
-}  // namespace reader
-}  // namespace tint
diff --git a/src/reader/wgsl/token.cc b/src/reader/wgsl/token.cc
index a845d99..0a91ca6 100644
--- a/src/reader/wgsl/token.cc
+++ b/src/reader/wgsl/token.cc
@@ -189,14 +189,10 @@
       return "offset";
     case Token::Type::kOut:
       return "out";
-    case Token::Type::kPremerge:
-      return "premerge";
     case Token::Type::kPrivate:
       return "private";
     case Token::Type::kPtr:
       return "ptr";
-    case Token::Type::kRegardless:
-      return "regardless";
     case Token::Type::kReturn:
       return "return";
     case Token::Type::kSet:
@@ -217,8 +213,6 @@
       return "uniform";
     case Token::Type::kUniformConstant:
       return "uniform_constant";
-    case Token::Type::kUnless:
-      return "unless";
     case Token::Type::kVar:
       return "var";
     case Token::Type::kVec2:
diff --git a/src/reader/wgsl/token.h b/src/reader/wgsl/token.h
index cca501b..8545cfa 100644
--- a/src/reader/wgsl/token.h
+++ b/src/reader/wgsl/token.h
@@ -200,14 +200,10 @@
     kOffset,
     /// A 'out'
     kOut,
-    /// A 'premerge'
-    kPremerge,
     /// A 'private'
     kPrivate,
     /// A 'ptr'
     kPtr,
-    /// A 'regardless'
-    kRegardless,
     /// A 'return'
     kReturn,
     /// A 'set'
@@ -228,8 +224,6 @@
     kUniform,
     /// A 'uniform_constant'
     kUniformConstant,
-    /// A 'unless'
-    kUnless,
     /// A 'var'
     kVar,
     /// A 'vec2'
@@ -483,8 +477,6 @@
   bool IsUniform() const { return type_ == Type::kUniform; }
   /// @returns true if token is a 'uniform_constant'
   bool IsUniformConstant() const { return type_ == Type::kUniformConstant; }
-  /// @returns true if token is a 'unless'
-  bool IsUnless() const { return type_ == Type::kUnless; }
   /// @returns true if token is a 'var'
   bool IsVar() const { return type_ == Type::kVar; }
   /// @returns true if token is a 'vec2'
diff --git a/src/type_determiner.cc b/src/type_determiner.cc
index 8604d7b..14eb480 100644
--- a/src/type_determiner.cc
+++ b/src/type_determiner.cc
@@ -43,7 +43,6 @@
 #include "src/ast/type/vector_type.h"
 #include "src/ast/type_constructor_expression.h"
 #include "src/ast/unary_op_expression.h"
-#include "src/ast/unless_statement.h"
 #include "src/ast/variable_decl_statement.h"
 
 namespace tint {
@@ -214,11 +213,6 @@
     }
     return true;
   }
-  if (stmt->IsUnless()) {
-    auto* u = stmt->AsUnless();
-    return DetermineResultType(u->condition()) &&
-           DetermineStatements(u->body());
-  }
   if (stmt->IsVariableDecl()) {
     auto* v = stmt->AsVariableDecl();
     variable_stack_.set(v->variable()->name(), v->variable());
diff --git a/src/type_determiner_test.cc b/src/type_determiner_test.cc
index 40090f5..124407a 100644
--- a/src/type_determiner_test.cc
+++ b/src/type_determiner_test.cc
@@ -52,7 +52,6 @@
 #include "src/ast/type/vector_type.h"
 #include "src/ast/type_constructor_expression.h"
 #include "src/ast/unary_op_expression.h"
-#include "src/ast/unless_statement.h"
 #include "src/ast/variable_decl_statement.h"
 
 namespace tint {
@@ -337,36 +336,6 @@
   EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
 }
 
-TEST_F(TypeDeterminerTest, Stmt_Unless) {
-  ast::type::I32Type i32;
-  ast::type::F32Type f32;
-
-  auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 2));
-  auto* lhs_ptr = lhs.get();
-
-  auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.3f));
-  auto* rhs_ptr = rhs.get();
-
-  ast::StatementList body;
-  body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
-                                                            std::move(rhs)));
-
-  ast::UnlessStatement unless(
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 3)),
-      std::move(body));
-
-  EXPECT_TRUE(td()->DetermineResultType(&unless));
-  ASSERT_NE(unless.condition()->result_type(), nullptr);
-  ASSERT_NE(lhs_ptr->result_type(), nullptr);
-  ASSERT_NE(rhs_ptr->result_type(), nullptr);
-  EXPECT_TRUE(unless.condition()->result_type()->IsI32());
-  EXPECT_TRUE(lhs_ptr->result_type()->IsI32());
-  EXPECT_TRUE(rhs_ptr->result_type()->IsF32());
-}
-
 TEST_F(TypeDeterminerTest, Stmt_VariableDecl) {
   ast::type::I32Type i32;
   auto var =
diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc
index 2316d17..3093e61 100644
--- a/src/writer/wgsl/generator_impl.cc
+++ b/src/writer/wgsl/generator_impl.cc
@@ -55,7 +55,6 @@
 #include "src/ast/type_constructor_expression.h"
 #include "src/ast/uint_literal.h"
 #include "src/ast/unary_op_expression.h"
-#include "src/ast/unless_statement.h"
 #include "src/ast/variable_decl_statement.h"
 
 namespace tint {
@@ -665,9 +664,6 @@
   if (stmt->IsVariableDecl()) {
     return EmitVariable(stmt->AsVariableDecl()->variable());
   }
-  if (stmt->IsUnless()) {
-    return EmitUnless(stmt->AsUnless());
-  }
 
   error_ = "unknown statement type";
   return false;
@@ -846,18 +842,6 @@
   return true;
 }
 
-bool GeneratorImpl::EmitUnless(ast::UnlessStatement* stmt) {
-  make_indent();
-
-  out_ << "unless (";
-  if (!EmitExpression(stmt->condition())) {
-    return false;
-  }
-  out_ << ")";
-
-  return EmitStatementBlockAndNewline(stmt->body());
-}
-
 }  // namespace wgsl
 }  // namespace writer
 }  // namespace tint
diff --git a/src/writer/wgsl/generator_impl.h b/src/writer/wgsl/generator_impl.h
index b262a6d..a0ec427 100644
--- a/src/writer/wgsl/generator_impl.h
+++ b/src/writer/wgsl/generator_impl.h
@@ -194,10 +194,6 @@
   /// @param expr the expression to emit
   /// @returns true if the expression was emitted
   bool EmitUnaryOp(ast::UnaryOpExpression* expr);
-  /// Handles generating an unless statement
-  /// @param stmt the statement to generate
-  /// @returns true if the statement was successfully emitted
-  bool EmitUnless(ast::UnlessStatement* stmt);
   /// Handles generating a variable
   /// @param var the variable to generate
   /// @returns true if the variable was emitted
diff --git a/src/writer/wgsl/generator_impl_unless_test.cc b/src/writer/wgsl/generator_impl_unless_test.cc
deleted file mode 100644
index 413f3b5..0000000
--- a/src/writer/wgsl/generator_impl_unless_test.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2020 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <memory>
-
-#include "gtest/gtest.h"
-#include "src/ast/identifier_expression.h"
-#include "src/ast/kill_statement.h"
-#include "src/ast/unless_statement.h"
-#include "src/writer/wgsl/generator_impl.h"
-
-namespace tint {
-namespace writer {
-namespace wgsl {
-namespace {
-
-using GeneratorImplTest = testing::Test;
-
-TEST_F(GeneratorImplTest, Emit_Unless) {
-  auto cond = std::make_unique<ast::IdentifierExpression>("cond");
-
-  ast::StatementList body;
-  body.push_back(std::make_unique<ast::KillStatement>());
-  body.push_back(std::make_unique<ast::KillStatement>());
-
-  ast::UnlessStatement u(std::move(cond), std::move(body));
-
-  GeneratorImpl g;
-  g.increment_indent();
-
-  ASSERT_TRUE(g.EmitStatement(&u)) << g.error();
-  EXPECT_EQ(g.result(), R"(  unless (cond) {
-    kill;
-    kill;
-  }
-)");
-}
-
-}  // namespace
-}  // namespace wgsl
-}  // namespace writer
-}  // namespace tint