Skip to content

openapi: the $dynamicAnchor memo is a parameter of 72 functions and is read by two #982

Closed

Description

@OmarAlJarrah

Problem

*schema.AnchorIndex, the memo behind $dynamicRef expansion, is a parameter of 72 production functions: 48 in schema and 24 in operation. Two of them read it, soleAnchorSite and dynamicHop. The other 70 pass it on, and run in compilers/openapi/openapi.go owns it as a local so that it can.

lowering.Ctx already holds three memos that copies share on purpose: defsReader, typePositions and reached. #172 planned this one as a Ctx accessor too (AnchorsNamed(name)). It was kept out because building it reports a diagnostic for a bound, which is reported once, at first use. A Ctx method can return that diagnostic the way AnchorIndex.sites does now.

A trial moved the memo into Ctx (morphic @201bb745). The walk had to go to a new leaf package, because lowering may not import nodeview or yaml. go build ./..., go vet ./compilers/..., go test ./... (36 packages) and internal/archtest passed. The diff was +30 production, +50 test and +14 archtest lines. Removing a parameter rewrites the lines that carry it and deletes none, and the new package, accessor and tests cost more than the parameter saves. The trial exposed two couplings:

  • TestLoweringCallGraph_ReadsEveryPackageThatLowers finds the packages the recursion pin reads by looking for a lowering.Ctx parameter. The moved walk has none, so it silently leaves the pin unless the package is listed by name.
  • TestValueKindSwitches_NameEveryValueKind treats "reaches ir" as "sees ir.ValueKind". A package that reaches ir only through ids fails its require.

The files involved have no non-comment change between @201bb745 and @3a706a7b, and the parameter counts hold at both. The line counts are from @201bb745.

Direction

A draft. Do not land it alone: it is a signature simplification that costs lines. #981 rewrites the same signatures to drop the hint parameter, and doing both in one pass pays for the rewrite once. If #981 is not taken, leave this as it is.

If it is taken: a leaf package for the walk and the memo, a Ctx.DynamicAnchorSites(name) that returns the sites and the once-only bounds diagnostic, the package named in the recursion pin, and the ValueKind test reading "sees" instead of "reaches".

Out of scope

Bundling lowering.Ctx, *compile.Types, the memo and depth into one struct. Ctx is deliberately a value, and a type under compilers/ may carry at most 20 methods.

Related: #981, #172, #454

Priority: P4, rule 1 (housekeeping that unblocks nothing). git grep -nE '\.sites\(' -- compilers ':!*_test.go' → 2 lines, both in schema/schema.go (morphic @3a706a7b).

Activity

  1. added
    type:choreRefactor or cleanup, no behavior change
    priority:P4Refactors, tests, CI, hostile-input hardening, cosmetic diagnostics, other formats
    on Oct 19, 2026
  2. OmarAlJarrah commented on Oct 20, 2026

    @OmarAlJarrah
    MemberAuthor

    Once #1001 merges, TestValueKindSwitches_NameEveryValueKind is gone. The exhaustive linter replaces it: it requires every switch over an enum in package ir to name every member, module-wide. It checks the switches where they are, with no requirement that a package reaching ir see ir.ValueKind, so the ValueKind obstacle in this issue's first list falls away. The ValueKind step in "If it is taken" is no longer needed.

  3. OmarAlJarrah commented on Oct 20, 2026

    @OmarAlJarrah
    MemberAuthor

    At 83ab508 (#1016) lowering.Ctx no longer holds defsReader. The internal/defs package is deleted, and the lowering reads where a $ref lands from the load phase's bindings (lowering.Ctx.Bindings). typePositions and reached remain. The $dynamicAnchor memo and its parameters are unchanged.

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

    priority:P4Refactors, tests, CI, hostile-input hardening, cosmetic diagnostics, other formatstype:choreRefactor or cleanup, no behavior change

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions