Repository navigation
fix: sharp/bin/spec writes each type of an example to a file of its own - #147
Merged
Merged
Conversation
Section 27 says a .sharp file that declares a type declares one. The runner wrote every type of a block, its setup and its example class into one file, which the rule will refuse. - build_files returns one file per type: split_types leads each with the file's namespace and import lines, and keeps what is no type, such as an extern line or a module block, with the first type. Each file keeps its own line map. - A block whose first line is a path comment stays one file as written, so one-type-per-file still shows its error. - Two files of one example at one path stop the run, in place of the rename to Name1.sharp, which hid two types of one name. sharp/spec-self-test.md gains file-per-type, and docs/architecture/spec-examples.md says how a fragment's types become files.
heyJordanParker
added a commit
that referenced
this pull request
Oct 16, 2026
Master brings #142, #146, #147, #148 and #149. Each conflict keeps both sides' behavior: - A lambda's result type: master's `AnalysisArtifacts::lambda_result` is the one mechanism. `try` in a lambda reads it, and #143's `BlockContext::lambda_result_type` with its setters is gone. - A `match`'s declared type reaching its PHP and its arms: master's code, with `Expression::Match` kept in `takes_declared_type`, without which the PHP `match` takes no declared type. - `==` on a struct or a case: master's per-side type arguments for a generic struct, and a generic enum's case fields read the enum's type arguments from the side that gives them, through `with_type_arguments`. - A call's declared type: master's `declared_return_type` goes through `as_declared_ancestor`, so `Result.Ok(…)` into a `Result<int, E>` fixes the case's type arguments for the arguments and for the result. - The bridge: master's `generic_statics`, with `class_metadata` taking the class it describes, as a generic enum's case needs. - Spec section 11 keeps master's inference bullets and #143's rule for a static call of a generic class.
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.
Fixes:
sharp/bin/specwrites every type of an example, its setup and its example class into one generated.sharpfile, so the one-type-per-file rule of section 27 would refuse 26 examples that pass today.This PR changes only the measure, as
sharp/bin/specchanges in a PR of its own. The rule itself comes in the section 27 feature PR.Problem
Section 27 says a
.sharpfile that declares a type declares one, named like the file.build_filewrote one file per block: the block's types, the types of the marker's setup, and theExampleorin <Class>wrapper class. 29 examples write several types into that one file:one-type-per-file, on purpose.one-body-per-methodandsub-interface-defaults, in their own text, which the feature PR splits.listenersis one: its setup declares the interfaceOrderEventand the eventsOrderPaidandOrderRefundedbeside its classOrderNotices.Solution
build_filesreturns one file per type.split_typesleads each file with the block'snamespaceandimportlines. Each type goes to the path its namespace and name give, as every other file already did. What is no type, such as anexternline or amoduleblock, stays with the first type, which the rule allows. A comment above a type goes with it. Each file keeps its own line map, so every reported line is still the spec's.// app/Tenant/Store/StoreService.sharp, stays one file as written, soone-type-per-filestill shows its error.variant_filesstops the run when two files of one example have one path. The rename toName1.sharpis gone, because it hid two types of one name. No example has two files at one path today.listenersnow compiles four files:app/OrderEvent.sharp,app/OrderPaid.sharp,app/OrderRefunded.sharpandapp/OrderNotices.sharp.sharp/spec-self-test.mdgainsfile-per-type. Its setup declaresTicketandSeat, and an error inSeatnamesapp/Seat.sharp.docs/architecture/spec-examples.mdsays how a fragment's types become files.Verification
Checked 201 examples, ignored 1, and 16 failbefore and after.diffof the two passing lists prints nothing. Both lists are below.line 8 of the generated app/Result.sharp, from the marker's setup or wrapper: Parse error encountered during parsing Expected one of Semicolon, CloseTag, found Publicis gone. That parse error came from the next type in the shared file, which now has its own file. The example's own error, atdocs/spec.md:4038, stays.sharp/bin/spec --self-testgives21 of 21 self-test examples give the problems they expect. Master's runner fails the newfile-per-type. It reports the error inapp/Ticket.sharp, the one file both types share.The 185 examples that pass before, on master's runner
The 185 examples that pass after, on this PR's runner