diff --git a/standard/classes.md b/standard/classes.md index 6d81a34ae..e08b1b2b0 100644 --- a/standard/classes.md +++ b/standard/classes.md @@ -5387,7 +5387,7 @@ The compiler generates code that uses the «TaskBuilderType» to implement the s - `«TaskBuilderType».Create()` is invoked to create an instance of the «TaskBuilderType», named `builder` in this list. - `builder.Start(ref stateMachine)` is invoked to associate the builder with a compiler-generated state machine instance, `stateMachine`. - - The builder must call `stateMachine.MoveNext()` either in `Start()` or after `Start()` has returned to advance the state machine. + - The builder shall call `stateMachine.MoveNext()` either in `Start()` or after `Start()` has returned to advance the state machine. - After `Start()` returns, the `async` method invokes `builder.Task` for the task to return from the async method. - Each call to `stateMachine.MoveNext()` will advance the state machine. - If the state machine completes successfully, `builder.SetResult()` is called, with the method return value, if any. diff --git a/standard/delegates.md b/standard/delegates.md index 201c5dcd5..bc7638d99 100644 --- a/standard/delegates.md +++ b/standard/delegates.md @@ -83,7 +83,7 @@ The only way to declare a delegate type is via a *delegate_declaration*. Every d ## 20.3 Delegate members -Every delegate type inherits members from the `Delegate` class as described in [§15.3.4](classes.md#1534-inheritance). In addition, every delegate type must provide a non-generic `Invoke` method whose parameter list matches the *formal_parameter_list* in the delegate declaration, whose return type matches the *return_type* or *ref_return_type* in the delegate declaration, and for returns-by-ref delegates whose *ref_kind* matches that in the delegate declaration. The `Invoke` method shall be at least as accessible as the containing delegate type. Calling the `Invoke` method on a delegate type is semantically equivalent to using the delegate invocation syntax ([§20.6](delegates.md#206-delegate-invocation)) . +Every delegate type inherits members from the `Delegate` class as described in [§15.3.4](classes.md#1534-inheritance). In addition, every delegate type shall provide a non-generic `Invoke` method whose parameter list matches the *formal_parameter_list* in the delegate declaration, whose return type matches the *return_type* or *ref_return_type* in the delegate declaration, and for returns-by-ref delegates whose *ref_kind* matches that in the delegate declaration. The `Invoke` method shall be at least as accessible as the containing delegate type. Calling the `Invoke` method on a delegate type is semantically equivalent to using the delegate invocation syntax ([§20.6](delegates.md#206-delegate-invocation)) . Implementations may define additional members in the delegate type. diff --git a/standard/expressions.md b/standard/expressions.md index 3bdece8b4..3dd177077 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -619,7 +619,7 @@ During the run-time processing of a function member invocation ([§12.6.6](expre > > *end example* -- For an input, output, or reference argument, the variable reference is evaluated and the resulting storage location becomes the storage location represented by the parameter in the function member invocation. For an input or reference argument, the variable must be definitely assigned at the point of the method call. If the variable reference given as an output, or reference is an array element of a *reference_type*, a run-time check is performed to ensure that the element type of the array is identical to the type of the parameter. If this check fails, a `System.ArrayTypeMismatchException` is thrown. +- For an input, output, or reference argument, the variable reference is evaluated and the resulting storage location becomes the storage location represented by the parameter in the function member invocation. For an input or reference argument, the variable shall be definitely assigned at the point of the method call. If the variable reference given as an output, or reference is an array element of a *reference_type*, a run-time check is performed to ensure that the element type of the array is identical to the type of the parameter. If this check fails, a `System.ArrayTypeMismatchException` is thrown. Methods, indexers, and instance constructors may declare their right-most parameter to be a parameter array ([§15.6.2.6](classes.md#15626-parameter-arrays)). Such function members are invoked either in their normal form or in their expanded form depending on which is applicable ([§12.6.4.2](expressions.md#12642-applicable-function-member)): @@ -1005,8 +1005,8 @@ A function member is said to be an ***applicable function member*** with respect - Each argument in `A` corresponds to a parameter in the function member declaration as described in [§12.6.2.2](expressions.md#12622-corresponding-parameters), at most one argument corresponds to each parameter, and any parameter to which no argument corresponds is an optional parameter. - For each argument in `A`, the parameter-passing mode of the argument is identical to the parameter-passing mode of the corresponding parameter, and - for a value parameter or a parameter array, an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) exists from the argument expression to the type of the corresponding parameter, or - - for a `ref` or `out` parameter, there is an identity conversion between the type of the argument expression (if any) and the type of the corresponding parameter - - for an `in` parameter when the corresponding argument has the `in` modifier, there is an identity conversion between the type of the argument expression (if any) and the type of the corresponding parameter + - for a `ref` or `out` parameter, there is an identity conversion between the type of the argument expression (if any) and the type of the corresponding parameter, or + - for an `in` parameter when the corresponding argument has the `in` modifier, there is an identity conversion between the type of the argument expression (if any) and the type of the corresponding parameter, or - for an `in` parameter when the corresponding argument omits the `in` modifier, an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) exists from the argument expression to the type of the corresponding parameter. For a function member that includes a parameter array, if the function member is applicable by the above rules, it is said to be applicable in its ***normal form***. If a function member that includes a parameter array is not applicable in its normal form, the function member might instead be applicable in its ***expanded form***: @@ -1050,7 +1050,7 @@ When the implicit conversion from the argument type to the parameter type of an - If the method group results from a *simple_name*, an instance method is only applicable if `this` access is permitted [§12.8.13](expressions.md#12813-this-access). - When the method group results from a *member_access* which could be via either an instance or a type as described in [§12.8.7.2](expressions.md#12872-identical-simple-names-and-type-names), both instance and static methods are applicable. - A generic method whose type arguments (explicitly specified or inferred) do not all satisfy their constraints is not applicable. -- In the context of a method group conversion, there must exist an identity conversion ([§10.2.2](conversions.md#1022-identity-conversion)) or an implicit reference conversion ([§10.2.8](conversions.md#1028-implicit-reference-conversions)) from the method return type to the delegate’s return type. Otherwise, the candidate method is not applicable. +- In the context of a method group conversion, there shall exist an identity conversion ([§10.2.2](conversions.md#1022-identity-conversion)) or an implicit reference conversion ([§10.2.8](conversions.md#1028-implicit-reference-conversions)) from the method return type to the delegate’s return type. Otherwise, the candidate method is not applicable. #### 12.6.4.3 Better function member @@ -1458,7 +1458,7 @@ other tokens in the language. *end note* > *Note*: The above grammar is not ANTLR-ready due to the context sensitive lexical rules. As with other lexer generators ANTLR supports context sensitive lexical rules, for example using its *lexical modes*, -but this is an implementation detail and therefore not part of this Standard. *end note* +but this is an implementation detail and therefore not part of this specification. *end note* An *interpolated_string_expression* is classified as a value. If it is immediately converted to `System.IFormattable` or `System.FormattableString` with an implicit interpolated string conversion ([§10.2.5](conversions.md#1025-implicit-interpolated-string-conversions)), the interpolated string expression has that type. Otherwise, it has the type `string`. @@ -1475,7 +1475,7 @@ In an *interpolation_minimum_width* the *constant_expression* shall have an impl - If the alignment is positive the formatted string is right-aligned by prepending the padding, - Otherwise it is left-aligned by appending the padding. -The overall meaning of an *interpolated_string_expression*, including the above formatting and padding of interpolations, is defined by a conversion of the expression to a method invocation: if the type of the expression is `System.IFormattable` or `System.FormattableString` that method is `System.Runtime.CompilerServices.FormattableStringFactory.Create` ([§C.3](standard-library.md#c3-standard-library-types-not-defined-in-isoiec-23271)) which returns a value of type `System.FormattableString`; otherwise the type must be `string` and the method is `string.Format` ([§C.2](standard-library.md#c2-standard-library-types-defined-in-isoiec-23271)) which returns a value of type `string`. +The overall meaning of an *interpolated_string_expression*, including the above formatting and padding of interpolations, is defined by a conversion of the expression to a method invocation: if the type of the expression is `System.IFormattable` or `System.FormattableString` that method is `System.Runtime.CompilerServices.FormattableStringFactory.Create` ([§C.3](standard-library.md#c3-standard-library-types-not-defined-in-isoiec-23271)) which returns a value of type `System.FormattableString`; otherwise the type shall be `string` and the method is `string.Format` ([§C.2](standard-library.md#c2-standard-library-types-defined-in-isoiec-23271)) which returns a value of type `string`. In both cases, the argument list of the call consists of a *format string literal* with *format specifications* for each interpolation, and an argument for each expression corresponding to the format specifications. @@ -3159,7 +3159,7 @@ In both contexts the *stackalloc_expression* is only permitted to occur as: - The second and/or third operands of a *conditional_expression* ([§12.18](expressions.md#1218-conditional-operator)) which is itself the whole of `E`. -The *unmanaged_type* ([§8.8](types.md#88-unmanaged-types)) indicates the type of the items that will be stored in the newly allocated location, and the *expression* indicates the number of these items. Taken together, these specify the required allocation size. The type of *expression* must be implicitly convertible to the type `int`. +The *unmanaged_type* ([§8.8](types.md#88-unmanaged-types)) indicates the type of the items that will be stored in the newly allocated location, and the *expression* indicates the number of these items. Taken together, these specify the required allocation size. The type of *expression* shall be implicitly convertible to the type `int`. As the size of a stack allocation cannot be negative, it is a compile-time error to specify the number of items as a *constant_expression* that evaluates to a negative value. @@ -3169,7 +3169,7 @@ When a *stackalloc_initializer* is present: - If *unmanaged_type* is omitted, it is inferred following the rules for best common type ([§12.6.3.15](expressions.md#126315-finding-the-best-common-type-of-a-set-of-expressions)) for the set of *stackalloc_element_initializer*s. - If *constant_expression* is omitted it is inferred to be the number of *stackalloc_element_initializer*s. -- If *constant_expression* is present it must equal the number of *stackalloc_element_initializer*s. +- If *constant_expression* is present it shall equal the number of *stackalloc_element_initializer*s. Each *stackalloc_element_initializer* shall have an implicit conversion to *unmanaged_type* ([§10.2](conversions.md#102-implicit-conversions)). The *stackalloc_element_initializer*s initialize elements in the allocated memory in increasing order, starting with the element at index zero. In the absence of a *stackalloc_initializer*, the content of the newly allocated memory is undefined. @@ -4357,7 +4357,7 @@ If each operand `x` and `y` of a `==` or `!=` operator is classified either as a If an operand `e` is classified as a tuple, the elements `e1...en` shall be the results of evaluating the element expressions of the tuple expression. Otherwise if `e` is a value of a tuple type, the elements shall be `t.Item1...t.Itemn` where `t` is the result of evaluating `e`. -The operands `x` and `y` of a tuple equality operator shall have the same arity, or a compile time error occurs. For each pair of elements `xi` and `yi`, the same equality operator must apply, and must yield a result of type `bool`, `dynamic`, a type that has an implicit conversion to `bool`, or a type that defines the `true` and `false` operators. +The operands `x` and `y` of a tuple equality operator shall have the same arity, or a compile time error occurs. For each pair of elements `xi` and `yi`, the same equality operator shall apply, and shall yield a result of type `bool`, `dynamic`, a type that has an implicit conversion to `bool`, or a type that defines the `true` and `false` operators. The tuple equality operator `x == y` is evaluated as follows: @@ -4423,7 +4423,7 @@ User defined conversions are not considered by the `is` operator. > - If the compile-time type of `e` is the same as `T`, or if an implicit reference conversion ([§10.2.8](conversions.md#1028-implicit-reference-conversions)), boxing conversion ([§10.2.9](conversions.md#1029-boxing-conversions)), wrapping conversion ([§10.6](conversions.md#106-conversions-involving-nullable-types)), or an explicit unwrapping conversion ([§10.6](conversions.md#106-conversions-involving-nullable-types)) exists from the compile-time type of `E` to `T`: > - If `C` is of a non-nullable value type, the result of the operation is `true`. > - Otherwise, the result of the operation is equivalent to evaluating `E != null`. -> - Otherwise, if an explicit reference conversion ([§10.3.5](conversions.md#1035-explicit-reference-conversions)) or unboxing conversion ([§10.3.7](conversions.md#1037-unboxing-conversions)) exists from `C` to `T`, or if `C` or `T` is an open type ([§8.4.3](types.md#843-open-and-closed-types)), then runtime checks as above must be peformed. +> - Otherwise, if an explicit reference conversion ([§10.3.5](conversions.md#1035-explicit-reference-conversions)) or unboxing conversion ([§10.3.7](conversions.md#1037-unboxing-conversions)) exists from `C` to `T`, or if `C` or `T` is an open type ([§8.4.3](types.md#843-open-and-closed-types)), then runtime checks as above shall be peformed. > - Otherwise, no reference, boxing, wrapping, or unwrapping conversion of `E` to type `T` is possible, and the result of the operation is `false`. > A compiler may implement optimisations based on the compile-time type. > @@ -4811,7 +4811,7 @@ The first operand of the `?:` operator shall be an expression that can be impli If `ref` is present: -- An identity conversion must exist between the types of the two *variable_reference*s, and type of the result can be either type. If either type is `dynamic`, type inference prefers `dynamic` ([§8.7](types.md#87-the-dynamic-type)). If either type is a tuple type ([§8.3.11](types.md#8311-tuple-types)), type inference includes the element names when the element names in the same ordinal position match in both tuples. +- An identity conversion shall exist between the types of the two *variable_reference*s, and type of the result can be either type. If either type is `dynamic`, type inference prefers `dynamic` ([§8.7](types.md#87-the-dynamic-type)). If either type is a tuple type ([§8.3.11](types.md#8311-tuple-types)), type inference includes the element names when the element names in the same ordinal position match in both tuples. - The result is a variable reference, which is writeable if both *variable_reference*s are writeable. > *Note*: When `ref` is present, the *conditional_expression* returns a variable reference, which can be assigned to a reference variable using the `= ref` operator or passed as a reference/input/output parameter. *end note* @@ -6335,7 +6335,7 @@ The left operand of an assignment shall be an expression classified as a variabl The `=` operator is called the ***simple assignment operator***. It assigns the value or values of the right operand to the variable, property, indexer element or tuple elements given by the left operand. The left operand of the simple assignment operator shall not be an event access (except as described in [§15.8.2](classes.md#1582-field-like-events)). The simple assignment operator is described in [§12.21.2](expressions.md#12212-simple-assignment). -The operator `= ref` is called the ***ref assignment operator***. It makes the right operand, which must be a *variable_reference* ([§9.5](variables.md#95-variable-references)), the referent of the reference variable designated by the left operand. The ref assignment operator is described in [§12.21.3](expressions.md#12213-ref-assignment). +The operator `= ref` is called the ***ref assignment operator***. It makes the right operand, which shall be a *variable_reference* ([§9.5](variables.md#95-variable-references)), the referent of the reference variable designated by the left operand. The ref assignment operator is described in [§12.21.3](expressions.md#12213-ref-assignment). The assignment operators other than the `=` and `= ref` operators are called the ***compound assignment operators***. These operators perform the indicated operation on the two operands, and then assign the resulting value to the variable, property, or indexer element given by the left operand. The compound assignment operators are described in [§12.21.4](expressions.md#12214-compound-assignment). @@ -6497,7 +6497,7 @@ The operation makes the left operand an alias of the right operand variable. The The ref assignment operator yields a *variable_reference* of the assigned type. It is writeable if the left operand is writeable. -The ref assignment operator must not read the storage location referenced by the right operand. +The ref assignment operator shall not read the storage location referenced by the right operand. > *Example*: Here are some examples of using `= ref`: > @@ -6610,7 +6610,11 @@ constant_expression ; ``` -A constant expression may be either a value type or a reference type. If a constant expression is a value type, it must be one of the following types: `sbyte`, `byte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `char`, `float`, `double`, `decimal`, `bool,` or any enumeration type. If a constant expression is a reference type, it must be the `string` type, a default value expression ([§12.8.20](expressions.md#12820-default-value-expressions)) for some reference type, or the value of the expression must be `null`. +A constant expression shall either have the value `null` or one of the following types: + +- `sbyte`, `byte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `char`, `float`, `double`, `decimal`, `bool`, `string`; +- an enumeration type; or +- a default value expression ([§12.8.20](expressions.md#12820-default-value-expressions)) for a reference type. Only the following constructs are permitted in constant expressions: diff --git a/standard/lexical-structure.md b/standard/lexical-structure.md index 6f718ff1f..c55aac18d 100644 --- a/standard/lexical-structure.md +++ b/standard/lexical-structure.md @@ -124,7 +124,7 @@ If the following token is among this list, or an identifier in such a context, t > > *end example* -A *relational_expression* ([§12.12.1](expressions.md#12121-general)) can have the form “*relational_expression* `is` *type*” or “*relational_expression* `is` *constant_pattern*,” either of which might be a valid parse of a qualified identifier. In this case, an attempt is made to bind it as a type ([§7.8.1](basic-concepts.md#781-general)); however, if that fails, it is bound as an expression, and the result must be a constant. +When recognising a *relational_expression* ([§12.12.1](expressions.md#12121-general)) if both the “*relational_expression* `is` *type*” and “*relational_expression* `is` *constant_pattern*” alternatives are applicable, and *type* resolves to an accessible type, then the “*relational_expression* `is` *type*” alternative shall be chosen. ## 6.3 Lexical analysis @@ -1447,7 +1447,7 @@ fragment PP_End_Region ; ``` -No semantic meaning is attached to a region; regions are intended for use by the programmer or by automated tools to mark a section of source code. There must be one `#endregion` directive matching every `#region` directive. The message specified in a `#region` or `#endregion` directive likewise has no semantic meaning; it merely serves to identify the region. Matching `#region` and `#endregion` directives may have different *PP_Message*s. +No semantic meaning is attached to a region; regions are intended for use by the programmer or by automated tools to mark a section of source code. There shall be one `#endregion` directive matching every `#region` directive. The message specified in a `#region` or `#endregion` directive likewise has no semantic meaning; it merely serves to identify the region. Matching `#region` and `#endregion` directives may have different *PP_Message*s. The lexical processing of a region: diff --git a/standard/namespaces.md b/standard/namespaces.md index 0ed3676fd..1b89053b9 100644 --- a/standard/namespaces.md +++ b/standard/namespaces.md @@ -64,7 +64,7 @@ A *namespace_declaration* may occur as a top-level declaration in a *compilation Namespaces are implicitly `public` and the declaration of a namespace cannot include any access modifiers. -Within a *namespace_body*, the optional *using_directive*s import the names of other namespaces, types and members, allowing them to be referenced directly instead of through qualified names. The optional *namespace_member_declaration*s contribute members to the declaration space of the namespace. Note that all *using_directive*s must appear before any member declarations. +Within a *namespace_body*, the optional *using_directive*s import the names of other namespaces, types and members, allowing them to be referenced directly instead of through qualified names. The optional *namespace_member_declaration*s contribute members to the declaration space of the namespace. Note that all *using_directive*s shall appear before any member declarations. The *qualified_identifier* of a *namespace_declaration* may be a single identifier or a sequence of identifiers separated by “`.`” tokens. The latter form permits a program to define a nested namespace without lexically nesting several namespace declarations. @@ -305,7 +305,7 @@ Each *extern_alias_directive* or *using_alias_directive* in a *compilation_unit* > > The using alias named `X` causes an error since there is already an alias named `X` in the same compilation unit. The class named `Y` does not conflict with the extern alias named `Y` since these names are added to distinct declaration spaces. The former is added to the global declaration space and the latter is added to the alias declaration space for this compilation unit. > -> When an alias name matches the name of a member of a namespace, usage of either must be appropriately qualified: +> When an alias name matches the name of a member of a namespace, usage of either shall be appropriately qualified: > > > ```csharp @@ -355,7 +355,7 @@ Just like regular members, names introduced by *alias_directives* are hidden by > > *end example* -The order in which *extern_alias_directive*s are written has no significance. Likewise, the order in which *using_alias_directive*s are written has no significance, but all *using_alias_directives* must come after all *extern_alias_directive*s in the same compilation unit or namespace body. Resolution of the *namespace_or_type_name* referenced by a *using_alias_directive* is not affected by the *using_alias_directive* itself or by other *using_directive*s in the immediately containing compilation unit or namespace body, but may be affected by *extern_alias_directive*s in the immediately containing compilation unit or namespace body. In other words, the *namespace_or_type_name* of a *using_alias_directive* is resolved as if the immediately containing compilation unit or namespace body had no *using_directive*s but has the correct set of *extern_alias_directive*s. +The order in which *extern_alias_directive*s are written has no significance. Likewise, the order in which *using_alias_directive*s are written has no significance, but all *using_alias_directives* shall come after all *extern_alias_directive*s in the same compilation unit or namespace body. Resolution of the *namespace_or_type_name* referenced by a *using_alias_directive* is not affected by the *using_alias_directive* itself or by other *using_directive*s in the immediately containing compilation unit or namespace body, but may be affected by *extern_alias_directive*s in the immediately containing compilation unit or namespace body. In other words, the *namespace_or_type_name* of a *using_alias_directive* is resolved as if the immediately containing compilation unit or namespace body had no *using_directive*s but has the correct set of *extern_alias_directive*s. > *Example*: In the following code > diff --git a/standard/standard-library.md b/standard/standard-library.md index 79a6d3c3c..dc386f567 100644 --- a/standard/standard-library.md +++ b/standard/standard-library.md @@ -449,7 +449,7 @@ namespace System.Threading ## C.3 Standard Library Types not defined in ISO/IEC 23271 -The following types, including the members listed, must be defined in a conforming standard library. (These types might be defined in a future edition of ISO/IEC 23271.) It is expected that many of these types will have more members available than are listed. +The following types, including the members listed, shall be defined in a conforming standard library. (These types might be defined in a future edition of ISO/IEC 23271.) It is expected that many of these types will have more members available than are listed. A conforming implementation may provide `Task.GetAwaiter()` and `Task.GetAwaiter()` as extension methods. diff --git a/standard/statements.md b/standard/statements.md index 5a1427c9f..f32ea7811 100644 --- a/standard/statements.md +++ b/standard/statements.md @@ -366,7 +366,7 @@ implicitly_typed_local_variable_declarator ; ``` -An *implicity_typed_local_variable_declaration* introduces a single local variable, *identifier*. The *expression* or *variable_reference* must have a compile-time type, `T`. The first alternative declares a variable with type `T` and an initial value of *expression*. The second alternative declares a ref variable with type `ref T` and an initial value of `ref` *variable_reference*. +An *implicity_typed_local_variable_declaration* introduces a single local variable, *identifier*. The *expression* or *variable_reference* shall have a compile-time type, `T`. The first alternative declares a variable with type `T` and an initial value of *expression*. The second alternative declares a ref variable with type `ref T` and an initial value of `ref` *variable_reference*. > *Example*: > @@ -431,7 +431,7 @@ local_variable_initializer An *explicity_typed_local_variable_declaration* introduces one or more local variables with the specified *type*. -If a *local_variable_initializer* is present then its type must be appropriate according to the rules of simple assignment ([§12.21.2](expressions.md#12212-simple-assignment)) or array initialization ([§17.7](arrays.md#177-array-initializers)) and its value is assigned as the initial value of the variable. +If a *local_variable_initializer* is present then its type shall be appropriate according to the rules of simple assignment ([§12.21.2](expressions.md#12212-simple-assignment)) or array initialization ([§17.7](arrays.md#177-array-initializers)) and its value is assigned as the initial value of the variable. #### 13.6.2.4 Ref local variable declarations @@ -449,7 +449,7 @@ ref_local_variable_declarator ; ``` -The initializing *variable_reference* must have type *type* and meet the same requirements as for a *ref assignment* ([§12.21.3](expressions.md#12213-ref-assignment)). +The initializing *variable_reference* shall have type *type* and meet the same requirements as for a *ref assignment* ([§12.21.3](expressions.md#12213-ref-assignment)). If *ref_kind* is `ref readonly`, the *identifier*(s) being declared are references to variables that are treated as read-only. Otherwise, if *ref_kind* is `ref`, the *identifier*(s) being declared are references to variables that shall be writable. @@ -561,7 +561,7 @@ Grammar note: When recognising a *local_function_body* if both the *null_conditi Unless specified otherwise below, the semantics of all grammar elements is the same as for *method_declaration* ([§15.6.1](classes.md#1561-general)), read in the context of a local function instead of a method. -The *identifier* of a *local_function_declaration* must be unique in its declared block scope, including any enclosing local variable declaration spaces. One consequence of this is that overloaded *local_function_declaration*s are not allowed. +The *identifier* of a *local_function_declaration* shall be unique in its declared block scope, including any enclosing local variable declaration spaces. One consequence of this is that overloaded *local_function_declaration*s are not allowed. A *local_function_declaration* may include one `async` ([§15.15](classes.md#1515-async-functions)) modifier and one `unsafe` ([§23.1](unsafe-code.md#231-general)) modifier. If the declaration includes the `async` modifier then the return type shall be `void` or a `«TaskType»` type ([§15.15.1](classes.md#15151-general)). The `unsafe` modifier uses the containing lexical scope. The `async` modifier does not use the containing lexical scope. It is a compile-time error for *type_parameter_list* or *formal_parameter_list* to contain *attributes*. @@ -604,7 +604,7 @@ Local function bodies are always reachable. The endpoint of a local function dec > > In other words, the location of a local function declaration doesn’t affect the reachability of any statements in the containing function. *end example* -If the type of the argument to a local function is `dynamic`, the function to be called must be resolved at compile time, not runtime. +If the type of the argument to a local function is `dynamic`, the function to be called shall be resolved at compile time, not runtime. ## 13.7 Expression statements @@ -1596,7 +1596,7 @@ finally_clause ; ``` -A *try_statement* consists of the keyword `try` followed by a *block*, then zero or more *catch_clauses*, then an optional *finally_clause*. There must be at least one *catch_clause* or a *finally_clause*. +A *try_statement* consists of the keyword `try` followed by a *block*, then zero or more *catch_clauses*, then an optional *finally_clause*. There shall be at least one *catch_clause* or a *finally_clause*. In an *exception_specifier* the *type*, or its effective base class if it is a *type_parameter*, shall be `System.Exception` or a type that derives from it. diff --git a/standard/structs.md b/standard/structs.md index 2c128e2d5..1f54c76f1 100644 --- a/standard/structs.md +++ b/standard/structs.md @@ -518,8 +518,8 @@ The safe-context records which context a value may be copied into. Given an assi There are three different safe-context values, the same as the ref-safe-context values defined for reference variables ([§9.7.2](variables.md#972-ref-safe-contexts)): **declaration-block**, **function-member**, and **caller-context**. The safe-context of an expression constrains its use as follows: -- For a return statement `return e1`, the safe-context of `e1` must be caller-context. -- For an assignment `e1 = e2` the safe-context of `e2` must be at least as wide a context as the safe-context of `e1`. +- For a return statement `return e1`, the safe-context of `e1` shall be caller-context. +- For an assignment `e1 = e2` the safe-context of `e2` shall be at least as wide a context as the safe-context of `e1`. For a method invocation if there is a `ref` or `out` argument of a `ref struct` type (including the receiver unless the type is `readonly`), with safe-context `S1`, then no argument (including the receiver) may have a narrower safe-context than `S1`. diff --git a/standard/variables.md b/standard/variables.md index f088735e5..744b61945 100644 --- a/standard/variables.md +++ b/standard/variables.md @@ -1054,7 +1054,7 @@ All reference variables obey safety rules that ensure the ref-safe-context of th > *Note*: The related notion of a *safe-context* is defined in ([§16.4.12](structs.md#16412-safe-context-constraint)), along with associated constraints. *end note* -For any variable, the ***ref-safe-context*** of that variable is the context where a *variable_reference* ([§9.5](variables.md#95-variable-references)) to that variable is valid. The referent of a reference variable must have a ref-safe-context that is at least as wide as the ref-safe-context of the reference variable itself. +For any variable, the ***ref-safe-context*** of that variable is the context where a *variable_reference* ([§9.5](variables.md#95-variable-references)) to that variable is valid. The referent of a reference variable shall have a ref-safe-context that is at least as wide as the ref-safe-context of the reference variable itself. > *Note*: The compiler determines the ref-safe-context through a static analysis of the program text. The ref-safe-context reflects the lifetime of a variable at runtime. *end note* @@ -1232,5 +1232,5 @@ A `new` expression that invokes a constructor obeys the same rules as a method i - Neither a reference parameter, nor an output parameter, nor an input parameter, nor a `ref` local, nor a parameter or local of a `ref struct` type shall be captured by lambda expression or local function. - Neither a reference parameter, nor an output parameter, nor an input parameter, nor a parameter of a `ref struct` type shall be an argument for an iterator method or an `async` method. - Neither a `ref` local, nor a local of a `ref struct` type shall be in context at the point of a `yield return` statement or an `await` expression. -- For a ref reassignment `e1 = ref e2`, the ref-safe-context of `e2` must be at least as wide a context as the *ref-safe-context* of `e1`. -- For a ref return statement `return ref e1`, the ref-safe-context of `e1` must be the caller-context. +- For a ref reassignment `e1 = ref e2`, the ref-safe-context of `e2` shall be at least as wide a context as the *ref-safe-context* of `e1`. +- For a ref return statement `return ref e1`, the ref-safe-context of `e1` shall be the caller-context.