Skip to content

dotnet format on Linux incorrectly reports CS0660 warning for generated partial class with IEquatable<> implementation #53563

@cdaley0

Description

@cdaley0

To Reproduce

dotnet format on Linux reports no issues with the following code:

public partial class MyClass : IEquatable<MyClass>
{
    public bool Equals(MyClass? other) => throw new NotImplementedException();

    public override bool Equals(object? obj) => Equals(obj as MyClass);

    public override int GetHashCode() => throw new NotImplementedException();

    public static bool operator ==(MyClass? lhs, MyClass? rhs) => lhs is null ? rhs is null : lhs.Equals(rhs);

    public static bool operator !=(MyClass? lhs, MyClass? rhs) => !(lhs == rhs);
} 

However, running dotnet format --verify-no-changes results in a CS0660 warning if I use the OneOf library's source generator.

[GenerateOneOf]
public partial class MyClass : OneOfBase<string, double>, IEquatable<MyClass>
{
    public bool Equals(MyClass? other) => throw new NotImplementedException();

    public override bool Equals(object? obj) => Equals(obj as MyClass);

    public override int GetHashCode() => throw new NotImplementedException();

    public static bool operator ==(MyClass? lhs, MyClass? rhs) => lhs is null ? rhs is null : lhs.Equals(rhs);

    public static bool operator !=(MyClass? lhs, MyClass? rhs) => !(lhs == rhs);
}

[GenerateOneOf] causes an additional partial class definition for MyClass to be created. This seems to be confusing dotnet format and making it believe that object.Equals has not been overridden even though it has. I get:

error CS0660: 'MyClass' defines operator == or operator != but does not override Object.Equals(object o)

Running dotnet-format without --verify-no-changes causes it to insert a second object.Equals override which then causes the code to fail to compile.

Note that this issue does not occur with the windows version of dotnet format.

Exceptions (if any)

Further technical details

details of dotnet --info

.NET SDK: Version: 10.0.105 Commit: a612c2a105 Workload version: 10.0.100-manifests.0793c108 MSBuild version: 18.0.11+a612c2a10

Runtime Environment:
OS Name: ubuntu
OS Version: 24.04
OS Platform: Linux
RID: ubuntu.22.04-x64
Base Path: /var/snap/dotnet/common/dotnet/sdk/10.0.105/

.NET workloads installed:
There are no installed workloads to display.
Configured to use workload sets when installing new manifests.
No workload sets are installed. Run "dotnet workload restore" to install a workload set.

Host:
Version: 10.0.5
Architecture: x64
Commit: a612c2a105

.NET SDKs installed:
10.0.105 [/var/snap/dotnet/common/dotnet/sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 10.0.5 [/var/snap/dotnet/common/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 10.0.5 [/var/snap/dotnet/common/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
None

Environment variables:
DOTNET_INSTALL_DIR [/var/snap/dotnet/common/dotnet]

global.json file:
Not found

Learn more:
https://aka.ms/dotnet/info

Download .NET:
https://aka.ms/dotnet/download

- The IDE (VS / VS Code/ VS4Mac) you're running on, and its version

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions