about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/parser/src/grammar.rs13
-rw-r--r--crates/parser/src/lib.rs4
-rw-r--r--crates/parser/src/tests/top_entries.rs49
3 files changed, 65 insertions, 1 deletions
diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs
index eee9a8c0cd5..6ffb4c191b5 100644
--- a/crates/parser/src/grammar.rs
+++ b/crates/parser/src/grammar.rs
@@ -122,6 +122,19 @@ pub(crate) mod entry {
             }
             m.complete(p, ERROR);
         }
+
+        pub(crate) fn type_(p: &mut Parser) {
+            let m = p.start();
+            types::type_(p);
+            if p.at(EOF) {
+                m.abandon(p);
+                return;
+            }
+            while !p.at(EOF) {
+                p.bump_any();
+            }
+            m.complete(p, ERROR);
+        }
     }
 }
 
diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs
index 5c0e997ea10..72d529d6cfd 100644
--- a/crates/parser/src/lib.rs
+++ b/crates/parser/src/lib.rs
@@ -110,6 +110,8 @@ pub enum TopEntryPoint {
     Pattern,
     Type,
     Expr,
+    /// Edge case -- macros generally don't expand to attributes, with the
+    /// exception of `cfg_attr` which does!
     MetaItem,
 }
 
@@ -120,8 +122,8 @@ impl TopEntryPoint {
             TopEntryPoint::MacroStmts => grammar::entry::top::macro_stmts,
             TopEntryPoint::MacroItems => grammar::entry::top::macro_items,
             TopEntryPoint::Pattern => grammar::entry::top::pattern,
+            TopEntryPoint::Type => grammar::entry::top::type_,
             // FIXME
-            TopEntryPoint::Type => grammar::entry::prefix::ty,
             TopEntryPoint::Expr => grammar::entry::prefix::expr,
             TopEntryPoint::MetaItem => grammar::entry::prefix::meta_item,
         };
diff --git a/crates/parser/src/tests/top_entries.rs b/crates/parser/src/tests/top_entries.rs
index 48359150638..dcf61b6aca5 100644
--- a/crates/parser/src/tests/top_entries.rs
+++ b/crates/parser/src/tests/top_entries.rs
@@ -175,6 +175,55 @@ fn macro_pattern() {
     );
 }
 
+#[test]
+fn type_() {
+    check(
+        TopEntryPoint::Type,
+        "Option<!>",
+        expect![[r#"
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Option"
+                  GENERIC_ARG_LIST
+                    L_ANGLE "<"
+                    TYPE_ARG
+                      NEVER_TYPE
+                        BANG "!"
+                    R_ANGLE ">"
+        "#]],
+    );
+    check(
+        TopEntryPoint::Type,
+        "() () ()",
+        expect![[r#"
+            ERROR
+              TUPLE_TYPE
+                L_PAREN "("
+                R_PAREN ")"
+              WHITESPACE " "
+              L_PAREN "("
+              R_PAREN ")"
+              WHITESPACE " "
+              L_PAREN "("
+              R_PAREN ")"
+        "#]],
+    );
+    check(
+        TopEntryPoint::Type,
+        "$$$",
+        expect![[r#"
+            ERROR
+              ERROR
+                DOLLAR "$"
+              DOLLAR "$"
+              DOLLAR "$"
+            error 0: expected type
+        "#]],
+    );
+}
+
 #[track_caller]
 fn check(entry: TopEntryPoint, input: &str, expect: expect_test::Expect) {
     let (parsed, _errors) = super::parse(entry, input);