Skip to content

Scoreboard harness: sibling corpus modules and stdlib on the module path #83

Closed

Description

@biuld

Part of #74 (Phase 1). Harness-only: no compiler semantics change. Two defects cost 243 of the 377 unresolved passing files.

1. Load a case's sibling modules from the containing directory (13 files)

support_sources (crates/psrs-driver/tests/suite.rs:351) loads path.with_extension("") as a directory. That matches the corpus layout for cases that ship a support directory, but misses cases whose sibling modules sit in the same directory:

  • passing/Import/M2.purs imports M1, which is passing/Import/M1.purs
  • passing/Coercible/Lib.purs imports Coercible.Lib2, which is passing/Coercible/Lib2.purs

Load the containing directory's other .purs files alongside the same-stem directory. Watch for name collisions and for cases where a sibling is deliberately broken.

2. Put stdlib/lib on the scoreboard module path (230 files)

163 files fail on Prelude, 64 on Effect.Console, and one each on Data.Symbol, Data.Unit, and Effect. stdlib/lib exists on disk and crates/psrs-driver/src/prelude.rs already reads it in trusted-prefix order, so the harness should use the same loader rather than a parallel one.

This interacts with Phase 3: the number it recovers is bounded by how much library exists, and grows as the library does. Report the blocked-on-library count separately from the blocked-on-lowering count so the two phases stay distinguishable.

Acceptance

passing resolution improves by at least 13 from defect 1 with no other change, and the scoreboard prints separate histograms for missing-library, harness-loading, and lowering blockers.

Activity

  1. added
    area:harnessScoreboard, corpus, or measurement infrastructure
    gate:L2Blocks module, import, export and name resolution (D-04 L2)
    gate:L5Blocks type classes and instances (D-04 L5)
    gate:L6/M7Blocks runtime and the standard library (D-04 L6, M7)
    gate:M8Blocks the warning and optimization gates (D-04 M8-W, M8-O)
    on Oct 1, 2026
  2. biuld commented on Oct 1, 2026

    @biuld
    OwnerAuthor

    Landed in #108, with the acceptance measured rather than assumed.

    Both defects are fixed

    Siblings. A case is assembled by the driver's own loader (load_program_files), which indexes each search directory by declared module name and follows the import graph, with the support directory searched first so a support module wins over a file beside the case. 17 sibling modules load across the corpus.

    One subtlety cost a real regression: tests/upstream/failing alone has three files declaring module M1 (ExportExplicit.purs, DuplicateModule.purs, and the support module ExportExplicit1/M1.purs). The first version resolved names against the category root too, and M2 agreement fell from 54/70 to 49/70 — ImportModule, ImportExplicit, ImportExplicit2, and ExportExplicit1/3 agreed for the wrong reason, because the root supplied a different M1 and the diagnostic each case expects stopped appearing. A case in a category root is now never given siblings; the rule has its own test.

    The library. check_program_lenient_with_prelude and check_program_kinds_lenient_with_prelude join compile_program_sources_with_prelude, reusing the same prelude::prepend. No compiler semantics change: the trusted prefix is subtracted from every diagnostic index, which the boards depend on.

    Attribution. A case is measured by its own modules; a sibling's diagnostics never decide agreement.

    Measured, over the 413 non-FFI passing files

    Sources Resolved
    own modules only, no library 36
    plus siblings, no library 45
    own modules only, with the library 42
    plus siblings, with the library 52

    Of the 361 unresolved files: 214 blocked on a library module, 2 on a sibling this compiler cannot lower yet (passing/RedefinedFixity/M2.purs and M3.purs import a module declaring infixr ... as $, which is #86), 0 on assembly, 7 another resolution error, 4 the DEC-16 lone-surrogate cases, 134 in surface lowering.

    The acceptance is not met as written

    The issue asks for at least 13 recovered by sibling loading with no other change. Measured on its own, sibling loading recovers 9. Four of the thirteen cases still need the library on the path before they resolve, so the two defects are worth 9 and 6 individually and 16 together. Both numbers are recorded in D-04 rather than the most flattering one.

    Three histograms

    The boards now print missing library module, harness loading, and every other blocking stage, so Phase 2 and Phase 3 stay distinguishable: 216 / 0 / 134+48+7+4+3+1. The harness also names the two cases blocked on a sibling that exists on disk but does not lower, since those are Phase 2's blockers wearing the library's clothes.

    Evidence

    cargo fmt --all --check; cargo clippy --workspace --all-targets -- -D warnings; PSRS_REQUIRE_WASMTIME=1 cargo test --workspace (982 passed, 0 failed, 0 skipped); CI green on #108. Scoreboards: L1 904/908, L2 54/70 + 52/413, L3 27/48, L6 0/413.

    #93 and #83 are both closed, so Phase 1 has two slices left: #81 (map TypeCheckErrorKind to official errorCodes, 153 cases) and #82 (a lenient type-check entry point and the L4/L5 scoreboards).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:harnessScoreboard, corpus, or measurement infrastructureenhancementNew feature or requestgate:L2Blocks module, import, export and name resolution (D-04 L2)gate:L5Blocks type classes and instances (D-04 L5)gate:L6/M7Blocks runtime and the standard library (D-04 L6, M7)gate:M8Blocks the warning and optimization gates (D-04 M8-W, M8-O)

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions