fix: correctness sweep for latent emission and pipeline defects - #48
Merged
Conversation
All caught by the snapshot corpus's compile gate and pinned by new fixtures or diagnostic tests: - An instance MarkDirty() on the serialized class emitted ClassName.MarkDirty()() via ToDisplayString plus appended parens; use the method name with the proper receiver. - KeyValuePair fields: the setter compared with a nonexistent != (setters now fall back to EqualityComparer<T> when the type has no inequality operator, with Nullable<T> lifting respected), deserialization assigned to undeclared key/value locals (now declared, uniquely named), and a bogus ClearX() calling KVP.Clear() was emitted (data-structure methods now require an actual collection type). - Struct/record-struct emission marked Serialize/Deserialize virtual (CS0106). With that fixed, the SG3009 contract was inverted and shown to be unsatisfiable: it demanded a user Deserialize that always collided with the generated one, while rules consume the generated instance method. SG3009 now fires on a user-declared Deserialize instead. - Migration content structs and timer emission referenced IGenericReader and Core unqualified, compiling only for classes under Server.*; both are fully qualified now. - The generator's Migrations map is mutated from source-output callbacks that can run concurrently; now a ConcurrentDictionary. Removed the no-op CultureInfo set/restore in Initialize. - Duplicate migration files for a class and version were silently ignored (SG3011) and files above the current version were dead data (SG3012); both are reported now, and warnings survive successful generation instead of being dropped. The file at the current version is the schema record and is not flagged. Corpus impact: 25 of 3,786 real-corpus sources change, all migration content structs and timer classes picking up qualified names; zero diagnostics fire on the real corpus. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Summary
Fixes every latent defect surfaced by #47's compile gate, plus the pipeline hygiene issues found during the incrementality analysis. Each fix is pinned by a new snapshot fixture or diagnostic test that failed before the fix (6 red tests → all green).
Fixes
MarkDirty()()emission: an instanceMarkDirty()on the serialized class emittedClassName.MarkDirty()()(ToDisplayString()already includes qualification and parens). Now emits the method name with the proper receiver. Pinned by theCustomMarkDirtyfixture.KeyValuePairFieldfixture):!=— setters now fall back toEqualityComparer<T>.Default.Equalsfor types without an inequality operator (withNullable<T>operator lifting respected, soint?fields are unchanged);key/valuelocals — now declared with unique names so multiple pair fields can't collide;ClearX()callingKVP.Clear()was emitted — data-structure methods now require an actual array/collection/dictionary type.Serialize/Deserializewere markedvirtual(CS0106). Fixing that exposed that the SG3009 contract was unsatisfiable: it required a user-declaredDeserialize, which always collides with the generated one (both flavors, CS0111), while the migration rules consume the generated instance method. SG3009 is inverted: it now fires when a value type declares a conflictingDeserialize. The Structs fixture'sKnownBrokenmarker is gone.IGenericReader) and timer emission (Core.Now) only compiled for classes underServer.*. Both fully qualified now — pinned by the newNonServerNamespacefixture, which generates a versioned class with a timer outsideServer.*and must compile.Migrationsmap is mutated from source-output callbacks that can run concurrently — now aConcurrentDictionary. Also removed the no-opCultureInfoset/restore inInitialize.Proof
>=and lit up the entire corpus — the manifest run caught it immediately.)🤖 Generated with Claude Code