Skip to content
Open
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 method***s and ***conditional attribute class***es.
The attribute `Conditional` enables the definition of ***conditional methods***, ***conditional local function***s, and ***conditional attribute class***es.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the original style continues to be followed with the last two items:

Suggested change
The attribute `Conditional` enables the definition of ***conditional methods***, ***conditional local function***s, and ***conditional attribute class***es.
The attribute `Conditional` enables the definition of ***conditional method***s, ***conditional local function***s, and ***conditional attribute class***es.


#### 23.5.3.2 Conditional methods

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

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

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

A compile time error ocurrs if a non-static local function is made conditional.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm interested in why this is the case - and maybe readers would be too?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A compile time error ocurrs if a non-static local function is made conditional.
A compile time error occurs if a non-static local function is made conditional.


#### 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 @@ -836,6 +842,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 member method that calls that local function is used. Consider the following: if member 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!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should separate out the normative and informative here (and remove the exclamation mark preferrably...) Showing this as actual example code would be useful too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed! My original PR (#994) had a version of this text in an example, but that appears to have been lost. I'll work with Bill to restore it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is resolved by PR #1548.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lambdas and anonymous methods are in the same boat as local functions.


### 23.5.7 Code analysis attributes

#### 23.5.7.1 General
Expand Down Expand Up @@ -956,7 +964,7 @@
> ```csharp
> #nullable enable
> public class X
> {

Check warning on line 967 in standard/attributes.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/attributes.md#L967

MDC032::Line length 86 > maximum 81
> private void ThrowIfNull([DoesNotReturnIf(true)] bool isNull, string argumentName)
> {
> if (!isNull)
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