diff --git a/parser/Cargo.toml b/parser/Cargo.toml index b27bb50..26241c4 100644 --- a/parser/Cargo.toml +++ b/parser/Cargo.toml @@ -32,6 +32,7 @@ unic-emoji-char = "0.9.0" unic-ucd-ident = "0.9.0" unicode_names2 = "0.5.0" thiserror = "1.0" +fnv = "1.0.7" [dev-dependencies] insta = "1.14.0" diff --git a/parser/src/function.rs b/parser/src/function.rs index 28cb44f..b2b24a8 100644 --- a/parser/src/function.rs +++ b/parser/src/function.rs @@ -1,7 +1,6 @@ use crate::ast; use crate::error::{LexicalError, LexicalErrorType}; -use ahash::RandomState; -use std::collections::HashSet; +use fnv::FnvHashSet; pub struct ArgumentList { pub args: Vec, @@ -54,7 +53,8 @@ pub fn parse_args(func_args: Vec) -> Result { diff --git a/parser/src/string.rs b/parser/src/string.rs index 078ac1e..e76821d 100644 --- a/parser/src/string.rs +++ b/parser/src/string.rs @@ -14,6 +14,19 @@ pub fn parse_strings( let initial_end = values[0].2; let initial_kind = (values[0].1 .1 == StringKind::U).then(|| "u".to_owned()); + // Optimization: fast-track the common case of a single string. + if values.len() == 1 && matches!(&values[0].1 .1, StringKind::Normal | StringKind::U) { + let value = values.into_iter().last().unwrap().1 .0; + return Ok(Expr::new( + initial_start, + initial_end, + ExprKind::Constant { + value: Constant::Str(value), + kind: initial_kind, + }, + )); + } + // Determine whether the list of values contains any f-strings. (If not, we can return a // single Constant at the end, rather than a JoinedStr.) let mut has_fstring = false;