()
| 2653 | } |
| 2654 | } |
| 2655 | literal.push_str(&self.process_string_escapes(&content[piece_start.min(content.len())..])); |
| 2656 | if !literal.is_empty() { |
| 2657 | segments.push(FormatSegment::Literal(literal)); |
| 2658 | } |
| 2659 | Ok(segments) |
| 2660 | } |
| 2661 | |
| 2662 | // Lex and parse one interpolation hole from its original source slice, |
| 2663 | // shifting sub-token spans to the hole's true position in the line. |
| 2664 | fn parse_hole_expression( |
| 2665 | &mut self, |
| 2666 | hole_src: &'a str, |
| 2667 | span: &Span, |
| 2668 | offset: usize, |
| 2669 | ) -> Result<Expression, ParserError> { |
| 2670 | let mut token_spans = Lexer::tokenize(hole_src); |
| 2671 | for (_, s) in &mut token_spans { |
| 2672 | s.line = span.line; |
| 2673 | s.col = span.col + 1 + offset as u32 + s.col.saturating_sub(1); |
| 2674 | s.source_line = span.source_line.clone(); |
| 2675 | } |
| 2676 | let mut sub = Parser::new_with_spans(token_spans); |
| 2677 | sub.type_names = self.type_names.clone(); |
| 2678 | sub.enum_names = self.enum_names.clone(); |
| 2679 | sub.next_lambda_id = self.next_lambda_id; |
| 2680 | let expr = sub.parse_expression()?; |
| 2681 | if !matches!(sub.peek(), Some(Token::Eof) | None) { |
| 2682 | return Err(sub.error("unexpected trailing tokens in format string interpolation")); |
nothing calls this directly
no test coverage detected