Skip to content

Commit

Permalink
Add, update compiler error and warning messages for ref struct inte…
Browse files Browse the repository at this point in the history
…rfaces (#41948)

* Add, update messages in dotnet/roslyn#73567

The PR for `ref struct` interfaces added new compiler error and warning messages. It also updates a few messages. This commit creates the stubs for the new messages, and updates the text for updated messages.

* incorporate additional ref struct error conditions

* Edit pass
  • Loading branch information
BillWagner authored Jul 31, 2024
1 parent 598f078 commit a4fa2cd
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 64 deletions.
4 changes: 4 additions & 0 deletions .openpublishing.redirection.csharp.json
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,10 @@
"source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs8964.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/parameter-argument-mismatch"
},
{
"source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs9050.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/ref-struct-errors"
},
{
"source_path_from_root": "/docs/csharp/language-reference/compiler-options/addmodule-compiler-option.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-options/inputs"
Expand Down
45 changes: 0 additions & 45 deletions docs/csharp/language-reference/compiler-messages/cs9050.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ f1_keywords:
- "CS9194"
- "CS9202"
- "CS9211"
- "CS9240"
helpviewer_keywords:
- "CS0171"
- "CS0188"
Expand Down Expand Up @@ -105,6 +106,7 @@ helpviewer_keywords:
- "CS9194"
- "CS9202"
- "CS9211"
- "CS9240"
ms.date: 11/02/2023
---
# Resolve warnings related to language features and versions
Expand Down Expand Up @@ -146,6 +148,7 @@ That's be design. The text closely matches the text of the compiler error / warn
- **CS9194**: *Argument may not be passed with the `ref` keyword. To pass `ref` arguments to `in` parameters, upgrade to language version 12 or greater.*
- **CS9202**: *Feature is not available in C# 12.0. Please use newer language version*
- **CS9211**: *The diagnosticId argument to the 'Experimental' attribute must be a valid identifier.*
- **CS9240**: *Target runtime doesn't support by-ref-like generics.*

In addition, the following errors and warnings relate to struct initialization changes in recent versions:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ f1_keywords:
- "CS8332"
- "CS8337"
- "CS8338"
- "CS8345"
- "CS8351"
- "CS8373"
- "CS8374"
Expand Down Expand Up @@ -98,7 +97,6 @@ helpviewer_keywords:
- "CS8332"
- "CS8337"
- "CS8338"
- "CS8345"
- "CS8351"
- "CS8373"
- "CS8374"
Expand Down Expand Up @@ -172,7 +170,6 @@ That's by design. The text closely matches the text of the compiler error / warn
- [**CS8332**](#writable-reference-variables-require-a-writable-referent): *Cannot assign to a member of variable or use it as the right hand side of a `ref` assignment because it is a readonly variable*
- [**CS8337**](#reference-variable-restrictions): *The first parameter of a '`ref`' extension method must be a value type or a generic type constrained to struct.*
- [**CS8338**](#reference-variable-restrictions): *The first '`in`' or '`ref readonly`' parameter of the extension method must be a concrete (non-generic) value type.*
- [**CS8345**](#ref-safety-violations): *Field or auto-implemented property cannot be of type unless it is an instance member of a `ref struct`.*
- [**CS8351**](#ref-safety-violations): *Branches of a `ref` conditional operator cannot refer to variables with incompatible declaration scopes*
- [**CS8373**](#incorrect-syntax): *The left-hand side of a `ref` assignment must be a ref variable.*
- [**CS8374**](#ref-safety-violations): *Cannot ref-assign source has a narrower escape scope than destination.*
Expand All @@ -183,8 +180,8 @@ That's by design. The text closely matches the text of the compiler error / warn
- [**CS9078**](#ref-safety-violations): *Cannot return by reference a member of parameter through a `ref` parameter; it can only be returned in a return statement*
- [**CS9079**](#ref-safety-violations): *Cannot ref-assign because source can only escape the current method through a return statement.*
- [**CS9096**](#ref-safety-violations): *Cannot ref-assign because source has a wider value escape scope than destination allowing assignment through source of values with narrower escapes scopes than destination.*
- [**CS9101**](#unscoped-ref-restrictions): *UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members.*
- [**CS9102**](#unscoped-ref-restrictions): *UnscopedRefAttribute cannot be applied to an interface implementation.*
- [**CS9101**](#unscoped-ref-restrictions): *UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members.*
- [**CS9102**](#unscoped-ref-restrictions): *UnscopedRefAttribute cannot be applied to an interface implementation because implemented member doesn't have this attribute.*
- [**CS9104**](#reference-variable-restrictions): *A `using` statement resource of type cannot be used in async methods or async lambda expressions.*
- [**CS9190**](#incorrect-syntax): *`readonly` modifier must be specified after `ref`.*
- [**CS9199**](#reference-variable-restrictions): *A `ref readonly` parameter cannot have the Out attribute.*
Expand Down Expand Up @@ -285,8 +282,8 @@ To fix the error, remove the reference variable where it isn't allowed:

The `unscoped` qualifier on `ref` parameters isn't allowed in some locations:

- **CS9101**: *UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or or init-only members.*
- **CS9102**: *UnscopedRefAttribute cannot be applied to an interface implementation.*
- **CS9101**: *UnscopedRefAttribute can only be applied to struct instance or virtual interface methods and properties, and cannot be applied to constructors or or init-only members.*
- **CS9102**: *UnscopedRefAttribute cannot be applied to an interface implementation because implemented member doesn't have this attribute..*

You must remove the `unscoped` modifier on the parameter declaration that caused the error.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
title: Errors and warnings associated with `ref struct` types
description: Learn about errors and warnings related to `ref struct` types. The compiler enforces several restrictions on `ref struct` types to enforce ref safety rules
f1_keywords:
- "CS8343"
- "CS8344"
- "CS8345"
- "CS9048"
- "CS9050"
- "CS9059"
- "CS9241"
- "CS9242"
- "CS9243"
- "CS9244"
- "CS9245"
- "CS9246"
- "CS9247"
helpviewer_keywords:
- "CS8343"
- "CS8344"
- "CS8345"
- "CS9048"
- "CS9050"
- "CS9059"
- "CS9241"
- "CS9242"
- "CS9243"
- "CS9244"
- "CS9245"
- "CS9246"
- "CS9247"
ms.date: 07/30/2024
---
# Errors and warnings associated with `ref struct` types

- [**CS8343**](#ref-struct-interface-implementations): *`ref structs` cannot implement interfaces*
- [**CS8344**](#ref-struct-interface-implementations): *`foreach` statement cannot operate on enumerators in async or iterator methods because type is a `ref struct` or a type parameter that allows `ref struct`.*
- [**CS8345**](#ref-safety-violations): *Field or auto-implemented property cannot be of type unless it is an instance member of a `ref struct`.*
- [**CS9048**](#ref-safety-violations): *The `scoped` modifier can be used for refs and `ref struct` values only.*
- [**CS9050**](#ref-safety-violations): *A `ref` field cannot refer to a `ref struct`.*
- [**CS9059**](#ref-safety-violations): *A ref field can only be declared in a ref struct.*
- [**CS9241**](#ref-struct-interface-implementations): *'ref struct' is already specified.*
- [**CS9242**](#ref-struct-interface-implementations): *The 'allows' constraint clause must be the last constraint specified.*
- [**CS9243**](#ref-struct-interface-implementations): *Cannot allow ref structs for a type parameter known from other constraints to be a class.*
- [**CS9244**](#ref-struct-interface-implementations): *The type may not be a `ref struct` or a type parameter allowing ref structs in order to use it as parameter in the generic type or method.*
- [**CS9245**](#ref-struct-interface-implementations): *Type cannot implement interface member for `ref struct` type.*
- [**CS9246**](#ref-struct-interface-implementations): *A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct.*
- [**CS9247**](#ref-struct-interface-implementations): *foreach statement cannot operate on enumerators of type because it is a type parameter that allows ref struct and it is not known at compile time to implement `IDisposable`.*

## ref safety violations

- **CS8345**: *Field or auto-implemented property cannot be of type unless it is an instance member of a `ref struct`.*
- **CS9048**: *The `scoped` modifier can be used for refs and `ref struct` values only.*
- **CS9050**: *A `ref` field cannot refer to a `ref struct`.*
- **CS9059**: *A `ref` field can only be declared in a `ref struct`.*

A [`ref struct`](../builtin-types/ref-struct.md) type can include `ref` fields. Other types aren't allowed `ref` fields. The compiler enforces restrictions on the declarations and use of `ref struct` types to enforce ref safety rules on instances of any `ref struct` type:

- Only `ref struct` types can contain auto-implemented `ref` properties.
- Only `ref struct` types or `ref` variables can have the `scoped` modifier.
- A `ref` field can be declared only in a `ref struct` type.
- A `ref` field can't refer to a `ref struct` type/

Violating any of these rules produces one of the listed errors. If you intended to use that language feature, convert the type to a `ref struct`. Otherwise, remove the disallowed construct.

## ref struct interface implementations

- **CS8343**: *`ref structs` cannot implement interfaces*
- **CS8344**: *`foreach` statement cannot operate on enumerators in async or iterator methods because type is a `ref struct` or a type parameter that allows `ref struct`.*
- **CS9241**: *'ref struct' is already specified.*
- **CS9242**: *The 'allows' constraint clause must be the last constraint specified.*
- **CS9243**: *Cannot allow ref structs for a type parameter known from other constraints to be a class.*
- **CS9244**: *The type may not be a `ref struct` or a type parameter allowing ref structs in order to use it as parameter in the generic type or method.*
- **CS9245**: *Type cannot implement interface member for `ref struct` type.*
- **CS9246**: *A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct.*
- **CS9247**: *foreach statement cannot operate on enumerators of type because it is a type parameter that allows ref struct and it is not known at compile time to implement `IDisposable`.*

Prior to C# 13, [`ref struct`](../builtin-types/ref-struct.md) types can't implement interfaces; the compiler generates *CS8343*. Beginning with C# 13, `ref struct` types can implement interfaces, subject to the following rules:

- A `ref struct` can't be converted to an instance of an interface it implements. This restriction includes the implicit conversion when you use a `ref struct` type as an argument when the parameter is an interface type. The conversion results in a boxing conversion, which violates ref safety.
- A `ref struct` that implements an interface *must* implement all interface members. The `ref struct` must implement members where the interface includes a default implementation.

Beginning with C# 13, a `ref struct` can be used as a type argument for a generic type parameter, if and only if the generic type parameter has the [`allows ref struct`](../../programming-guide/generics/constraints-on-type-parameters.md#allows-ref-struct) anti-constraint. When you use the `allows ref struct` anti-constraint you must follow these rules:

- A `ref struct` is used as a type argument, the type parameter *must* have the `allows ref struct` anti-constraint.- The `allows ref struct` anti-constraint must be last in the `where` clause for that parameter
- Uses of instances the type parameter must obey ref safety rules.
1 change: 1 addition & 0 deletions docs/csharp/language-reference/keywords/ref.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ You use the `ref` keyword in the following contexts:
- As the part of a [conditional ref expression](../operators/conditional-operator.md#conditional-ref-expression) or a [ref assignment operator](../operators/assignment-operator.md#ref-assignment).
- In a `struct` declaration, to declare a `ref struct`. For more information, see the [`ref` structure types](../builtin-types/ref-struct.md) article.
- In a `ref struct` definition, to declare a `ref` field. For more information, see the [`ref` fields](../builtin-types/ref-struct.md#ref-fields) section of the [`ref` structure types](../builtin-types/ref-struct.md) article.
- In a generic type declaration to specify that a type parameter [`allows ref struct`](../../programming-guide/generics/constraints-on-type-parameters.md#allows-ref-struct) types.
17 changes: 10 additions & 7 deletions docs/csharp/language-reference/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ items:
CS0171, CS0188, CS0843, CS8904, CS1738, CS8022, CS8023, CS8024, CS8025, CS8026, CS8058, CS8059, CS8107, CS8192, CS8302,
CS8303, CS8304, CS8305, CS8306, CS8314, CS8320, CS8370, CS8371, CS8400, CS8401, CS8511, CS8627, CS8630, CS8652, CS8703,
CS8704, CS8706, CS8773, CS8912, CS8919, CS8929, CS8936, CS8957, CS8967, CS9014, CS9015, CS9016, CS9017, CS9058, CS9064,
CS9103, CS9171, CS9194, CS9202, CS9204
CS9103, CS9171, CS9194, CS9202, CS9204, CS9240
- name: Assembly references
href: ./compiler-messages/assembly-references.md
displayName: >
Expand All @@ -460,10 +460,15 @@ items:
displayName: >
ref safety,
CS0192, CS0199, CS0206, CS0631, CS0767, CS1510, CS1605, CS1623, CS1649, CS1651, CS1655, CS1657, CS1741, CS1939, CS1988,
CS7084, CS8166, CS8167, CS8168, CS8169. CS8325, CS8326, CS8327, CS8329, CS8330, CS8331, CS8332, CS8337, CS8338, CS8345,
CS8351, CS8373, CS8374, CS8388, CS8977, CS9072, CS9077, CS9078, CS9079, CS9085, CS9086, CS9087, CS9089, CS9091, CS9092,
CS9093, CS9094, CS9095, CS9096, CS9097, CS9101, CS9102, CS9104, CS9190, CS9191, CS9192, CS9193, CS9195, CS9196, CS9197,
CS9198, CS9199, CS9200, CS9201
CS7084, CS8166, CS8167, CS8168, CS8169. CS8325, CS8326, CS8327, CS8329, CS8330, CS8331, CS8332, CS8337, CS8338, CS8351,
CS8373, CS8374, CS8388, CS8977, CS9072, CS9077, CS9078, CS9079, CS9085, CS9086, CS9087, CS9089, CS9091, CS9092, CS9093,
CS9094, CS9095, CS9096, CS9097, CS9101, CS9102, CS9104, CS9190, CS9191, CS9192, CS9193, CS9195, CS9196, CS9197, CS9198,
CS9199, CS9200, CS9201
- name: "`ref struct` types"
href: ./compiler-messages/ref-struct-errors.md
displayName: >
ref struct,
CS8343, CS8344, CS8345, CS9048, CS9050, CS9059, CS9241, CS9242, CS9243, CS9244, CS9245, CS9246, CS9247
- name: Iterator methods
href: ./compiler-messages/iterator-yield.md
displayName: >
Expand Down Expand Up @@ -2012,8 +2017,6 @@ items:
href: ./compiler-messages/CS8817.md
- name: CS9043
href: ./compiler-messages/cs9043.md
- name: CS9050
href: ./compiler-messages/cs9050.md
- name: Level 1 warning messages
items:
- name: CS0183
Expand Down
2 changes: 1 addition & 1 deletion docs/csharp/misc/cs0401.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ms.assetid: 94eac5a8-7344-44d2-9d0c-a9954993603d
---
# Compiler Error CS0401

The new() constraint must be the last constraint specified
The new() constraint must be the last restrictive constraint specified

When using multiple constraints, list all other constraints before the new() constraint.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,6 @@ f1_keywords:
- "CS8340"
- "CS8341"
- "CS8342"
- "CS8343"
- "CS8344"
- "CS8346"
- "CS8347"
- "CS8348"
Expand Down Expand Up @@ -584,15 +582,13 @@ f1_keywords:
- "CS9045"
- "CS9046"
- "CS9047"
- "CS9048"
- "CS9049"
- "CS9051"
- "CS9052"
- "CS9053"
- "CS9054"
- "CS9056"
- "CS9057"
- "CS9059"
- "CS9060"
- "CS9061"
- "CS9062"
Expand Down

0 comments on commit a4fa2cd

Please sign in to comment.