about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-12-23 10:37:30 +0000
committerGitHub <noreply@github.com>2020-12-23 10:37:30 +0000
commitfd1fcf2c2e90ab04103a6aa9d033ec64dcc8d555 (patch)
tree31b5facb6a7a24a113e32fd6afa76f326ab8e3a2
parentb0d81d98dbc4cea6920793c7e2952a0d38ec543e (diff)
parentbdd8c0b68f097c7d1a65a5b85b94f0a79affa506 (diff)
downloadrust-fd1fcf2c2e90ab04103a6aa9d033ec64dcc8d555.tar.gz
rust-fd1fcf2c2e90ab04103a6aa9d033ec64dcc8d555.zip
Merge #7010
7010: Update ungrammar for const block patterns r=matklad a=Veykril

Fixes #6848

Adds const blocks and const block patterns to the AST and parses them.

Blocked on https://github.com/rust-analyzer/ungrammar/pull/17/, will merge that PR there once this one gets the OK so I can remove the local ungrammar dependency path and fix the Cargo.lock.

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
-rw-r--r--Cargo.lock4
-rw-r--r--crates/hir_def/src/body/lower.rs4
-rw-r--r--crates/parser/src/grammar/expressions/atom.rs9
-rw-r--r--crates/parser/src/grammar/items.rs7
-rw-r--r--crates/parser/src/grammar/patterns.rs14
-rw-r--r--crates/parser/src/syntax_kind/generated.rs1
-rw-r--r--crates/syntax/src/ast/generated/nodes.rs33
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0156_const_block_pat.rast76
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0156_const_block_pat.rs4
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0157_const_block.rast23
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0157_const_block.rs1
-rw-r--r--xtask/Cargo.toml2
-rw-r--r--xtask/src/ast_src.rs1
13 files changed, 172 insertions, 7 deletions
diff --git a/Cargo.lock b/Cargo.lock
index fbb79e01fc2..891cff55e37 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1827,9 +1827,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
 
 [[package]]
 name = "ungrammar"
-version = "1.4.0"
+version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68951379f3ced25754472ca5addbf74d7dab58c9818f49290a3d8caa3ab44fb7"
+checksum = "c11bffada52edc8f2a56160b286ea4640acf90ffcb21bded361ccb8ed43a1457"
 
 [[package]]
 name = "unicase"
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index 0f404be1b7c..978c3a32498 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -933,7 +933,9 @@ impl ExprCollector<'_> {
                 Pat::Box { inner }
             }
             // FIXME: implement
-            ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing,
+            ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) | ast::Pat::ConstBlockPat(_) => {
+                Pat::Missing
+            }
         };
         let ptr = AstPtr::new(&pat);
         self.alloc_pat(pattern, Either::Left(ptr))
diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs
index e897d5a52f0..c7a3556a775 100644
--- a/crates/parser/src/grammar/expressions/atom.rs
+++ b/crates/parser/src/grammar/expressions/atom.rs
@@ -46,6 +46,7 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet =
         T![continue],
         T![async],
         T![try],
+        T![const],
         T![loop],
         T![for],
         LIFETIME_IDENT,
@@ -115,6 +116,14 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
             block_expr(p);
             m.complete(p, EFFECT_EXPR)
         }
+        // test const_block
+        // fn f() { const { } }
+        T![const] if la == T!['{'] => {
+            let m = p.start();
+            p.bump(T![const]);
+            block_expr(p);
+            m.complete(p, EFFECT_EXPR)
+        }
         T!['{'] => {
             // test for_range_from
             // fn foo() {
diff --git a/crates/parser/src/grammar/items.rs b/crates/parser/src/grammar/items.rs
index 8999829b437..72b73f89174 100644
--- a/crates/parser/src/grammar/items.rs
+++ b/crates/parser/src/grammar/items.rs
@@ -96,7 +96,10 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker) -> Result<(), Marker> {
     let mut has_mods = false;
 
     // modifiers
-    has_mods |= p.eat(T![const]);
+    if p.at(T![const]) && p.nth(1) != T!['{'] {
+        p.eat(T![const]);
+        has_mods = true;
+    }
 
     // test_err async_without_semicolon
     // fn foo() { let _ = async {} }
@@ -167,7 +170,7 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker) -> Result<(), Marker> {
             m.complete(p, TRAIT);
         }
 
-        T![const] => {
+        T![const] if p.nth(1) != T!['{'] => {
             consts::konst(p, m);
         }
 
diff --git a/crates/parser/src/grammar/patterns.rs b/crates/parser/src/grammar/patterns.rs
index 7e7f73deeac..b53d5749f42 100644
--- a/crates/parser/src/grammar/patterns.rs
+++ b/crates/parser/src/grammar/patterns.rs
@@ -89,6 +89,7 @@ fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> {
     let m = match p.nth(0) {
         T![box] => box_pat(p),
         T![ref] | T![mut] => ident_pat(p, true),
+        T![const] => const_block_pat(p),
         IDENT => match p.nth(1) {
             // Checks the token after an IDENT to see if a pattern is a path (Struct { .. }) or macro
             // (T![x]).
@@ -386,3 +387,16 @@ fn box_pat(p: &mut Parser) -> CompletedMarker {
     pattern_single(p);
     m.complete(p, BOX_PAT)
 }
+
+// test const_block_pat
+// fn main() {
+//     let const { 15 } = ();
+//     let const { foo(); bar() } = ();
+// }
+fn const_block_pat(p: &mut Parser) -> CompletedMarker {
+    assert!(p.at(T![const]));
+    let m = p.start();
+    p.bump(T![const]);
+    expressions::block_expr(p);
+    m.complete(p, CONST_BLOCK_PAT)
+}
diff --git a/crates/parser/src/syntax_kind/generated.rs b/crates/parser/src/syntax_kind/generated.rs
index 980aa59794f..f69e71bdba6 100644
--- a/crates/parser/src/syntax_kind/generated.rs
+++ b/crates/parser/src/syntax_kind/generated.rs
@@ -170,6 +170,7 @@ pub enum SyntaxKind {
     RANGE_PAT,
     LITERAL_PAT,
     MACRO_PAT,
+    CONST_BLOCK_PAT,
     TUPLE_EXPR,
     ARRAY_EXPR,
     PAREN_EXPR,
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs
index 1588ba93ea2..c5b80bffe74 100644
--- a/crates/syntax/src/ast/generated/nodes.rs
+++ b/crates/syntax/src/ast/generated/nodes.rs
@@ -763,6 +763,7 @@ impl EffectExpr {
     pub fn try_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![try]) }
     pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) }
     pub fn async_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![async]) }
