Skip to content

Add diagnostics for record struct and record class declarations#52106

Open
BillWagner wants to merge 7 commits intodotnet:mainfrom
BillWagner:record-based-errors
Open

Add diagnostics for record struct and record class declarations#52106
BillWagner wants to merge 7 commits intodotnet:mainfrom
BillWagner:record-based-errors

Conversation

@BillWagner
Copy link
Member

@BillWagner BillWagner commented Mar 6, 2026

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR documents C# 9 and C# 10 compiler diagnostics related to record, record struct, and record class declarations, and wires the new documentation into the C# language reference navigation so F1/help keyword routing can land on a specific article instead of the generic “no specifics” page.

Changes:

  • Add a new “Record declarations” compiler-messages article covering CS8851, CS8858–CS8866, CS8870–CS8879, CS8907–CS8908, and CS8913.
  • Add the new article to the C# language reference TOC under “C# compiler messages”.
  • Remove newly documented diagnostic IDs from the generic “Sorry, we don’t have specifics…” fallback list.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md Removes record-related diagnostic IDs that are now covered by a dedicated article.
docs/csharp/language-reference/toc.yml Adds a new TOC entry for the record-declarations diagnostics article.
docs/csharp/language-reference/compiler-messages/record-declaration-errors.md New documentation page describing record declaration-related errors/warnings and how to resolve them.

@BillWagner BillWagner requested a review from gewarren March 6, 2026 18:07

To correct these errors, apply the following changes to your explicitly declared record members:

1. Change the accessibility of the `Equals` method, `GetHashCode`, `ToString`, the deconstruct method, and the `EqualityContract` property or `op_Equality` and `op_Inequality` operators to `public`. The compiler requires these members to be publicly accessible so that value-based [equality](../builtin-types/record.md#value-equality) works correctly across all calling contexts (**CS8873**).
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this really be an ordered list?


To correct these errors, apply the following changes to your positional record declarations:

1. Change any explicitly declared member that corresponds to a positional parameter so that it's a readable instance property or field with the same type as the parameter. The compiler needs the member to be readable and type-compatible so that the synthesized `Deconstruct` method and [positional pattern matching](../../fundamentals/functional/pattern-matching.md) can access the value correctly (**CS8866**).
Copy link
Contributor

Choose a reason for hiding this comment

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

Same question.


1. Change any explicitly declared member that corresponds to a positional parameter so that it's a readable instance property or field with the same type as the parameter. The compiler needs the member to be readable and type-compatible so that the synthesized `Deconstruct` method and [positional pattern matching](../../fundamentals/functional/pattern-matching.md) can access the value correctly (**CS8866**).
1. Ensure that each positional parameter is used to initialize its corresponding property in the constructor body when you provide an explicit constructor. The compiler raises a warning when a parameter goes unused because it typically indicates a typo or a mismatch between the parameter name and the property name, which would leave the property uninitialized (**CS8907**).
1. Change the type of a field declared in a record to a type that's valid in that context. Certain types, such as `Span<T>` or other ref struct types, can't be used as fields in a record because record types require all fields to be compatible with heap allocation and value-based equality (**CS8908**).
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
1. Change the type of a field declared in a record to a type that's valid in that context. Certain types, such as `Span<T>` or other ref struct types, can't be used as fields in a record because record types require all fields to be compatible with heap allocation and value-based equality (**CS8908**).
1. Change the type of a field declared in a record to a type that's valid in that context. Certain types, such as `Span<T>` or other `ref struct` types, can't be used as fields in a record because record types require all fields to be compatible with heap allocation and value-based equality (**CS8908**).


To correct these errors, apply the following changes:

1. Add a `GetHashCode` method whenever you define an `Equals` method. The [equality contract](../../programming-guide/statements-expressions-operators/equality-comparisons.md) requires that objects considered equal produce the same hash code, so the compiler enforces that these two methods are always defined together (**CS8851**).
Copy link
Contributor

Choose a reason for hiding this comment

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

Ordered list?


To correct these errors, apply the following changes:

1. Change the base type of a record class so that it inherits from `object` or from another record class. Record types rely on compiler-synthesized members for equality and copying that are only compatible with other record types, so the compiler doesn't allow a record to inherit from a non-record class (**CS8864**).
Copy link
Contributor

Choose a reason for hiding this comment

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

Ordered list?


To correct these errors, apply the following changes:

1. Rename any member called `Clone` in a record type to a different name. The compiler uses `Clone` internally to implement the copy semantics for [`with` expressions](../operators/with-expression.md), so declaring your own `Clone` member conflicts with the synthesized implementation (**CS8859**).
Copy link
Contributor

Choose a reason for hiding this comment

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

Ordered list?

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[C# 10 diagnostics] record struct and record class

3 participants