diff options
| author | bors <bors@rust-lang.org> | 2020-10-17 14:44:51 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-10-17 14:44:51 +0000 |
| commit | 6af9846fcc8797bf97e9fb387385208c2219f3d0 (patch) | |
| tree | 527522b82ce55cd2bcc37b14096e6c1de63660bc /compiler/rustc_parse/src/parser | |
| parent | dda2b5e3e260c14b868c494008af1c8981eaa5a8 (diff) | |
| parent | 03321b8cca91cd5d1f9c82a447add69329e52cea (diff) | |
| download | rust-6af9846fcc8797bf97e9fb387385208c2219f3d0.tar.gz rust-6af9846fcc8797bf97e9fb387385208c2219f3d0.zip | |
Auto merge of #77124 - spastorino:const-exprs-rfc-2920, r=oli-obk
Implement const expressions and patterns (RFC 2920) cc `@ecstatic-morse` `@lcnr` `@oli-obk` `@petrochenkov`
Diffstat (limited to 'compiler/rustc_parse/src/parser')
| -rw-r--r-- | compiler/rustc_parse/src/parser/expr.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/mod.rs | 27 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/pat.rs | 3 |
3 files changed, 29 insertions, 3 deletions
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 17cbaf65420..fb05f8791a5 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1060,6 +1060,8 @@ impl<'a> Parser<'a> { }) } else if self.eat_keyword(kw::Unsafe) { self.parse_block_expr(None, lo, BlockCheckMode::Unsafe(ast::UserProvided), attrs) + } else if self.check_inline_const() { + self.parse_const_expr(lo.to(self.token.span)) } else if self.is_do_catch_block() { self.recover_do_catch(attrs) } else if self.is_try_block() { diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index c1094681221..7970ad36456 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -18,8 +18,9 @@ use rustc_ast::ptr::P; use rustc_ast::token::{self, DelimToken, Token, TokenKind}; use rustc_ast::tokenstream::{self, DelimSpan, TokenStream, TokenTree, TreeAndSpacing}; use rustc_ast::DUMMY_NODE_ID; -use rustc_ast::{self as ast, AttrStyle, AttrVec, Const, CrateSugar, Extern, Unsafe}; -use rustc_ast::{Async, MacArgs, MacDelimiter, Mutability, StrLit, Visibility, VisibilityKind}; +use rustc_ast::{self as ast, AnonConst, AttrStyle, AttrVec, Const, CrateSugar, Extern, Unsafe}; +use rustc_ast::{Async, Expr, ExprKind, MacArgs, MacDelimiter, Mutability, StrLit}; +use rustc_ast::{Visibility, VisibilityKind}; use rustc_ast_pretty::pprust; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, FatalError, PResult}; use rustc_session::parse::ParseSess; @@ -545,6 +546,11 @@ impl<'a> Parser<'a> { self.check_or_expected(self.token.can_begin_const_arg(), TokenType::Const) } + fn check_inline_const(&mut self) -> bool { + self.check_keyword(kw::Const) + && self.look_ahead(1, |t| t == &token::OpenDelim(DelimToken::Brace)) + } + /// Checks to see if the next token is either `+` or `+=`. /// Otherwise returns `false`. fn check_plus(&mut self) -> bool { @@ -864,13 +870,28 @@ impl<'a> Parser<'a> { /// Parses constness: `const` or nothing. fn parse_constness(&mut self) -> Const { - if self.eat_keyword(kw::Const) { + // Avoid const blocks to be parsed as const items + if self.look_ahead(1, |t| t != &token::OpenDelim(DelimToken::Brace)) + && self.eat_keyword(kw::Const) + { Const::Yes(self.prev_token.uninterpolated_span()) } else { Const::No } } + /// Parses inline const expressions. + fn parse_const_expr(&mut self, span: Span) -> PResult<'a, P<Expr>> { + self.sess.gated_spans.gate(sym::inline_const, span); + self.eat_keyword(kw::Const); + let blk = self.parse_block()?; + let anon_const = AnonConst { + id: DUMMY_NODE_ID, + value: self.mk_expr(blk.span, ExprKind::Block(blk, None), AttrVec::new()), + }; + Ok(self.mk_expr(span, ExprKind::ConstBlock(anon_const), AttrVec::new())) + } + /// Parses mutability (`mut` or nothing). fn parse_mutability(&mut self) -> Mutability { if self.eat_keyword(kw::Mut) { Mutability::Mut } else { Mutability::Not } diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 5aced9dc37c..15db2066a30 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -313,6 +313,9 @@ impl<'a> Parser<'a> { let pat = self.parse_pat_with_range_pat(false, None)?; self.sess.gated_spans.gate(sym::box_patterns, lo.to(self.prev_token.span)); PatKind::Box(pat) + } else if self.check_inline_const() { + // Parse `const pat` + PatKind::Lit(self.parse_const_expr(lo.to(self.token.span))?) } else if self.can_be_ident_pat() { // Parse `ident @ pat` // This can give false positives and parse nullary enums, |
