Diagnostics & Quick Fixes
Relevant source files
The following files were used as context for generating this wiki page:
Diagnostics in Pop Lang are treated as structured semantic APIs rather than simple formatted strings. They serve as a bridge between the compiler's analysis and the user experience in terminals, IDEs, and build servers. The system is designed to provide clear answers regarding what is wrong, why it is wrong, and how it can be corrected through automated or manual actions.
Sources: architecture/17-diagnostics-warnings-and-quick-fixes.md:5-13, AGENTS.md:389-391
Structured Diagnostic Model
The core of the system is a structured Diagnostic object that contains all necessary metadata for rendering and machine consumption. Unlike traditional compilers that emit strings directly from passes, Pop Lang passes return typed arguments and spans to a shared sink.
Components of a Diagnostic
A diagnostic consists of several key fields used to describe an issue:
- DiagnosticCode: A stable, uppercase ID (e.g.,
POP2001). - Severity: The impact of the diagnostic (Error, Warning, Information, Hint).
- PrimarySpan: The specific source location causing the issue.
- OriginChain: A mapping back through source-origin chains for generated or desugared code.
- QuickFixes: A list of actionable corrections.
Sources: architecture/17-diagnostics-warnings-and-quick-fixes.md:15-32, architecture/decisions/0010-structured-diagnostics-and-fixes.md:12-16
Severity Levels
| Severity | Description |
|---|---|
| Error | Artifact cannot be produced; the program is invalid. |
| Warning | Program is valid but likely incorrect, unsafe, or fragile. |
| Information | Relevant build information without a defect. |
| Hint | Low-noise editor guidance, often hidden in CLI output. |
Sources: architecture/17-diagnostics-warnings-and-quick-fixes.md:36-45
Diagnostic Categories and Ranges
Pop Lang uses stable code ranges to categorize issues, facilitating easy identification and suppression policies.
| Range | Category |
|---|---|
POP0001–POP0999 | Lexing, parsing, syntax, formatting |
POP1000–POP1999 | Namespaces, symbols, visibility, libraries |
POP2000–POP2999 | Types, inference, generics, conversions |
POP3000–POP3999 | Flow, initialization, effects, coroutines |
POP4000–POP4999 | UDAs, compile-time evaluation |
POP5000–POP5999 | Unsafe code, FFI, GC, concurrency |
POP6000–POP6999 | Style, API design, performance, documentation |
POP7000–POP7999 | MIR, backend, linker, target capability |
Sources: architecture/17-diagnostics-warnings-and-quick-fixes.md:51-62, crates/compiler/documentation/src/lib.rs:567-586
Architecture and Data Flow
Diagnostics are produced by various compiler subsystems and collected by the driver. The driver is responsible for sorting and rendering them after query results stabilize.
The diagram shows how various compiler subsystems feed diagnostics into a shared sink for processing by the Driver.
Sources: architecture/17-diagnostics-warnings-and-quick-fixes.md:113-128, crates/compiler/driver/src/front_end.rs:163-170
Error Recovery
The compiler is designed to continue analysis after encountering errors to provide comprehensive IDE feedback. It uses ErrorType to satisfy follow-on constraints and employs "cascade control" to prevent a single root cause from generating dozens of fictional errors.
Sources: architecture/17-diagnostics-warnings-and-quick-fixes.md:132-143
Warning System and Waves
New warnings are introduced via "Warning Waves." This allows users to opt-in to newer, potentially breaking warnings (when treated as errors) in a controlled manner.
Warning Groups
Warnings are organized into PascalCase groups such as Correctness, Nullability, ApiDesign, and Style. ApiDesign warnings are particularly used to enforce Pop Lang's non-OOP default, flagging unnecessary class ceremony or stateless utility classes.
Sources: architecture/17-diagnostics-warnings-and-quick-fixes.md:155-171
Scoped Suppression
Warnings can be suppressed at the declaration or file scope using the @SuppressWarning attribute.
- Requirement: A reason string is mandatory.
- Restriction: Errors and compiler incidents (internal bugs) cannot be suppressed.
Sources: architecture/17-diagnostics-warnings-and-quick-fixes.md:195-207
Quick Fix Model
Quick fixes are versioned text edits that are semantically aware. They are categorized by their applicability to ensure safety when auto-applying fixes.
The relationship between a Quick Fix and its safety/applicability level.
Sources: architecture/17-diagnostics-warnings-and-quick-fixes.md:215-230, architecture/decisions/0010-structured-diagnostics-and-fixes.md:17-21
Applicability Levels
- Safe: Semantics are preserved; the correction is uniquely proved. Eligible for "Fix All."
- RequiresReview: A likely correction that requires a meaningful behavior choice from the user.
- Unsafe: Potentially destructive edits that are never included in "Fix All."
Sources: architecture/17-diagnostics-warnings-and-quick-fixes.md:224-228, architecture/decisions/0027-ratatui-terminal-presentation.md:78-86
Presentation and Rendering
Pop Lang supports multiple output formats to accommodate different tooling needs. The same diagnostic object is used to render:
- Terminal Text: Compact, high-quality layout with color-coded underlines and labels.
- JSON/SARIF: Machine-readable formats for CI/CD and security tooling.
- LSP: Interactive diagnostics and code actions for editors.
- Ratatui: Interactive terminal UI for reviewing workspace edits and selecting fixes.
Sources: architecture/17-diagnostics-warnings-and-quick-fixes.md:283-294, architecture/decisions/0027-ratatui-terminal-presentation.md:12-16
Deterministic Ordering
To ensure consistent output across parallel builds, diagnostics are sorted by:
- Package/Bubble/Module order (from build graph).
- Normalized file path.
- Source span (start/end).
- Severity and Diagnostic Code.
Sources: architecture/17-diagnostics-warnings-and-quick-fixes.md:298-306, crates/compiler/driver/src/front_end.rs:748-757
Summary
The Diagnostics and Quick Fixes system in Pop Lang is a robust, structured framework that treats compiler feedback as a first-class API. By categorizing issues into stable ranges, utilizing warning waves for evolution, and providing semantically-aware quick fixes with clear applicability levels, the project ensures a high-quality developer experience while maintaining strict architectural invariants. This system is critical for enforcing the project's "No Lua regression" policy and maintaining strong static typing throughout the ecosystem.