v0.20.0#406
Merged
Merged
Conversation
…` and `DropLocalBlocks` stages for backend dialects that do not support these constructs
…k-join-any, since dynamic span logic is currently not supported
Add hierarchical (root-DB) clones of the cross-design RT clk/rst analyses that previously required the flat DB, computed via design-tree navigation (subDBs.get(ownerRef) down, parentSubDBOpt up) with no global member index: new_relatedAnnotMap, new_dependentRTDomainOwners, new_resolvedClkRstMap, new_isDependentOn. Gated against the flat versions by new_clkRstEquivalenceCheck (run from SanityCheck): flat XYZ == oldToNew.new_XYZ across the test corpus. Migrate three stages off the flat DB using these clones: - ExplicitClkRstCfg: drop the rebindGetSet=false hack - AddClkRst: flat Stage -> GlobalStage (per-sub-DB patching; pre-pass for cross-design clk/rst OUT tracking) - ToED: flat Stage -> HierarchyStage Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
MagnetMap.getHierarchical resolves each magnet ConnectPoint's design context (owner + container design) once under its owning sub-DB getSet, then runs the distance / inside-owner matching purely on the root-aware design tree (designBlockOwnershipMap) — no flattening, no ref-resolving global getSet. Rename the temporary equivalence gate new_clkRstEquivalenceCheck -> new_hierEquivalenceCheck and extend it to also assert magnetConnectionMap == oldToNew.new_magnetConnectionMap. Validated across the full unit suite (incl. AES's cross-design magnet hierarchies). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Expose new_magnetPointInfo (each magnet ConnectPoint -> its owner design + name), precomputed cross-design by MagnetMap.getHierarchical, so migrating consumers never re-resolve a ConnectPoint that lives in another sub-DB. - ConnectMagnets: drop the rebindGetSet=false hack; classify connections via new_magnetConnectionMap + new_magnetPointInfo and the root-aware design tree (parentOf via designBlockOwnershipMap), create connections per sub-DB. - AddMagnets: flat Stage -> GlobalStage; accumulate missing magnets once over new_magnetConnectionMap (climbing designBlockOwnershipMap), then add each design's ports under its own sub-DB getSet. No stage sets rebindGetSet=false anymore. Full unit suite green (incl. AES). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
No stage overrides rebindGetSet to false anymore (ExplicitClkRstCfg and ConnectMagnets were migrated to read the new_* root-DB analyses), so drop the knob and the outer-flat-getSet escape hatch: HierarchyStage.transformSubDB now always sees the root DB and the current sub-DB's getSet. Full unit suite green. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…ndentOn DropTimedRTWaits now reads the clk rate from the hierarchical rootDB.new_resolvedClkRstMap (lookup hoisted out of the MetaDesign into the sub-DB getSet context) instead of the flat resolvedClkRstMap. With that, the flat isDependentOn extension in DFOwnerAnalysis has no remaining caller (ExplicitClkRstCfg moved to new_isDependentOn earlier), so it is removed along with its now-unused tailrec import. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
check is now a lazy val that dispatches on the DB representation: - hierarchical root: run each sub-DB's subDBCheck, then rootDBCheck once; - in-hierarchy sub-DB: subDBCheck only; - old-style flat DB: both groups on itself (preserves today's behavior). subDBCheck holds the per-design structural checks (name, connectivity, direct-ref); rootDBCheck holds the whole-tree checks (magnet connectivity, dangling ports, derived-domain cycles, clk/rst rate, wait) plus the device-top port location/direction checks. rootDBCheck still uses the flat implementations and is dormant on the root for now — it will be rewired to the hierarchical new_* analyses and the call sites switched to oldToNew.check in a follow-up. The two callers (SanityCheck, Design) now read the lazy val. directRefCheck runs slightly earlier (before the magnet/dangling checks); the full suite confirms no check-ordering test depends on that. The device-top location/direction checks stay after domainClkRateCheck so the reported error is unchanged when a design lacks both a clock rate and a clock location. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
First rootDBCheck member rewired to run on the hierarchical root: same DFS as the flat check but over new_dependentRTDomainOwners, naming cycle members via new_fullNameViaInst routed through each owner's sub-DB (domainOwnerToSubDB). Wired into new_hierEquivalenceCheck so it runs on every design that passes the flat check, asserting it does not falsely flag a valid design. Error-message exactness for the cycle case is validated by ElaborationChecksSpec once callers switch to oldToNew.check (Step 2c). rootDBCheck itself is unchanged (still flat, still the production path) until all members are rewired. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Second rootDBCheck member rewired for the root. The flat usesClk filter is cross-design and flat-only, but is equivalent to "the resolver produced a clock" — new_resolvedClkRstMap(owner)._1.isDefined — so the resolved-clock map drives both the device-top filter and the explicit rate. Per-owner local reads (getThisOrOwnerDesign.isDeviceTop, isTop position, getFullName, the clk timing constraint) are routed through the owner's sub-DB getSet via atOwner, mirroring new_resolvedClkRstMap. Device-top domains live in the toptop's sub-DB, so their getFullName is the correct full path. Wired into new_hierEquivalenceCheck so every passing design confirms it does not falsely flag a valid design; the error message is validated by ElaborationChecksSpec's "clock missing timing constraint check" at Step 2c. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Third rootDBCheck member rewired. Iterates each sub-DB's RT waits under that sub-DB's getSet (the root has no members of its own) and reads the clock rate from new_resolvedClkRstMap. The error hierarchy uses new_fullNameViaInst so a wait in a nested design reports its full instance path (plain getFullName on a sub-DB would be relative). Wired into new_hierEquivalenceCheck for passing-design validation; the wait error messages are validated by ElaborationChecksSpec at Step 2c. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…ep 2b) Two device-top-only checks rewired for the root. Each iterates designMemberList (root-aware), and for the device-top design resolves its members under that design's sub-DB getSet via domainOwnerToSubDB(design).atGetSet. Device top == toptop, so getFullName yields the correct full path. Bodies are otherwise identical to the flat checks. Wired into new_hierEquivalenceCheck (the Platform device-top design exercises them); error messages validated at Step 2c. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Last rootDBCheck member rewired. Aggregates assignment coverage and the connected-point set across all sub-DBs (each design's assignments/connections live in its own sub-DB) plus the cross-design magnet connections. Input ports are checked from each parent sub-DB (which owns the instance + its connections), reading the child design's port list via the root-aware designMemberTable; output ports per instantiated design (designBlockInstMap keys, matching the flat version — the toptop's own ports are device IO, not dangling) under its own sub-DB getSet. The dcl width is resolved inside the sub-DB getSet (a DFBits width-param ref can't resolve against the root getSet). Wired into new_hierEquivalenceCheck; no false positives across the suite. All seven rootDBCheck members now have hierarchical clones (magnet is covered by the existing map comparison). Error messages validated at Step 2c. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
check's isRoot branch now runs new_rootDBCheck (the new_* clones) instead of the flat rootDBCheck, and both callers (SanityCheck.transform, Design post-elaboration) call designDB.oldToNew.check, so the production connectivity/RT/device-top checks run on the hierarchical root. The flat rootDBCheck remains only on the (now unreached) isOldStyleFlatDB branch — dead, to be removed in Step 3. Two fixes surfaced by the error tests once the hierarchical path went live: - new_fullNameViaInst now mirrors the flat naming (design CLASS name, e.g. Internal2.dmn) by resolving the enclosing design in its own sub-DB rather than via the parent instance path. - new_portLocationCheck iterates `members` directly: the root-aware designMemberList already includes the design block as the head, so the flat code's `design :: members` would double-count it (spurious Top-vs-Top collisions / doubled "missing" errors). Removed the now-redundant new_* check calls from new_hierEquivalenceCheck (the production root path exercises them); the gate keeps the analysis comparisons. Full suite green (StagesSpec 434, CoreSpec 74, lib 152, platforms 1), ElaborationChecksSpec error messages match. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Production runs the hierarchical new_rootDBCheck on the root via oldToNew.check; the flat rootDBCheck and the six flat check methods were only reachable through the now-unreached isOldStyleFlatDB branch of `check`. Remove that branch and the dead flat checks (checkDanglingPorts, circularDerivedDomainsCheck, domainClkRateCheck, waitCheck, portLocationCheck, portResourceDirCheck). The flat clk/rst analyses they consumed stay alive via the equivalence gate and the DFMember CLK_FREQ folder until Steps 3b/3c. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
new_hierEquivalenceCheck was temporary scaffolding that asserted the flat RT clk/rst + magnet analyses matched their hierarchical clones on every design passing SanityCheck. The hierarchical path is now the sole production path (Steps 2c/3a) and the equivalence is locked in by the test suite, so drop the gate and its SanityCheck call site. The flat magnetConnectionMap was only consumed by the gate and the (deleted) flat checks, so remove it too. MagnetMap.get (flat) is now dead and will be removed with the getHierarchical->get rename in Step 3d. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
… 3c) resolvedClkRstMap is now a single representation-dispatched lazy val: the hierarchical body runs on the root, a sub-DB delegates to its root, and an old-style flat DB is converted via oldToNew first. The only flat entry point is the CLK_FREQ const-folder (DFMember.Special), which only runs on a complete immutable DB (disabled during elaboration), so the oldToNew conversion is always valid there. This lets the entire flat clk/rst chain go: relatedAnnotMap, pbnsToPort, fullNameViaInst, dependentRTDomainOwners, reversedDependents, the getResolvedClkRst/usesClkRst/usesClk/usesRst/relaxed extensions, and fillDomainMap. hasClkAnnot/hasRstAnnot (representation-agnostic) move up to the surviving constraints extension. new_resolvedClkRstMap loses its prefix here (callers in ExplicitClkRstCfg/DropTimedRTWaits updated); the remaining new_* analyses are renamed in Step 3d. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
With every flat counterpart deleted (Steps 3a-3c), the hierarchical analyses are the sole implementations, so rename them to canonical names: magnetConnectionMap, magnetPointInfo, magnetData, relatedAnnotMap, pbnsToPort, designEnclosingDomain, getRTOwnerWithSub, fullNameViaInst, dependentRTDomainOwners, isDependentOn, checkDanglingPorts, circularDerivedDomainsCheck, domainClkRateCheck, waitCheck, portLocationCheck, portResourceDirCheck, rootDBCheck. Callers in ExplicitClkRstCfg/ConnectMagnets/AddMagnets updated; the stale new-style/equivalence-gate comment block is rewritten. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The flat MagnetMap.get (full-member-index magnet matching) lost its only caller when the flat magnetConnectionMap was removed in Step 3b. Drop it and rename the surviving hierarchical getHierarchical to the canonical get (its sole call site is DB.magnetData). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
After dropping the new_ prefix, the doc comments that described each method as a "Hierarchical clone of <X>" / "Routed clone of <X>" now name the method itself, and a couple referenced deleted flat helpers (getRTOwnerOption, the flat usesClk filter). Reword them to describe the methods directly. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
SanityCheck used oldToNew twice per invocation (once for the checks, once for the round-trip), and oldToNew is O(members) while SanityCheck runs after every stage. Compute the hierarchical DB once and thread it into both the check and hierarchicalDBRoundTripCheck. (The gate removed in Step 3b had been a third oldToNew call.) Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
SanityCheck.transform now builds the hierarchical DB once, runs the four structural checks (refCheck, memberExistenceCheck, ownershipCheck, orderCheck) per sub-DB under each sub-DB's own getSet, then runs the design checks via hierDB.check. The temporary hierarchicalDBRoundTripCheck is removed. Investigation (instrumenting each check independently across all 434 StagesSpec tests) showed refCheck was the only check that failed on sub-DB scope; the other three are per-sub-DB-safe. refCheck had two cross-design assumptions, both fixed by fetching the child design's sub-DB via rootDB.subDBs and reading it under that sub-DB's getSet: * instPortsByNameSet read child ports via inst.getDesignBlock.members(Folded), which threw NoSuchElementException because the child design isn't an owner in the parent sub-DB. * the "removed member" refTable scan flagged inst.designRef -> childBlock (a legitimate cross-sub-DB reference); it now whitelists DFDesignBlock targets that are live subDBs keys. Both carry a TODO for the future unification of DFDesignInst.designRef with the child DFDesignBlock.ownerRef (the subDBs key), which collapses the lookups to rootDB.subDBs.get(inst.designRef). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…apable PrintCodeString was a no-op dependency anchor that happened to `extends Stage`; it is now a `BundleStage`, removing it from the flat-DB stage list. The printer layer (shared `Printer`/`AbstractPrinter` traits, inherited by DFPrinter, VerilogPrinter and VHDLPrinter) is now able to render a hierarchical root DB, not just a flat one: * `withGetSet` constructs a same-typed sub-printer bound to a sub-DB's getSet; `csDB`/`printedDB` render each design under its owning sub-DB (the root's own getSet throws on ref resolution). * designs are rendered in post-order DFS of the design tree, matching the flat `designMemberList` order (the `subDBs` ListMap is pre-order). * const globals are aggregated across sub-DBs with first-occurrence dedup. * `DB.hierGlobalNamedDFTypes` promotes a named type to global when any sub-DB marks it global (a sub-DB sees only one design, so a type used as IO in a child but a plain local in a parent would otherwise be printed twice); these are excluded from each design's local type declarations. * `printerForDesign` routes a blackbox component/module declaration to the referenced blackbox design's own sub-DB (its port list lives there). Validated byte-identical against the flat path across all of StagesSpec (DFHDL 434, Verilog+VHDL 78). HierarchicalPrintSpec is a permanent round-trip guard, since the pipeline still feeds the printer a flat DB for now. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The interfaces work will model interface declarations as DFDesignBlock(InstMode.Interface) and views as new DFTypes, so the placeholder DFInterfaceOwner owner is no longer needed. Drops it from the DFMember hierarchy and ReadWriter, narrows DFNet.Ref to DFVal-only, simplifies DFNet.Connection.unapply / FlatNet, and removes the per-stage interface cases (AddClkRst, ToRT, ToED) and the <-> printer path. Updates the IR reference docs to match. Co-Authored-By: Claude Opus 4.8 <[email protected]>
With DFInterfaceOwner gone, every DFOwner is a DFBlock and DFNet.Ref is DFVal-only, so several fallback/recursion branches became unreachable (E121 'unreachable case except for null' warnings). Removes the dead branches in getOwnerBlock, getVeryLastMember, the ToED domain-owner and GlobalizePortVectorParams ref matches, and simplifies the now-trivial DFVal matches in Printer.csDFNet and FoldControlSteps.lhsDcl. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Adds two composite DFTypes for the interfaces/views feature: - DFInterface: a bundle of named ports/fields, like DFStruct but structural (no bit representation; never lowered to Bits). - DFView (sealed): a directed view over a DFInterface. DFView.AsIs carries a per-leaf-port direction overlay (dirMap); DFView.Flipped is the converse of another view (IR analog of VHDL 'converse). Both reuse the DFStruct/DFVector conventions for =~/isSimilarTo/getRefs/copyWithNewRefs; the bit-data methods throw, as these are not packable types. Also adds InstMode.Interface so an interface declaration can be represented as a DFDesignBlock(InstMode.Interface) (an 'empty design'). The new variants surface exhaustivity warnings in the type printers (DFTypePrinter, VHDLTypePrinter); emitting interfaces/views to HDL is the deferred backend phase. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Adds a basic Interface frontend (trait Interface + DFInterface/RTInterface/ EDInterface), mirroring Design's lifecycle but trimmed for a nested 'empty design': scope is DFC.Scope.Interface, the owner is a Design.Block built with InstMode.Interface, and param collection + instance creation reuse Design.Inst. Drops the top-level/device-top/resource and top-check machinery (never applies to a nested interface). Adds HasConstParams as a common ancestor of Design and Interface so the compiler plugin can key constant-parameter handling on it rather than on Design specifically. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Teaches the compiler plugin about interfaces by generalizing the Design-keyed constant-parameter machinery to the shared HasConstParams ancestor: - MetaContextPlacerPhase now gates body-parameter generation on dfhdl.core.HasConstParams (was dfhdl.core.Design), so interfaces get the same '<> CONST' param-to-member generation. Renames genDesignBodyParams -> genContainerBodyParams. - Renames the param-generation helpers for container generality: r__For_Plugin.genDesignParam -> genContainerParam, and the plugin's genDesignParamSym/genDesignParamValDef -> genContainerParam* . PreTyperPhase recognizes interface parents (EDInterface/RTInterface/DFInterface) and excludes them from auto-@top: an interface with '<> CONST' params would otherwise match shouldAddTop and then be rejected by the Design-only TopAnnotPhase. TopAnnotPhase is intentionally left Design-only (no @top for interfaces). Co-Authored-By: Claude Opus 4.8 <[email protected]>
An interface is purely structural (ports + views, no behavioral statements), so
the DF/RT/ED distinction has nothing to act on. Replace the trait Interface +
DFInterface/RTInterface/EDInterface variants with a single domain-neutral
`Interface` based on the ED domain under the hood: ED is terminal in the
lowering pipeline (DF -> RT -> ED), so an ED interface is never transformed by
ToRT/ToED nor given clk/rst, and the same Interface is reusable inside a design
of any domain.
Updates the plugin's interface recognition to the single name (Set("Interface")).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Interface DFVal members (ports and const parameters) are internal wiring; external code should reach them only through a view's `.VIEW`. Enforce this at compile time in MetaContextPlacerPhase.prepareForValDef: any non-protected (and non-private) DFVal declared in a class extending Interface is rejected. The check runs post-typer so `<:< Interface` resolves transitively, catching ports declared in indirect subclasses that a pre-typer syntactic check would miss. Native `protected` access control then blocks `ifc.port` selections and hides the members from IDE autocomplete. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Document how to define and use interfaces: declaration, protected ports/params, views (in/out/flip/generic), instantiation and view projection, nested interfaces (AXI4-Lite), vector views, HDL mapping, and the restrictions summary. Wire the chapter into the nav. Co-Authored-By: Claude Opus 4.8 <[email protected]>
An interface is purely structural and carries no initial values. Add a NotInsideInterface[A] compile-time constraint (AssertGiven over the declaration scope encoded in the modifier's `A` type parameter) and apply it to both `init` overloads and `initFile`, producing a clear error message at the call site. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Fold the anchored-direction port and projection-terminal design into the user-guide interfaces chapter: new terminology entries, an Anchored-Direction Ports section (flippable vs anchored, the two view rules, and sibling vs parent-to-child connection behavior), a projection-terminals table (VIEW/FLIP/FLIPALL/MONITOR/DRIVER), and updated restrictions. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Align the user-guide with the finalized projection-terminal family (ASIS/FLIP/FLIPALL/MONITOR/DRIVER), renaming the plain `.VIEW` terminal to `.ASIS` so every terminal is parallel and maps 1:1 to the IR Terminal enum. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Update the interface/view IR types to the finalized design:
- DFInterface.fieldMap now carries a per-field direction via a new
DFInterface.Field(dfType, dir) (VAR = flippable, IN/OUT = anchored).
Field extends HasRefCompare so the field map compares with `=~`.
- DFView collapses to a single concrete type (drop AsIs/Flipped). It
stores only its overlay over the interface: a leaf `dirMap` plus a
`nestedMap` of chosen sub-views, with a derived `projectedFieldMap`
that merges in the field types on demand (no duplication). Adds the
flip/flipAll/monitor/driver direction transforms; flip leaves anchored
leaves untouched, flipAll is the true VHDL 'converse.
- Add Modifier.Terminal{AsIs,Flip,FlipAll,Monitor,Driver}, reshape
ViewSite to Template | Projection(terminal), and add the IR-only
Dir.VIEW(site) marker.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
- Treat INOUT as a first-class anchored direction; it is its own converse, so flip/flipAll leave it unchanged (matching SV inout modports and VHDL 'converse inout->inout). Documented on `invert` and DFInterface.Field. - Add DFInterface.Field.isSimilarTo and leverage it from both DFInterface.isSimilarTo and DFView.isSimilarTo (with size checks), removing the duplicated per-field logic. - DFView.prot_=~ now compares `projectedFieldMap =~` (a ListMap of HasRefCompare Fields), folding the leaf dirMap and nested sub-views into a single comparison. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Note that an anchored port may be <> INOUT (a bidirectional, self- converse direction that flip/flipAll leave unchanged, mapping to SV inout modports and VHDL inout mode-view elements), and show the view.inout(...) builder form. Co-Authored-By: Claude Opus 4.8 <[email protected]>
The init/initFile interface restriction constrained the modifier's `A` type parameter (`NotInsideInterface[A]`). That extra constraint destabilized inference of the register/assignable markers carried in `A` at call sites like `(Bit <> VAR.REG).init(1)`, so the resulting register lost its assignable-REG marker and a later `.din` failed with "This is not an assignable register" (e.g. in FoldControlSteps and DropRTProcess). Detect the interface scope via the ambient `DFC.Scope.Interface` given (present inside an interface body) instead, so the constraint no longer touches `A` and register inference is unaffected. The rejection behavior is unchanged. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Add `opaque type StaticRef = DFRef.OneWay[DFDesignBlock]` (fully opaque, no subtype bound) so the refs used as stable structural keys are not treated as ordinary references by accident. It provides an explicit `.asRef` unwrap, an `apply`/`Conversion` from `DFOwner.Ref` (covering both `OneWay[DFDesignBlock]` and the unified `ownerRef` sub-DB keys), and its own `CanEqual`/`ReadWriter`. Retype the three structural-key sites to `StaticRef`: `DB.subDBs` keys, `DFDesignInst.designRef`, and `DFInterface.interfaceRef`. Every site that genuinely needs the underlying ref now unwraps via `.asRef` (resolution, refTable/designBlockByKey lookups), and sub-DB keys built from `ownerRef` wrap via `StaticRef(...)`, across the IR, core, and the hierarchy stages. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Previously, cancelling a running tool (simulator/builder) with Ctrl+C only worked under foreground sbt, and could leave the tool (and its children) running, stall on heavy tool output, continue past the cancelled step, or print the notice twice. - handle both delivery mechanisms: SIGINT (sbt/standalone) and the Thread.interrupt() the sbtn background-job thread receives. - force-kill the whole process tree via the underlying java.lang.Process (descendants + destroyForcibly), so Windows tools that fork workers (gw_sh, vsim -> vsimk, ...) don't survive. - wait on the underlying process rather than os-lib's waitFor(), which joins the output-pumper thread; under an output flood that join blocked on the back-pressured writer and made the abort feel slow. - propagate a stack-trace-free ToolInterruptedException, caught at the DFApp boundary, so the run stops cleanly without a noisy trace and without sys.exit (which would tear down the reusable sbtn/sbt-shell server JVM). Co-Authored-By: Claude Opus 4.8 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.