wgsl-reader: hex prefix only is an error

These are errors:

    let a = 0x;
    let b = -0x;

Fixes: tint:1338
Change-Id: I9d26ad66e32deb954550c0ecfbda0a9005bcd380
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/72380
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: David Neto <dneto@google.com>
Auto-Submit: David Neto <dneto@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/reader/wgsl/lexer.cc b/src/reader/wgsl/lexer.cc
index 00c0f8d..ada6580 100644
--- a/src/reader/wgsl/lexer.cc
+++ b/src/reader/wgsl/lexer.cc
@@ -681,6 +681,10 @@
                   "...) has too many digits"};
     }
   }
+  if (first == end) {
+    return {Token::Type::kError, source,
+            "integer or float hex literal has no significant digits"};
+  }
 
   pos_ = end;
   location_.column += (end - start);
diff --git a/src/reader/wgsl/lexer_test.cc b/src/reader/wgsl/lexer_test.cc
index 24faeb3..fbfea7a 100644
--- a/src/reader/wgsl/lexer_test.cc
+++ b/src/reader/wgsl/lexer_test.cc
@@ -400,6 +400,28 @@
         HexSignedIntData{"-0x80000000", std::numeric_limits<int32_t>::min()},
         HexSignedIntData{"0x7FFFFFFF", std::numeric_limits<int32_t>::max()}));
 
+TEST_F(LexerTest, HexPrefixOnly_IsError) {
+  // Could be the start of a hex integer or hex float, but is neither.
+  Source::FileContent content("0x");
+  Lexer l("test.wgsl", &content);
+
+  auto t = l.next();
+  ASSERT_TRUE(t.Is(Token::Type::kError));
+  EXPECT_EQ(t.to_str(),
+            "integer or float hex literal has no significant digits");
+}
+
+TEST_F(LexerTest, NegativeHexPrefixOnly_IsError) {
+  // Could be the start of a hex integer or hex float, but is neither.
+  Source::FileContent content("-0x");
+  Lexer l("test.wgsl", &content);
+
+  auto t = l.next();
+  ASSERT_TRUE(t.Is(Token::Type::kError));
+  EXPECT_EQ(t.to_str(),
+            "integer or float hex literal has no significant digits");
+}
+
 TEST_F(LexerTest, IntegerTest_HexSignedTooLarge) {
   Source::FileContent content("0x80000000");
   Lexer l("test.wgsl", &content);