Repository navigation
Sweep the EF translators for name-only dispatch and default operand classification #295
Description
Problem
EF Core's defect in dotnet/efcore#39329 is the same family as this repository's receiver-shaped dispatch trap: it decided on a method's name and argument count and assumed the rest of the signature, so an overload nobody wrote an arm for was handled as if it were the expected one.
The plugin's translators check the declaring type before dispatching (ValueRangesMethodCallTranslator.Translate, ValueSetsMethodCallTranslator, ValueSetsMemberTranslator), but inside TranslateRangeSetCall the arms dispatch on method.Name and arguments.Count == 1, and the operand is classified by Operand(): the set type, else the element type, else a range. An overload added later with another operand type (a value set, a different range type) would be translated as a range without an error. That is the _-produces-a-value shape the engine rules forbid, one layer up.
Change
- A sweep over
src/**/Query/, in the style ofEngineDispatchConventionTests: every arm that dispatches on a member name also matches the parameter types (or theMethodInfo/generic definition) it handles, and every operand classification ends in a throwing arm rather than a default type. - Fix the arms it finds, starting with
Operand()inTranslateRangeSetCall. - Seed: add a
RangeSet.Containsoverload with a new operand type and show the sweep fails before any translation test does.
Done when
The sweep runs in the conventions project with its seed, and no name-dispatched arm in the EF packages accepts an operand type it does not name.
Activity
CaffeinatedCoder commentedon Oct 25, 2026
Scheduled for 10.3.0 (#408), 2026-10-25, moved here from #36. It goes ahead of #405, #406 and #191, so the translator arms they add, each dispatched on a method name, are written under the sweep.
mainfirst, then cherry-picked with-xintorelease/10.x. If it isn't ready before those land, it moves to the next minor rather than holding the tag.Re-checked 2026-10-25:
Operand()inTranslateRangeSetCallstill treats any operand that isn't the set or element type as a range, on both lines (ValueRangesMethodCallTranslator.cs:376-379).CaffeinatedCoder commentedon Oct 25, 2026
PR #432. It differs from the plan above in one way: the sweep is behavioral, not a syntax rule over
src/**/Query/. A syntax sweep can't see the seed this issue names, because the seed adds a public overload in core and touches no translator.TranslatorDispatchSweepTestsinstead starts from the public API (QueryMembers), hands every member over every discovered type to the translator providers with one operand per declared parameter type, and requires each operand to be mapped as that type.With the seed (
RangeSet.Contains(StringSet)) and the old translators, it reports "an operand declared StringSet is mapped as daterange" on every range type, while all 300 EF translation tests pass. The translators now map an operand from its declared type and throwMissingArmfor any other, whichMissingArmTestsholds.The interceptor's
RangeSetContains.Equivalenthas the same fallback. That's #320, in its own PR, since the sweep calls the translators directly and doesn't reach the interceptor.Merge pull request #432 from CaffeinatedCoder/test/295-translator-nam…
CaffeinatedCoder commentedon Oct 25, 2026
Fixed on
mainby PR #432 (9caa202). Therelease/10.xcherry-pick is #433.Merge pull request #435 from CaffeinatedCoder/test/433-translator-dis…
fix: RangeSetContains.Equivalent refuses a Contains overload it has n…