Skip to content

Commit b21ed24

Browse files
authored
Merge pull request #4116 from charliermarsh/charlie/f-string
Avoid creating unused JoinedStr in FStringParser
2 parents a414677 + 51b6571 commit b21ed24

14 files changed

Lines changed: 587 additions & 751 deletions

‎parser/src/fstring.rs‎

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::{
44
error::{FStringError, FStringErrorType, ParseError},
55
parser::parse_expression,
66
};
7+
use itertools::Itertools;
78
use std::{iter, mem, str};
89

910
struct FStringParser<'a> {
@@ -105,19 +106,16 @@ impl<'a> FStringParser<'a> {
105106
nested -= 1;
106107
if nested == 0 {
107108
formatted_value_piece.push(next);
108-
spec_constructor.push(
109-
self.expr(ExprKind::FormattedValue {
110-
value: Box::new(
111-
FStringParser::new(
112-
&formatted_value_piece,
113-
Location::default(),
114-
&self.recurse_lvl + 1,
115-
)
116-
.parse()?,
117-
),
118-
conversion: ConversionFlag::None as _,
119-
format_spec: None,
120-
}),
109+
let values = FStringParser::new(
110+
&formatted_value_piece,
111+
Location::default(),
112+
&self.recurse_lvl + 1,
113+
)
114+
.parse()?;
115+
spec_constructor.push(values
116+
.into_iter()
117+
.exactly_one()
118+
.expect("Expected formatted value to produce exactly one expression.")
121119
);
122120
formatted_value_piece.clear();
123121
} else {
@@ -129,11 +127,13 @@ impl<'a> FStringParser<'a> {
129127
}
130128
'{' => {
131129
nested += 1;
132-
spec_constructor.push(self.expr(ExprKind::Constant {
133-
value: constant_piece.to_owned().into(),
134-
kind: None,
135-
}));
136-
constant_piece.clear();
130+
if !constant_piece.is_empty() {
131+
spec_constructor.push(self.expr(ExprKind::Constant {
132+
value: constant_piece.to_owned().into(),
133+
kind: None,
134+
}));
135+
constant_piece.clear();
136+
}
137137
formatted_value_piece.push(next);
138138
formatted_value_piece.push(' ');
139139
}
@@ -144,11 +144,13 @@ impl<'a> FStringParser<'a> {
144144
}
145145
self.chars.next();
146146
}
147-
spec_constructor.push(self.expr(ExprKind::Constant {
148-
value: constant_piece.to_owned().into(),
149-
kind: None,
150-
}));
151-
constant_piece.clear();
147+
if !constant_piece.is_empty() {
148+
spec_constructor.push(self.expr(ExprKind::Constant {
149+
value: constant_piece.to_owned().into(),
150+
kind: None,
151+
}));
152+
constant_piece.clear();
153+
}
152154
if nested > 0 {
153155
return Err(UnclosedLbrace);
154156
}
@@ -241,7 +243,7 @@ impl<'a> FStringParser<'a> {
241243
Err(UnclosedLbrace)
242244
}
243245

244-
fn parse(mut self) -> Result<Expr, FStringErrorType> {
246+
fn parse(mut self) -> Result<Vec<Expr>, FStringErrorType> {
245247
if self.recurse_lvl >= 2 {
246248
return Err(ExpressionNestedTooDeeply);
247249
}
@@ -287,7 +289,7 @@ impl<'a> FStringParser<'a> {
287289
}))
288290
}
289291

290-
Ok(self.expr(ExprKind::JoinedStr { values }))
292+
Ok(values)
291293
}
292294
}
293295

@@ -298,7 +300,7 @@ fn parse_fstring_expr(source: &str) -> Result<Expr, ParseError> {
298300

299301
/// Parse an fstring from a string, located at a certain position in the sourcecode.
300302
/// In case of errors, we will get the location and the error returned.
301-
pub fn parse_located_fstring(source: &str, location: Location) -> Result<Expr, FStringError> {
303+
pub fn parse_located_fstring(source: &str, location: Location) -> Result<Vec<Expr>, FStringError> {
302304
FStringParser::new(source, location, 0)
303305
.parse()
304306
.map_err(|error| FStringError { error, location })
@@ -308,7 +310,7 @@ pub fn parse_located_fstring(source: &str, location: Location) -> Result<Expr, F
308310
mod tests {
309311
use super::*;
310312

311-
fn parse_fstring(source: &str) -> Result<Expr, FStringErrorType> {
313+
fn parse_fstring(source: &str) -> Result<Vec<Expr>, FStringErrorType> {
312314
FStringParser::new(source, Location::default(), 0).parse()
313315
}
314316

Lines changed: 44 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,54 @@
11
---
2-
source: parser/src/fstring.rs
2+
source: compiler/parser/src/fstring.rs
33
expression: parse_ast
44
---
5-
Located {
6-
location: Location {
7-
row: 0,
8-
column: 0,
5+
[
6+
Located {
7+
location: Location {
8+
row: 0,
9+
column: 0,
10+
},
11+
custom: (),
12+
node: Constant {
13+
value: Str(
14+
"user=",
15+
),
16+
kind: None,
17+
},
918
},
10-
custom: (),
11-
node: JoinedStr {
12-
values: [
13-
Located {
14-
location: Location {
15-
row: 0,
16-
column: 0,
17-
},
18-
custom: (),
19-
node: Constant {
20-
value: Str(
21-
"user=",
22-
),
23-
kind: None,
24-
},
25-
},
26-
Located {
27-
location: Location {
28-
row: 0,
29-
column: 0,
30-
},
31-
custom: (),
32-
node: Constant {
33-
value: Str(
34-
"",
35-
),
36-
kind: None,
37-
},
38-
},
39-
Located {
19+
Located {
20+
location: Location {
21+
row: 0,
22+
column: 0,
23+
},
24+
custom: (),
25+
node: Constant {
26+
value: Str(
27+
"",
28+
),
29+
kind: None,
30+
},
31+
},
32+
Located {
33+
location: Location {
34+
row: 0,
35+
column: 0,
36+
},
37+
custom: (),
38+
node: FormattedValue {
39+
value: Located {
4040
location: Location {
41-
row: 0,
42-
column: 0,
41+
row: 1,
42+
column: 2,
4343
},
4444
custom: (),
45-
node: FormattedValue {
46-
value: Located {
47-
location: Location {
48-
row: 1,
49-
column: 2,
50-
},
51-
custom: (),
52-
node: Name {
53-
id: "user",
54-
ctx: Load,
55-
},
56-
},
57-
conversion: 114,
58-
format_spec: None,
45+
node: Name {
46+
id: "user",
47+
ctx: Load,
5948
},
6049
},
61-
],
50+
conversion: 114,
51+
format_spec: None,
52+
},
6253
},
63-
}
54+
]

0 commit comments

Comments
 (0)