@@ -363,12 +363,29 @@ pub struct Parser<'a> {
363363 options: ParserOptions,
364364 /// Ensures the stack does not overflow by limiting recursion depth.
365365 recursion_counter: RecursionCounter,
366- /// Cached errors from `parse_prefix` calls that returned `Err`. See
366+ /// Cached failures from `parse_prefix` calls that returned `Err`. See
367367 /// [`Parser::parse_prefix`] for the 2^N patterns this guards.
368- failed_prefix_positions: BTreeMap<usize, ParserError >,
369- /// Cached errors from the speculative reserved-word prefix arm. See
368+ failed_prefix_positions: BTreeMap<usize, ExprPrefixError >,
369+ /// Cached failures from the speculative reserved-word prefix arm. See
370370 /// [`Parser::parse_prefix`] for the 2^N patterns this guards.
371- failed_reserved_word_prefix_positions: BTreeMap<usize, ParserError>,
371+ failed_reserved_word_prefix_positions: BTreeMap<usize, ExprPrefixError>,
372+ }
373+
374+ /// Copy marker for a [`ParserError`] cached by the `parse_prefix` failure
375+ /// memoization, so the caches hold no strings.
376+ #[derive(Debug, Clone, Copy)]
377+ enum ExprPrefixError {
378+ RecursionLimitExceeded,
379+ Err,
380+ }
381+
382+ impl From<&ParserError> for ExprPrefixError {
383+ fn from(e: &ParserError) -> Self {
384+ match e {
385+ ParserError::RecursionLimitExceeded => Self::RecursionLimitExceeded,
386+ _ => Self::Err,
387+ }
388+ }
372389}
373390
374391impl<'a> Parser<'a> {
@@ -1737,16 +1754,24 @@ impl<'a> Parser<'a> {
17371754 // chains where the reserved arm fails but the unreserved fallback
17381755 // succeeds (e.g. `case-case-...c`).
17391756 let start_index = self.index;
1740- if let Some(cached) = self.failed_prefix_positions.get(&start_index) {
1741- return Err(cached.clone( ));
1757+ if let Some(& cached) = self.failed_prefix_positions.get(&start_index) {
1758+ return Err(self.cached_prefix_error( cached, self.peek_token_ref() ));
17421759 }
17431760 let result = self.parse_prefix_inner();
17441761 if let Err(ref e) = result {
1745- self.failed_prefix_positions.insert(start_index, e.clone ());
1762+ self.failed_prefix_positions.insert(start_index, e.into ());
17461763 }
17471764 result
17481765 }
17491766
1767+ /// Rebuild the error for a cached prefix failure at the `found` token.
1768+ fn cached_prefix_error(&self, cached: ExprPrefixError, found: &TokenWithSpan) -> ParserError {
1769+ match cached {
1770+ ExprPrefixError::RecursionLimitExceeded => ParserError::RecursionLimitExceeded,
1771+ ExprPrefixError::Err => self.expected_ref::<()>("an expression", found).unwrap_err(),
1772+ }
1773+ }
1774+
17501775 fn parse_prefix_inner(&mut self) -> Result<Expr, ParserError> {
17511776 // PostgreSQL allows any string literal to be preceded by a type name, indicating that the
17521777 // string literal represents a literal of that type. Some examples:
@@ -1838,11 +1863,11 @@ impl<'a> Parser<'a> {
18381863 // succeeds, the overall `parse_prefix` returns `Ok` and the
18391864 // outer cache never fires. Chains like `case-case-...c`
18401865 // need this per-arm cache to break the doubling.
1841- let try_parse_result = if let Some(cached) = self
1866+ let try_parse_result = if let Some(& cached) = self
18421867 .failed_reserved_word_prefix_positions
18431868 .get(&next_token_index)
18441869 {
1845- Err(cached.clone( ))
1870+ Err(self.cached_prefix_error( cached, self.get_current_token() ))
18461871 } else {
18471872 self.try_parse(|parser| parser.parse_expr_prefix_by_reserved_word(&w, span))
18481873 };
@@ -1861,7 +1886,7 @@ impl<'a> Parser<'a> {
18611886 // special expression (to maintain backwards compatibility of parsing errors).
18621887 Err(e) => {
18631888 self.failed_reserved_word_prefix_positions
1864- .insert(next_token_index, e.clone ());
1889+ .insert(next_token_index, (&e).into ());
18651890 if !self.dialect.is_reserved_for_identifier(w.keyword) {
18661891 if let Ok(Some(expr)) = self.maybe_parse(|parser| {
18671892 parser.parse_expr_prefix_by_unreserved_word(&w, span)
0 commit comments