Skip to main content

Module coalesce

Module coalesce 

Source
Expand description

Cross-source diagnostic coalescing.

When a single underlying problem produces a diagnostic on many pages — for example, one bad theme: key in _quarto.yml triggering Q-14-1 once per rendered page — the renderer should collapse them into a single emission that lists the affected pages, rather than printing the same ariadne block hundreds of times.

§The primary key is the source location

Two diagnostics whose location resolves to the same source span in the same file are presumed to be the same error and are grouped together. We deliberately do not include the code or title in the grouping key — the source location alone is the relation’s primary key (decision recorded in claude-notes/plans/2026-05-22-theme-diagnostic-epic.md).

If two unrelated checks ever land at the same span this is a design risk; the v1 cost (one merged emission with a possibly mixed-content representative) is low. We will widen the key to (location, code) if it turns out to bite.

§File identity is the resolved path, not the raw FileId

A raw FileId is only globally meaningful when it is hash-based (path-derived, e.g. quarto_yaml::file_id_for_filename). Sequential per-context ids are not: every document’s primary file is FileId(0) in its own SourceContext, so keying on the raw id would falsely merge diagnostics from different files that happen to sit at identical byte offsets.

Each input entry carries its own Option<SourceContext>, so the group key resolves the file component through it: if the location’s FileId is registered in the entry’s context, the key is the registered file path; otherwise it falls back to the raw id (hash-based ids that aren’t registered in per-document contexts stay stable and collision-safe). The two key flavors never compare equal to each other.

Both fallback edges fail toward splitting groups, never toward false merges:

  • paths are compared verbatim (no canonicalization), so two contexts registering the same file under different spellings (./_quarto.yml vs _quarto.yml) form two groups;
  • the same id resolving in one entry’s context but not another’s (e.g. one entry has no context at all) forms two groups.

§What does not coalesce

Diagnostics whose location is one of:

pass through as singleton groups (one entry each). These shapes don’t reduce to a single contiguous byte range, so we can’t form a stable group key for them. This is the same conservative contract as SourceInfo::resolve_byte_range.

Structs§

CoalescedDiagnostic
One entry from a coalesced render summary.

Constants§

AFFECTED_FILES_CAP
Maximum number of file names rendered inline in the “Affected files:” tail before switching to “… (and N others)”.

Functions§

coalesce_by_source
Group the input by source location and return one CoalescedDiagnostic per group, in encounter order.