Drop the implicit List<Entity> conversion that makes three params overloads uncallable - #853
Merged
Merged
Conversation
…loads uncallable
Entity had implicit conversions to itself from both Entity[] and List<Entity>, each
building a FiniteSet. The List one meant a list also converted to a single Entity,
so for any member with both an IEnumerable<Entity> overload and a params Entity[]
overload the params form became applicable in its expanded form, neither candidate
was better, and the call did not compile:
var equations = new List<Entity> { "x - 1", "y - 2" };
new EquationSystem(equations); // error CS0121
new FiniteSet(equations); // error CS0121
MathS.Equations(equations); // error CS0121
Not three defects -- one conversion breaking every params Entity[] overload in the
library, including any added later. A sweep of all 2602 members in PublicApi.txt for
the IEnumerable<T>/T[] overload pattern found exactly these three, and each was
confirmed by compiling the call in isolation. The array, IEnumerable<Entity> and
variadic forms always compiled; only a concrete List<Entity> broke, which is how it
reached a 2.0 preview unnoticed.
The Entity[] conversion is kept. An array binds to the params overload in its normal
form by an identity conversion, which wins outright, so it never had the ambiguity.
The new test compiling is the regression guard: restore the conversion and the test
project stops building. Sources/.editorconfig gets a per-file header section for it,
since Tests/UnitTests/Common still carries the 2022 template.
Verified: 6055 C# tests and 130 F# tests pass, the library, F# wrapper and Utils
build clean, and all ten call shapes in the ambiguity matrix now compile.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
preview.1 is published, and it has the conversion. Every other entry in the file describes a change from 1.3.0 or 1.4.0, so the file's implicit frame is release-to-release and a reader already on preview.1 would not learn from it that this one lands on them. Checked: #848 is the only other commit to touch the file since the preview.1 tag, and what it added is a 1.4.0 section, not a preview delta. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
preview.2 was tagged while this branch sat unmerged, so it ships the conversion too and the previous commit's "gone from preview.2" is wrong. Naming the version that removes something from a branch that has not merged bets on merge order; the entry now says "the release that follows them" and stops guessing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Rafael-SOWNet
marked this pull request as ready for review
August 9, 2026 20:08
This was referenced Aug 9, 2026
Rafael-SOWNet
added a commit
that referenced
this pull request
Aug 10, 2026
Closes #861. #853 removed the conversion from List<Entity> because it made three params overloads uncallable, and kept the one from Entity[] on the narrow ground that it never produced that ambiguity -- an array binds to the params overload in its normal form by an identity conversion, which wins outright. True, and beside the point, as Happypig375 pointed out on the issue: an array carries an order and can repeat an element, a set has neither, so the conversion silently discarded part of what it was handed. That disqualifies it on its own. The question to ask of an implicit conversion is what it loses, not whether it breaks an overload today, and set types are built explicitly nearly everywhere for this reason. Measured before writing anything: removing it broke exactly one place in the repository, which was the test pinning it. Nothing in the library, no other test, no sample. That test now says the opposite, and still earns its keep the same way -- the file compiling is what says the conversion has not come back. Verified: 6084 C# tests and 130 F# tests pass. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Rafael-SOWNet
added a commit
that referenced
this pull request
Aug 10, 2026
* Drop the implicit Entity[] to Entity conversion as well Closes #861. #853 removed the conversion from List<Entity> because it made three params overloads uncallable, and kept the one from Entity[] on the narrow ground that it never produced that ambiguity -- an array binds to the params overload in its normal form by an identity conversion, which wins outright. True, and beside the point, as Happypig375 pointed out on the issue: an array carries an order and can repeat an element, a set has neither, so the conversion silently discarded part of what it was handed. That disqualifies it on its own. The question to ask of an implicit conversion is what it loses, not whether it breaks an overload today, and set types are built explicitly nearly everywhere for this reason. Measured before writing anything: removing it broke exactly one place in the repository, which was the test pinning it. Nothing in the library, no other test, no sample. That test now says the opposite, and still earns its keep the same way -- the file compiling is what says the conversion has not come back. Verified: 6084 C# tests and 130 F# tests pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Drop the implicit pair to Interval conversion Closes #867. A two-element tuple became an Interval with both endpoints included. A tuple says nothing about whether either endpoint is in, so the conversion had to supply that, and it chose the reading opposite to the notation: (1, 5) is the open interval in ordinary mathematical writing, and this produced the closed one. A caller writing what looks like an open interval got a closed one, with 1 a member of it, and nothing said so. Where the array conversion removed in #866 dropped information that was there, this one produced information that was not. Same fault from the other side, and the same remedy -- ask for the interval by name, which makes the choice visible instead of assumed: MathS.Interval(1, 5) closed MathS.Interval(1, false, 5, false) open Measured before writing anything: nothing in the library, the tests, the F# wrapper or the utilities used it. Zero compile errors on removal, where #866 had one. The other pairs in the API are left alone, and checked rather than assumed: an integration Range, the arguments of Substitute, the cases of MathS.Piecewise and ToProvided are all ordered pairs whose halves have distinct stated roles. None of them has to guess what it was handed. Verified: 6085 C# tests and 130 F# tests pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <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.
Entityhas implicit conversions to itself from bothEntity[]andList<Entity>, each building aFiniteSet. TheList<Entity>one has a side effect: a list also converts to a singleEntity, so for any member that has both anIEnumerable<Entity>overload and aparams Entity[]overload, the params form becomes applicable in its expanded form. Neither candidate is better than the other, and the call does not compile.This is not three separate defects. It is one conversion making every
params Entity[]overload in the library uncallable with a list — including any added later.How the three were found
Rather than fix the one I tripped over, I swept all 2602 members in
PublicApi.txtfor theIEnumerable<T>/T[]single-parameter overload pattern. Exactly three matched, and each was then confirmed by compiling the call in isolation:new EquationSystem(list)new FiniteSet(list)MathS.Equations(list)Entity[]IEnumerable<Entity>Only a concrete
List<Entity>ever broke — an array, anIEnumerable<Entity>-typed expression, and the variadic form all compiled fine. That is why it survived to a 2.0 preview.What changes
The
List<Entity>conversion is removed. TheEntity[]conversion is kept: an array binds to theparamsoverload in its normal form by an identity conversion, which wins outright, so it never produced the ambiguity.Breaking, so it wants the 2.0 window — recorded in
BREAKING-CHANGES.md, andPublicApi.txtupdated.Regression guard
ListArgumentOverloadTestcalls all three members with aList<Entity>. The guard is that the test project compiles — restore the conversion and the build breaks, which a runtime assertion could not catch.Sources/.editorconfiggets a per-file header section for the new file, sinceTests/UnitTests/Commonstill carries the 2022 template and IDE0073 is an error.Verification
Utilsbuild cleanThe two
NETSDK1100failures in a full solution build are the WinForms/WPF sample projects, which cannot build on Linux; unrelated to this change.🤖 Generated with Claude Code