-
Notifications
You must be signed in to change notification settings - Fork 5.1k
[release/9.0-staging] [STJ] Fix formatting of flag enums when values are overlapping. #117806
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[release/9.0-staging] [STJ] Fix formatting of flag enums when values are overlapping. #117806
Conversation
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis |
Before merging, let's also cherry pick the improvement from #117839 once merged. cc @PranavSenthilnathan EDIT: now done. |
* [STJ] Only compute PopCount once when topologically sorting Enums Packs the calculated (once per entry) PopCount into the high 32 bits of the long and the original index into the low 32 bits. Then that can just be sorted using the heavily optimized Array.Sort() method. After sorting just extract the low 32 bits as the original array index. As before, we negate the actual _PopCount_ to ensure that `Key`s with more on-bits (e.g. more flags represented) will sort **first**. This trades 2 x O(N log N) [average case] to 2 x O(N^2) [worst case] calls to the `popcount` instruction (or the emulation if NET is not defined) for N **shift-left-32** and **or** + N x **truncate to 32 bits**. It _also_ eliminates the overhead of the `CompareTo` method as it's now a direct `long` low-level compare. * PR Feedback Switched to Tuple * PR Feedback Switched to native tuple syntax Co-authored-by: Pranav Senthilnathan <[email protected]> * Update src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs --------- Co-authored-by: Eirik Tsarpalis <[email protected]>
We are going to hold off on backporting this to .NET 9. If more customer impact is reported before migrating to .NET 10 is an option, we will reconsider the backport. |
Backport of #117730 to release/9.0-staging
/cc @eiriktsarpalis
Customer Impact
Fixes a regression introduced in .NET 9 impacting formatting of enum flag types as strings, when the enums define values whose bits are a subset of other values. This results in the enum either being formatted as a non-canonical combination of values or being formatted using its underlying numeric value.
Regression
The regression was introduced by #105032, which added support for customizable enum labels. This necessitated a departure from the built-in string formatting for enums in favor of a custom solution, which has created a bug tail.
Testing
New test cases were added for
[Flags]
scenarios with overlapping values.Risk
Low. The fix involves topologically sorting of the built-in enum values which changes the string-based formatting of enum values but doesn't impact the underlying value being marshalled (as likewise the regression didn't impact the underlying value either).