about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-01-02 14:46:05 +0000
committerGitHub <noreply@github.com>2022-01-02 14:46:05 +0000
commit68013ee315c72379c536941ba83c888e083d7441 (patch)
tree192701feabd468e3be884422721059a281a0a435
parentddb420a86e7947e76085a986aba6100440c38e58 (diff)
parent640cc27ff07e36d45dd2259b4a37ce797df0559e (diff)
downloadrust-68013ee315c72379c536941ba83c888e083d7441.tar.gz
rust-68013ee315c72379c536941ba83c888e083d7441.zip
Merge #11165
11165: internal: start enforcing invariants for top-level entry points r=matklad a=matklad

bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
-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 97c27c453b0..4c58ea9ba64 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 e1a265d817c..6ffb4c191b5 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 c5014be6c33..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,
 }
 
@@ -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 fa25ffd0a26..dcf61b6aca5 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]