+    pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
     pub fn block_expr(&self) -> Option<BlockExpr> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1251,6 +1252,14 @@ impl TupleStructPat {
     pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct ConstBlockPat {
+    pub(crate) syntax: SyntaxNode,
+}
+impl ConstBlockPat {
+    pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
+    pub fn block_expr(&self) -> Option<BlockExpr> { support::child(&self.syntax) }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct RecordPatFieldList {
     pub(crate) syntax: SyntaxNode,
 }
@@ -1369,6 +1378,7 @@ pub enum Pat {
     SlicePat(SlicePat),
     TuplePat(TuplePat),
     TupleStructPat(TupleStructPat),
+    ConstBlockPat(ConstBlockPat),
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum FieldList {
@@ -2772,6 +2782,17 @@ impl AstNode for TupleStructPat {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
+impl AstNode for ConstBlockPat {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == CONST_BLOCK_PAT }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
 impl AstNode for RecordPatFieldList {
     fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_PAT_FIELD_LIST }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -3242,12 +3263,15 @@ impl From<TuplePat> for Pat {
 impl From<TupleStructPat> for Pat {
     fn from(node: TupleStructPat) -> Pat { Pat::TupleStructPat(node) }
 }
+impl From<ConstBlockPat> for Pat {
+    fn from(node: ConstBlockPat) -> Pat { Pat::ConstBlockPat(node) }
+}
 impl AstNode for Pat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
             IDENT_PAT | BOX_PAT | REST_PAT | LITERAL_PAT | MACRO_PAT | OR_PAT | PAREN_PAT
             | PATH_PAT | WILDCARD_PAT | RANGE_PAT | RECORD_PAT | REF_PAT | SLICE_PAT
-            | TUPLE_PAT | TUPLE_STRUCT_PAT => true,
+            | TUPLE_PAT | TUPLE_STRUCT_PAT | CONST_BLOCK_PAT => true,
             _ => false,
         }
     }
@@ -3268,6 +3292,7 @@ impl AstNode for Pat {
             SLICE_PAT => Pat::SlicePat(SlicePat { syntax }),
             TUPLE_PAT => Pat::TuplePat(TuplePat { syntax }),
             TUPLE_STRUCT_PAT => Pat::TupleStructPat(TupleStructPat { syntax }),
+            CONST_BLOCK_PAT => Pat::ConstBlockPat(ConstBlockPat { syntax }),
             _ => return None,
         };
         Some(res)
@@ -3289,6 +3314,7 @@ impl AstNode for Pat {
             Pat::SlicePat(it) => &it.syntax,
             Pat::TuplePat(it) => &it.syntax,
             Pat::TupleStructPat(it) => &it.syntax,
+            Pat::ConstBlockPat(it) => &it.syntax,
         }
     }
 }
@@ -4137,6 +4163,11 @@ impl std::fmt::Display for TupleStructPat {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for ConstBlockPat {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for RecordPatFieldList {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
diff --git a/crates/syntax/test_data/parser/inline/ok/0156_const_block_pat.rast b/crates/syntax/test_data/parser/inline/ok/0156_const_block_pat.rast
new file mode 100644
index 00000000000..8ff4822c4ef
--- /dev/null
+++ b/crates/syntax/test_data/parser/inline/ok/0156_const_block_pat.rast
@@ -0,0 +1,76 @@
+SOURCE_FILE@0..78
+  FN@0..77
+    FN_KW@0..2 "fn"
+    WHITESPACE@2..3 " "
+    NAME@3..7
+      IDENT@3..7 "main"
+    PARAM_LIST@7..9
+      L_PAREN@7..8 "("
+      R_PAREN@8..9 ")"
+    WHITESPACE@9..10 " "
+    BLOCK_EXPR@10..77
+      L_CURLY@10..11 "{"
+      WHITESPACE@11..16 "\n    "
+      LET_STMT@16..38
+        LET_KW@16..19 "let"
+        WHITESPACE@19..20 " "
+        CONST_BLOCK_PAT@20..32
+          CONST_KW@20..25 "const"
+          WHITESPACE@25..26 " "
+          BLOCK_EXPR@26..32
+            L_CURLY@26..27 "{"
+            WHITESPACE@27..28 " "
+            LITERAL@28..30
+              INT_NUMBER@28..30 "15"
+            WHITESPACE@30..31 " "
+            R_CURLY@31..32 "}"
+        WHITESPACE@32..33 " "
+        EQ@33..34 "="
+        WHITESPACE@34..35 " "
+        TUPLE_EXPR@35..37
+          L_PAREN@35..36 "("
+          R_PAREN@36..37 ")"
+        SEMICOLON@37..38 ";"
+      WHITESPACE@38..43 "\n    "
+      LET_STMT@43..75
+        LET_KW@43..46 "let"
+        WHITESPACE@46..47 " "
+        CONST_BLOCK_PAT@47..69
+          CONST_KW@47..52 "const"
+          WHITESPACE@52..53 " "
+          BLOCK_EXPR@53..69
+            L_CURLY@53..54 "{"
+            WHITESPACE@54..55 " "
+            EXPR_STMT@55..61
+              CALL_EXPR@55..60
+                PATH_EXPR@55..58
+                  PATH@55..58
+                    PATH_SEGMENT@55..58
+                      NAME_REF@55..58
+                        IDENT@55..58 "foo"
+                ARG_LIST@58..60
+                  L_PAREN@58..59 "("
+                  R_PAREN@59..60 ")"
+              SEMICOLON@60..61 ";"
+            WHITESPACE@61..62 " "
+            CALL_EXPR@62..67
+              PATH_EXPR@62..65
+                PATH@62..65
+                  PATH_SEGMENT@62..65
+                    NAME_REF@62..65
+                      IDENT@62..65 "bar"
+              ARG_LIST@65..67
+                L_PAREN@65..66 "("
+                R_PAREN@66..67 ")"
+            WHITESPACE@67..68 " "
+            R_CURLY@68..69 "}"
+        WHITESPACE@69..70 " "
+        EQ@70..71 "="
+        WHITESPACE@71..72 " "
+        TUPLE_EXPR@72..74
+          L_PAREN@72..73 "("
+          R_PAREN@73..74 ")"
+        SEMICOLON@74..75 ";"
+      WHITESPACE@75..76 "\n"
+      R_CURLY@76..77 "}"
+  WHITESPACE@77..78 "\n"
diff --git a/crates/syntax/test_data/parser/inline/ok/0156_const_block_pat.rs b/crates/syntax/test_data/parser/inline/ok/0156_const_block_pat.rs
new file mode 100644
index 00000000000..dce9defac2f
--- /dev/null
+++ b/crates/syntax/test_data/parser/inline/ok/0156_const_block_pat.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let const { 15 } = ();
+    let const { foo(); bar() } = ();
+}
diff --git a/crates/syntax/test_data/parser/inline/ok/0157_const_block.rast b/crates/syntax/test_data/parser/inline/ok/0157_const_block.rast
new file mode 100644
index 00000000000..d5d2c8fe306
--- /dev/null
+++ b/crates/syntax/test_data/parser/inline/ok/0157_const_block.rast
@@ -0,0 +1,23 @@
+SOURCE_FILE@0..21
+  FN@0..20
+    FN_KW@0..2 "fn"
+    WHITESPACE@2..3 " "
+    NAME@3..4
+      IDENT@3..4 "f"
+    PARAM_LIST@4..6
+      L_PAREN@4..5 "("
+      R_PAREN@5..6 ")"
+    WHITESPACE@6..7 " "
+    BLOCK_EXPR@7..20
+      L_CURLY@7..8 "{"
+      WHITESPACE@8..9 " "
+      EFFECT_EXPR@9..18
+        CONST_KW@9..14 "const"
+        WHITESPACE@14..15 " "
+        BLOCK_EXPR@15..18
+          L_CURLY@15..16 "{"
+          WHITESPACE@16..17 " "
+          R_CURLY@17..18 "}"
+      WHITESPACE@18..19 " "
+      R_CURLY@19..20 "}"
+  WHITESPACE@20..21 "\n"
diff --git a/crates/syntax/test_data/parser/inline/ok/0157_const_block.rs b/crates/syntax/test_data/parser/inline/ok/0157_const_block.rs
new file mode 100644
index 00000000000..a2e3565a321
--- /dev/null
+++ b/crates/syntax/test_data/parser/inline/ok/0157_const_block.rs
@@ -0,0 +1 @@
+fn f() { const { } }
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
index 78a0b54ba66..96b4ea448d4 100644
--- a/xtask/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -15,7 +15,7 @@ flate2 = "1.0"
 pico-args = "0.3.1"
 proc-macro2 = "1.0.8"
 quote = "1.0.2"
-ungrammar = "1.4"
+ungrammar = "1.5"
 walkdir = "2.3.1"
 write-json = "0.1.0"
 xshell = "0.1"
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index a69ced5ccf4..2b8012bdd55 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -132,6 +132,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
         "RANGE_PAT",
         "LITERAL_PAT",
         "MACRO_PAT",
+        "CONST_BLOCK_PAT",
         // atoms
         "TUPLE_EXPR",
         "ARRAY_EXPR",