From 096ddeb4bc7d5ea17d612155a8c027839ad30b9d Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 18:10:44 -0400 Subject: [PATCH 01/14] Add inline array feature --- standard/conversions.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/standard/conversions.md b/standard/conversions.md index 0144c757c..02c255ed0 100644 --- a/standard/conversions.md +++ b/standard/conversions.md @@ -443,6 +443,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 5436db04b8d9046386a02c226dbf15ae4ae266ac Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 18:13:36 -0400 Subject: [PATCH 02/14] Add inline array feature --- standard/conversions.md | 1 + 1 file changed, 1 insertion(+) diff --git a/standard/conversions.md b/standard/conversions.md index 02c255ed0..e5cda956a 100644 --- a/standard/conversions.md +++ b/standard/conversions.md @@ -691,6 +691,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 3d79ceab71e72f5f68895602d918afc88c4e732f Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 18:20:33 -0400 Subject: [PATCH 03/14] Add inline array feature --- standard/expressions.md | 157 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 155 insertions(+), 2 deletions(-) diff --git a/standard/expressions.md b/standard/expressions.md index 0ae84f22b..c61af5dd6 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -2443,7 +2443,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). @@ -2459,10 +2459,12 @@ 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)). #### 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: @@ -2496,6 +2498,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 66fd51ce5da08c46ff096991ed65942d71dfafa2 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 18:24:23 -0400 Subject: [PATCH 04/14] Add inline array feature --- standard/structs.md | 89 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/standard/structs.md b/standard/structs.md index d60c82349..01fae3468 100644 --- a/standard/structs.md +++ b/standard/structs.md @@ -461,6 +461,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 Class and struct differences ### 16.5.1 General From d301dc2e8fd32246366d32c760b028c165fb7e04 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 18:28:11 -0400 Subject: [PATCH 05/14] Add inline array feature --- standard/attributes.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/standard/attributes.md b/standard/attributes.md index a64dda4e7..0a440923d 100644 --- a/standard/attributes.md +++ b/standard/attributes.md @@ -500,6 +500,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.10.1](attributes.md#235101-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.11.1](attributes.md#235111-the-setsrequiredmembers-attribute)) and `System.Runtime.CompilerServices.RequiredMemberAttribute` ([§23.5.11.2](attributes.md#235112-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)). @@ -1523,6 +1524,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 no `IndexerName` attribute is present for an indexer, then the name `Item` is used by default. The `IndexerName` attribute enables a developer to override this default and specify a different name. From ff8bf02b2f15554e4d826dd7bde768d9ddbeaf48 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 18:32:45 -0400 Subject: [PATCH 06/14] Add inline array feature --- standard/standard-library.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/standard/standard-library.md b/standard/standard-library.md index b12154453..2f8eddd66 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); @@ -1492,6 +1500,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 a0cef5c9843c58ce2eb82bc490260a7152a7b1cb Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 18:49:02 -0400 Subject: [PATCH 07/14] fix md formatting --- standard/structs.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/standard/structs.md b/standard/structs.md index 01fae3468..0ce765740 100644 --- a/standard/structs.md +++ b/standard/structs.md @@ -461,7 +461,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)). @@ -522,7 +522,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. @@ -1241,7 +1241,9 @@ The safe-context of an object initializer expression is the narrowest of: 3. The safe-context of the RHS of assignments in member initializers to non-readonly setters, or the ref-safe-context in the case of ref assignment. > *Note*: Another way of modeling this is to consider any argument to a member initializer that can be assigned to the receiver as being an argument to the constructor. *end note* + + > *Example*: The following illustrates how an object initializer narrows the safe-context of the resulting value: > > From 42b8860d036dd9634649290657526678ba601d9b Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 18:52:12 -0400 Subject: [PATCH 08/14] fix md formatting --- standard/attributes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/attributes.md b/standard/attributes.md index 0a440923d..7b8996a54 100644 --- a/standard/attributes.md +++ b/standard/attributes.md @@ -1524,7 +1524,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 06331def01a2753dda34869db9b18410f761be22 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 18:53:48 -0400 Subject: [PATCH 09/14] fix md formatting --- standard/conversions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/conversions.md b/standard/conversions.md index e5cda956a..07d05bf0c 100644 --- a/standard/conversions.md +++ b/standard/conversions.md @@ -451,7 +451,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 d6ca674ebfe7daace24b9e2dcfef69bfc3f3a21c Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 19:03:20 -0400 Subject: [PATCH 10/14] fix md formatting --- standard/expressions.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/standard/expressions.md b/standard/expressions.md index c61af5dd6..9ed8bcbcf 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -2544,7 +2544,7 @@ with *argument* as the index, on an instance of `System.ReadOnlySpan` that wa ```csharp static T GetItem(«InlineArrayType» array) -``` +``` > *Example*: > @@ -2586,7 +2586,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`** @@ -2608,15 +2608,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 0ba1b1f25589c7e860f5662a15d159106fca672e Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 6 Apr 2026 19:09:45 -0400 Subject: [PATCH 11/14] fix links --- standard/expressions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/expressions.md b/standard/expressions.md index 9ed8bcbcf..9b10bab19 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -2459,7 +2459,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)). #### 12.8.12.2 Array access From 011068cf0448a8e58465038a3c4399bd1c034e5f Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Tue, 7 Apr 2026 06:58:51 -0400 Subject: [PATCH 12/14] fix md formatting --- standard/expressions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/expressions.md b/standard/expressions.md index 9b10bab19..7afdcd4cf 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -2526,7 +2526,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 b4e248434a3e212b15cf8810d61398edfa1a6708 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Tue, 7 Apr 2026 07:06:27 -0400 Subject: [PATCH 13/14] fix md formatting --- standard/expressions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/expressions.md b/standard/expressions.md index 7afdcd4cf..249cab0f9 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -2512,7 +2512,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 950f0f192e8081bd1825550d636d0536cb18ad55 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Tue, 7 Apr 2026 07:08:23 -0400 Subject: [PATCH 14/14] fix md formatting --- standard/expressions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/expressions.md b/standard/expressions.md index 249cab0f9..ea03d6c25 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -2596,7 +2596,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)