Repository navigation
Phase 2: close frontend surface-lowering coverage #75
Copy link
Copy link
Closed
7 / 77 of 7 issues completedLabels
Milestone
Description
Why this phase is next
134 of the 377 unresolved passing files stop in surface lowering, before resolution, kinds, or types ever run. They are the largest single blocker in the corpus and they gate every later phase: a file that cannot lower cannot be type-checked, cannot be compiled, and cannot be executed. No standard library or backend work makes them pass.
Measured breakdown of the 134 (passing resolution, 36/413 today):
| Stage | Files | Dominant form |
|---|---|---|
| expression | 43 | ascription e :: T, in both (e :: T) and bare e :: T form |
| pattern | 41 | multi-field constructor patterns, record patterns inside constructor patterns, pattern bindings |
| declaration | 26 | operator, constructor-operator, and type-operator aliases |
| type | 12 | type wildcards, row constructor constraints |
| guards | 10 | guarded equations and guarded case alternatives |
multi-scrutinee case |
2 | case a, b of |
Scope
Land these forms on the shared spine — AST, HIR, THIR, Core — not as special cases:
- Ascription
e :: Tin expression position, including nested chains (((e :: b -> Int) :: forall b. b -> Int)). - Multi-field constructor patterns, record patterns nested in a constructor pattern, and pattern bindings in
let/where. - Operator, constructor-operator (
infixr 6 Cons as :), and type-operator aliases, as declarations and in export/import conflict checking. - Type wildcards (
_in a type), row constructor constraints, andPrim.Row-style constraints where they do not require an open-row runtime layout. - Guards on equations and
casealternatives, including comma-separated guard lists anddoinside a guard. casewith multiple scrutinees.- Unary minus, which
pursdesugars tonegate— without it,failing/2109-negate.pursreports no diagnostic at all.
Gate
passing module resolution reaches 100% of files that do not require a missing library module, and the per-stage blocker counts above each fall to zero. New syntax lands with a purs differential case, not only a local test.
Sub-issues
Tracked as children of this epic.
References
docs/design/D-04-suite-roadmap.md— M2 measured baseline, FE-03..FE-07, FE-17crates/psrs-ast/src/lower.rs— surface lowering, source of thethis <stage> syntax is not supported yetdiagnosticscrates/psrs-syntax/src/parser/— parser coverage is ahead of lowering here; several forms already parse and fail to lowerdocs/design/frontend/semantics/— the design each form must match
Validation
cargo fmt --all --check
cargo test --workspace
cargo clippy --workspace --all-targets -- -D warnings
PSRS_ORACLE=annotations cargo test -p psrs-driver --test suite l2_resolution -- --ignored --nocapture
Reactions are currently unavailable
Activity
biuld commentedon Oct 3, 2026
Phase 2 acceptance is met. Closing the epic.
All six sub-issues are
Done: #84 (ascription), #85 (patterns), #86 (operators,constructor-operators, type-operator aliases), #87 (type wildcards,
Prim.Rowconstraints, polykind application), #88 (guarded equations, multi-scrutinee
cases), #89 (the
Primhierarchy and unary minus), #90 (instance declarationsand signatures).
The phase's own criterion — the surface-lowering blocker count — is zero,
measured on
masteratfe40d17withPSRS_ORACLE=annotations cargo test -p psrs-driver --test suite -- --ignored --nocapture:l6_runtime_scoreboardreports no P2 surface-lowering failures, down from 61 atthe
5298aadbaseline.What now holds the
passingsuiteAll 354 first-stage blockers remain, and none of them is the front end:
passingresolution is 59/413. The next phase is therefore not a front-endphase: #76 (Phase 3 — standard library), whose three issues now carry measured
Corpus cases— #95 = 305, #96 = 12, #94 = 0 by first blocking stage.#94 measures 0 for a real reason worth recording:
stdlib/lib/Prelude.pursexists and resolves, so no file's first blocker is
Prelude. Its missingclasses and value functions surface later, as the 8 unknown-name, 3 type-check,
and 1 kind-check blockers behind the library modules. Counting by first blocking
stage understates it, and #94 should be scheduled on that understanding rather
than on its board number.
Twenty-five of the 342 name a library module that no open issue owns —
Data.Eq,Data.Symbol,Data.Predicate,Data.Monoid,Data.Foldable,Data.Array,Data.Unit,Data.Ordering,Data.Newtype,Data.Generic.Rep,Data.Functor.Contravariant,Data.Function.Uncurried,Data.Bifunctor, andData.Bifoldable. That gap is filed separately rather than left implicit.The visible-type-application limits recorded in #87 are not Phase 2 work; they
are filed as their own frontend slice because they share one root cause with
#100's polykind instantiation.
feat(frontend): check the expression ascription against its written type