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);