Repository: dtolnay/syn
Pull request #930 (2020-11-27 05:49:23)

Parse const blocks in expression position
Part of #921. Const blocks in pattern position to be implemented separately.


Patch:
diff --git a/src/expr.rs b/src/expr.rs
index 345ba826..1ee063d7 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -1718,6 +1718,8 @@ pub(crate) mod parsing {
             input.call(expr_yield).map(Expr::Yield)
         } else if input.peek(Token![unsafe]) {
             input.call(expr_unsafe).map(Expr::Unsafe)
+        } else if input.peek(Token![const]) {
+            input.call(expr_const).map(Expr::Verbatim)
         } else if input.peek(token::Brace) {
             input.call(expr_block).map(Expr::Block)
         } else if input.peek(Token![..]) {
@@ -1912,6 +1914,8 @@ pub(crate) mod parsing {
             Expr::TryBlock(input.call(expr_try_block)?)
         } else if input.peek(Token![unsafe]) {
             Expr::Unsafe(input.call(expr_unsafe)?)
+        } else if input.peek(Token![const]) {
+            Expr::Verbatim(input.call(expr_const)?)
         } else if input.peek(token::Brace) {
             Expr::Block(input.call(expr_block)?)
         } else {
@@ -2485,6 +2489,19 @@ pub(crate) mod parsing {
         })
     }
 
+    #[cfg(feature = "full")]
+    fn expr_const(input: ParseStream) -> Result<TokenStream> {
+        let begin = input.fork();
+        input.parse::<Token![const]>()?;
+
+        let content;
+        braced!(content in input);
+        content.call(Attribute::parse_inner)?;
+        content.call(Block::parse_within)?;
+
+        Ok(verbatim::between(begin, input))
+    }
+
     #[cfg(feature = "full")]
     pub fn expr_block(input: ParseStream) -> Result<ExprBlock> {
         let label: Option<Label> = input.parse()?;
diff --git a/src/stmt.rs b/src/stmt.rs
index 9e2ad5ee..ba2b22e5 100644
--- a/src/stmt.rs
+++ b/src/stmt.rs
@@ -171,7 +171,7 @@ pub mod parsing {
             || input.peek(Token![extern])
             || input.peek(Token![use])
             || input.peek(Token![static]) && (input.peek2(Token![mut]) || input.peek2(Ident))
-            || input.peek(Token![const])
+            || input.peek(Token![const]) && !input.peek2(token::Brace)
             || input.peek(Token![unsafe]) && !input.peek2(token::Brace)
             || input.peek(Token![async])
                 && (input.peek2(Token![unsafe])


Test patch:
diff --git a/tests/repo/mod.rs b/tests/repo/mod.rs
index cff63e99..8b444549 100644
--- a/tests/repo/mod.rs
+++ b/tests/repo/mod.rs
@@ -12,10 +12,7 @@ const REVISION: &str = "9d78d1d02761b906038ba4d54c5f3427f920f5fb";
 
 #[rustfmt::skip]
 static EXCLUDE: &[&str] = &[
-    // TODO: const block (#921)
-    "src/test/ui/inline-const/const-expr-array-init.rs",
-    "src/test/ui/inline-const/const-expr-basic.rs",
-    "src/test/ui/inline-const/const-expr-reference.rs",
+    // TODO: const block in pattern position (#921)
     "src/test/ui/inline-const/const-match-pat-range.rs",
     "src/test/ui/inline-const/const-match-pat.rs",
 
diff --git a/tests/test_precedence.rs b/tests/test_precedence.rs
index c436450a..f8027b19 100644
--- a/tests/test_precedence.rs
+++ b/tests/test_precedence.rs
@@ -253,7 +253,10 @@ fn librustc_brackets(mut librustc_expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
 
     impl MutVisitor for BracketsVisitor {
         fn visit_expr(&mut self, e: &mut P<Expr>) {
-            noop_visit_expr(e, self);
+            match e.kind {
+                ExprKind::ConstBlock(..) => {}
+                _ => noop_visit_expr(e, self),
+            }
             match e.kind {
                 ExprKind::If(..) | ExprKind::Block(..) | ExprKind::Let(..) => {}
                 _ => {