Skip to content

A record that declares operator == doesn't compile in C# (CS0111) or Rust (E0119) because the record already supplies equality #301

Closed

Description

@matt-edmondson

What's wrong

A ClassDeclaration { IsRecord = true } with a member FunctionDeclaration("==") { Kind = FunctionKind.Operator } generates output that doesn't compile in two targets.

  • C#: the generator writes public record class Point with the user's operator ==, and the comparison-pair logic from C#: declaring only one of a comparison operator pair (==/!=, </>, <=/>=) generates code that fails with CS0216 #236 (MissingComparisonPartners, Coder/Languages/CSharpGenerator.cs around L321) adds operator !=. A C# record already synthesises both operators, so the compiler rejects both:

    • error CS0111: Type 'Point' already defines a member called 'op_Equality' with the same parameter types
    • the same error for op_Inequality

    Declaring only != fails the same way, because the partner logic then adds ==.

  • Rust: the record gets #[derive(Clone, Debug, PartialEq)] (Coder/Languages/RustGenerator.cs around L591-595), and the declared == becomes impl PartialEq for Point { fn eq ... } (the operator-trait mapping around L229 and L813). The result is error[E0119]: conflicting implementations of trait 'PartialEq' for type 'Point'.

Reproduction

Build this AST: a record Point with an int x field and bool operator ==(Point rhs) returning true. Generate C# and Rust, then compile the output with dotnet build and rustc. You get the errors above. The same AST without IsRecord compiles in both targets.

Suggested fix

  • C#: when a record declares == or !=, don't emit the operator itself and don't run MissingComparisonPartners for ==/!=. Either write the user's equality as public virtual bool Equals(Point? other) (records let you override that), or write the inexpressible note.
  • Rust: leave PartialEq out of the record's derive list when the type declares == (or !=), so the user's impl PartialEq is the only one.

Acceptance criteria

  • C# and Rust compile tests (*GeneratedSourceCompilesTests) cover:
    • a record that declares ==
    • a record that declares only !=
  • Records that don't declare equality operators keep their current output.

Activity

  1. matt-edmondson commented on Oct 19, 2026

    @matt-edmondson
    ContributorAuthor

    Triage


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions