Skip to content

Commit a4dbcb5

Browse files
committed
Expand format_args!() in rust_ast_lowering.
1 parent e839451 commit a4dbcb5

File tree

19 files changed

+535
-384
lines changed

19 files changed

+535
-384
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3699,6 +3699,7 @@ name = "rustc_ast_pretty"
36993699
version = "0.0.0"
37003700
dependencies = [
37013701
"rustc_ast",
3702+
"rustc_parse_format",
37023703
"rustc_span",
37033704
]
37043705

compiler/rustc_ast/src/ast.rs

+5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
//! - [`Attribute`]: Metadata associated with item.
1919
//! - [`UnOp`], [`BinOp`], and [`BinOpKind`]: Unary and binary operators.
2020
21+
pub use crate::format::*;
2122
pub use crate::util::parser::ExprPrecedence;
2223
pub use GenericArgs::*;
2324
pub use UnsafeSource::*;
@@ -1269,6 +1270,7 @@ impl Expr {
12691270
ExprKind::Try(..) => ExprPrecedence::Try,
12701271
ExprKind::Yield(..) => ExprPrecedence::Yield,
12711272
ExprKind::Yeet(..) => ExprPrecedence::Yeet,
1273+
ExprKind::FormatArgs(..) => ExprPrecedence::FormatArgs,
12721274
ExprKind::Err => ExprPrecedence::Err,
12731275
}
12741276
}
@@ -1498,6 +1500,9 @@ pub enum ExprKind {
14981500
/// with a `ByteStr` literal.
14991501
IncludedBytes(Lrc<[u8]>),
15001502

1503+
/// A `format_args!()` expression.
1504+
FormatArgs(P<FormatArgs>),
1505+
15011506
/// Placeholder for an expression that wasn't syntactically well formed in some way.
15021507
Err,
15031508
}

compiler/rustc_builtin_macros/src/format/ast.rs renamed to compiler/rustc_ast/src/format.rs

