Skip to content

Commit e9d9f0d

Browse files
authored
Properly close format string delimiter (#2997)
1 parent 8eea534 commit e9d9f0d

File tree

2 files changed

+66
-14
lines changed

2 files changed

+66
-14
lines changed

src/lexer.rs

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -675,15 +675,13 @@ impl<'src> Lexer<'src> {
675675

676676
/// Lex an opening or closing delimiter
677677
fn lex_delimiter(&mut self, kind: TokenKind) -> CompileResult<'src> {
678-
use Delimiter::*;
679-
680678
match kind {
681-
BraceL => self.open_delimiter(Brace),
682-
BraceR => self.close_delimiter(Brace)?,
683-
BracketL => self.open_delimiter(Bracket),
684-
BracketR => self.close_delimiter(Bracket)?,
685-
ParenL => self.open_delimiter(Paren),
686-
ParenR => self.close_delimiter(Paren)?,
679+
BraceL => self.open_delimiter(Delimiter::Brace),
680+
BraceR => self.close_delimiter(Delimiter::Brace)?,
681+
BracketL => self.open_delimiter(Delimiter::Bracket),
682+
BracketR => self.close_delimiter(Delimiter::Bracket)?,
683+
ParenL => self.open_delimiter(Delimiter::Paren),
684+
ParenR => self.close_delimiter(Delimiter::Paren)?,
687685
_ => {
688686
return Err(self.internal_error(format!(
689687
"Lexer::lex_delimiter called with non-delimiter token: `{kind}`",
@@ -692,7 +690,9 @@ impl<'src> Lexer<'src> {
692690
}
693691

694692
// Emit the delimiter token
695-
self.lex_single(kind)
693+
self.lex_single(kind)?;
694+
695+
Ok(())
696696
}
697697

698698
/// Push a delimiter onto the open delimiter stack
@@ -900,12 +900,12 @@ impl<'src> Lexer<'src> {
900900

901901
if format && self.rest_starts_with(Self::INTERPOLATION_START) {
902902
self.presume_str(Self::INTERPOLATION_START)?;
903-
self.token(if format_string_kind.is_some() {
904-
FormatStringContinue
903+
if format_string_kind.is_some() {
904+
self.token(FormatStringContinue);
905905
} else {
906-
FormatStringStart
907-
});
908-
self.open_delimiter(Delimiter::FormatString(kind));
906+
self.token(FormatStringStart);
907+
self.open_delimiter(Delimiter::FormatString(kind));
908+
}
909909
} else {
910910
self.presume_str(kind.delimiter())?;
911911

@@ -2197,6 +2197,46 @@ mod tests {
21972197
),
21982198
}
21992199

2200+
test! {
2201+
name: format_string_followed_by_recipe,
2202+
text: "foo := f'{{'foo'}}{{'bar'}}'\nbar:",
2203+
tokens: (
2204+
Identifier: "foo",
2205+
Whitespace: " ",
2206+
ColonEquals: ":=",
2207+
Whitespace: " ",
2208+
Identifier: "f",
2209+
FormatStringStart: "'{{",
2210+
StringToken: "'foo'",
2211+
FormatStringContinue: "}}{{",
2212+
StringToken: "'bar'",
2213+
FormatStringEnd: "}}'",
2214+
Eol: "\n",
2215+
Identifier: "bar",
2216+
Colon,
2217+
),
2218+
}
2219+
2220+
test! {
2221+
name: indented_format_string_followed_by_recipe,
2222+
text: "foo := f'''{{'foo'}}{{'bar'}}'''\nbar:",
2223+
tokens: (
2224+
Identifier: "foo",
2225+
Whitespace: " ",
2226+
ColonEquals: ":=",
2227+
Whitespace: " ",
2228+
Identifier: "f",
2229+
FormatStringStart: "'''{{",
2230+
StringToken: "'foo'",
2231+
FormatStringContinue: "}}{{",
2232+
StringToken: "'bar'",
2233+
FormatStringEnd: "}}'''",
2234+
Eol: "\n",
2235+
Identifier: "bar",
2236+
Colon,
2237+
),
2238+
}
2239+
22002240
error! {
22012241
name: tokenize_space_then_tab,
22022242
input: "a:

tests/format_string.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,3 +354,15 @@ fn undefined_variable_error() {
354354
)
355355
.run();
356356
}
357+
358+
#[test]
359+
fn format_string_followed_by_recipe() {
360+
Test::new()
361+
.justfile(
362+
"
363+
foo := f'{{'foo'}}{{'bar'}}'
364+
bar:
365+
",
366+
)
367+
.run();
368+
}

0 commit comments

Comments
 (0)