Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 8 additions & 17 deletions src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -782,23 +782,14 @@ private static SourceText GenerateForUnion(ContextGenerationSpec contextSpec, Ty
continue;
}

string patternTypeFQN = caseSpec.PatternType.FullyQualifiedName;

if (patternTypeFQN == typeMetadata.TypeRef.FullyQualifiedName)
{
// Recursive case: the case type is the union type itself. A type pattern `T`
// applied to a union is equivalent to `T or { Value: T }`, so a bare type
// pattern here is also satisfied by the union instance itself. That both binds
// the union rather than its payload -- making the converter recurse on the same
// value forever -- and renders any later arm unreachable. Match the payload
// explicitly so that only the unwrapped value is bound.
writer.WriteLine($"{{ Value: {patternTypeFQN} caseValue{deconArmIndex} }} => (typeof({caseSpec.CaseType.FullyQualifiedName}), (object?)caseValue{deconArmIndex}),");
}
else
{
writer.WriteLine($"{patternTypeFQN} caseValue{deconArmIndex} => (typeof({caseSpec.CaseType.FullyQualifiedName}), (object?)caseValue{deconArmIndex}),");
}

// Match the payload through a property pattern rather than applying a type
// pattern to the union itself. A type pattern `T` applied to a union is
// equivalent to `T or { Value: T }`, so for a case whose type is the union
// type itself the union instance also matches: that would bind the union
// rather than its payload -- making the converter recurse on the same value
// forever -- and would render every later arm unreachable. The explicit form
// binds only the unwrapped value and behaves the same for all other cases.
writer.WriteLine($"{{ Value: {caseSpec.PatternType.FullyQualifiedName} caseValue{deconArmIndex} }} => (typeof({caseSpec.CaseType.FullyQualifiedName}), (object?)caseValue{deconArmIndex}),");
Comment on lines +785 to +792

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm the tests pass. I'll defer to area experts.

deconArmIndex++;
}

Expand Down