Unnamed repository; edit this file 'description' to name the repository.
Merge #11165
11165: internal: start enforcing invariants for top-level entry points r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
bors[bot] 2022-01-02
parent ddb420a · parent 640cc27 · commit 68013ee
-rw-r--r--crates/hir_def/src/macro_expansion_tests/mbe/tt_conversion.rs2
-rw-r--r--crates/parser/src/grammar.rs26
-rw-r--r--crates/parser/src/lib.rs6
-rw-r--r--crates/parser/src/tests/top_entries.rs76
4 files changed, 107 insertions, 3 deletions
diff --git a/crates/hir_def/src/macro_expansion_tests/mbe/tt_conversion.rs b/crates/hir_def/src/macro_expansion_tests/mbe/tt_conversion.rs
index 97c27c453b..4c58ea9ba6 100644
--- a/crates/hir_def/src/macro_expansion_tests/mbe/tt_conversion.rs
+++ b/crates/hir_def/src/macro_expansion_tests/mbe/tt_conversion.rs
@@ -141,7 +141,7 @@ macro_rules! m1 { () => (Some(x) left overs) }
macro_rules! m2 { () => ($) }
fn main() {
- let Some(x) = ();
+ let Some(x)left overs = ();
let /* parse error: expected pattern */
$ = ();
}
diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs
index e1a265d817..6ffb4c191b 100644
--- a/crates/parser/src/grammar.rs
+++ b/crates/parser/src/grammar.rs
@@ -109,6 +109,32 @@ pub(crate) mod entry {
items::mod_contents(p, false);
m.complete(p, MACRO_ITEMS);
}
+
+ pub(crate) fn pattern(p: &mut Parser) {
+ let m = p.start();
+ patterns::pattern_single(p);
+ if p.at(EOF) {
+ m.abandon(p);
+ return;
+ }
+ while !p.at(EOF) {
+ p.bump_any();
+ }
+ 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 c5014be6c3..72d529d6cf 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,
}
@@ -119,9 +121,9 @@ impl TopEntryPoint {
TopEntryPoint::SourceFile => grammar::entry::top::source_file,
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::Pattern => grammar::entry::prefix::pat,
- 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 fa25ffd0a2..dcf61b6aca 100644
--- a/crates/parser/src/tests/top_entries.rs
+++ b/crates/parser/src/tests/top_entries.rs
@@ -146,6 +146,82 @@ fn macro_pattern() {
R_PAREN ")"
"#]],
);
+
+ check(
+ TopEntryPoint::Pattern,
+ "None leftover tokens",
+ expect![[r#"
+ ERROR
+ IDENT_PAT
+ NAME
+ IDENT "None"
+ WHITESPACE " "
+ IDENT "leftover"
+ WHITESPACE " "
+ IDENT "tokens"
+ "#]],
+ );
+
+ check(
+ TopEntryPoint::Pattern,
+ "@err",
+ expect![[r#"
+ ERROR
+ ERROR
+ AT "@"
+ IDENT "err"
+ error 0: expected 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]