Skip to content

Commit 038fee1

Browse files
committed
rustfmt: support const block items
1 parent bbbd215 commit 038fee1

File tree

7 files changed

+206
-100
lines changed

7 files changed

+206
-100
lines changed

src/tools/rustfmt/src/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2177,7 +2177,7 @@ pub(crate) fn rewrite_assign_rhs_with_comments<S: Into<String>, R: Rewrite + Spa
21772177
} else {
21782178
shape
21792179
};
2180-
let rhs = rewrite_assign_rhs_expr(context, &lhs, ex, shape, rhs_kind, rhs_tactics)?;
2180+
let rhs: String = rewrite_assign_rhs_expr(context, &lhs, ex, shape, rhs_kind, rhs_tactics)?;
21812181
if contains_comment {
21822182
let rhs = rhs.trim_start();
21832183
combine_strs_with_missing_comments(context, &lhs, rhs, between_span, shape, allow_extend)

src/tools/rustfmt/src/items.rs

Lines changed: 155 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1999,56 +1999,60 @@ pub(crate) fn rewrite_struct_field(
19991999
combine_strs_with_missing_comments(context, &attrs_str, field_str, missing_span, shape, false)
20002000
}
20012001

2002-
pub(crate) struct StaticParts<'a> {
2002+
pub(crate) struct StaticPartsLhs<'a> {
20032003
prefix: &'a str,
20042004
safety: ast::Safety,
20052005
vis: &'a ast::Visibility,
20062006
ident: symbol::Ident,
20072007
generics: Option<&'a ast::Generics>,
20082008
ty: &'a ast::Ty,
20092009
mutability: ast::Mutability,
2010-
expr_opt: Option<&'a ast::Expr>,
20112010
defaultness: Option<ast::Defaultness>,
2011+
}
2012+
2013+
pub(crate) struct StaticParts<'a> {
2014+
lhs: Option<StaticPartsLhs<'a>>,
2015+
rhs: Option<&'a ast::Expr>,
20122016
span: Span,
20132017
}
20142018

20152019
impl<'a> StaticParts<'a> {
20162020
pub(crate) fn from_item(item: &'a ast::Item) -> Self {
2017-
let (defaultness, prefix, safety, ident, ty, mutability, expr_opt, generics) =
2018-
match &item.kind {
2019-
ast::ItemKind::Static(s) => (
2020-
None,
2021-
"static",
2022-
s.safety,
2023-
s.ident,
2024-
&s.ty,
2025-
s.mutability,
2026-
s.expr.as_deref(),
2027-
None,
2028-
),
2029-
ast::ItemKind::Const(c) => (
2030-
Some(c.defaultness),
2031-
"const",
2032-
ast::Safety::Default,
2033-
c.ident,
2034-
&c.ty,
2035-
ast::Mutability::Not,
2036-
c.rhs.as_ref().map(|rhs| rhs.expr()),
2037-
Some(&c.generics),
2038-
),
2039-
_ => unreachable!(),
2040-
};
2041-
StaticParts {
2042-
prefix,
2043-
safety,
2044-
vis: &item.vis,
2045-
ident,
2046-
generics,
2047-
ty,
2048-
mutability,
2049-
expr_opt,
2050-
defaultness,
2051-
span: item.span,
2021+
match &item.kind {
2022+
ast::ItemKind::Static(s) => StaticParts {
2023+
lhs: Some(StaticPartsLhs {
2024+
prefix: "static",
2025+
safety: s.safety,
2026+
vis: &item.vis,
2027+
ident: s.ident,
2028+
generics: None,
2029+
ty: &s.ty,
2030+
mutability: s.mutability,
2031+
defaultness: None,
2032+
}),
2033+
rhs: s.expr.as_deref(),
2034+
span: item.span,
2035+
},
2036+
ast::ItemKind::Const(c) => StaticParts {
2037+
lhs: Some(StaticPartsLhs {
2038+
prefix: "const",
2039+
safety: ast::Safety::Default,
2040+
vis: &item.vis,
2041+
ident: c.ident,
2042+
generics: Some(&c.generics),
2043+
ty: &c.ty,
2044+
mutability: ast::Mutability::Not,
2045+
defaultness: Some(c.defaultness),
2046+
}),
2047+
rhs: c.rhs.as_ref().map(|rhs| rhs.expr()),
2048+
span: item.span,
2049+
},
2050+
ast::ItemKind::ConstBlock(b) => StaticParts {
2051+
lhs: None,
2052+
rhs: Some(&b.body),
2053+
span: item.span,
2054+
},
2055+
_ => unreachable!(),
20522056
}
20532057
}
20542058

@@ -2063,15 +2067,17 @@ impl<'a> StaticParts<'a> {
20632067
_ => unreachable!(),
20642068
};
20652069
StaticParts {
2066-
prefix: "const",
2067-
safety: ast::Safety::Default,
2068-
vis: &ti.vis,
2069-
ident,
2070-
generics,
2071-
ty,
2072-
mutability: ast::Mutability::Not,
2073-
expr_opt,
2074-
defaultness: Some(defaultness),
2070+
lhs: Some(StaticPartsLhs {
2071+
prefix: "const",
2072+
safety: ast::Safety::Default,
2073+
vis: &ti.vis,
2074+
ident,
2075+
generics,
2076+
ty,
2077+
mutability: ast::Mutability::Not,
2078+
defaultness: Some(defaultness),
2079+
}),
2080+
rhs: expr_opt,
20752081
span: ti.span,
20762082
}
20772083
}
@@ -2087,88 +2093,142 @@ impl<'a> StaticParts<'a> {
20872093
_ => unreachable!(),
20882094
};
20892095
StaticParts {
2090-
prefix: "const",
2091-
safety: ast::Safety::Default,
2092-
vis: &ii.vis,
2093-
ident,
2094-
generics,
2095-
ty,
2096-
mutability: ast::Mutability::Not,
2097-
expr_opt,
2098-
defaultness: Some(defaultness),
2096+
lhs: Some(StaticPartsLhs {
2097+
prefix: "const",
2098+
safety: ast::Safety::Default,
2099+
vis: &ii.vis,
2100+
ident,
2101+
generics,
2102+
ty,
2103+
mutability: ast::Mutability::Not,
2104+
defaultness: Some(defaultness),
2105+
}),
2106+
rhs: expr_opt,
20992107
span: ii.span,
21002108
}
21012109
}
21022110
}
21032111

