Replace Unsafe.Unbox with StrongBox for JSON source-generated struct accessors - #133997
Open
jkoritzinsky wants to merge 2 commits into
Open
jkoritzinsky wants to merge 2 commits into
jkoritzinsky wants to merge 2 commits into
Conversation
…accessors Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
|
Tagging subscribers to this area: @dotnet/area-system-text-json |
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
One or more issues must be addressed before approval.
Get a fresh assessment by requesting another Copilot review.
Review tier: Lite
Findings: 3
Open (5)
Keep customized struct creators StrongBox-compatible · New Wrap pre-populated parameterized structs before generated setters · New Do not expose StrongBox through JsonTypeInfo.CreateObject · New Preserve struct mutations made by deserialization callbacks · New Preserve callbacks for parameterized source-generated structs · New
What changed in this PR
This PR replaces Unsafe.Unbox<T> with StrongBox<T> for source-generated struct deserialization accessors.
Changes:
- Adds StrongBox-aware generated getters, setters, and reflection fallbacks.
- Wraps source-generated value-type instances during deserialization.
- Updates object converters and compilation references.
| File | Description |
|---|---|
| src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/CompilationHelper.cs | Updated as part of this pull request. |
| src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.cs | Updated as part of this pull request. |
| src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs | Updated as part of this pull request. |
| src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Helpers.cs | Updated as part of this pull request. |
| src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs | Updated as part of this pull request. |
| src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectDefaultConverter.cs | Updated as part of this pull request. |
| src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs | Updated as part of this pull request. |
| { | ||
| return typeGenerationSpec.TypeRef.IsValueType | ||
| ? $"""static (obj, value) => {GetUnboxExpression(contextSpec, declaringTypeFQN)}.{propertyName} = value!""" | ||
| ? $"""static (obj, value) => (({StrongBoxTypeRef}<{declaringTypeFQN}>)obj).Value.{propertyName} = value!""" |
Member
There was a problem hiding this comment.
I concur, this is a breaking change unfortunately. Users can access, modify, or wrap the delegate directly via the JsonPropertyInfo.Set property and anybody doing so today is relying on the current implicit contract.
…mpiler warnings - Ensure JsonTypeInfo<T>.CreateObject continues returning boxed T instead of StrongBox<T> - Wrap CreateObject return values and pre-populated values in StrongBox<T> in object converters - Support custom CreateObject modifier delegates for source-generated structs - Preserve struct mutations in deserialization callbacks by unboxing and copying back - Add tests for CreateObject return types, custom modifiers, and struct callbacks Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Comment on lines
+43
to
+45
| obj = IsValueType && jsonTypeInfo.IsSourceGenerated && state.Current.ReturnValue is not StrongBox<T> | ||
| ? new StrongBox<T>((T)state.Current.ReturnValue!) | ||
| : state.Current.ReturnValue!; |
| private static JsonTypeInfo<T> CreateCore<T>(JsonConverter converter, JsonSerializerOptions options) | ||
| { | ||
| var typeInfo = new JsonTypeInfo<T>(converter, options); | ||
| typeInfo.IsSourceGenerated = true; |
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.


Description
This change replaces usages of Unsafe.Unbox in the System.Text.Json source generator with StrongBox for struct member getters and setters during deserialization and serialization.
Key changes:
Note
This pull request was created with GitHub Copilot.