diff --git a/standard/arrays.md b/standard/arrays.md index 7f0611678..56131fc25 100644 --- a/standard/arrays.md +++ b/standard/arrays.md @@ -114,7 +114,7 @@ Elements of arrays created by *array_creation_expression*s are always initialize Array elements are accessed using the *array access* variant of *element_access* expressions ([§12.8.12.2](expressions.md#128122-array-access)) of the form `A[I₁, I₂, ..., Iₓ]`, where `A` is an expression of an array type and each `Iₑ` is an expression of type `int`, `uint`, `long`, `ulong`, or can be implicitly converted to one or more of these types. The result of an array access is a variable reference ([§9.5](variables.md#95-variable-references)) to the array element selected by the indices. -Array elements of single-dimensional arrays can also be accessed using an array access expression where the sole index, `I₁`, is an expression of type `Index`, `Range`, or can be implicitly converted to one or both of these types. If `I₁` is of type `Index`, or has been implicitly converted to that type, then the result of the array access is a variable reference to the array element selected by the index value. If `I₁` is of type `Range`, or has been implicitly converted to that type, then the result of the element access is a new array formed from a shallow copy of the array elements with indices in the `Range`, maintaining the element order. +Array elements of single-dimensional arrays can also be accessed using an array access expression where the sole index, `I₁`, is an expression of type `Index`, `Range`, or can be implicitly converted to one or both of these types. If `I₁` is of type `Index`, or has been implicitly converted to that type, then the result of the array access is a variable reference to the array element selected by the index value. If `I₁` is of type `Range`, or has been implicitly converted to that type, then the result of the array access is a new array formed from a shallow copy of the array elements with indices in the `Range`, maintaining the element order. The elements of an array can be enumerated using a `foreach` statement ([§13.9.5](statements.md#1395-the-foreach-statement)). diff --git a/standard/attributes.md b/standard/attributes.md index ab1108635..a92828783 100644 --- a/standard/attributes.md +++ b/standard/attributes.md @@ -1074,7 +1074,7 @@ It is an error if the `System.Runtime.CompilerServices.EnumeratorCancellation` a - The `EnumeratorCancellation` attribute is applied to a parameter of a type other than `CancellationToken`, - or if the `EnumeratorCancellation` attribute is applied to a parameter on a method that is not an asynchronous iterator ([§15.15](classes.md#1515-synchronous-and-asynchronous-iterators)), -- or if the `EnumeratorCancellation` attribute is applied to a parameter on a method that returns an asynchronous enumerable interface ([§15.15.3](classes.md#15153-enumerable-interfaces)) rather than an asynchronous enumerator interface ([§15.15.2](classes.md#15152-enumerator-interfaces)). +- or if the `EnumeratorCancellation` attribute is applied to a parameter on a method that returns an asynchronous enumerator interface ([§15.15.2](classes.md#15152-enumerator-interfaces)) rather than an asynchronous enumerable interface ([§15.15.3](classes.md#15153-enumerable-interfaces)). The iterator will not have access to the `CancellationToken` argument for `GetAsyncEnumerator` when no attributes have this parameter. diff --git a/standard/basic-concepts.md b/standard/basic-concepts.md index 46ad70efa..499c701e7 100644 --- a/standard/basic-concepts.md +++ b/standard/basic-concepts.md @@ -282,7 +282,7 @@ Depending on the context in which a member declaration takes place, only certain > *Note*: A type declared as a member of a class can have any of the permitted kinds of declared accessibility, whereas a type declared as a member of a namespace can have only `public` or `internal` declared accessibility. *end note* - Struct members can have `public`, `internal`, or `private` declared accessibility and default to `private` declared accessibility because structs are implicitly sealed. Struct members introduced in a `struct` (that is, not inherited by that struct) cannot have `protected`, `protected internal`, or `private protected` declared accessibility. > *Note*: A type declared as a member of a struct can have `public`, `internal`, or `private` declared accessibility, whereas a type declared as a member of a namespace can have only `public` or `internal` declared accessibility. *end note* -- Interface members implicitly have `public` declared accessibility. No access modifiers are allowed on interface member declarations. +- Interface members implicitly have `public` declared accessibility. - Enumeration members implicitly have `public` declared accessibility. No access modifiers are allowed on enumeration member declarations. ### 7.5.3 Accessibility domains diff --git a/standard/conversions.md b/standard/conversions.md index 7c382d757..bd77516f0 100644 --- a/standard/conversions.md +++ b/standard/conversions.md @@ -396,7 +396,7 @@ The following conversions are classified as explicit conversions: - Explicit nullable conversions ([§10.3.4](conversions.md#1034-explicit-nullable-conversions)) - Explicit tuple conversions ([§10.3.6](conversions.md#1036-explicit-tuple-conversions)) - Explicit reference conversions ([§10.3.5](conversions.md#1035-explicit-reference-conversions)) -- Explicit interface conversions +- Explicit interface conversions (§10.3.5) - Unboxing conversions ([§10.3.7](conversions.md#1037-unboxing-conversions)) - Explicit type parameter conversions ([§10.3.8](conversions.md#1038-explicit-conversions-involving-type-parameters)) - User-defined explicit conversions ([§10.3.9](conversions.md#1039-user-defined-explicit-conversions)) diff --git a/standard/expressions.md b/standard/expressions.md index 66830f240..12fac7022 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -5077,7 +5077,7 @@ The null coalescing operator is right-associative, meaning that operations are g The type of the expression `a ?? b` depends on which implicit conversions are available on the operands. In order of preference, the type of `a ?? b` is `A₀`, `A`, or `B`, where `A` is the type of `a` (provided that `a` has a type), `B` is the type of `b`(provided that `b` has a type), and `A₀` is the underlying type of `A` if `A` is a nullable value type, or `A` otherwise. Specifically, `a ?? b` is processed as follows: -- If `A` exists and is an unmanaged type ([§8.8](types.md#88-unmanaged-types)) or known to be a non-nullable value type, a compile-time error occurs. +- If `A` exists and is a non-nullable value type or a pointer type in unsafe code, a compile-time error occurs. - Otherwise, if `A` exists and `b` is a dynamic expression, the result type is `dynamic`. At run-time, `a` is first evaluated. If `a` is not `null`, `a` is converted to `dynamic`, and this becomes the result. Otherwise, `b` is evaluated, and this becomes the result. - Otherwise, if `A` exists and is a nullable value type and an implicit conversion exists from `b` to `A₀`, the result type is `A₀`. At run-time, `a` is first evaluated. If `a` is not `null`, `a` is unwrapped to type `A₀`, and this becomes the result. Otherwise, `b` is evaluated and converted to type `A₀`, and this becomes the result. - Otherwise, if `A` exists and an implicit conversion exists from `b` to `A`, the result type is `A`. At run-time, `a` is first evaluated. If `a` is not `null`, `a` becomes the result. Otherwise, `b` is evaluated and converted to type `A`, and this becomes the result. diff --git a/standard/interfaces.md b/standard/interfaces.md index 0b7201a24..a84b055e2 100644 --- a/standard/interfaces.md +++ b/standard/interfaces.md @@ -100,7 +100,7 @@ A type T is ***output-unsafe*** if one of the following holds: - `T` is a contravariant type parameter - `T` is an array type with an output-unsafe element type -- `T` is an interface or delegate type `Sᵢ,... Aₑ` constructed from a generic type `S` where for at least one `Aᵢ` one of the following holds: +- `T` is an interface or delegate type `S` constructed from a generic type `S` where for at least one `Aᵢ` one of the following holds: - `Xᵢ` is covariant or invariant and `Aᵢ` is output-unsafe. - `Xᵢ` is contravariant or invariant and `Aᵢ` is input-unsafe. @@ -440,7 +440,7 @@ Interface properties are declared using *property_declaration*s ([§15.7.1](clas > *Note*: As an interface cannot contain instance fields, an interface property cannot be an instance auto-property, as that would require the declaration of implicit hidden instance fields. *end note* - The type of an interface property shall be output-safe if there is a get accessor, and shall be input-safe if there is a set accessor. -- An interface method declaration that has a block body or expression body as a *method_body* is `virtual`; the `virtual` modifier is not required, but is allowed. +- An interface property or interface property accessor declaration that has a block body or expression body is `virtual`; the `virtual` modifier is not required, but is allowed. - An instance *property_declaration* that has no implementation is `abstract`; the `abstract` modifier is not required, but is allowed. It is *never* considered to be an automatically implemented property ([§15.7.4](classes.md#1574-automatically-implemented-properties)). ### 19.4.5 Interface events @@ -451,9 +451,9 @@ Interface events are declared using *event_declaration*s ([§15.8.1](classes.md# - *event_modifier* shall not include `override`. - A derived interface may implement an abstract interface event declared in a base interface ([§15.8.5](classes.md#1585-virtual-sealed-override-and-abstract-accessors)). -- It is a compile-time error for *variable_declarators* in an instance *event_declaration* to contain any *variable_initializer*s. -- An instance event with the `virtual` or `sealed` modifiers must declare accessors. It is *never* considered to be an automatically implemented field-like event ([§15.8.2](classes.md#1582-field-like-events)). -- An instance event with the `abstract` modifier must not declare accessors. +- It is a compile-time error for *variable_declarators* in an interface *event_declaration* to contain any *variable_initializer*s. +- An interface event with the `virtual` or `sealed` modifiers must declare accessors. It is *never* considered to be an automatically implemented field-like event ([§15.8.2](classes.md#1582-field-like-events)). +- An interface event with the `abstract` modifier must not declare accessors. - The type of an interface event shall be input-safe. ### 19.4.6 Interface indexers @@ -1463,7 +1463,7 @@ When a class implements an interface, it implicitly also implements all that int ### 19.6.8 Abstract classes and interfaces -Like a non-abstract class, an abstract class shall provide implementations for all abstract members of the interfaces that are listed in the base class list of the class or struct which do not have a reachable implementation; where an implementation can become unreachable due to reabstraction [§19.4.3](interfaces.md#1943-interface-methods). However, an abstract class is permitted to map interface methods onto abstract methods. +Like a non-abstract class, an abstract class shall provide implementations for all abstract members of the interfaces that are listed in the base class list of the class which do not have a reachable implementation; where an implementation can become unreachable due to reabstraction [§19.4.3](interfaces.md#1943-interface-methods). However, an abstract class is permitted to map interface methods onto abstract methods. > *Example*: > diff --git a/standard/patterns.md b/standard/patterns.md index 8646f42c5..72d42d398 100644 --- a/standard/patterns.md +++ b/standard/patterns.md @@ -90,7 +90,7 @@ The runtime type of the value is tested against the *type* in the pattern using Given a pattern input value ([§11.1](patterns.md#111-general)) *e*, if the *simple_designation* is *discard_designation*, it denotes a discard ([§9.2.9.2](variables.md#9292-discards)), and the value of *e* is not bound to anything. (Although a declared variable with the name `_` may be in scope at that point, that named variable is not seen in this context.) Otherwise, if the *simple_designation* is *single_variable_designation*, a local variable ([§9.2.9](variables.md#929-local-variables)) of the given type named by the given identifier is introduced. That local variable is assigned the value of the pattern input value when the pattern *matches* the value. -Certain combinations of static type of the pattern input value and the given type are considered incompatible and result in a compile-time error. A value of static type `E` is said to be ***pattern compatible*** with the type `T` if there exists an identity conversion, an implicit or explicit reference conversion, a boxing conversion, or an unboxing conversion from `E` to `T`, or if either `E` or `T` is an open type ([§8.4.3](types.md#843-open-and-closed-types)). A declaration pattern naming a type `T` is *applicable to* every type `E` for which `E` is pattern compatible with `T`. +Certain combinations of static type of the pattern input value and the given type are considered incompatible and result in a compile-time error. A value of static type `E` is said to be ***pattern compatible*** with the type `T` if there exists an identity conversion, an implicit or explicit reference conversion, a boxing conversion, an unboxing conversion, or an implicit or explicit nullable value type conversion from `E` to `T`, or if either `E` or `T` is an open type ([§8.4.3](types.md#843-open-and-closed-types)). A declaration pattern naming a type `T` is *applicable to* every type `E` for which `E` is pattern compatible with `T`. > *Note*: The support for open types can be most useful when checking types that may be either struct or class types, and boxing is to be avoided. *end note* diff --git a/standard/portability-issues.md b/standard/portability-issues.md index 40f1f9eb8..05a15fb8c 100644 --- a/standard/portability-issues.md +++ b/standard/portability-issues.md @@ -32,9 +32,8 @@ A conforming implementation is required to document its choice of behavior in ea 1. The mechanism for determining whether a program is compiled as a class library or as an application. ([§7.1](basic-concepts.md#71-application-startup)) 1. The policy or mechanisms used by an implementation for the creation and destruction of application domains. ([§7.1](basic-concepts.md#71-application-startup)) 1. The exit code if the effective entry point method terminates due to an exception. ([§7.2](basic-concepts.md#72-application-termination)) -1. Whether or not finalizers are run as part of application termination. ([§7.2](basic-concepts.md#72-application-termination)) +1. Whether or not finalizers are run as part of application termination. ([§7.2](basic-concepts.md#72-application-termination), §7.9) 1. Whether APIs allow a finalizer to be run more than once. ([§7.9](basic-concepts.md#79-automatic-memory-management)) -1. Whether or not finalizers are run as part of application termination. ([§7.9](basic-concepts.md#79-automatic-memory-management)) 1. The API surface provided by `Expression` beyond the requirement for a `Compile` method. ([§8.6](types.md#86-expression-tree-types)) 1. The precise structure of the expression tree, as well as the exact process for creating it, when an anonymous function is converted to an expression-tree. ([§10.7.3](conversions.md#1073-evaluation-of-lambda-expression-conversions-to-expression-tree-types)) 1. The reason a conversion to a compatible delegate type may fail at compile-time. ([§10.7.3](conversions.md#1073-evaluation-of-lambda-expression-conversions-to-expression-tree-types)) diff --git a/standard/statements.md b/standard/statements.md index 654a36f98..566c113b4 100644 --- a/standard/statements.md +++ b/standard/statements.md @@ -1937,7 +1937,7 @@ non_ref_local_variable_declaration A ***resource type*** is either a class or non-ref struct that implements either or both of the `System.IDisposable` or `System.IAsyncDisposable` interfaces, which includes a single parameterless method named `Dispose` and/or `DisposeAsync`; or a ref struct that includes a method named `Dispose` having the same signature as that declared by `System.IDisposable`. Code that is using a resource can call `Dispose` or `DisposeAsync` to indicate that the resource is no longer needed. -If the form of *resource_acquisition* is *local_variable_declaration* then the type of the *local_variable_declaration* shall be either `dynamic` or a resource type. If the form of *resource_acquisition* is *expression* then this expression shall have a resource type. If `await` is present, the resource type shall implement `System.IAsyncDisposable`. A `ref struct` type cannot be the resource type for a `using` statement with the `await` modifier. +If the form of *resource_acquisition* is *non_ref_local_variable_declaration* then the type of the *non_ref_local_variable_declaration* shall be either `dynamic` or a resource type. If the form of *resource_acquisition* is *expression* then this expression shall have a resource type. If `await` is present, the resource type shall implement `System.IAsyncDisposable`. A `ref struct` type cannot be the resource type for a `using` statement with the `await` modifier. Local variables declared in a *resource_acquisition* are read-only, and shall include an initializer. A compile-time error occurs if the embedded statement attempts to modify these local variables (via assignment or the `++` and `--` operators), take the address of them, or pass them as reference or output parameters. diff --git a/standard/structs.md b/standard/structs.md index 749fa6cad..316c9c61c 100644 --- a/standard/structs.md +++ b/standard/structs.md @@ -69,16 +69,18 @@ It is a compile-time error if a ref struct type is used in any of the following - As the element type of an array. - As the declared type of a field of a class or a struct that does not have the `ref` modifier. -- Being boxed to `System.ValueType` or `System.Object`. - As a type argument. - As the type of a tuple element. -- An async method. -- An iterator. -- There is no conversion from a `ref struct` type to the type `object` or the type `System.ValueType`. +- In an async method. +- In an iterator. +- As the receiver type for a method group conversion to a delegate type. +- As a captured variable in a lambda expression or a local function. + +In addition, the following restrictions apply to a `ref struct` type: + +- A `ref struct` type shall not be boxed to `System.ValueType` or `System.Object`. - A `ref struct` type shall not be declared to implement any interface. - An instance method declared in `object` or in `System.ValueType` but not overridden in a `ref struct` type shall not be called with a receiver of that `ref struct` type. -- An instance method of a `ref struct` type shall not be captured by method group conversion to a delegate type. -- A ref struct shall not be captured by a lambda expression or a local function. > *Note*: A `ref struct` shall not declare `async` instance methods nor use a `yield return` or `yield break` statement within an instance method, because the implicit `this` parameter cannot be used in those contexts. *end note* diff --git a/standard/types.md b/standard/types.md index 0a275ffd0..d72ed6aca 100644 --- a/standard/types.md +++ b/standard/types.md @@ -381,7 +381,7 @@ The finite set of values of type `decimal` are of the form (–1)ᵛ × *c* × 1 A `decimal` is represented as an integer scaled by a power of ten. For `decimal`s with an absolute value less than `1.0m`, the value is exact to at least the 28th decimal place. For `decimal`s with an absolute value greater than or equal to `1.0m`, the value is exact to at least 28 digits. Contrary to the `float` and `double` data types, decimal fractional numbers such as `0.1` can be represented exactly in the decimal representation. In the `float` and `double` representations, such numbers often have non-terminating binary expansions, making those representations more prone to round-off errors. -If either operand of a binary operator is of `decimal` type then standard numeric promotions are applied, as detailed in [§12.4.7](expressions.md#1247-numeric-promotions), and the operation is performed with `double` precision. +If either operand of a binary operator is of `decimal` type then standard numeric promotions are applied, as detailed in [§12.4.7](expressions.md#1247-numeric-promotions), and the operation is performed with `decimal` precision. The result of an operation on values of type `decimal` is that which would result from calculating an exact result (preserving scale, as defined for each operator) and then rounding to fit the representation. Results are rounded to the nearest representable value, and, when a result is equally close to two representable values, to the value that has an even number in the least significant digit position (this is known as “banker’s rounding”). That is, results are exact to at least the 28th decimal place. Note that rounding may produce a zero value from a non-zero value. diff --git a/standard/unsafe-code.md b/standard/unsafe-code.md index 1929d0dd7..4d66346c8 100644 --- a/standard/unsafe-code.md +++ b/standard/unsafe-code.md @@ -121,7 +121,7 @@ A *pointer_type* is written as an *unmanaged_type* ([§8.8](types.md#88-unmanage ```ANTLR pointer_type - : value_type ('*')+ + : unmanaged_type ('*')+ | 'void' ('*')+ ; ```