Repository: typst/typst
File: crates/typst-syntax/src/parser.rs (Rust)

Code before:

    /// Generate an error for an exceeded maximum depth check.
    ///
    /// This function has to guarantee some sort of forward progress, otherwise
    /// the parser might loop indefinitely. One token is eaten in all cases, if
    /// that token is an opening delimiter, try to balance the opening and
    /// closing grouping delimiters before continuing.
    fn depth_check_error(&mut self, stop_set: Option<SyntaxSet>) {
        let m = self.marker();

        let mut balance: usize = 0;
        let mut eat_balanced = |p: &mut Parser| -> bool {
            if p.at_set(syntax_set!(LeftBracket, LeftBrace, LeftParen)) {
                balance = balance.saturating_add(1);
            } else if p.at_set(syntax_set!(RightBracket, RightBrace, RightParen)) {
                balance = balance.saturating_sub(1);
            }
            p.eat();
            balance == 0
        };
        self.with_nl_mode(AtNewline::Continue, |p| {
            while {
                let balanced = eat_balanced(p);
                let at_stop = stop_set.is_none_or(|s| p.at_set(s));
                !(balanced && at_stop || p.end())
            } {}
        });

        self.wrap(m, SyntaxKind::Text);
        let node = self.nodes.last_mut().unwrap();
        node.convert_to_error("maximum parsing depth exceeded");
    }
}


Review comment (suggestion):
I think a `loop` with an explicit break is easier to follow here, especially because it removes the negation.

This also makes it slightly better to inline `eat_balanced`, but I'm fine with it as-is.

```suggestion
            loop {
                let balanced = eat_balanced(p);
                let at_stop = stop_set.is_none_or(|s| p.at_set(s));
                if balanced && at_stop || p.end() {
                    break;
                }
            }
```

Code after:
    /// return a handle that automatically decreases it again when dropped.
    fn increase_depth(&mut self) -> Option<impl DerefMut<Target = Self>> {
        if self.depth < MAX_DEPTH {
            self.depth += 1;
            Some(defer(self, |p| p.depth -= 1))
        } else {
            self.depth_check_error(None);
            None
        }
    }

    /// Generate an error for an exceeded maximum depth check.
    fn depth_check_error(&mut self, stop_set: Option<SyntaxSet>) {
        let m = self.marker();

        let mut balance: usize = 0;
        // This function has to guarantee some sort of forward progress,
        // otherwise the parser might loop indefinitely. One token is eaten in
        // all cases, if that token is an opening delimiter, try to balance the
        // opening and closing grouping delimiters before continuing.
        self.with_nl_mode(AtNewline::Continue, |p| {
            loop {
                if p.at_set(syntax_set!(LeftBracket, LeftBrace, LeftParen)) {
                    balance = balance.saturating_add(1);
                } else if p.at_set(syntax_set!(RightBracket, RightBrace, RightParen)) {
                    balance = balance.saturating_sub(1);
                }
                p.eat();

                let at_stop = stop_set.is_none_or(|s| p.at_set(s));
                if (balance == 0 && at_stop) || p.end() {
                    break;
                }
            }
        });

        self.wrap_error(m, "maximum parsing depth exceeded");
    }
}