Skip to content

Commit c3e8d79

Browse files
committed
Parse inline const expressions
1 parent 3c4ad55 commit c3e8d79

File tree

10 files changed

+60
-3
lines changed

10 files changed

+60
-3
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,6 +1152,7 @@ impl Expr {
11521152
match self.kind {
11531153
ExprKind::Box(_) => ExprPrecedence::Box,
11541154
ExprKind::Array(_) => ExprPrecedence::Array,
1155+
ExprKind::ConstBlock(_) => ExprPrecedence::ConstBlock,
11551156
ExprKind::Call(..) => ExprPrecedence::Call,
11561157
ExprKind::MethodCall(..) => ExprPrecedence::MethodCall,
11571158
ExprKind::Tup(_) => ExprPrecedence::Tup,
@@ -1207,6 +1208,8 @@ pub enum ExprKind {
12071208
Box(P<Expr>),
12081209
/// An array (`[a, b, c, d]`)
12091210
Array(Vec<P<Expr>>),
1211+
/// Allow anonymous constants from an inline `const` block
1212+
ConstBlock(AnonConst),
12101213
/// A function call
12111214
///
12121215
/// The first field resolves to the function itself,

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,6 +1106,9 @@ pub fn noop_visit_expr<T: MutVisitor>(
11061106
match kind {
11071107
ExprKind::Box(expr) => vis.visit_expr(expr),
11081108
ExprKind::Array(exprs) => visit_exprs(exprs, vis),
1109+
ExprKind::ConstBlock(anon_const) => {
1110+
vis.visit_anon_const(anon_const);
1111+
}
11091112
ExprKind::Repeat(expr, count) => {
11101113
vis.visit_expr(expr);
11111114
vis.visit_anon_const(count);

compiler/rustc_ast/src/token.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ pub fn ident_can_begin_expr(name: Symbol, span: Span, is_raw: bool) -> bool {
153153
kw::Do,
154154
kw::Box,
155155
kw::Break,
156+
kw::Const,
156157
kw::Continue,
157158
kw::False,
158159
kw::For,

compiler/rustc_ast/src/util/parser.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ pub enum ExprPrecedence {
282282
ForLoop,
283283
Loop,
284284
Match,
285+
ConstBlock,
285286
Block,
286287
TryBlock,
287288
Struct,
@@ -346,6 +347,7 @@ impl ExprPrecedence {
346347
ExprPrecedence::ForLoop |
347348
ExprPrecedence::Loop |
348349
ExprPrecedence::Match |
350+
ExprPrecedence::ConstBlock |
349351
ExprPrecedence::Block |
350352
ExprPrecedence::TryBlock |
351353
ExprPrecedence::Async |

compiler/rustc_ast/src/visit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
717717
ExprKind::Array(ref subexpressions) => {
718718
walk_list!(visitor, visit_expr, subexpressions);
719719
}
720+
ExprKind::ConstBlock(ref anon_const) => visitor.visit_anon_const(anon_const),
720721
ExprKind::Repeat(ref element, ref count) => {
721722
visitor.visit_expr(element);
722723
visitor.visit_anon_const(count)

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
3030
let kind = match e.kind {
3131
ExprKind::Box(ref inner) => hir::ExprKind::Box(self.lower_expr(inner)),
3232
ExprKind::Array(ref exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
33+
ExprKind::ConstBlock(_) => {
34+
unimplemented!();
35+
}
3336
ExprKind::Repeat(ref expr, ref count) => {
3437
let expr = self.lower_expr(expr);
3538
let count = self.lower_anon_const(count);

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1714,6 +1714,14 @@ impl<'a> State<'a> {
17141714
self.end();
17151715
}
17161716

1717+
fn print_expr_anon_const(&mut self, expr: &ast::AnonConst, attrs: &[ast::Attribute]) {
1718+
self.ibox(INDENT_UNIT);
1719+
self.s.word("const");
1720+
self.print_inner_attributes_inline(attrs);
1721+
self.print_expr(&expr.value);
1722+
self.end();
1723+
}
1724+
17171725
fn print_expr_repeat(
17181726
&mut self,
17191727
element: &ast::Expr,
@@ -1890,6 +1898,9 @@ impl<'a> State<'a> {
18901898
ast::ExprKind::Array(ref exprs) => {
18911899
self.print_expr_vec(&exprs[..], attrs);
18921900
}
1901+
ast::ExprKind::ConstBlock(ref anon_const) => {
1902+
self.print_expr_anon_const(anon_const, attrs);
1903+
}
18931904
ast::ExprKind::Repeat(ref element, ref count) => {
18941905
self.print_expr_repeat(element, count, attrs);
18951906
}

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,8 @@ impl<'a> Parser<'a> {
10601060
})
10611061
} else if self.eat_keyword(kw::Unsafe) {
10621062
self.parse_block_expr(None, lo, BlockCheckMode::Unsafe(ast::UserProvided), attrs)
1063+
} else if self.check_inline_const() {
1064+
self.parse_const_expr(lo.to(self.token.span))
10631065
} else if self.is_do_catch_block() {
10641066
self.recover_do_catch(attrs)
10651067
} else if self.is_try_block() {

compiler/rustc_parse/src/parser/mod.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ use rustc_ast::ptr::P;
1818
use rustc_ast::token::{self, DelimToken, Token, TokenKind};
1919
use rustc_ast::tokenstream::{self, DelimSpan, TokenStream, TokenTree, TreeAndSpacing};
2020
use rustc_ast::DUMMY_NODE_ID;
21-
use rustc_ast::{self as ast, AttrStyle, AttrVec, Const, CrateSugar, Extern, Unsafe};
22-
use rustc_ast::{Async, MacArgs, MacDelimiter, Mutability, StrLit, Visibility, VisibilityKind};
21+
use rustc_ast::{self as ast, AnonConst, AttrStyle, AttrVec, Const, CrateSugar, Extern, Unsafe};
22+
use rustc_ast::{Async, Expr, ExprKind, MacArgs, MacDelimiter, Mutability, StrLit};
23+
use rustc_ast::{Visibility, VisibilityKind};
2324
use rustc_ast_pretty::pprust;
2425
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, FatalError, PResult};
2526
use rustc_session::parse::ParseSess;
@@ -545,6 +546,11 @@ impl<'a> Parser<'a> {
545546
self.check_or_expected(self.token.can_begin_const_arg(), TokenType::Const)
546547
}
547548

549+
fn check_inline_const(&mut self) -> bool {
550+
self.check_keyword(kw::Const)
551+
&& self.look_ahead(1, |t| t == &token::OpenDelim(DelimToken::Brace))
552+
}
553+
548554
/// Checks to see if the next token is either `+` or `+=`.
549555
/// Otherwise returns `false`.
550556
fn check_plus(&mut self) -> bool {
@@ -864,13 +870,28 @@ impl<'a> Parser<'a> {
864870

865871
/// Parses constness: `const` or nothing.
866872
fn parse_constness(&mut self) -> Const {
867-
if self.eat_keyword(kw::Const) {
873+
// Avoid const blocks to be parsed as const items
874+
if self.look_ahead(1, |t| t != &token::OpenDelim(DelimToken::Brace))
875+
&& self.eat_keyword(kw::Const)
876+
{
868877
Const::Yes(self.prev_token.uninterpolated_span())
869878
} else {
870879
Const::No
871880
}
872881
}
873882

883+
/// Parses inline const expressions.
884+
fn parse_const_expr(&mut self, span: Span) -> PResult<'a, P<Expr>> {
885+
self.sess.gated_spans.gate(sym::inline_const, span);
886+
self.eat_keyword(kw::Const);
887+
let blk = self.parse_block()?;
888+
let anon_const = AnonConst {
889+
id: DUMMY_NODE_ID,
890+
value: self.mk_expr(blk.span, ExprKind::Block(blk, None), AttrVec::new()),
891+
};
892+
Ok(self.mk_expr(span, ExprKind::ConstBlock(anon_const), AttrVec::new()))
893+
}
894+
874895
/// Parses mutability (`mut` or nothing).
875896
fn parse_mutability(&mut self) -> Mutability {
876897
if self.eat_keyword(kw::Mut) { Mutability::Mut } else { Mutability::Not }
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// check-pass
2+
// compile-flags: -Z parse-only
3+
4+
#![feature(inline_const)]
5+
fn foo() -> i32 {
6+
const {
7+
let x = 5 + 10;
8+
x / 3
9+
}
10+
}

0 commit comments

Comments
 (0)