Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
Expand Down Expand Up @@ -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),
}
Expand Down
66 changes: 24 additions & 42 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}));

Expand All @@ -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)
}));

Expand Down Expand Up @@ -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,
Expand All @@ -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 {
Expand Down Expand Up @@ -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);
Expand All @@ -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),
}
}
Expand All @@ -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,
Expand All @@ -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),
Expand Down Expand Up @@ -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),
Expand All @@ -2655,15 +2633,19 @@ 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);
hir::AnonConst {
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),
}
}))
}
Expand Down
12 changes: 2 additions & 10 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
19 changes: 3 additions & 16 deletions compiler/rustc_parse/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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))?;
Expand Down
13 changes: 5 additions & 8 deletions compiler/rustc_parse/src/parser/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(_, _)
Expand All @@ -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,
}
}
Expand All @@ -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()?
};
Expand Down
12 changes: 2 additions & 10 deletions compiler/rustc_parse/src/parser/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions src/tools/rustfmt/tests/source/issue-6788.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fn foo() {
let a = [(); const { let x = 1; x }];
}

fn foo() {
let x = [(); const { 1 }];
}
10 changes: 10 additions & 0 deletions src/tools/rustfmt/tests/target/issue-6788.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
fn foo() {
let a = [(); const {
let x = 1;
x
}];
}

fn foo() {
let x = [(); const { 1 }];
}
Loading