+20-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use rustc_ast::ptr::P;
2-
use rustc_ast::Expr;
1+
use crate::ptr::P;
2+
use crate::Expr;
33
use rustc_data_structures::fx::FxHashMap;
44
use rustc_span::symbol::{Ident, Symbol};
55
use rustc_span::Span;
@@ -39,7 +39,7 @@ use rustc_span::Span;
3939
/// Basically the "AST" for a complete `format_args!()`.
4040
///
4141
/// E.g., `format_args!("hello {name}");`.
42-
#[derive(Clone, Debug)]
42+
#[derive(Clone, Encodable, Decodable, Debug)]
4343
pub struct FormatArgs {
4444
pub span: Span,
4545
pub template: Vec<FormatArgsPiece>,
@@ -49,7 +49,7 @@ pub struct FormatArgs {
4949
/// A piece of a format template string.
5050
///
5151
/// E.g. "hello" or "{name}".
52-
#[derive(Clone, Debug)]
52+
#[derive(Clone, Encodable, Decodable, Debug)]
5353
pub enum FormatArgsPiece {
5454
Literal(Symbol),
5555
Placeholder(FormatPlaceholder),
@@ -59,7 +59,7 @@ pub enum FormatArgsPiece {
5959
///
6060
/// E.g. `1, 2, name="ferris", n=3`,
6161
/// but also implicit captured arguments like `x` in `format_args!("{x}")`.
62-
#[derive(Clone, Debug)]
62+
#[derive(Clone, Encodable, Decodable, Debug)]
6363
pub struct FormatArguments {
6464
arguments: Vec<FormatArgument>,
6565
num_unnamed_args: usize,
@@ -121,18 +121,22 @@ impl FormatArguments {
121121
&self.arguments[..self.num_explicit_args]
122122
}
123123

124-
pub fn into_vec(self) -> Vec<FormatArgument> {
125-
self.arguments
124+
pub fn all_args(&self) -> &[FormatArgument] {
125+
&self.arguments[..]
126+
}
127+
128+
pub fn all_args_mut(&mut self) -> &mut [FormatArgument] {
129+
&mut self.arguments[..]
126130
}
127131
}
128132

129-
#[derive(Clone, Debug)]
133+
#[derive(Clone, Encodable, Decodable, Debug)]
130134
pub struct FormatArgument {
131135
pub kind: FormatArgumentKind,
132136
pub expr: P<Expr>,
133137
}
134138

135-
#[derive(Clone, Debug)]
139+
#[derive(Clone, Encodable, Decodable, Debug)]
136140
pub enum FormatArgumentKind {
137141
/// `format_args(…, arg)`
138142
Normal,
@@ -152,7 +156,7 @@ impl FormatArgumentKind {
152156
}
153157
}
154158

155-
#[derive(Clone, Debug, PartialEq, Eq)]
159+
#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
156160
pub struct FormatPlaceholder {
157161
/// Index into [`FormatArgs::arguments`].
158162
pub argument: FormatArgPosition,
@@ -164,7 +168,7 @@ pub struct FormatPlaceholder {
164168
pub format_options: FormatOptions,
165169
}
166170

167-
#[derive(Clone, Debug, PartialEq, Eq)]
171+
#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
168172
pub struct FormatArgPosition {
169173
/// Which argument this position refers to (Ok),
170174
/// or would've referred to if it existed (Err).
@@ -175,7 +179,7 @@ pub struct FormatArgPosition {
175179
pub span: Option<Span>,
176180
}
177181

178-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
182+
#[derive(Copy, Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
179183
pub enum FormatArgPositionKind {
180184
/// `{}` or `{:.*}`
181185
Implicit,
@@ -185,7 +189,7 @@ pub enum FormatArgPositionKind {
185189
Named,
186190
}
187191

188-
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
192+
#[derive(Copy, Clone, Encodable, Decodable, Debug, PartialEq, Eq, Hash)]
189193
pub enum FormatTrait {
190194
/// `{}`
191195
Display,
@@ -207,7 +211,7 @@ pub enum FormatTrait {
207211
UpperHex,
208212
}
209213

210-
#[derive(Clone, Debug, Default, PartialEq, Eq)]
214+
#[derive(Clone, Encodable, Decodable, Default, Debug, PartialEq, Eq)]
211215
pub struct FormatOptions {
212216
/// The width. E.g. `{:5}` or `{:width$}`.
213217
pub width: Option<FormatCount>,
@@ -221,7 +225,7 @@ pub struct FormatOptions {
221225
pub flags: u32,
222226
}
223227

224-
#[derive(Clone, Debug, PartialEq, Eq)]
228+
#[derive(Copy, Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
225229
pub enum FormatAlignment {
226230
/// `{:<}`
227231
Left,
@@ -231,7 +235,7 @@ pub enum FormatAlignment {
231235
Center,
232236
}
233237

234-
#[derive(Clone, Debug, PartialEq, Eq)]
238+
#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
235239
pub enum FormatCount {
236240
/// `{:5}` or `{:.5}`
237241
Literal(usize),

compiler/rustc_ast/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ pub mod ast_traits;
4242
pub mod attr;
4343
pub mod entry;
4444
pub mod expand;
45+
pub mod format;
4546
pub mod mut_visit;
4647
pub mod node_id;
4748
pub mod ptr;
@@ -51,6 +52,7 @@ pub mod visit;
5152

5253
pub use self::ast::*;
5354
pub use self::ast_traits::{AstDeref, AstNodeWrapper, HasAttrs, HasNodeId, HasSpan, HasTokens};
55+
pub use self::format::*;
5456

5557
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
5658

compiler/rustc_ast/src/mut_visit.rs

+14
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@ pub trait MutVisitor: Sized {
297297
fn visit_inline_asm_sym(&mut self, sym: &mut InlineAsmSym) {
298298
noop_visit_inline_asm_sym(sym, self)
299299
}
300+
301+
fn visit_format_args(&mut self, fmt: &mut FormatArgs) {
302+
noop_visit_format_args(fmt, self)
303+
}
300304
}
301305

302306
/// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful
@@ -1284,6 +1288,15 @@ pub fn noop_visit_inline_asm_sym<T: MutVisitor>(
12841288
vis.visit_path(path);
12851289
}
12861290

1291+
pub fn noop_visit_format_args<T: MutVisitor>(fmt: &mut FormatArgs, vis: &mut T) {
1292+
for arg in fmt.arguments.all_args_mut() {
1293+
if let FormatArgumentKind::Named(name) = &mut arg.kind {
1294+
vis.visit_ident(name);
1295+
}
1296+
vis.visit_expr(&mut arg.expr);
1297+
}
1298+
}
1299+
12871300
pub fn noop_visit_expr<T: MutVisitor>(
12881301
Expr { kind, id, span, attrs, tokens }: &mut Expr,
12891302
vis: &mut T,
@@ -1423,6 +1436,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
14231436
visit_opt(expr, |expr| vis.visit_expr(expr));
14241437
}
14251438
ExprKind::InlineAsm(asm) => vis.visit_inline_asm(asm),
1439+
ExprKind::FormatArgs(fmt) => vis.visit_format_args(fmt),
14261440
ExprKind::MacCall(mac) => vis.visit_mac_call(mac),
14271441
ExprKind::Struct(se) => {
14281442
let StructExpr { qself, path, fields, rest } = se.deref_mut();

compiler/rustc_ast/src/util/parser.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ pub enum ExprPrecedence {
271271
Try,
272272
InlineAsm,
273273
Mac,
274+
FormatArgs,
274275

275276
Array,
276277
Repeat,
@@ -335,7 +336,8 @@ impl ExprPrecedence {
335336
| ExprPrecedence::Index
336337
| ExprPrecedence::Try
337338
| ExprPrecedence::InlineAsm
338-
| ExprPrecedence::Mac => PREC_POSTFIX,
339+
| ExprPrecedence::Mac
340+
| ExprPrecedence::FormatArgs => PREC_POSTFIX,
339341

340342
// Never need parens
341343
ExprPrecedence::Array

compiler/rustc_ast/src/visit.rs

+13
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,9 @@ pub trait Visitor<'ast>: Sized {
242242
fn visit_inline_asm(&mut self, asm: &'ast InlineAsm) {
243243
walk_inline_asm(self, asm)
244244
}
245+
fn visit_format_args(&mut self, fmt: &'ast FormatArgs) {
246+
walk_format_args(self, fmt)
247+
}
245248
fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) {
246249
walk_inline_asm_sym(self, sym)
247250
}
@@ -756,6 +759,15 @@ pub fn walk_inline_asm_sym<'a, V: Visitor<'a>>(visitor: &mut V, sym: &'a InlineA
756759
visitor.visit_path(&sym.path, sym.id);
757760
}
758761

762+
pub fn walk_format_args<'a, V: Visitor<'a>>(visitor: &mut V, fmt: &'a FormatArgs) {
763+
for arg in fmt.arguments.all_args() {
764+
if let FormatArgumentKind::Named(name) = arg.kind {
765+
visitor.visit_ident(name);
766+
}
767+
visitor.visit_expr(&arg.expr);
768+
}
769+
}
770+
759771
pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
760772
walk_list!(visitor, visit_attribute, expression.attrs.iter());
761773

@@ -895,6 +907,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
895907
ExprKind::MacCall(mac) => visitor.visit_mac_call(mac),
896908
ExprKind::Paren(subexpression) => visitor.visit_expr(subexpression),
897909
ExprKind::InlineAsm(asm) => visitor.visit_inline_asm(asm),
910+
ExprKind::FormatArgs(f) => visitor.visit_format_args(f),
898911
ExprKind::Yield(optional_expression) => {
899912
walk_list!(visitor, visit_expr, optional_expression);
900913
}

compiler/rustc_ast_lowering/src/expr.rs

+1
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
292292
ExprKind::InlineAsm(asm) => {
293293
hir::ExprKind::InlineAsm(self.lower_inline_asm(e.span, asm))
294294
}
295+
ExprKind::FormatArgs(fmt) => self.lower_format_args(e.span, fmt),
295296
ExprKind::Struct(se) => {
296297
let rest = match &se.rest {
297298
StructRest::Base(e) => Some(self.lower_expr(e)),

0 commit comments

Comments
 (0)