2104-
fn rewrite_static(
2112+
fn rewrite_static_lhs(
21052113
context: &RewriteContext<'_>,
2106-
static_parts: &StaticParts<'_>,
2114+
lhs: &StaticPartsLhs<'_>,
21072115
offset: Indent,
2108-
) -> Option<String> {
2116+
) -> Option<[String; 2]> {
2117+
let StaticPartsLhs {
2118+
prefix,
2119+
safety,
2120+
vis,
2121+
ident,
2122+
generics,
2123+
ty,
2124+
mutability,
2125+
defaultness,
2126+
} = *lhs;
2127+
21092128
// For now, if this static (or const) has generics, then bail.
2110-
if static_parts
2111-
.generics
2112-
.is_some_and(|g| !g.params.is_empty() || !g.where_clause.is_empty())
2113-
{
2129+
if generics.is_some_and(|g| !g.params.is_empty() || !g.where_clause.is_empty()) {
21142130
return None;
21152131
}
21162132

21172133
let colon = colon_spaces(context.config);
21182134
let mut prefix = format!(
21192135
"{}{}{}{} {}{}{}",
2120-
format_visibility(context, static_parts.vis),
2121-
static_parts.defaultness.map_or("", format_defaultness),
2122-
format_safety(static_parts.safety),
2123-
static_parts.prefix,
2124-
format_mutability(static_parts.mutability),
2125-
rewrite_ident(context, static_parts.ident),
2136+
format_visibility(context, vis),
2137+
defaultness.map_or("", format_defaultness),
2138+
format_safety(safety),
2139+
prefix,
2140+
format_mutability(mutability),
2141+
rewrite_ident(context, ident),
21262142
colon,
21272143
);
2128-
// 2 = " =".len()
2129-
let ty_shape =
2130-
Shape::indented(offset.block_only(), context.config).offset_left(prefix.len() + 2)?;
2131-
let ty_str = match static_parts.ty.rewrite(context, ty_shape) {
2144+
let ty_shape = Shape::indented(offset.block_only(), context.config)
2145+
.offset_left(prefix.len() + const { " =".len() })?;
2146+
let ty_str = match ty.rewrite(context, ty_shape) {
21322147
Some(ty_str) => ty_str,
21332148
None => {
21342149
if prefix.ends_with(' ') {
21352150
prefix.pop();
21362151
}
21372152
let nested_indent = offset.block_indent(context.config);
21382153
let nested_shape = Shape::indented(nested_indent, context.config);
2139-
let ty_str = static_parts.ty.rewrite(context, nested_shape)?;
2154+
let ty_str = ty.rewrite(context, nested_shape)?;
21402155
format!(
21412156
"{}{}",
21422157
nested_indent.to_string_with_newline(context.config),
21432158
ty_str
21442159
)
21452160
}
21462161
};
2162+
Some([prefix, ty_str])
2163+
}
21472164

2148-
if let Some(expr) = static_parts.expr_opt {
2149-
let comments_lo = context.snippet_provider.span_after(static_parts.span, "=");
2150-
let expr_lo = expr.span.lo();
2151-
let comments_span = mk_sp(comments_lo, expr_lo);
2165+
fn rewrite_static_rhs(
2166+
context: &RewriteContext<'_>,
2167+
lhs: String,
2168+
rhs: &ast::Expr,
2169+
span: Span,
2170+
offset: Indent,
2171+
end: &'static str,
2172+
) -> Option<String> {
2173+
let comments_lo = context.snippet_provider.span_after(span, "=");
2174+
let expr_lo = rhs.span.lo();
2175+
let comments_span = mk_sp(comments_lo, expr_lo);
21522176

2153-
let lhs = format!("{prefix}{ty_str} =");
2177+
let remaining_width = context.budget(offset.block_indent + end.len());
2178+
rewrite_assign_rhs_with_comments(
2179+
context,
2180+
&lhs,
2181+
rhs,
2182+
Shape::legacy(remaining_width, offset.block_only()),
2183+
&RhsAssignKind::Expr(&rhs.kind, rhs.span),
2184+
RhsTactics::Default,
2185+
comments_span,
2186+
true,
2187+
)
2188+
.ok()
2189+
.map(|res| recover_comment_removed(res, span, context))
2190+
.map(|s| if s.ends_with(end) { s } else { s + end })
2191+
}
21542192

2155-
// 1 = ;
2156-
let remaining_width = context.budget(offset.block_indent + 1);
2157-
rewrite_assign_rhs_with_comments(
2158-
context,
2159-
&lhs,
2160-
expr,
2161-
Shape::legacy(remaining_width, offset.block_only()),
2162-
&RhsAssignKind::Expr(&expr.kind, expr.span),
2163-
RhsTactics::Default,
2164-
comments_span,
2165-
true,
2166-
)
2167-
.ok()
2168-
.map(|res| recover_comment_removed(res, static_parts.span, context))
2169-
.map(|s| if s.ends_with(';') { s } else { s + ";" })
2170-
} else {
2171-
Some(format!("{prefix}{ty_str};"))
2193+
fn rewrite_static(
2194+
context: &RewriteContext<'_>,
2195+
static_parts: &StaticParts<'_>,
2196+
offset: Indent,
2197+
) -> Option<String> {
2198+
match *static_parts {
2199+
StaticParts {
2200+
lhs: Some(ref lhs),
2201+
rhs: None,
2202+
span: _,
2203+
} => {
2204+
let [prefix, ty] = rewrite_static_lhs(context, lhs, offset)?;
2205+
Some(format!("{prefix}{ty};"))
2206+
}
2207+
StaticParts {
2208+
lhs: Some(ref lhs),
2209+
rhs: Some(rhs),
2210+
span,
2211+
} => {
2212+
let [prefix, ty] = rewrite_static_lhs(context, lhs, offset)?;
2213+
let lhs = format!("{prefix}{ty} =");
2214+
rewrite_static_rhs(context, lhs, rhs, span, offset, ";")
2215+
}
2216+
StaticParts {
2217+
lhs: None,
2218+
rhs: Some(rhs),
2219+
span,
2220+
} => rhs
2221+
.rewrite_result(
2222+
context,
2223+
Shape::legacy(context.budget(offset.block_indent), offset.block_only()),
2224+
)
2225+
.ok()
2226+
.map(|res| recover_comment_removed(res, span, context)),
2227+
StaticParts {
2228+
lhs: None,
2229+
rhs: None,
2230+
span: _,
2231+
} => unreachable!(),
21722232
}
21732233
}
21742234

src/tools/rustfmt/src/parse/macros/cfg_if.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::panic::{AssertUnwindSafe, catch_unwind};
33
use rustc_ast::ast;
44
use rustc_ast::token::TokenKind;
55
use rustc_parse::exp;
6-
use rustc_parse::parser::ForceCollect;
6+
use rustc_parse::parser::{AllowConstBlockItems, ForceCollect};
77
use rustc_span::symbol::kw;
88

99
use crate::parse::macros::build_stream_parser;

src/tools/rustfmt/src/parse/macros/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use rustc_ast::ast;
22
use rustc_ast::token::{Delimiter, NonterminalKind, NtExprKind::*, NtPatKind::*, TokenKind};
33
use rustc_ast::tokenstream::TokenStream;
44
use rustc_parse::MACRO_ARGUMENTS;
5-
use rustc_parse::parser::{ForceCollect, Parser, Recovery};
5+
use rustc_parse::parser::{AllowConstBlockItems, ForceCollect, Parser, Recovery};
66
use rustc_session::parse::ParseSess;
77
use rustc_span::symbol;
88

@@ -67,7 +67,7 @@ fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option<MacroArg> {
6767
parse_macro_arg!(
6868
Item,
6969
NonterminalKind::Item,
70-
|parser: &mut Parser<'b>| parser.parse_item(ForceCollect::No),
70+
|parser: &mut Parser<'b>| parser.parse_item(ForceCollect::No, AllowConstBlockItems::Yes),
7171
|x: Option<Box<ast::Item>>| x
7272
);
7373

src/tools/rustfmt/src/visitor.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,9 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
530530
self.format_missing_with_indent(source!(self, item.span).lo());
531531
self.format_foreign_mod(foreign_mod, item.span);
532532
}
533-
ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => {
533+
ast::ItemKind::Static(..)
534+
| ast::ItemKind::Const(..)
535+
| ast::ItemKind::ConstBlock(..) => {
534536
self.visit_static(&StaticParts::from_item(item));
535537
}
536538
ast::ItemKind::Fn(ref fn_kind) => {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#![feature(const_block_items)]
2+
3+
const {
4+
5+
6+
assert!(true)
7+
}
8+
9+
#[cfg(false)] const { assert!(false) }
10+
11+
12+
#[cfg(false)]
13+
// foo
14+
const
15+
16+
{
17+
// bar
18+
assert!(false)
19+
// baz
20+
}
21+
22+
23+
#[expect(unused)]
24+
const { let a = 1; assert!(true); }

0 commit comments

Comments
 (0)