Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion standard/attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@

#### 23.5.3.1 General

The attribute `Conditional` enables the definition of ***conditional methods*** and ***conditional attribute classes***.
The attribute `Conditional` enables the definition of ***conditional methods***, ***conditional local functions***, and ***conditional attribute classes***.

#### 23.5.3.2 Conditional methods

Expand Down Expand Up @@ -664,6 +664,12 @@
>
> *end example*

#### §conditional-local-function Conditional local functions

A local function may be made conditional in the same sense as a conditional method ([§23.5.3.2](attributes.md#23532-conditional-methods)).

A conditional local function shall have the modifier `static`.

#### 23.5.3.3 Conditional attribute classes

An attribute class ([§23.2](attributes.md#232-attribute-classes)) decorated with one or more `Conditional` attributes is a conditional attribute class. A conditional attribute class is thus associated with the conditional compilation symbols declared in its `Conditional` attributes.
Expand Down Expand Up @@ -833,6 +839,8 @@

For invocations that occur within declarations of instance constructors, static constructors, finalizers and operators the member name used is implementation-dependent.

For an invocation that occurs within a local function, the name of the method that calls that local function is used. Consider the following: if method `M` calls local function `F1`, which in turn calls local function `F2`, and `F2` has a parameter marked with this attribute, the method name passed to `F2` is `M`, because a local function is *not* a function member!

### 23.5.7 Code analysis attributes

#### 23.5.7.1 General
Expand Down Expand Up @@ -953,11 +961,11 @@
> ```csharp
> #nullable enable
> public class X
> {

Check warning on line 964 in standard/attributes.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/attributes.md#L964

MDC032::Line length 86 > maximum 81
> private void ThrowIfNull([DoesNotReturnIf(true)] bool isNull, string argumentName)
> {
> if (!isNull)
> {

Check warning on line 968 in standard/attributes.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/attributes.md#L968

MDC032::Line length 96 > maximum 81
> throw new ArgumentException(argumentName, $"argument {argumentName} can't be null");
> }
> }
Expand Down Expand Up @@ -1003,7 +1011,7 @@
>
> <!-- Example: {template:"code-in-class-lib", name:"NotNullAttribute"} -->
> ```csharp
> #nullable enable

Check warning on line 1014 in standard/attributes.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/attributes.md#L1014

MDC032::Line length 89 > maximum 81
> public static void ThrowWhenNull([NotNull] object? value, string valueExpression = "") =>
> _ = value ?? throw new ArgumentNullException(valueExpression);
>
Expand Down Expand Up @@ -1085,7 +1093,7 @@
> }
> }
> }
>

Check warning on line 1096 in standard/attributes.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/attributes.md#L1096

MDC032::Line length 103 > maximum 81
> static async IAsyncEnumerable<string> GetStringsAsync([EnumeratorCancellation] CancellationToken token)
> {
> for (int i = 0; i < 10; i++)
Expand Down
13 changes: 10 additions & 3 deletions standard/statements.md
Original file line number Diff line number Diff line change
Expand Up @@ -487,9 +487,9 @@ A *local_function_declaration* declares a local function.

```ANTLR
local_function_declaration
: local_function_modifier* return_type local_function_header
: attributes? local_function_modifier* return_type local_function_header
local_function_body
| ref_local_function_modifier* ref_kind ref_return_type
| attributes? ref_local_function_modifier* ref_kind ref_return_type
local_function_header ref_local_function_body
;

Expand All @@ -506,18 +506,21 @@ local_function_modifier

ref_local_function_modifier
: 'static'
| 'extern'
| unsafe_modifier // unsafe code support
;

local_function_body
: block
| '=>' null_conditional_invocation_expression ';'
| '=>' expression ';'
| ';'
;

ref_local_function_body
: block
| '=>' 'ref' variable_reference ';'
| ';'
;
```

Expand Down Expand Up @@ -562,7 +565,11 @@ Unless specified otherwise below, the semantics of all grammar elements is the s

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.14](classes.md#1514-async-functions)) modifier and one `unsafe` ([§24.1](unsafe-code.md#241-general)) modifier. If the declaration includes the `async` modifier then the return type shall be `void` or a `«TaskType»` type ([§15.14.1](classes.md#15141-general)). If the declaration includes the `static` modifier, the function is a ***static local function***; otherwise, it is a ***non-static local function***. It is a compile-time error for *type_parameter_list* or *parameter_list* to contain *attributes*. If the local function is declared in an unsafe context ([§24.2](unsafe-code.md#242-unsafe-contexts)), the local function may include unsafe code, even if the local function declaration doesn’t include the `unsafe` modifier.
A *local_function_declaration* may include one `async` ([§15.14](classes.md#1514-async-functions)) modifier and one `unsafe` ([§24.1](unsafe-code.md#241-general)) modifier. If the declaration includes the `async` modifier then the return type shall be `void` or a `«TaskType»` type ([§15.14.1](classes.md#15141-general)). If the declaration includes the `static` modifier, the function is a ***static local function***; otherwise, it is a ***non-static local function***. If the local function is declared in an unsafe context ([§24.2](unsafe-code.md#242-unsafe-contexts)), the local function may include unsafe code, even if the local function declaration doesn’t include the `unsafe` modifier.

An external local function shall have the modifier `static`, and its *local_function_body* or *ref_local_function_body* shall be a semicolon.

A *local_function_body* or *ref_local_function_body* shall be a semicolon only for an external local function.

A local function is declared at block scope. A non-static local function may capture variables from the enclosing scope while a static local function shall not (so it has no access to enclosing locals, parameters, non-static local functions, or `this`). It is a compile-time error if a captured variable is read by the body of a non-static local function but is not definitely assigned before each call to the function. A compiler shall determine which variables are definitely assigned on return ([§9.4.4.33](variables.md#94433-rules-for-variables-in-local-functions)).

Expand Down
Loading