Skip to content

Fix #4610 net10.0 follow-up: enum-aware Contains path for MemoryExtensions#4616

Merged
jeremydmiller merged 1 commit into
masterfrom
fix/4610-net10-memory-extensions-contains
Jun 3, 2026
Merged

Fix #4610 net10.0 follow-up: enum-aware Contains path for MemoryExtensions#4616
jeremydmiller merged 1 commit into
masterfrom
fix/4610-net10-memory-extensions-contains

Conversation

@jeremydmiller
Copy link
Copy Markdown
Member

Context

#4610 fixed values.Contains(p.EnumMember) against an EnumStorage.AsString document member by routing the case through EnumIsOneOfWhereFragment in EnumerableContains.Parse. That worked on net9.0 locally and in CI, but the regression test file is now failing on net10.0 in CI for both open PRs (#4613, #4615) with the same Writing values of 'YourEnum[]' is not supported for parameters having NpgsqlDbType '-2147483639' shape from the original bug.

Root cause

On net10.0 the C# compiler resolves array.Contains(x) to MemoryExtensions.Contains via the implicit T[]ReadOnlySpan<T> conversion — not Enumerable.Contains. Marten's parser registry has a dedicated MemoryExtensionsContains parser at LinqParsing.cs:52 (ahead of EnumerableContains at line 53) precisely to handle that case, and its Parse had the same raw-CommandParameter-from-enum-array bug:

// MemoryExtensionsContains.cs:33 (pre-fix)
return new IsOneOfFilter(collectionMember, new CommandParameter(constant.Value));

#4610's fix only patched EnumerableContainsMemoryExtensionsContains was missed because the local test runs were on net9.0 only.

Fix

Mirror the same enum-aware branch into MemoryExtensionsContains.Parse:

if (collectionMember.MemberType.IsEnum && constant.Value is not null)
{
    var arrayValue = constant.Value is Array
        ? constant.Value
        : ((IEnumerable)constant.Value).Cast<object>().ToArray();

    return new EnumIsOneOfWhereFragment(
        arrayValue,
        options.Serializer().EnumStorage,
        collectionMember.TypedLocator);
}

The existing Bug_enum_asstring_array_contains regression tests already cover both parsers — they target the user-facing shape (values.Contains(p.Status)), and each .NET version routes that shape to a different parser.

Verified

  • Bug_enum_asstring_array_contains: 6/6 pass on net9.0
  • Bug_enum_asstring_array_contains: 6/6 pass on net10.0 ← the regression
  • Full LinqTests on net10.0: 1269 passed, 0 failed

Once this lands, the CI failures on #4613 and #4615 should clear with a rerun (they're not touching either parser, just running into the same flaky net10 fallout).

🤖 Generated with Claude Code

…sions

#4610 fixed `values.Contains(p.EnumMember)` against an EnumStorage.AsString
document member by routing the case through `EnumIsOneOfWhereFragment` in
`EnumerableContains.Parse`. That worked on net9.0 but the regression test
file failed on net10.0 in CI for PR #4613 and #4615 with the same
`Writing values of 'YourEnum[]' is not supported for parameters having
NpgsqlDbType '-2147483639'` shape from the original bug.

Root cause: on net10.0 the C# compiler resolves `array.Contains(x)` to
`MemoryExtensions.Contains` (via the implicit `T[]` → `ReadOnlySpan<T>`
conversion), not `Enumerable.Contains`. The match runs through
`MemoryExtensionsContains.Parse`, not `EnumerableContains.Parse`, and the
former had the identical enum-array-as-raw-CommandParameter bug — #4610's
fix had only patched the latter.

Mirror the same fix into `MemoryExtensionsContains.Parse`. The existing
Bug_enum_asstring_array_contains regression tests now cover both parsers
because they target the user-facing shape (`values.Contains(p.Status)`) and
each .NET version routes that to a different parser.

Verified:
  - Bug_enum_asstring_array_contains: 6/6 pass on net9.0
  - Bug_enum_asstring_array_contains: 6/6 pass on net10.0
  - Full LinqTests on net10.0: 1269 passed, 0 failed

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant