Skip to content

Commit 8efc383

Browse files
committed
Move FormatArgs structure to its own module.
1 parent 3ffcb65 commit 8efc383

File tree

2 files changed

+172
-163
lines changed

2 files changed

+172
-163
lines changed

compiler/rustc_builtin_macros/src/format.rs

Lines changed: 13 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use rustc_ast as ast;
21
use rustc_ast::ptr::P;
32
use rustc_ast::token;
43
use rustc_ast::tokenstream::TokenStream;
4+
use rustc_ast::Expr;
55
use rustc_data_structures::fx::FxHashSet;
66
use rustc_errors::{pluralize, Applicability, MultiSpan, PResult};
77
use rustc_expand::base::{self, *};
@@ -12,6 +12,9 @@ use rustc_span::{BytePos, InnerSpan, Span};
1212
use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY;
1313
use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiagnostics, LintId};
1414

15+
mod ast;
16+
use ast::*;
17+
1518
mod expand;
1619
use expand::expand_parsed_format_args;
1720

@@ -23,160 +26,7 @@ use expand::expand_parsed_format_args;
2326
// 3. Finally, `expand_parsed_format_args` will turn that `FormatArgs` structure
2427
// into the expression that the macro expands to.
2528

26-
// Definitions:
27-
//
28-
// format_args!("hello {abc:.xyz$}!!", abc="world");
29-
// └──────────────────────────────────────────────┘
30-
// FormatArgs
31-
//
32-
// format_args!("hello {abc:.xyz$}!!", abc="world");
33-
// └─────────┘
34-
// argument
35-
//
36-
// format_args!("hello {abc:.xyz$}!!", abc="world");
37-
// └───────────────────┘
38-
// template
39-
//
40-
// format_args!("hello {abc:.xyz$}!!", abc="world");
41-
// └────┘└─────────┘└┘
42-
// pieces
43-
//
44-
// format_args!("hello {abc:.xyz$}!!", abc="world");
45-
// └────┘ └┘
46-
// literal pieces
47-
//
48-
// format_args!("hello {abc:.xyz$}!!", abc="world");
49-
// └─────────┘
50-
// placeholder
51-
//
52-
// format_args!("hello {abc:.xyz$}!!", abc="world");
53-
// └─┘ └─┘
54-
// positions (could be names, numbers, empty, or `*`)
55-
56-
/// (Parsed) format args.
57-
///
58-
/// Basically the "AST" for a complete `format_args!()`.
59-
///
60-
/// E.g., `format_args!("hello {name}");`.
61-
#[derive(Clone, Debug)]
62-
pub struct FormatArgs {
63-
pub span: Span,
64-
pub template: Vec<FormatArgsPiece>,
65-
pub arguments: Vec<(P<ast::Expr>, FormatArgKind)>,
66-
}
67-
68-
#[derive(Clone, Debug)]
69-
pub enum FormatArgsPiece {
70-
Literal(Symbol),
71-
Placeholder(FormatPlaceholder),
72-
}
73-
74-
#[derive(Clone, Debug)]
75-
pub enum FormatArgKind {
76-
/// `format_args(…, arg)`
77-
Normal,
78-
/// `format_args(…, arg = 1)`
79-
Named(Ident),
80-
/// `format_args("… {arg} …")`
81-
Captured(Ident),
82-
}
83-
84-
impl FormatArgKind {
85-
pub fn ident(&self) -> Option<Ident> {
86-
match self {
87-
&Self::Normal => None,
88-
&Self::Named(id) => Some(id),
89-
&Self::Captured(id) => Some(id),
90-
}
91-
}
92-
}
93-
94-
#[derive(Clone, Debug, PartialEq, Eq)]
95-
pub struct FormatPlaceholder {
96-
/// Index into [`FormatArgs::arguments`].
97-
pub argument: FormatArgPosition,
98-
/// The span inside the format string for the full `{…}` placeholder.
99-
pub span: Option<Span>,
100-
/// `{}`, `{:?}`, or `{:x}`, etc.
101-
pub format_trait: FormatTrait,
102-
/// `{}` or `{:.5}` or `{:-^20}`, etc.
103-
pub format_options: FormatOptions,
104-
}
105-
106-
#[derive(Clone, Debug, PartialEq, Eq)]
107-
pub struct FormatArgPosition {
108-
/// Which argument this position refers to (Ok),
109-
/// or would've referred to if it existed (Err).
110-
pub index: Result<usize, usize>,
111-
/// What kind of position this is. See [`FormatArgsPositionKind`].
112-
pub kind: FormatArgPositionKind,
113-
/// The span of the name or number.
114-
pub span: Option<Span>,
115-
}
116-
117-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
118-
pub enum FormatArgPositionKind {
119-
/// `{}` or `{.*}`
120-
Implicit,
121-
/// `{1}` or `{:1$}` or `{:.1$}`
122-
Number,
123-
/// `{a}` or `{:a$}` or `{:.a$}`
124-
Named,
125-
}
126-
127-
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
128-
pub enum FormatTrait {
129-
/// `{}`
130-
Display,
131-
/// `{:?}`
132-
Debug,
133-
/// `{:e}`
134-
LowerExp,
135-
/// `{:E}`
136-
UpperExp,
137-
/// `{:o}`
138-
Octal,
139-
/// `{:p}`
140-
Pointer,
141-
/// `{:b}`
142-
Binary,
143-
/// `{:x}`
144-
LowerHex,
145-
/// `{:X}`
146-
UpperHex,
147-
}
148-
149-
#[derive(Clone, Debug, Default, PartialEq, Eq)]
150-
pub struct FormatOptions {
151-
/// The width. E.g. `{:5}` or `{:width$}`.
152-
pub width: Option<FormatCount>,
153-
/// The precision. E.g. `{:.5}` or `{:.precision$}`.
154-
pub precision: Option<FormatCount>,
155-
/// The alignment. E.g. `{:>}` or `{:<}` or `{:^}`.
156-
pub alignment: Option<FormatAlignment>,
157-
/// The fill character. E.g. the `.` in `{:.>10}`.
158-
pub fill: Option<char>,
159-
/// The `+`, `-`, `0`, `#`, `x?` and `X?` flags.
160-
pub flags: u32,
161-
}
162-
163-
#[derive(Clone, Debug, PartialEq, Eq)]
164-
pub enum FormatAlignment {
165-
/// `{:<}`
166-
Left,
167-
/// `{:>}`
168-
Right,
169-
/// `{:^}`
170-
Center,
171-
}
172-
173-
#[derive(Clone, Debug, PartialEq, Eq)]
174-
pub enum FormatCount {
175-
/// `{:0}` or `{:.0}`
176-
Literal(usize),
177-
/// `{:.*}`, `{:.0$}`, or `{:a$}`, etc.
178-
Argument(FormatArgPosition),
179-
}
29+
// See format/ast.rs forthe FormatArgs structure.
18030

18131
// Only used in parse_args and report_invalid_references,
18232
// to indicate how a referred argument was used.
@@ -201,8 +51,8 @@ fn parse_args<'a>(
20151
ecx: &mut ExtCtxt<'a>,
20252
sp: Span,
20353
tts: TokenStream,
204-
) -> PResult<'a, (P<ast::Expr>, Vec<(P<ast::Expr>, FormatArgKind)>)> {
205-
let mut args = Vec::<(P<ast::Expr>, FormatArgKind)>::new();
54+
) -> PResult<'a, (P<Expr>, Vec<(P<Expr>, FormatArgKind)>)> {
55+
let mut args = Vec::<(P<Expr>, FormatArgKind)>::new();
20656

20757
let mut p = ecx.new_parser_from_tts(tts);
20858

@@ -305,8 +155,8 @@ fn parse_args<'a>(
305155

306156
pub fn make_format_args(
307157
ecx: &mut ExtCtxt<'_>,
308-
efmt: P<ast::Expr>,
309-
mut args: Vec<(P<ast::Expr>, FormatArgKind)>,
158+
efmt: P<Expr>,
159+
mut args: Vec<(P<Expr>, FormatArgKind)>,
310160
append_newline: bool,
311161
) -> Result<FormatArgs, ()> {
312162
let start_of_named_args =
@@ -341,8 +191,8 @@ pub fn make_format_args(
341191
};
342192

343193
let str_style = match fmt_style {
344-
ast::StrStyle::Cooked => None,
345-
ast::StrStyle::Raw(raw) => Some(raw as usize),
194+
rustc_ast::StrStyle::Cooked => None,
195+
rustc_ast::StrStyle::Raw(raw) => Some(raw as usize),
346196
};
347197

348198
let fmt_str = fmt_str.as_str(); // for the suggestions below
@@ -669,7 +519,7 @@ pub fn make_format_args(
669519
ecx.buffered_early_lint.push(BufferedEarlyLint {
670520
span: arg_name.span.into(),
671521
msg: format!("named argument `{}` is not used by name", arg_name.name).into(),
672-
node_id: ast::CRATE_NODE_ID,
522+
node_id: rustc_ast::CRATE_NODE_ID,
673523
lint_id: LintId::of(&NAMED_ARGUMENTS_USED_POSITIONALLY),
674524
diagnostic: BuiltinLintDiagnostics::NamedArgumentUsedPositionally {
675525
position_sp_to_replace,
@@ -850,7 +700,7 @@ fn report_invalid_references(
850700
template: &[FormatArgsPiece],
851701
fmt_span: Span,
852702
num_explicit_args: usize,
853-
args: &[(P<ast::Expr>, FormatArgKind)],
703+
args: &[(P<Expr>, FormatArgKind)],
854704
parser: parse::Parser<'_>,
855705
) {
856706
let num_args_desc = match num_explicit_args {
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
use rustc_ast::ptr::P;
2+
use rustc_ast::Expr;
3+
use rustc_span::symbol::{Ident, Symbol};
4+
use rustc_span::Span;
5+
6+
// Definitions:
7+
//
8+
// format_args!("hello {abc:.xyz$}!!", abc="world");
9+
// └──────────────────────────────────────────────┘
10+
// FormatArgs
11+
//
12+
// format_args!("hello {abc:.xyz$}!!", abc="world");
13+
// └─────────┘
14+
// argument
15+
//
16+
// format_args!("hello {abc:.xyz$}!!", abc="world");
17+
// └───────────────────┘
18+
// template
19+
//
20+
// format_args!("hello {abc:.xyz$}!!", abc="world");
21+
// └────┘└─────────┘└┘
22+
// pieces
23+
//
24+
// format_args!("hello {abc:.xyz$}!!", abc="world");
25+
// └────┘ └┘
26+
// literal pieces
27+
//
28+
// format_args!("hello {abc:.xyz$}!!", abc="world");
29+
// └─────────┘
30+
// placeholder
31+
//
32+
// format_args!("hello {abc:.xyz$}!!", abc="world");
33+
// └─┘ └─┘
34+
// positions (could be names, numbers, empty, or `*`)
35+
36+
/// (Parsed) format args.
37+
///
38+
/// Basically the "AST" for a complete `format_args!()`.
39+
///
40+
/// E.g., `format_args!("hello {name}");`.
41+
#[derive(Clone, Debug)]
42+
pub struct FormatArgs {
43+
pub span: Span,
44+
pub template: Vec<FormatArgsPiece>,
45+
pub arguments: Vec<(P<Expr>, FormatArgKind)>,
46+
}
47+
48+
#[derive(Clone, Debug)]
49+
pub enum FormatArgsPiece {
50+
Literal(Symbol),
51+
Placeholder(FormatPlaceholder),
52+
}
53+
54+
#[derive(Clone, Debug)]
55+
pub enum FormatArgKind {
56+
/// `format_args(…, arg)`
57+
Normal,
58+
/// `format_args(…, arg = 1)`
59+
Named(Ident),
60+
/// `format_args("… {arg} …")`
61+
Captured(Ident),
62+
}
63+
64+
impl FormatArgKind {
65+
pub fn ident(&self) -> Option<Ident> {
66+
match self {
67+
&Self::Normal => None,
68+
&Self::Named(id) => Some(id),
69+
&Self::Captured(id) => Some(id),
70+
}
71+
}
72+
}
73+
74+
#[derive(Clone, Debug, PartialEq, Eq)]
75+
pub struct FormatPlaceholder {
76+
/// Index into [`FormatArgs::arguments`].
77+
pub argument: FormatArgPosition,
78+
/// The span inside the format string for the full `{…}` placeholder.
79+
pub span: Option<Span>,
80+
/// `{}`, `{:?}`, or `{:x}`, etc.
81+
pub format_trait: FormatTrait,
82+
/// `{}` or `{:.5}` or `{:-^20}`, etc.
83+
pub format_options: FormatOptions,
84+
}
85+
86+
#[derive(Clone, Debug, PartialEq, Eq)]
87+
pub struct FormatArgPosition {
88+
/// Which argument this position refers to (Ok),
89+
/// or would've referred to if it existed (Err).
90+
pub index: Result<usize, usize>,
91+
/// What kind of position this is. See [`FormatArgsPositionKind`].
92+
pub kind: FormatArgPositionKind,
93+
/// The span of the name or number.
94+
pub span: Option<Span>,
95+
}
96+
97+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
98+
pub enum FormatArgPositionKind {
99+
/// `{}` or `{.*}`
100+
Implicit,
101+
/// `{1}` or `{:1$}` or `{:.1$}`
102+
Number,
103+
/// `{a}` or `{:a$}` or `{:.a$}`
104+
Named,
105+
}
106+
107+
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
108+
pub enum FormatTrait {
109+
/// `{}`
110+
Display,
111+
/// `{:?}`
112+
Debug,
113+
/// `{:e}`
114+
LowerExp,
115+
/// `{:E}`
116+
UpperExp,
117+
/// `{:o}`
118+
Octal,
119+
/// `{:p}`
120+
Pointer,
121+
/// `{:b}`
122+
Binary,
123+
/// `{:x}`
124+
LowerHex,
125+
/// `{:X}`
126+
UpperHex,
127+
}
128+
129+
#[derive(Clone, Debug, Default, PartialEq, Eq)]
130+
pub struct FormatOptions {
131+
/// The width. E.g. `{:5}` or `{:width$}`.
132+
pub width: Option<FormatCount>,
133+
/// The precision. E.g. `{:.5}` or `{:.precision$}`.
134+
pub precision: Option<FormatCount>,
135+
/// The alignment. E.g. `{:>}` or `{:<}` or `{:^}`.
136+
pub alignment: Option<FormatAlignment>,
137+
/// The fill character. E.g. the `.` in `{:.>10}`.
138+
pub fill: Option<char>,
139+
/// The `+`, `-`, `0`, `#`, `x?` and `X?` flags.
140+
pub flags: u32,
141+
}
142+
143+
#[derive(Clone, Debug, PartialEq, Eq)]
144+
pub enum FormatAlignment {
145+
/// `{:<}`
146+
Left,
147+
/// `{:>}`
148+
Right,
149+
/// `{:^}`
150+
Center,
151+
}
152+
153+
#[derive(Clone, Debug, PartialEq, Eq)]
154+
pub enum FormatCount {
155+
/// `{:0}` or `{:.0}`
156+
Literal(usize),
157+
/// `{:.*}`, `{:.0$}`, or `{:a$}`, etc.
158+
Argument(FormatArgPosition),
159+
}

0 commit comments

Comments
 (0)