From 03d9c1e86d2d0271f1c0007decf64da63627738c Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 18:10:44 -0400 Subject: [PATCH 01/20] Add inline array feature Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/conversions.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/standard/conversions.md b/standard/conversions.md index 4aedc39f9..978862cbb 100644 --- a/standard/conversions.md +++ b/standard/conversions.md @@ -460,6 +460,16 @@ Although an implicit conversion to `object` is permitted, a warning shall be iss > > *end example* +### §ImplicitInlineArrayConversions Implicit inline array conversions + +The implicit inline array (§InlineArray) conversions are: + +- From an expression designating a writable inline array with element type `T` to `System.Span` +- From an expression designating a writable inline array with element type `T` to `System.ReadonlySpan` +- From an expression designating a readonly inline array with element type `T` to `System.ReadonlySpan` + +The conversion of an inline array to a `System.Span` or `System.ReadonlySpan` ignores any declared operators in the inline array type that might otherwise appear to be applicable. See §InlineArray for more information.] + ## 10.3 Explicit conversions ### 10.3.1 General From 0d9aec73893db7e7f3b41667e025af98799e4cfe Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 18:13:36 -0400 Subject: [PATCH 02/20] Add inline array feature Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/conversions.md | 1 + 1 file changed, 1 insertion(+) diff --git a/standard/conversions.md b/standard/conversions.md index 978862cbb..45836ebc1 100644 --- a/standard/conversions.md +++ b/standard/conversions.md @@ -714,6 +714,7 @@ The following implicit conversions are classified as standard implicit conversio - Boxing conversions ([§10.2.9](conversions.md#1029-boxing-conversions)) - Implicit constant expression conversions ([§10.2.11](conversions.md#10211-implicit-constant-expression-conversions)) - Implicit conversions involving type parameters ([§10.2.12](conversions.md#10212-implicit-conversions-involving-type-parameters)) +- Implicit inline array conversions (§ImplicitInlineArrayConversions) The standard implicit conversions specifically exclude user-defined implicit conversions. From f0d8bea08782a106c27390295a426d3463243df3 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 18:20:33 -0400 Subject: [PATCH 03/20] Add inline array feature Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/expressions.md | 157 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 155 insertions(+), 2 deletions(-) diff --git a/standard/expressions.md b/standard/expressions.md index 35091f18d..af9a5b3d8 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -2424,7 +2424,7 @@ The *primary_expression* of an *element_access* shall not be an *array_creation_ An *element_access* is dynamically bound ([§12.3.3](expressions.md#1233-dynamic-binding)) if at least one of the following holds: - The *primary_expression* has compile-time type `dynamic`. -- At least one expression of the *argument_list* has compile-time type `dynamic`. +- At least one expression of the *argument_list* has compile-time type `dynamic`, and the *primary_no_array_creation_expression* does not have an inline array type (§InlineArray) or there is more than one *argument* in the *argument_list*. In this case the compile-time type of the *element_access* depends on the compile-time type of its *primary_expression*: if it has an array type then the compile-time type is the element type of that array type; otherwise the compile-time type is `dynamic` and the *element_access* is classified as a value of type `dynamic`. The rules below to determine the meaning of the *element_access* are then applied at run-time, using the run-time type instead of the compile-time type of those of the *primary_expression* and *argument_list* expressions which have the compile-time type `dynamic`. If the *primary_expression* does not have compile-time type `dynamic`, then the element access undergoes a limited compile-time check as described in [§12.6.5](expressions.md#1265-compile-time-checking-of-dynamic-member-invocation). @@ -2440,7 +2440,7 @@ In this case the compile-time type of the *element_access* depends on the compil > > *end example* -If the *primary_expression* of an *element_access* is: +If the *primary_expression* of an *element_access* is a value of an *array_type*, the *element_access* is an array access ([§12.8.11.2](expressions.md#128112-array-access)). Otherwise, if the *primary_no_array_creation_expression* of an *element_access* is a variable or value of an inline array type and the *argument_list* consists of a single argument, the *element_access* is an inline array element access (§InlineArrayElementAccess). Otherwise, the *primary_no_array_creation_expression* shall be a variable or value of a class, struct, or interface type that has one or more indexer members, in which case the *element_access* is an indexer access ([§12.8.11.3](expressions.md#128113-indexer-access)). - a value of an array type, the *element_access* is an array access ([§12.8.12.2](expressions.md#128122-array-access)); - a value of `string` type, the *element_access* is a string access ([§12.8.12.3](expressions.md#128123-string-access)); @@ -2448,6 +2448,8 @@ If the *primary_expression* of an *element_access* is: #### 12.8.12.2 Array access +For access to elements in an inline array (§InlineArray) see §InlineArrayElementAccess. + For an array access the *argument_list* shall not contain named arguments or by-reference arguments ([§15.6.2.3](classes.md#15623-by-reference-parameters)). The number of expressions in the *argument_list* shall be the same as the rank of the *array_type*, and each expression shall be: @@ -2481,6 +2483,157 @@ The run-time processing of an array access of the form `P[A]`, where `P` is a *p - The value of each expression in the *argument_list* is checked against the actual bounds of each dimension of the array instance referenced by `P`. If one or more values are out of range, a `System.IndexOutOfRangeException` is thrown and no further steps are executed. - The variable reference of the array element given by the index expressions is computed, and this becomes the result of the array access. +#### §InlineArrayElementAccess Inline array element access + +For access to an element in an inline array (§InlineArray), the *primary_no_array_creation_expression* of the *element_access* shall designate an inline array. Furthermore, the *argument_list* shall contain a single *argument*, which is not a named argument ([§12.6.2.1](expressions.md#12621-general)). That *argument* shall be of type `int`, or be implicitly convertible to type `int`, `System.Index`, or `System.Range`. + +It is a compile-time error if *argument* is a constant expression whose value results in an index outside the bounds of the inline array. If at runtime the value of *argument* results in an index outside the bounds of the inline array, a `System.IndexOutOfRangeException` is thrown. + +**When *argument*’s type is `int`** + +If *primary_no_array_creation_expression* is a writable variable, the result of evaluating an inline array element access is a writable variable equivalent to invoking the indexer + +```csharp +public ref T this[int index] { get; } +``` + +with *argument* as the index, on an instance of `System.Span` that was created from the inline array designated by *primary_no_array_creation_expression*. For the purpose of ref-safety analysis, the safe-context ([§9.7.2.1]variables.md#9721-general)) of the access is equivalent to that for an invocation of a method with the signature + +```csharp +static ref T GetItem(ref «InlineArrayType» array) +``` + +The resulting variable is considered movable if and only if *primary_no_array_creation_expression* is movable. + +If *primary_no_array_creation_expression* is a readonly variable, the result of evaluating an inline array element access is a readonly variable equivalent to invoking the indexer + +```csharp +public ref readonly T this[int index] { get; } +``` + +with *argument* as the index, on an instance of `System.ReadOnlySpan` that was created from the inline array designated by *primary_no_array_creation_expression*. For the purpose of ref-safety analysis, the safe-context of the access is equivalent to that for an invocation of a method with the signature + +```csharp +static ref readonly T GetItem(in «InlineArrayType» array) +``` + +The resulting variable is considered movable if and only if *primary_no_array_creation_expression* is movable. + +If *primary_no_array_creation_expression* is a value, the result of evaluating an inline array element access is a value equivalent to invoking the indexer + +```csharp +public ref readonly T this[int index] { get; } +``` + +with *argument* as the index, on an instance of `System.ReadOnlySpan` that was created from the inline array designated by *primary_no_array_creation_expression*. For the purpose of ref-safety analysis the safe-context of the access are equivalent to that for an invocation of a method with the signature + +```csharp +static T GetItem(«InlineArrayType» array) +``` + +> *Example*: +> +> +> ```csharp +> [System.Runtime.CompilerServices.InlineArray(10)] +> public struct Buffer10 +> { +> private T _element0; +> } +> public class Program +> { +> void M1(Buffer10 x) +> { +> ref int a = ref x[0]; // OK +> } +> void M2(in Buffer10 x) +> { +> ref readonly int a = ref x[0]; // OK +> ref int b = ref x[0]; // Error; x is readonly +> } +> Buffer10 GetBuffer() => default; +> void M3() +> { +> int a = GetBuffer()[0]; // OK +> ref readonly int b = ref GetBuffer()[0];// Error, rhs is a value +> ref int c = ref GetBuffer()[0]; // Error; rhs is a value +> } +> } +> ``` +> +> *end example* + +**When *argument*’s type is implicitly convertible to `int`** + +The value of *argument* is converted to `int` and the element access is interpreted as described when *argument*’s type is `int` + +**When *argument*’s type is implicitly convertible to `System.Index`** + +*argument* is converted to `System.Index` and then to an `int`-based index value indicating the element position relative to the start of the inline array. Then, the element access is interpreted as described when *argument*’s type is `int`. + +Using an index of `System.Index` to access an element in a non-inline array is described in [§12.8.12.2](expressions.md#128122-array-access). However, note carefully that that process is *not* used when an inline array is indexed using a `System.Index`. Specifically, an inline array element access ignores any declared indexers in the inline array type. See §InlineArray for more information .] + +**When *argument*’s type is implicitly convertible to `System.Range`** + +If *primary_no_array_creation_expression* is a writable variable, the result of evaluating an inline array element access is a variable equivalent to invoking the method + +```csharp +public Span Slice (int start, int length) +``` + +passing the `int` equivalents of the Range’s start and end Indexes, respectively, on an instance of `System.Span` that was created from the inline array designated by *primary_no_array_creation_expression*. For the purpose of ref-safety analysis, the safe-context ([§9.7.2.1]variables.md#9721-general)) of the access is equivalent to that for an invocation of a method with the signature + +```csharp +static System.Span GetSlice(ref «InlineArrayType» array) +``` + +If *primary_no_array_creation_expression* is a readonly variable, the result of evaluating an inline array element access is a value equivalent to invoking the method + +```csharp +public ReadOnlySpan Slice (int start, int length) +``` + +passing the `int` equivalents of the Range’s start and end Indexes, respectively, on an instance of `System.ReadOnlySpan` that was created from the inline array designated by *primary_no_array_creation_expression*. For the purpose of ref-safety analysis, the safe-context of the access is equivalent to that for an invocation of a method with the signature + +```csharp +static System.ReadOnlySpan GetSlice(in «InlineArrayType» array) +``` + +Using an index of `System.Range` to access an element in a non-inline array is described in [§12.8.12.2](expressions.md#128122-array-access). However, note carefully that that process is *not* used when an inline array is indexed using a `System.Range`. Specifically, an inline array element access ignores any declared Slice methods in the inline array type. See §InlineArray for more information .] + +If *primary_no_array_creation_expression* is a value, an error is reported. + +> *Example*: +> +> +> +> ```csharp +> [System.Runtime.CompilerServices.InlineArray(10)] +> public struct Buffer10 +> { +> private T _element0; +> } +> public class Program +> { +> void M1(Buffer10 x) +> { +> System.Span a = x[..]; // OK +> } +> void M2(in Buffer10 x) +> { +> System.ReadOnlySpan a = x[..]; // OK +> System.Span b = x[..]; // Error; no implicit conversion +> } +> Buffer10 GetBuffer() => default; +> void M3() +> { +> _ = GetBuffer()[..]; // Error; rhs is a value +> } +> } +> ``` +> +> *end example* + #### 12.8.12.3 String access For a string access the *argument_list* of the *element_access* shall contain a single unnamed value argument ([§15.6.2.2](classes.md#15622-value-parameters)) which shall be: From 04007afabb16531901809dfdeb5c07ef2f91f2b7 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 18:24:23 -0400 Subject: [PATCH 04/20] Add inline array feature Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/structs.md | 89 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/standard/structs.md b/standard/structs.md index 830439f33..82b9b9bc6 100644 --- a/standard/structs.md +++ b/standard/structs.md @@ -462,6 +462,95 @@ constructor declaration. The body of the method assigns each parameter of the De If the instance members accessed in the body do not include a property with a non-`readonly` `get` accessor, then the synthesized `Deconstruct` method is `readonly`. The method can be declared explicitly. It is an error if the explicit declaration does not match the expected signature or accessibility, or is static. +## §InlineArray Inline arrays + +A struct type decorated with the attribute `System.Runtime.CompilerServices.InlineArrayAttribute` (§InlineArrayAttribute) is an ***inline array type***, which is a managed type. An instance of that type is an ***inline array***, a structure that contains a contiguous block of a given number of elements of the same type, and nothing else. It’s the safe-code equivalent of unsafe-code’s fixed-size buffer ([§24.8](unsafe-code.md#248-fixed-size-buffers)). + +With some limitations (see later below), an inline array can be used like an array ([§17](arrays.md#17-arrays)). + +Consider the following: + + +```csharp +var buffer = new Buffer(); + +for (int i = 0; i < 5; ++i) +{ + buffer[i] = i; +} + +foreach (var i in buffer) +{ + Console.WriteLine(i); +} + +Console.WriteLine($"buffer[^2] = >{buffer[^2]}<"); +Console.WriteLine($"buffer[1..^0][0] = >{buffer[1..^0][0]}<"); + +[System.Runtime.CompilerServices.InlineArray(5)] +public struct Buffer +{ + private int _element0; + // other, optional, non-instance-field members +} +``` + +which produces this output: + +```console +0 +1 +2 +3 +4 +buffer[^2] = >3< +buffer[1..^0][0] = >1< +``` + +The attribute constructor requires a positive-valued `int` argument that indicates the number of elements in each inline array created from this type, in this case, five. The struct type shall declare exactly one instance field, whose type becomes that of the inline array’s elements. The accessibility of the instance field has no impact on the program’s ability to access the inline array via its struct-instance name, in this case, `buffer`. + +There are a number of restrictions on the instance field’s declaration: + +- It shall not contain the *field_modifier*s `readonly`, `ref`, `required`, or `volatile`. +- It shall not be declared as a *fixed_size_buffer_declaration* ([§24.8](unsafe-code.md#248-fixed-size-buffers)). +- *type* shall be a type valid as a type argument. + +`buffer` is an instance of `Buffer`, and contains an array of five `int` with element `buffer[0]` occupying the same memory as `buffer._element0`. However, unlike an array type, which has a public `Length` property, `buffer` is not derived from `System.Array`, and has no such member. + +> *Note*: One could add a public `Length` property to `Buffer` (which returns `sizeof(Buffer)/sizeof(int)`, but that property would have to be an unsafe member. Alternatively, one could perform an implicit conversion to `System.Span` or `System.ReadOnlySpan` and use their `Length` property. *end note* + +An inline array is a collection; as such, it can be iterated over by a `foreach` statement, as shown. + +The elements of the inline array can be accessed for read or write via subscripting (§InlineArrayElementAccess). + +A list pattern (11.2.x[rcj1.1]) shall not be used in the context of an inline array. + +An inline array type is a valid constructible collection target type for a collection literal. + +Any indexers or `Slice` methods declared for an inline array type that have signatures matching those defined for non-inline array processing, shall not be used during inline array element access. +> *Example*: Consider the following: +> +> +```csharp +> var buffer = new Buffer(); +> int x = buffer[2]; // element access +> +> [System.Runtime.CompilerServices.InlineArray(5)] +> public struct Buffer +> { +> private int _element0; +> public int this[int index] // NOT USED for element access +> { +> get +> { +> … +> } +> } +> } +> ``` +> +> Even though the struct declares an indexer taking an `int` argument, that indexer is not used by element access `buffer[2]`. *end example* + ## 16.5 Record struct and non-record struct differences A record struct differs from a non-record struct in several important ways: From 537281eade3365bab9ef06d019195af65aa7fab0 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 18:28:11 -0400 Subject: [PATCH 05/20] Add inline array feature Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/attributes.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/standard/attributes.md b/standard/attributes.md index 7e051460c..f0455ee23 100644 --- a/standard/attributes.md +++ b/standard/attributes.md @@ -512,6 +512,7 @@ A number of attributes affect the language in some way. These attributes include - `System.Runtime.CompilerServices.InterpolatedStringHandlerAttribute` and `System.Runtime.CompilerServices.InterpolatedStringHandlerArgumentAttribute`, which are used to declare a custom interpolated string expression handler ([§23.5.11.1](attributes.md#235111-custom-interpolated-string-expression-handlers)) and to call one of its constructors, respectively. - System.Diagnostics.CodeAnalysis.UnscopedRefAttribute ([§23.5.8](attributes.md#2358-the-unscopedref-attribute)), which allows an otherwise implicitly scoped ref to be treated as not being scoped. - `System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute` ([§23.5.12.1](attributes.md#235121-the-setsrequiredmembers-attribute)) and `System.Runtime.CompilerServices.RequiredMemberAttribute` ([§23.5.12.2](attributes.md#235122-the-requiredmember-attribute)), which are used in required-member contexts ([§15.7.1](classes.md#1571-general)). +- `System.Runtime.CompilerServices.InlineArrayAttribute` (§InlineArrayAttribute), which marks a struct type as an inline array type (§InlineArray). The Nullable static analysis attributes ([§23.5.7](attributes.md#2357-code-analysis-attributes)) can improve the correctness of warnings generated for nullabilities and null states ([§8.9.5](types.md#895-nullabilities-and-null-states)). @@ -1577,6 +1578,10 @@ This attribute indicates that the constructor it decorates sets all required mem This attribute indicates that the current type has one or more required members ([§15.7.1](classes.md#1571-general)), or that a specific member of that type is required. However, it is an error for this attribute to be used explicitly. Instead, the presence of the modifier `required` results in the type or member being treated as if it were decorated with this attribute. +### §InlineArrayAttribute The InlineArray attribute + +The attribute `InlineArray` is used to identify a non-record struct as an inline array type. For further information and examples of its use, see §InlineArray. + ## 23.6 Attributes for interoperation For interoperation with other languages, an indexer may be implemented using indexed properties. If the indexer is not decorated with `IndexerNameAttribute`, then the name `Item` is used by default. `IndexerNameAttribute` enables a developer to override this default and specify a different name. From 124aeb0f4d8414229bf783407b539f8470e8320b Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 18:32:45 -0400 Subject: [PATCH 06/20] Add inline array feature Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/standard-library.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/standard/standard-library.md b/standard/standard-library.md index 0a9b31518..a1da19db4 100644 --- a/standard/standard-library.md +++ b/standard/standard-library.md @@ -892,6 +892,14 @@ namespace System.Runtime.CompilerServices void UnsafeOnCompleted(Action continuation); } + [AttributeUsage(AttributeTargets.Struct, AllowMultiple=false)] + public sealed class InlineArrayAttribute : Attribute + { + public InlineArrayAttribute(int length); + + public int Length { get; } + } + public interface INotifyCompletion { void OnCompleted(Action continuation); @@ -1525,6 +1533,7 @@ The following library types are referenced in this specification. The full names - `global::System.Runtime.CompilerServices.FormattableStringFactory` - `global::System.Runtime.CompilerServices.ICriticalNotifyCompletion` - `global::System.Runtime.CompilerServices.IndexerNameAttribute` +- `global::System.Runtime.CompilerServices.InlineArrayAttribute` - `global::System.Runtime.CompilerServices.INotifyCompletion` - `global::System.Runtime.CompilerServices.InterpolatedStringHandlerArgumentAttribute` - `global::System.Runtime.CompilerServices.InterpolatedStringHandlerAttribute` From d4770a60efb9a2205fa739c4dcb544264d74e2f1 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 18:49:02 -0400 Subject: [PATCH 07/20] fix md formatting Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/structs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/standard/structs.md b/standard/structs.md index 82b9b9bc6..165af1fc8 100644 --- a/standard/structs.md +++ b/standard/structs.md @@ -462,7 +462,7 @@ constructor declaration. The body of the method assigns each parameter of the De If the instance members accessed in the body do not include a property with a non-`readonly` `get` accessor, then the synthesized `Deconstruct` method is `readonly`. The method can be declared explicitly. It is an error if the explicit declaration does not match the expected signature or accessibility, or is static. -## §InlineArray Inline arrays +## §InlineArray Inline arrays A struct type decorated with the attribute `System.Runtime.CompilerServices.InlineArrayAttribute` (§InlineArrayAttribute) is an ***inline array type***, which is a managed type. An instance of that type is an ***inline array***, a structure that contains a contiguous block of a given number of elements of the same type, and nothing else. It’s the safe-code equivalent of unsafe-code’s fixed-size buffer ([§24.8](unsafe-code.md#248-fixed-size-buffers)). @@ -523,7 +523,7 @@ An inline array is a collection; as such, it can be iterated over by a `foreach` The elements of the inline array can be accessed for read or write via subscripting (§InlineArrayElementAccess). -A list pattern (11.2.x[rcj1.1]) shall not be used in the context of an inline array. +A list pattern ([§11.2.11](patterns.md#11211-list-pattern)) shall not be used in the context of an inline array. An inline array type is a valid constructible collection target type for a collection literal. From 3303db31f605e8051a0af7ebd15ed32bcfb6e9c2 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 18:52:12 -0400 Subject: [PATCH 08/20] fix md formatting Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/attributes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/attributes.md b/standard/attributes.md index f0455ee23..bcea5f643 100644 --- a/standard/attributes.md +++ b/standard/attributes.md @@ -1578,7 +1578,7 @@ This attribute indicates that the constructor it decorates sets all required mem This attribute indicates that the current type has one or more required members ([§15.7.1](classes.md#1571-general)), or that a specific member of that type is required. However, it is an error for this attribute to be used explicitly. Instead, the presence of the modifier `required` results in the type or member being treated as if it were decorated with this attribute. -### §InlineArrayAttribute The InlineArray attribute +### §InlineArrayAttribute The InlineArray attribute The attribute `InlineArray` is used to identify a non-record struct as an inline array type. For further information and examples of its use, see §InlineArray. From 218a994973a516d411c5dee7ba5da745b171cf6b Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 18:53:48 -0400 Subject: [PATCH 09/20] fix md formatting Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/conversions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/conversions.md b/standard/conversions.md index 45836ebc1..33b54d857 100644 --- a/standard/conversions.md +++ b/standard/conversions.md @@ -468,7 +468,7 @@ The implicit inline array (§InlineArray) conversions are: - From an expression designating a writable inline array with element type `T` to `System.ReadonlySpan` - From an expression designating a readonly inline array with element type `T` to `System.ReadonlySpan` -The conversion of an inline array to a `System.Span` or `System.ReadonlySpan` ignores any declared operators in the inline array type that might otherwise appear to be applicable. See §InlineArray for more information.] +The conversion of an inline array to a `System.Span` or `System.ReadonlySpan` ignores any declared operators in the inline array type that might otherwise appear to be applicable. See §InlineArray for more information. ## 10.3 Explicit conversions From 3841ca0e0f60dfc4f96dfce73ef07b2333e4cc70 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 19:03:20 -0400 Subject: [PATCH 10/20] fix md formatting Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/expressions.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/standard/expressions.md b/standard/expressions.md index af9a5b3d8..f6459c013 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -2529,7 +2529,7 @@ with *argument* as the index, on an instance of `System.ReadOnlySpan` that wa ```csharp static T GetItem(«InlineArrayType» array) -``` +``` > *Example*: > @@ -2571,7 +2571,7 @@ The value of *argument* is converted to `int` and the element access is interpre *argument* is converted to `System.Index` and then to an `int`-based index value indicating the element position relative to the start of the inline array. Then, the element access is interpreted as described when *argument*’s type is `int`. -Using an index of `System.Index` to access an element in a non-inline array is described in [§12.8.12.2](expressions.md#128122-array-access). However, note carefully that that process is *not* used when an inline array is indexed using a `System.Index`. Specifically, an inline array element access ignores any declared indexers in the inline array type. See §InlineArray for more information .] +Using an index of `System.Index` to access an element in a non-inline array is described in [§12.8.12.2](expressions.md#128122-array-access). However, note carefully that that process is *not* used when an inline array is indexed using a `System.Index`. Specifically, an inline array element access ignores any declared indexers in the inline array type. See §InlineArray for more information. **When *argument*’s type is implicitly convertible to `System.Range`** @@ -2593,15 +2593,15 @@ If *primary_no_array_creation_expression* is a readonly variable, the result of public ReadOnlySpan Slice (int start, int length) ``` -passing the `int` equivalents of the Range’s start and end Indexes, respectively, on an instance of `System.ReadOnlySpan` that was created from the inline array designated by *primary_no_array_creation_expression*. For the purpose of ref-safety analysis, the safe-context of the access is equivalent to that for an invocation of a method with the signature +passing the `int` equivalents of the Range’s start and end Indexes, respectively, on an instance of `System.ReadOnlySpan` that was created from the inline array designated by *primary_no_array_creation_expression*. For the purpose of ref-safety analysis, the safe-context of the access is equivalent to that for an invocation of a method with the signature ```csharp static System.ReadOnlySpan GetSlice(in «InlineArrayType» array) ``` -Using an index of `System.Range` to access an element in a non-inline array is described in [§12.8.12.2](expressions.md#128122-array-access). However, note carefully that that process is *not* used when an inline array is indexed using a `System.Range`. Specifically, an inline array element access ignores any declared Slice methods in the inline array type. See §InlineArray for more information .] +Using an index of `System.Range` to access an element in a non-inline array is described in [§12.8.12.2](expressions.md#128122-array-access). However, note carefully that that process is *not* used when an inline array is indexed using a `System.Range`. Specifically, an inline array element access ignores any declared Slice methods in the inline array type. See §InlineArray for more information. -If *primary_no_array_creation_expression* is a value, an error is reported. +If *primary_no_array_creation_expression* is a value, an error is reported. > *Example*: > From f47e7108627c9827846b1b591f5370b2bc202acd Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 19:09:45 -0400 Subject: [PATCH 11/20] fix links Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/expressions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/expressions.md b/standard/expressions.md index f6459c013..a964adba3 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -2440,7 +2440,7 @@ In this case the compile-time type of the *element_access* depends on the compil > > *end example* -If the *primary_expression* of an *element_access* is a value of an *array_type*, the *element_access* is an array access ([§12.8.11.2](expressions.md#128112-array-access)). Otherwise, if the *primary_no_array_creation_expression* of an *element_access* is a variable or value of an inline array type and the *argument_list* consists of a single argument, the *element_access* is an inline array element access (§InlineArrayElementAccess). Otherwise, the *primary_no_array_creation_expression* shall be a variable or value of a class, struct, or interface type that has one or more indexer members, in which case the *element_access* is an indexer access ([§12.8.11.3](expressions.md#128113-indexer-access)). +If the *primary_expression* of an *element_access* is a value of an *array_type*, the *element_access* is an array access ([§12.8.12.2](expressions.md#128122-array-access)). Otherwise, if the *primary_no_array_creation_expression* of an *element_access* is a variable or value of an inline array type and the *argument_list* consists of a single argument, the *element_access* is an inline array element access (§InlineArrayElementAccess). Otherwise, the *primary_no_array_creation_expression* shall be a variable or value of a class, struct, or interface type that has one or more indexer members, in which case the *element_access* is an indexer access ([§12.8.12.4](expressions.md#128124-indexer-access)). - a value of an array type, the *element_access* is an array access ([§12.8.12.2](expressions.md#128122-array-access)); - a value of `string` type, the *element_access* is a string access ([§12.8.12.3](expressions.md#128123-string-access)); From d2ed38915905713a3578ba2c6ce8b812f758be25 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Tue, 7 Apr 2026 06:58:51 -0400 Subject: [PATCH 12/20] fix md formatting Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/expressions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/expressions.md b/standard/expressions.md index a964adba3..36bfffe47 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -2511,7 +2511,7 @@ If *primary_no_array_creation_expression* is a readonly variable, the result of public ref readonly T this[int index] { get; } ``` -with *argument* as the index, on an instance of `System.ReadOnlySpan` that was created from the inline array designated by *primary_no_array_creation_expression*. For the purpose of ref-safety analysis, the safe-context of the access is equivalent to that for an invocation of a method with the signature +with *argument* as the index, on an instance of `System.ReadOnlySpan` that was created from the inline array designated by *primary_no_array_creation_expression*. For the purpose of ref-safety analysis, the safe-context of the access is equivalent to that for an invocation of a method with the signature ```csharp static ref readonly T GetItem(in «InlineArrayType» array) From 364c6f2bf3a3776f03f8000b0a6f6ce90b25a79d Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Tue, 7 Apr 2026 07:06:27 -0400 Subject: [PATCH 13/20] fix md formatting Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/expressions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/expressions.md b/standard/expressions.md index 36bfffe47..67308dc4c 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -2497,7 +2497,7 @@ If *primary_no_array_creation_expression* is a writable variable, the result of public ref T this[int index] { get; } ``` -with *argument* as the index, on an instance of `System.Span` that was created from the inline array designated by *primary_no_array_creation_expression*. For the purpose of ref-safety analysis, the safe-context ([§9.7.2.1]variables.md#9721-general)) of the access is equivalent to that for an invocation of a method with the signature +with *argument* as the index, on an instance of `System.Span` that was created from the inline array designated by *primary_no_array_creation_expression*. For the purpose of ref-safety analysis, the safe-context ([§9.7.2.1](variables.md#9721-general)) of the access is equivalent to that for an invocation of a method with the signature ```csharp static ref T GetItem(ref «InlineArrayType» array) From eac9ec817ac726d0a8a15c7852dbacd427981c8e Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Tue, 7 Apr 2026 07:08:23 -0400 Subject: [PATCH 14/20] fix md formatting Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/expressions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/expressions.md b/standard/expressions.md index 67308dc4c..da73848ef 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -2581,7 +2581,7 @@ If *primary_no_array_creation_expression* is a writable variable, the result of public Span Slice (int start, int length) ``` -passing the `int` equivalents of the Range’s start and end Indexes, respectively, on an instance of `System.Span` that was created from the inline array designated by *primary_no_array_creation_expression*. For the purpose of ref-safety analysis, the safe-context ([§9.7.2.1]variables.md#9721-general)) of the access is equivalent to that for an invocation of a method with the signature +passing the `int` equivalents of the Range’s start and end Indexes, respectively, on an instance of `System.Span` that was created from the inline array designated by *primary_no_array_creation_expression*. For the purpose of ref-safety analysis, the safe-context ([§9.7.2.1](variables.md#9721-general)) of the access is equivalent to that for an invocation of a method with the signature ```csharp static System.Span GetSlice(ref «InlineArrayType» array) From 83df14042e3abb900f4c73945884603b01f6fc97 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Tue, 15 Sep 2026 11:20:47 -0400 Subject: [PATCH 15/20] tweak attribute text Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/attributes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/attributes.md b/standard/attributes.md index bcea5f643..80b31055b 100644 --- a/standard/attributes.md +++ b/standard/attributes.md @@ -1580,7 +1580,7 @@ This attribute indicates that the current type has one or more required members ### §InlineArrayAttribute The InlineArray attribute -The attribute `InlineArray` is used to identify a non-record struct as an inline array type. For further information and examples of its use, see §InlineArray. +This attribute is used to identify a non-record struct as an inline array type. For further information and examples of its use, see §InlineArray. ## 23.6 Attributes for interoperation From 3319449b8b48da5411293bc9b709cabf568f44f4 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Mon, 21 Sep 2026 17:09:32 -0400 Subject: [PATCH 16/20] Fix inline array links and example metadata Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bce5e82a-89fd-4655-bc08-6d6ba97f0cc6 Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/structs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/standard/structs.md b/standard/structs.md index 165af1fc8..ba29692e3 100644 --- a/standard/structs.md +++ b/standard/structs.md @@ -523,14 +523,14 @@ An inline array is a collection; as such, it can be iterated over by a `foreach` The elements of the inline array can be accessed for read or write via subscripting (§InlineArrayElementAccess). -A list pattern ([§11.2.11](patterns.md#11211-list-pattern)) shall not be used in the context of an inline array. +A list pattern (§list-pattern-new-clause) shall not be used in the context of an inline array. An inline array type is a valid constructible collection target type for a collection literal. Any indexers or `Slice` methods declared for an inline array type that have signatures matching those defined for non-inline array processing, shall not be used during inline array element access. > *Example*: Consider the following: > -> +> ```csharp > var buffer = new Buffer(); > int x = buffer[2]; // element access From b7102b458283acf1f289ce19105dccc854a727d3 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Mon, 21 Sep 2026 17:22:38 -0400 Subject: [PATCH 17/20] Compile inline array indexer example Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bce5e82a-89fd-4655-bc08-6d6ba97f0cc6 Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/structs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/standard/structs.md b/standard/structs.md index ba29692e3..e27d8a70b 100644 --- a/standard/structs.md +++ b/standard/structs.md @@ -530,7 +530,7 @@ An inline array type is a valid constructible collection target type for a colle Any indexers or `Slice` methods declared for an inline array type that have signatures matching those defined for non-inline array processing, shall not be used during inline array element access. > *Example*: Consider the following: > -> +> ```csharp > var buffer = new Buffer(); > int x = buffer[2]; // element access @@ -543,7 +543,7 @@ Any indexers or `Slice` methods declared for an inline array type that have sign > { > get > { -> … +> return 0; > } > } > } From eee052f5ec50a0b142036a6450a817497d392440 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Mon, 21 Sep 2026 20:16:23 -0400 Subject: [PATCH 18/20] Use finalized list pattern cross-reference Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bce5e82a-89fd-4655-bc08-6d6ba97f0cc6 Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/structs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/structs.md b/standard/structs.md index e27d8a70b..049779cc8 100644 --- a/standard/structs.md +++ b/standard/structs.md @@ -523,7 +523,7 @@ An inline array is a collection; as such, it can be iterated over by a `foreach` The elements of the inline array can be accessed for read or write via subscripting (§InlineArrayElementAccess). -A list pattern (§list-pattern-new-clause) shall not be used in the context of an inline array. +A list pattern ([§11.2.11](patterns.md#11211-list-pattern)) shall not be used in the context of an inline array. An inline array type is a valid constructible collection target type for a collection literal. From ea339180da93bd4c69afd1223eb60bac30a58bce Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Tue, 22 Sep 2026 11:51:44 -0400 Subject: [PATCH 19/20] Apply suggestion from @BillWagner Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/structs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/structs.md b/standard/structs.md index 049779cc8..afbae0c4d 100644 --- a/standard/structs.md +++ b/standard/structs.md @@ -531,7 +531,7 @@ Any indexers or `Slice` methods declared for an inline array type that have sign > *Example*: Consider the following: > > -```csharp +> ```csharp > var buffer = new Buffer(); > int x = buffer[2]; // element access > From 0cb9b6a20bd851fb7b9d25d5a66d34d43b0ff863 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Wed, 14 Oct 2026 14:31:24 -0400 Subject: [PATCH 20/20] Remove feature-owned trailing whitespace in C12 source #1620 Only trailing whitespace in the authoritative feature additions; all non-whitespace source content, code tokens, annotations and normative wording unchanged. Preserve the source-owned inline-array blockquote correction. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21570b74-c6f5-4fc5-ab6d-7546918d6ddb --- standard/expressions.md | 2 +- standard/structs.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/standard/expressions.md b/standard/expressions.md index da73848ef..0f92441ba 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -2554,7 +2554,7 @@ static T GetItem(«InlineArrayType» array) > Buffer10 GetBuffer() => default; > void M3() > { -> int a = GetBuffer()[0]; // OK +> int a = GetBuffer()[0]; // OK > ref readonly int b = ref GetBuffer()[0];// Error, rhs is a value > ref int c = ref GetBuffer()[0]; // Error; rhs is a value > } diff --git a/standard/structs.md b/standard/structs.md index afbae0c4d..e90107d7b 100644 --- a/standard/structs.md +++ b/standard/structs.md @@ -491,7 +491,7 @@ Console.WriteLine($"buffer[1..^0][0] = >{buffer[1..^0][0]}<"); public struct Buffer { private int _element0; - // other, optional, non-instance-field members + // other, optional, non-instance-field members } ``` @@ -539,7 +539,7 @@ Any indexers or `Slice` methods declared for an inline array type that have sign > public struct Buffer > { > private int _element0; -> public int this[int index] // NOT USED for element access +> public int this[int index] // NOT USED for element access > { > get > {