Repository navigation
fix: keep an overload of a generated member that differs by arity or ref kind - #236
Open
CaffeinatedCoder wants to merge 4 commits into
Open
CaffeinatedCoder wants to merge 4 commits into
CaffeinatedCoder wants to merge 4 commits into
Conversation
…ref kind ValueObjectDeclaration.MethodsWithSignature and ClosedSetTypes.SameParameters matched a hand-written method to a generated one by name and parameter types alone. A generic Parse<TFormat>(string, IFormatProvider?), a From(in int) or From(ref int), a TryParse whose last parameter is by value, a generic or by-value TryFormat, and a closed set's generic Parse or by-value TryParse were refused as the generated member written by hand (CMTK1011), on the type and on a base record or base class, though C# overloads by each and Metalama introduces the generated member beside it (measured in a scratch consumer: every row builds and calls the generated member, no LAMA error). Both now match only a method without type parameters, and compare each parameter's ref kind: by reference where the generated one is out, by value where it is by value. ref or in against out is no overload in C# (CS0663) and nullability none at all, so those stay CMTK1011. Input class (GTS): a method that shares a generated member's name and parameter types, by what differs (arity; in, ref or out against by value; ref and in against out; nullability) and where it is declared (the type, a base record of this assembly and of another, a closed set and its base class), over the declaration shapes the check reads (record struct, sealed record class, closed set). 34 rows in OverloadTests build and call the generated member, 10 reach the hand-written overload, and 8 controls in BuildOutcomeTests stay refused. The wrapped type only enters the check as From's parameter, so the rows wrap int, which has every generated parse and format. Siblings found by the same catalogue on the other signature checks (TryFrom, Revalidate, CompareTo, Equals, GetHashCode, PrintMembers, ToString()) are the next commit. Reverting the source refuses all 16 new value objects and sets in the test project (32 CMTK1011); comparing ref kinds exactly (ref against out as another method) fails the 6 ref and in controls and Every_error_is_one_of_ the_intended_ones. FabricTests looked up From and TryFrom by name, which an overload made ambiguous; it looks them up by signature. The surface snapshot renders a generic method's type parameters and a ref or in parameter, so an overload no longer reads as a duplicate line; Match gains <TResult>. Closes #226 Defect-Class: GTS Found-By: OR Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mber is another method
The previous commit's catalogue, run over the other checks that find a
hand-written member by name and parameters, found the same cause in seven
of them: each read a method of any arity and any ref kind.
Silent, measured with the check reverted:
- IsHandWrittenToString took a generic ToString<TFormat>() for the seam.
The value object printed "ToStringOverloadedByArity { Value = a }", what
a record prints, and a closed set printed its type name. A base record's
was CMTK1011 as an unsealed ToString().
- DeclaresCompareTo took a generic or by-in CompareTo(TSelf) for the
ordering seam and marked the ordering [HandWrittenOrdering], which the EF
Core satellite refuses to order by, though the ordering was generated.
- ValueObjectContractAspect skipped re-implementing a deeper base's explicit
IEquatable<TBase> beside a generic Equals<T>(TBase?), so a
HashSet<TBase> held two value objects holding 42.
Refused (CMTK1011, CMTK1008), where the generated member sits beside it:
a generic or by-in CompareTo(object), a base record's generic CompareTo,
TryFrom<T>(int) or TryFrom(in int) and Revalidate<T>() (InheritedSeams), a
generic Equals(TSelf) or GetHashCode() (EqualityDeclaredByHand), a base
record's (InheritedEquality, CMTK1023), and a generic PrintMembers.
Each check now reads only a method without type parameters whose
parameters are all by value (IsByValueAndNotGeneric), as every generated
member but TryParse and TryFormat is; those two are MethodsWithSignature's.
Input class (GTS): as in the previous commit, over the seams (ToString(),
CompareTo(TSelf), TryFrom, Revalidate) and what a record synthesizes or
calls (Equals, GetHashCode, PrintMembers, CompareTo(object)), on the type,
a base record, two levels up and in a closed set. 19 rows join
OverloadTests' 34, 4 the hand-written ones, and 3 check the ordering is
not marked hand-written. Reverting the commit refuses 5 of its types;
reverting IsHandWrittenToString alone fails the 3 ToString rows,
DeclaresCompareTo alone the 2 ordering rows, and the contract aspect's
check alone the deeper-base row.
Refs #226
Defect-Class: GTS
Found-By: VA
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 31, 2026
Open
Base automatically changed from
fix/closed-set-base-member-refused-2-3-1
to
release/2.3.1
October 31, 2026 07:48
# Conflicts: # CHANGELOG.md
# Conflicts: # CHANGELOG.md
This branch has not been deployed
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.
Closes #226
Stacked on #218 (
fix/closed-set-base-member-refused-2-3-1), whose base-class reads for closed sets this fix's closed-set rows need. Merge #218 first; this PR then retargets torelease/2.3.1.Problem
ValueObjectDeclaration.MethodsWithSignatureandClosedSetTypes.SameParametersmatched a hand-written method to a generated one by name and parameter types only. A legal overload was refused with CMTK1011 as the generated member written by hand:Parse<TFormat>(string, IFormatProvider?),From(in int),From(ref int), aTryParsewhose last parameter is by value, a generic or by-valueTryFormat, and a closed set's genericParseor by-valueTryParse. That happened on the type, on a base record and on a set's base class. C# overloads by each of these, and Metalama introduces the generated member beside it (measured in a scratch consumer: every row builds and calls the generated member).The same catalogue, run over the other name-and-parameters checks, found seven siblings (
Found-By: VA). Three were silent:ToString<TFormat>()was taken for the seam. The value object printedToStringOverloadedByArity { Value = a }, as a record does, and a closed set printed its type name.inCompareTo(TSelf)was taken for the ordering seam, so the ordering was marked[HandWrittenOrdering]and EF Core refused to order by it.Equals<T>(TBase?)stopped the value object re-implementing a deeper base's explicitIEquatable<TBase>, so aHashSet<TBase>held two value objects holding 42.The other four were refusals: a generic or by-reference
CompareTo(object),TryFrom,Revalidate,Equals,GetHashCodeorPrintMembers, on the type or a base record.Change
MethodsWithSignatureandSameParametersmatch only a method without type parameters, and compare each parameter's ref kind: by reference where the generated one isout, by value where it's by value.reforinagainstout(CS0663) and nullability stay CMTK1011.ValueObjectDeclaration.IsByValueAndNotGenericholds the seam and synthesized-member checks to the same rule:IsHandWrittenToString,InheritedSeams,PrintMembersDeclaredByHand,EqualityDeclaredByHand,InheritedEquality, the comparable aspect'sHandWrittenComparisonMembersandDeclaresCompareTo, and the contract aspect's re-implementedIEquatablecheck.design/aspects.md, three claims, two CHANGELOG lines.FabricTestslooks upFrom/TryFromby signature, since an overload made it ambiguous. The surface snapshot now prints a generic method's type parameters andin/ref, so an overload doesn't read as a duplicate line.Matchgains<TResult>.Tests
OverloadTests(new): 53 rows where the generated member sits beside a hand-written overload and is what a plain call reaches, 14 rows that reach the hand-written one, and 3 that check the ordering isn't marked hand-written. They cover the type (record struct, sealed record class), a base record in this assembly and in another (ProbeOverloadingRecord), two levels up, a closed set and its base class.BuildOutcomeTests: 8 control rows stay refused:ref/inagainstouton the type, a base record, a set and a set's base, arefTryFormat, and another nullability.ref/incontrols. Without the second commit, 5 of its types are refused. RevertingIsHandWrittenToString,DeclaresCompareToor the contract aspect's check alone fails its own rows (3, 2 and 1).tools/BuildVerdict: Generators.Tests 1249 passed, Conventions.Tests 2016, Samples 150.🤖 Generated with Claude Code