keep const blocks around
This commit is contained in:
parent
035b01b794
commit
a86cfbbaab
8 changed files with 61 additions and 88 deletions
|
|
@ -827,7 +827,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
hir_id,
|
||||
def_id: self.local_def_id(v.id),
|
||||
data: self.lower_variant_data(hir_id, item_kind, &v.data),
|
||||
disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const_to_anon_const(e)),
|
||||
disr_expr: v
|
||||
.disr_expr
|
||||
.as_ref()
|
||||
.map(|e| self.lower_anon_const_to_anon_const(e, e.value.span)),
|
||||
ident: self.lower_ident(v.ident),
|
||||
span: self.lower_span(v.span),
|
||||
}
|
||||
|
|
@ -917,7 +920,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
None => Ident::new(sym::integer(index), self.lower_span(f.span)),
|
||||
},
|
||||
vis_span: self.lower_span(f.vis.span),
|
||||
default: f.default.as_ref().map(|v| self.lower_anon_const_to_anon_const(v)),
|
||||
default: f
|
||||
.default
|
||||
.as_ref()
|
||||
.map(|v| self.lower_anon_const_to_anon_const(v, v.value.span)),
|
||||
ty,
|
||||
safety: self.lower_safety(f.safety, hir::Safety::Safe),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2425,15 +2425,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
);
|
||||
|
||||
let lowered_args = self.arena.alloc_from_iter(args.iter().map(|arg| {
|
||||
let const_arg = if let ExprKind::ConstBlock(anon_const) = &arg.kind {
|
||||
let def_id = self.local_def_id(anon_const.id);
|
||||
let def_kind = self.tcx.def_kind(def_id);
|
||||
assert_eq!(DefKind::AnonConst, def_kind);
|
||||
self.lower_anon_const_to_const_arg(anon_const)
|
||||
} else {
|
||||
self.lower_expr_to_const_arg_direct(arg)
|
||||
};
|
||||
|
||||
let const_arg = self.lower_expr_to_const_arg_direct(arg);
|
||||
&*self.arena.alloc(const_arg)
|
||||
}));
|
||||
|
||||
|
|
@ -2445,16 +2437,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
ExprKind::Tup(exprs) => {
|
||||
let exprs = self.arena.alloc_from_iter(exprs.iter().map(|expr| {
|
||||
let expr = if let ExprKind::ConstBlock(anon_const) = &expr.kind {
|
||||
let def_id = self.local_def_id(anon_const.id);
|
||||
let def_kind = self.tcx.def_kind(def_id);
|
||||
assert_eq!(DefKind::AnonConst, def_kind);
|
||||
|
||||
self.lower_anon_const_to_const_arg(anon_const)
|
||||
} else {
|
||||
self.lower_expr_to_const_arg_direct(&expr)
|
||||
};
|
||||
|
||||
let expr = self.lower_expr_to_const_arg_direct(&expr);
|
||||
&*self.arena.alloc(expr)
|
||||
}));
|
||||
|
||||
|
|
@ -2494,16 +2477,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
// then go unused as the `Target::ExprField` is not actually
|
||||
// corresponding to `Node::ExprField`.
|
||||
self.lower_attrs(hir_id, &f.attrs, f.span, Target::ExprField);
|
||||
|
||||
let expr = if let ExprKind::ConstBlock(anon_const) = &f.expr.kind {
|
||||
let def_id = self.local_def_id(anon_const.id);
|
||||
let def_kind = self.tcx.def_kind(def_id);
|
||||
assert_eq!(DefKind::AnonConst, def_kind);
|
||||
|
||||
self.lower_anon_const_to_const_arg(anon_const)
|
||||
} else {
|
||||
self.lower_expr_to_const_arg_direct(&f.expr)
|
||||
};
|
||||
let expr = self.lower_expr_to_const_arg_direct(&f.expr);
|
||||
|
||||
&*self.arena.alloc(hir::ConstArgExprField {
|
||||
hir_id,
|
||||
|
|
@ -2521,13 +2495,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
ExprKind::Array(elements) => {
|
||||
let lowered_elems = self.arena.alloc_from_iter(elements.iter().map(|element| {
|
||||
let const_arg = if let ExprKind::ConstBlock(anon_const) = &element.kind {
|
||||
let def_id = self.local_def_id(anon_const.id);
|
||||
assert_eq!(DefKind::AnonConst, self.tcx.def_kind(def_id));
|
||||
self.lower_anon_const_to_const_arg(anon_const)
|
||||
} else {
|
||||
self.lower_expr_to_const_arg_direct(element)
|
||||
};
|
||||
let const_arg = self.lower_expr_to_const_arg_direct(element);
|
||||
&*self.arena.alloc(const_arg)
|
||||
}));
|
||||
let array_expr = self.arena.alloc(hir::ConstArgArrayExpr {
|
||||
|
|
@ -2557,6 +2525,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
| ExprKind::Call(..)
|
||||
| ExprKind::Tup(..)
|
||||
| ExprKind::Array(..)
|
||||
| ExprKind::ConstBlock(..)
|
||||
)
|
||||
{
|
||||
return self.lower_expr_to_const_arg_direct(expr);
|
||||
|
|
@ -2574,6 +2543,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
span,
|
||||
}
|
||||
}
|
||||
ExprKind::ConstBlock(anon_const) => {
|
||||
let def_id = self.local_def_id(anon_const.id);
|
||||
assert_eq!(DefKind::AnonConst, self.tcx.def_kind(def_id));
|
||||
self.lower_anon_const_to_const_arg(anon_const, span)
|
||||
}
|
||||
_ => overly_complex_const(self),
|
||||
}
|
||||
}
|
||||
|
|
@ -2584,11 +2558,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
&mut self,
|
||||
anon: &AnonConst,
|
||||
) -> &'hir hir::ConstArg<'hir> {
|
||||
self.arena.alloc(self.lower_anon_const_to_const_arg(anon))
|
||||
self.arena.alloc(self.lower_anon_const_to_const_arg(anon, anon.value.span))
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
|
||||
fn lower_anon_const_to_const_arg(
|
||||
&mut self,
|
||||
anon: &AnonConst,
|
||||
span: Span,
|
||||
) -> hir::ConstArg<'hir> {
|
||||
let tcx = self.tcx;
|
||||
|
||||
// We cannot change parsing depending on feature gates available,
|
||||
|
|
@ -2599,7 +2577,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
if tcx.features().min_generic_const_args() {
|
||||
return match anon.mgca_disambiguation {
|
||||
MgcaDisambiguation::AnonConst => {
|
||||
let lowered_anon = self.lower_anon_const_to_anon_const(anon);
|
||||
let lowered_anon = self.lower_anon_const_to_anon_const(anon, span);
|
||||
ConstArg {
|
||||
hir_id: self.next_id(),
|
||||
kind: hir::ConstArgKind::Anon(lowered_anon),
|
||||
|
|
@ -2645,7 +2623,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
};
|
||||
}
|
||||
|
||||
let lowered_anon = self.lower_anon_const_to_anon_const(anon);
|
||||
let lowered_anon = self.lower_anon_const_to_anon_const(anon, anon.value.span);
|
||||
ConstArg {
|
||||
hir_id: self.next_id(),
|
||||
kind: hir::ConstArgKind::Anon(lowered_anon),
|
||||
|
|
@ -2655,7 +2633,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
/// See [`hir::ConstArg`] for when to use this function vs
|
||||
/// [`Self::lower_anon_const_to_const_arg`].
|
||||
fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
|
||||
fn lower_anon_const_to_anon_const(
|
||||
&mut self,
|
||||
c: &AnonConst,
|
||||
span: Span,
|
||||
) -> &'hir hir::AnonConst {
|
||||
self.arena.alloc(self.with_new_scopes(c.value.span, |this| {
|
||||
let def_id = this.local_def_id(c.id);
|
||||
let hir_id = this.lower_node_id(c.id);
|
||||
|
|
@ -2663,7 +2645,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
def_id,
|
||||
hir_id,
|
||||
body: this.lower_const_body(c.value.span, Some(&c.value)),
|
||||
span: this.lower_span(c.value.span),
|
||||
span: this.lower_span(span),
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1627,16 +1627,8 @@ impl<'a> Parser<'a> {
|
|||
let first_expr = self.parse_expr()?;
|
||||
if self.eat(exp!(Semi)) {
|
||||
// Repeating array syntax: `[ 0; 512 ]`
|
||||
let count = if self.eat_keyword(exp!(Const)) {
|
||||
// While we could just disambiguate `Direct` from `AnonConst` by
|
||||
// treating all const block exprs as `AnonConst`, that would
|
||||
// complicate the DefCollector and likely all other visitors.
|
||||
// So we strip the const blockiness and just store it as a block
|
||||
// in the AST with the extra disambiguator on the AnonConst
|
||||
self.parse_mgca_const_block(false)?
|
||||
} else {
|
||||
self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?
|
||||
};
|
||||
let count =
|
||||
self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?;
|
||||
self.expect(close)?;
|
||||
ExprKind::Repeat(first_expr, count)
|
||||
} else if self.eat(exp!(Comma)) {
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@ use rustc_ast::tokenstream::{
|
|||
};
|
||||
use rustc_ast::util::case::Case;
|
||||
use rustc_ast::{
|
||||
self as ast, AnonConst, AttrArgs, AttrId, BlockCheckMode, ByRef, Const, CoroutineKind,
|
||||
DUMMY_NODE_ID, DelimArgs, Expr, ExprKind, Extern, HasAttrs, HasTokens, MgcaDisambiguation,
|
||||
Mutability, Recovered, Safety, StrLit, Visibility, VisibilityKind,
|
||||
self as ast, AnonConst, AttrArgs, AttrId, ByRef, Const, CoroutineKind, DUMMY_NODE_ID,
|
||||
DelimArgs, Expr, ExprKind, Extern, HasAttrs, HasTokens, MgcaDisambiguation, Mutability,
|
||||
Recovered, Safety, StrLit, Visibility, VisibilityKind,
|
||||
};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::debug_assert_matches;
|
||||
|
|
@ -1269,19 +1269,6 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_mgca_const_block(&mut self, gate_syntax: bool) -> PResult<'a, AnonConst> {
|
||||
let kw_span = self.prev_token.span;
|
||||
let value = self.parse_expr_block(None, kw_span, BlockCheckMode::Default)?;
|
||||
if gate_syntax {
|
||||
self.psess.gated_spans.gate(sym::min_generic_const_args, kw_span.to(value.span));
|
||||
}
|
||||
Ok(AnonConst {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
value,
|
||||
mgca_disambiguation: MgcaDisambiguation::AnonConst,
|
||||
})
|
||||
}
|
||||
|
||||
/// Parses inline const expressions.
|
||||
fn parse_const_block(&mut self, span: Span) -> PResult<'a, Box<Expr>> {
|
||||
self.expect_keyword(exp!(Const))?;
|
||||
|
|
|
|||
|
|
@ -847,6 +847,7 @@ impl<'a> Parser<'a> {
|
|||
/// - A literal.
|
||||
/// - A numeric literal prefixed by `-`.
|
||||
/// - A single-segment path.
|
||||
/// - A const block (under mGCA)
|
||||
pub(super) fn expr_is_valid_const_arg(&self, expr: &Box<rustc_ast::Expr>) -> bool {
|
||||
match &expr.kind {
|
||||
ast::ExprKind::Block(_, _)
|
||||
|
|
@ -863,6 +864,10 @@ impl<'a> Parser<'a> {
|
|||
{
|
||||
true
|
||||
}
|
||||
ast::ExprKind::ConstBlock(_) => {
|
||||
self.psess.gated_spans.gate(sym::min_generic_const_args, expr.span);
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -874,14 +879,6 @@ impl<'a> Parser<'a> {
|
|||
let (value, mgca_disambiguation) = if self.token.kind == token::OpenBrace {
|
||||
let value = self.parse_expr_block(None, self.token.span, BlockCheckMode::Default)?;
|
||||
(value, MgcaDisambiguation::Direct)
|
||||
} else if self.eat_keyword(exp!(Const)) {
|
||||
// While we could just disambiguate `Direct` from `AnonConst` by
|
||||
// treating all const block exprs as `AnonConst`, that would
|
||||
// complicate the DefCollector and likely all other visitors.
|
||||
// So we strip the const blockiness and just store it as a block
|
||||
// in the AST with the extra disambiguator on the AnonConst
|
||||
let value = self.parse_mgca_const_block(true)?;
|
||||
(value.value, MgcaDisambiguation::AnonConst)
|
||||
} else {
|
||||
self.parse_unambiguous_unbraced_const_arg()?
|
||||
};
|
||||
|
|
|
|||
|
|
@ -658,16 +658,8 @@ impl<'a> Parser<'a> {
|
|||
};
|
||||
|
||||
let ty = if self.eat(exp!(Semi)) {
|
||||
let mut length = if self.eat_keyword(exp!(Const)) {
|
||||
// While we could just disambiguate `Direct` from `AnonConst` by
|
||||
// treating all const block exprs as `AnonConst`, that would
|
||||
// complicate the DefCollector and likely all other visitors.
|
||||
// So we strip the const blockiness and just store it as a block
|
||||
// in the AST with the extra disambiguator on the AnonConst
|
||||
self.parse_mgca_const_block(false)?
|
||||
} else {
|
||||
self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?
|
||||
};
|
||||
let mut length =
|
||||
self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?;
|
||||
|
||||
if let Err(e) = self.expect(exp!(CloseBracket)) {
|
||||
// Try to recover from `X<Y, ...>` when `X::<Y, ...>` works
|
||||
|
|
|
|||
7
src/tools/rustfmt/tests/source/issue-6788.rs
Normal file
7
src/tools/rustfmt/tests/source/issue-6788.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
fn foo() {
|
||||
let a = [(); const { let x = 1; x }];
|
||||
}
|
||||
|
||||
fn foo() {
|
||||
let x = [(); const { 1 }];
|
||||
}
|
||||
10
src/tools/rustfmt/tests/target/issue-6788.rs
Normal file
10
src/tools/rustfmt/tests/target/issue-6788.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
fn foo() {
|
||||
let a = [(); const {
|
||||
let x = 1;
|
||||
x
|
||||
}];
|
||||
}
|
||||
|
||||
fn foo() {
|
||||
let x = [(); const { 1 }];
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue