Skip to content
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

System.Text.Json emits uncompilable code #103515

Closed
SteveDunn opened this issue Jun 15, 2024 · 4 comments
Closed

System.Text.Json emits uncompilable code #103515

SteveDunn opened this issue Jun 15, 2024 · 4 comments
Labels
area-System.Text.Json bug source-generator Indicates an issue with a source generator feature
Milestone

Comments

@SteveDunn
Copy link
Contributor

Description

I had a bug report for my open source source generator project:
SteveDunn/Vogen#622

I looked at the emitted code and can see that it emits value == null rather than value is null. This caused a compilation error because the type in question has overloaded == operators, so the C# compiler reports:
CS0034: Operator '==' is ambiguous on operands of type 'Foo' and '<null>'

The line in question in STJ is here: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs#L977

Reproduction Steps

[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Foo))]
internal partial class JsonSourceGenerationContext : JsonSerializerContext;

internal class Foo
{
    public Foo(string value) => Value = value;
    
    public string Value { get; }

    public bool Equals(string primitive) => Value.Equals(primitive);

    public override bool Equals(Object obj) => Equals(obj as Foo);
    public bool Equals(Foo foo) => Value == foo.Value;

    public static bool operator ==(Foo left, Foo right) => Equals(left, right);
    public static bool operator !=(Foo left, Foo right) => !Equals(left, right);

    public static bool operator ==(Foo left, string right) => Equals(left.Value, right);
    public static bool operator !=(Foo left, string right) => !Equals(left.Value, right);


    public override int GetHashCode()
    {
        unchecked // Overflow is fine, just wrap
        {
            int hash = (int)2166136261;
            hash = (hash * 16777619) ^ GetType().GetHashCode();
            hash = (hash * 16777619) ^ EqualityComparer<string>.Default.GetHashCode(Value);
            return hash;
        }
    }
}

This should compile, but doesn't. Instead, the compiler reports:

CS0034: Operator '==' is ambiguous on operands of type 'Foo' and '<null>'

Expected behavior

For it to compile

Actual behavior

Emits error CS0034: Operator '==' is ambiguous on operands of type 'Foo' and '<null>'

Regression?

No, I think the source generator stuff in STJ is fairly new

Known Workarounds

If I change my type from a class to a struct, then the null check isn't emitted.

Configuration

.NET 8, Windows 11, X64, not specific to any particular configuration.

Other information

I plan on doing a fix and a PR

@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Jun 15, 2024
@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Jun 15, 2024
@vcsjones vcsjones added area-System.Text.Json and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Jun 15, 2024
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis
See info in area-owners.md if you want to be subscribed.

@eiriktsarpalis
Copy link
Member

The minimum language version currently supported by the STJ generator is C# 9 so I think we can replace == with is. Would you like to submit a PR that fixes it?

@eiriktsarpalis eiriktsarpalis added bug source-generator Indicates an issue with a source generator feature and removed untriaged New issue has not been triaged by the area owner labels Jun 15, 2024
@eiriktsarpalis eiriktsarpalis added this to the 9.0.0 milestone Jun 15, 2024
@SteveDunn
Copy link
Contributor Author

The minimum language version currently supported by the STJ generator is C# 9 so I think we can replace == with is. Would you like to submit a PR that fixes it?

Would love to @eiriktsarpalis . Hopefully do it this weekend (if I can remember how, it's been a while!)

@eiriktsarpalis
Copy link
Member

In the meantime, you could try disabling fast-path serialization as a workaround:

[JsonSourceGenerationOptions(GenerationMode = JsonSourceGenerationMode.Metadata)]
[JsonSerializable(typeof(Foo))]
internal partial class JsonSourceGenerationContext : JsonSerializerContext;

SteveDunn added a commit to SteveDunn/runtime that referenced this issue Jun 17, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Jul 18, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Text.Json bug source-generator Indicates an issue with a source generator feature
Projects
None yet
Development

No branches or pull requests

3 participants