Change Seq.empty to use Enumerable.Empty#19322
Conversation
❗ Release notes required
|
Seq.empty was implemented as a single-case DU (EmptyEnumerable) which caused serializers to detect the CompilationMapping attribute and treat it as an F# union type instead of a plain enumerable. This made Seq.empty serialize as "EmptyEnumerable" instead of [] with JSON.NET, STJ, and ASP.NET ObjectResult. Replace the implementation with System.Linq.Enumerable.Empty<'T>(), which returns a standard .NET type that serializes correctly. Also remove the EmptyEnumerable type and the related optimization in ConcatEnumerator that is no longer needed. Fixes dotnet#17864
fd7fb57 to
20f995d
Compare
|
Writing here as well as to https://github.com/dotnet/fsharp/pull/19317/changes . Even though this change is correct, we should first assess breaking changes even for de-generate scenarios, only merge this for upcoming major increase of FSharp.Core (together with .NET 11. Right now we still dually insert also to 10.0.300) and document the breaks. Few ideas:
Imo the compiler compat suite will allow to model these scenarios, the infrastructure around it will then exercise the various versioning configs that can happen. |
|
Closing in favor of #19317, which fixes the serialization issue without removing EmptyEnumerable<'T>, avoiding any breaking changes. I guess I wasn't the only one looking for good first issues and I guess his approach is better. Unfortunately I still have a lot to learn about F#'s internals. |
Description
Seq.emptywas implemented as a single-case DU (EmptyEnumerable) that carries a[CompilationMapping(SourceConstructFlags.SumType)]attribute. When serializers (JSON.NET, STJ, ASP.NET ObjectResult) inspect the runtime type via reflection, they detect this attribute and treat it as an F# union rather than a plain enumerable, causingSeq.emptyto serialize as"EmptyEnumerable"instead of[]or throwNotSupportedException.Replacing the implementation with
System.Linq.Enumerable.Empty<'T>()fixes this — the runtime type is now a standard .NET type that serializers handle correctly. The internalEmptyEnumerableDU and a related type-check optimization inConcatEnumeratorare no longer needed and have been removed.I basically did what was suggested in the ticket, so I hope I got it right. It's fun to hunt for simple issue that I might be able to help with.
Fixes #17864
Checklist