Skip to content

Add error catalog documentation#254

Merged
soareschen merged 5 commits into
mainfrom
error-catalog
Jul 5, 2026
Merged

Add error catalog documentation#254
soareschen merged 5 commits into
mainfrom
error-catalog

Conversation

@soareschen

Copy link
Copy Markdown
Collaborator

AI Summary

This PR adds a new error catalog to the CGP knowledge base: a fifth top-level documentation section, under docs/errors/, that documents the compiler errors CGP produces after a macro has expanded, organized by the kind of error a user sees rather than by the macro that produced it. It is a documentation-and-tests change only — no library crate, proc-macro, or runtime code is touched, so CGP's behavior is unchanged. The diff spans 49 files (+1582/−95): eleven new files establish the catalog, one new sub-skill teaches an agent to extract errors, several existing documents are rewired to point at the catalog, and the compile-fail test suite gains the fixtures that back the newly documented classes.

The work is deliberately incremental. This PR builds the catalog's framework and writes its first nine error classes; it does not finish migrating every failure-mode note out of the per-macro implementation docs. The catalog's README tracks which classes are done, and until a class is migrated its fixture keeps its old cross-link, so the two documentation systems stay consistent during the rollout.

High-level concepts

The catalog exists because a CGP macro expands to ordinary Rust, so most mistakes are not caught by the macro — they surface later, when the compiler type-checks the generated code, in diagnostics shaped by CGP's machinery in ways that are hard to read. A single mistake deep in a dependency graph can print a wall of errors naming generated types the user never wrote, and the true cause is often buried or suppressed entirely. The catalog names and maps these post-codegen failures so a reader can recognize a class on sight and know what to do about it.

The central organizing idea is the hidden-versus-surfaced axis: whether the compiler's diagnostic actually contains the root cause of a failure. When broken wiring is forced through a check trait — check_components! asserting CanUseComponent, which walks IsProviderFor — the compiler evaluates the provider's where clause and surfaces the concrete missing bound. When the same broken wiring is instead exercised by calling the consumer-trait method directly, the compiler sees the consumer trait's blanket impl among the candidates, finds it inapplicable, and falls back to a heuristic that reports only "the method's bounds were not satisfied" — hiding the dependency that actually failed. The same mistake therefore produces two completely different diagnostics, and the catalog isolates the hidden classes so a reader knows not to hunt for a cause that is not there.

A second recurring difficulty the catalog addresses is verbosity: because wiring is lazy, one unmet dependency surfaces at every provider that transitively needs it, so the compiler prints one error block per affected provider even though there is only one thing to fix. The catalog teaches that the error count reflects the depth of the dependency graph, not the number of mistakes, and shows how to find the single concrete-item block among the repeats.

The catalog is written for three readers at once, which is what distinguishes it from a debugging tutorial. The first is a future cargo-cgp tool author who needs a complete map of which classes hide the root cause and where it sits before a post-processor can decide what to extract, suppress, and re-present. The second is an agent debugging CGP code, here or in any downstream project. The third is an error-extraction sub-agent that reads a long error on the main agent's behalf and returns only its compact anatomy. Because all three need the same few facts — the class, whether the root cause is present, and its position — every document records exactly those and, as a firm rule, never pastes verbatim compiler output.

Finally, the catalog inherits CGP's existing acceptable/problematic/rejection split to decide where each failure is documented. An acceptable failure — one CGP intentionally defers to the compiler because it lacks a whole-program view — is documented here in full. A problematic failure — a CGP defect — has its observable error cataloged here while the explanation of why it is a defect stays under the owning macro's Known issues. A failure a macro catches by rejecting its input is not cataloged here at all; it stays with the macro. This keeps the catalog the canonical home for post-codegen compile-fail fixtures without duplicating or losing information.

The nine documented classes

The catalog is split into three subdirectories by the axis above, and this PR populates each. The hidden/ directory holds the one class whose diagnostic suppresses the cause. The checks/ directory holds the classes where a check surfaces the cause, plus the volume-dominated cascade. The wiring/ directory holds the whole-program structural failures with definite error codes.

The classes written in this PR are the following. In hidden/: unsatisfied dependency (E0599/E0277), the hidden case where a direct method call reports only that the method's bounds are unmet. In checks/: check-trait failure (E0277), its surfaced twin where a check names the concrete missing bound in a help: note; verbose dependency cascade, one deep mistake reported at every dependent provider; and unregistered namespace path (E0277), a #[prefix] redirect that lands on a path no entry binds. In wiring/: conflicting wiring (E0119/E0428), a key or name wired twice; orphan-rule violation (E0210/E0117), a prefixed #[default_impl] registered from the wrong crate; wiring cycle (E0275), a UseContext delegation that chases its own tail; namespace inheritance cycle (E0275), a circular parent chain caught eagerly at the cgp_namespace! definitions; and unconstrained generic (E0207), a per-entry generic that never reaches the key. Each document follows one fixed shape — what triggers it, the diagnostic, where the root cause is, resolving it, notes for tooling, backing fixtures, and related links — so a reader can navigate any of them by habit.

Structural changes

Beyond the new catalog directory, the PR rewires the surrounding knowledge base so every path into these errors now leads to the catalog. The structural changes are these.

  • New docs/errors/ section. Eleven new files: a README.md (the catalog's overview and index), an AGENTS.md (its authoring rules), and nine class documents across the hidden/, checks/, and wiring/ subdirectories.
  • New error-extraction sub-skill. docs/skills/cgp/references/error-extraction.md teaches an agent to reduce a long CGP error to a compact summary and, crucially, to delegate the reading to a sub-agent so a wall of generated-type errors never floods the main context. It is registered in the /cgp skill's router (SKILL.md).
  • Knowledge base is now five sections, not four. docs/README.md and docs/AGENTS.md are updated to introduce the errors directory, state the dividing line with the rest of the base (compiler-raised failures live here; macro-rejected input stays with the macro), and note the class-by-class migration.
  • Implementation entrypoint docs slimmed. The six docs/implementation/entrypoints/ documents (cgp_component, cgp_impl, cgp_namespace, check_components, delegate_and_check_components, delegate_components) have their ## Failure modes prose replaced by short cross-links to the catalog class, while retaining what the implementation doc uniquely owns — the error-span mechanics and, for a defect, the Known-issues explanation.
  • Debugging guide decoder updated. docs/guides/debugging.md gains a new E0599 "hidden" entry, expands the E0277 entry to cover CanUseComponent and namespace PathCons lookups, links every error-code entry to its catalog class, and flags the compiler's "increase the recursion limit" advice as wrong for a true cycle.
  • Reference and process docs updated. docs/reference/macros/cgp_namespace.md expands its Known issues with the unregistered-path and inheritance-cycle failures and the bare-key for-loop overlap; docs/implementation/AGENTS.md records the migration policy; crates/tests/AGENTS.md adds a rule to keep fixture subdirectories small (nest-split past ~a dozen) and to catalog post-codegen fixtures in docs/errors/.
  • Compile-fail fixtures added and re-linked. Five new fixtures with pinned .stderr back the newly documented classes — use_context_cycle, inheritance_cycle, unregistered_prefix_path, for_loop_bare_key, and dependency_cascade — and nine existing fixtures have their header comments re-pointed from the implementation docs to the catalog class they exercise.

Impacts

The changes ripple out to documentation structure, the test suite, and how agents work, without touching any shipped code. The concrete impacts are the following.

  • A canonical, reader-facing home for post-codegen errors now exists. A debugging agent or user can look up an error by its class and code, learn immediately whether the root cause is even present in the output, and jump to where it sits — rather than re-deriving that from a raw dump each time.
  • The per-macro implementation docs are no longer the place to read about post-codegen failures. They now delegate the "what the user sees" prose to the catalog and keep only span mechanics and defect explanations, so the two views stop duplicating each other. This is the intended split, but it means a reader must follow the cross-link to get the full anatomy.
  • CGP's own documentation contract changed shape. The knowledge base is now described as five sections everywhere it is counted, and the synchronization rule now binds a fifth view: a catalog document whose diagnostic the compiler no longer produces is a bug in the change that made it stale.
  • The test suite gains five compile-fail cases for previously untested classes. The wiring cycle, namespace inheritance cycle, unregistered namespace path, blanket-versus-blanket for-loop overlap, and the six-block dependency cascade are now pinned by .stderr snapshots, so a regression in any of these diagnostics changes a fixture. Verification is cargo nextest run -p cgp-compile-fail-tests, and the .stderr files are toolchain-pinned (regenerate with TRYBUILD=overwrite).
  • Every documented class is now backed by at least one fixture, and every post-codegen fixture cross-links to its class. The catalog and the compile-fail tree are kept mutually indexed, which is the invariant crates/tests/AGENTS.md and docs/errors/AGENTS.md now enforce.
  • Agents get a documented workflow for long errors. The new error-extraction sub-skill gives the /cgp skill an explicit "hand a long error to a sub-agent, act on the summary" pattern and the hidden-versus-surfaced shape knowledge, so agents stop reading cascades inline or chasing a cause a hidden error does not contain.
  • The migration is unfinished by design. Only the classes listed above are migrated; other implementation docs still carry their own failure-mode prose, and the catalog README is the status tracker. Reviewers should read this as the framework plus its first classes, not a completed consolidation.

Verification note

Because the change is confined to Markdown documentation and trybuild fixtures, there is no runtime surface to exercise; the meaningful check is that the new and existing compile-fail fixtures still fail to compile with the pinned diagnostics, via cargo nextest run -p cgp-compile-fail-tests. This report describes the committed state of the error-catalog branch relative to main; the fixtures were not re-run as part of writing it.

@soareschen soareschen added the AI label Jul 5, 2026
@soareschen soareschen merged commit e3dbeb9 into main Jul 5, 2026
3 checks passed
@soareschen soareschen deleted the error-catalog branch July 5, 2026 21:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant