added
S-waiting-on-review
labels
Jul 8, 2026arya dradjica added 11 commits
July 12, 2026 23:02
The code that calls `parser.bump()` or parses a non-terminal is moved from `parse_tt()` to `parse_tt_inner()`. This makes it possible to move the non-terminal parsing code even further, to `match_one()`. I marked the comment in the moved code as a `FIXME` because it reads like one. This makes `parse_tt()` look quite redundant, but once the full switch to DFS is made, I think it will handle some back-tracking logic. `tests/ui/macros` pass.
This will be used in the next commit to reference `MatcherLoc`s by index so that they can be compared and hashed efficiently.
Right now, if an ambiguity error occurs, `TtParser::{next,bb}_mps` are
relied on to extract information for diagnostics. This hinders movement
to depth-first traversal. This commit allows the `Tracker` to compute
`{next,bb}_mps` information without relying on `TtParser` to work in a
breadth-first way.
This information is recorded in a `HashSet`, mixing data from `next_mps`
and `bb_mps`. It *could* have been a `Vec` that gets cleared after a
`Parser::bump()` / non-terminal parse, but that be incompatible with
depth-first traversal in `TtParser`.
`CollectTrackerAndEmitter` can compute this data from `Tracker::matched_one()`. The collected data coalesces non-terminal `MatcherLoc`s with others, so `partition()` is used to separate them. The data is retrieved from a `HashSet`, but because the results are sorted, everything is deterministic. This removes some pressure on `TtParser` to use breadth-first traversal. `tests/ui/macros` pass.
When a meta-variable `MatcherLoc` is discovered, it would be nice to parse it immediately; but right now, it gets added to `bb_mps` and has to wait until everything in `cur_mps` is processed so `TtParser` can check for ambiguity. This commit adds an eager ambiguity checking step when a meta-variable `MatcherLoc` is being processed. This is a subtle but important change in the semantics of `match_one()`; it can now modify `cur_mps`, and effectively work from `parse_tt_inner()`. This is the first major step towards depth-first traversal.
The same infrastructure for checking for ambiguity for `MetaVarDecl` can also be used for processing `Eof`! This has several benefits: - `eof_mps` is removed and no longer needs to be passed around. - The two calls to `Tracker::failure()` are unified; specifically "reached EOF but no successful parses" and "ran out of mps". - The two calls to `TtParser::ambiguity_error()` are unified: specifically "multiple successful parses at EOF" and "multiple `MatcherLoc`s at a non-terminal parsing point". These unifications further motivate the original unification of the errors in `Tracker`, and show that the different kinds of merged errors *did* deserve to be grouped together semantically. `tests/ui/macros` pass.
If `parse_tt_inner()` -> `match_one()` -> `check_for_ambiguity()` detects ambiguity, it will clear `cur_mps`, which guarantees that the next thing to happen will be the check for ambiguity. This commit brings the ambiguity detection closer to the building of the ambiguity error by moving that code directly into `check_for_ambiguity()` (which now returns a `ParseResult`).
rust-bors Bot pushed a commit that referenced this pull request
Jul 13, 2026
rust-bors
Bot
added
S-waiting-on-bors
and removed S-waiting-on-review
Status: Awaiting review from the assignee but also interested parties.labels
Jul 14, 2026bal-e deleted the eager-ambig-detection branch
July 15, 2026 15:07This was referenced
Jul 24, 2026Open
Open