You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Revision of §13.6.2 *Local variable declarations* to fix errors and tidy up.
This clause has evolved over time as first implicitly typed, and now in v7 ref locals, have been introduced; the result ending up
as something worthy of Heath Robinson or Professor Branestawm ;-) The result alas is also not entirely correct, the initial version
was (almost), but subsequent kinds of local variables don't follow exactly the same rules...
As a simple example of what ended up going wrong is the assertion:
> A local variable declaration that declares multiple variables is equivalent to multiple declarations of single variables with the same type and *ref_kind*.
and its associated example. This was (almost) correct originally, but is not correct for implicitly typed or ref local declarations where the
initialization cannot be split from the declaration. (It was “almost” is it didn't allow for *for_initializer* or *resource_acqusition* cases
where such a split is not possible either.)
The rework divides local variable declarations into three subgroups, there really are four but we can get away with three (whether
we should can be debated). These groups are directly represented in the reworked grammar, which also replaces a lot of conditional English
prose. The clause starts with the general rules and then has a section for each subgroup detailing just the rules that apply in that case.
The changes have been kept to the §13.6.2 clause; there are related issues in at least §7.7.1 Scopes:General and §13.14 The using statement – neither of these
for example define the scope of a variable introduced in a *resource_acqusition*. Such issues are left for future (pre-v8) work!
The *local_variable_type* of a *local_variable_declaration* either directly specifies the type of the variables introduced by the declaration, or indicates with the identifier `var` that the type should be inferred based on an initializer. The type is followed by a list of *local_variable_declarator*s, each of which introduces a new variable. A *local_variable_declarator* consists of an *identifier* that names the variable, optionally followed by an “`=`” token and a *local_variable_initializer* that gives the initial value of the variable. However, it is a compile-time error to omit *local_variable_initializer* from a *local_variable_declarator* for a variable declared `ref` or `ref readonly`.
307
+
Local variable declarations fall into one of the three categories: implicitly typed, explicitly typed, and ref local.
327
308
328
-
A *local_variable_initializer* for a variable declared `ref` or `ref readonly` shall be of the form “`ref`*variable_reference*”. It is a compile time error if the scope of the local variable is wider than the ref-safe-context of the *variable_reference* ([§9.7.2](variables.md#972-ref-safe-contexts)).
329
-
330
-
If *local_variable_declaration* contains `ref readonly`, the *identifier*s being declared are references to variables that are treated as read-only, and their corresponding *local_variable_initializer*s shall each contain `ref`. Otherwise, if *local_variable_declaration* contains `ref` without `readonly`, the *identifier*s being declared are references to variables that shall be writable, and their corresponding *local_variable_initializer* shall each contain `ref`.
331
-
332
-
It is a compile-time error to declare a local variable `ref` or `ref readonly` or a variable of a `ref struct` type within a method declared with the *method_modifier*`async`, or an iterator ([§15.14](classes.md#1514-iterators)).
333
-
334
-
In the context of a local variable declaration, the identifier `var` acts as a contextual keyword ([§6.4.4](lexical-structure.md#644-keywords)). When the *local_variable_type* is specified as `var` and no type named `var` is in scope, the declaration is an ***implicitly typed local variable declaration***, whose type is inferred from the type of the associated initializer expression. Implicitly typed local variable declarations are subject to the following restrictions:
335
-
336
-
- The *local_variable_declaration* cannot include multiple *local_variable_declarator*s.
337
-
- The *local_variable_declarator* shall include a *local_variable_initializer*.
338
-
- The *local_variable_initializer* shall be an *expression*, optionally preceded by `ref`.
339
-
- The initializer *expression* shall have a compile-time type.
340
-
- The initializer *expression* cannot refer to the declared variable itself.
341
-
342
-
> *Example*: The following are incorrect implicitly typed local variable declarations:
>varx; // Error, no initializer to infer type from
347
-
>vary= {1, 2, 3}; // Error, array initializer not permitted
348
-
>varz=null; // Error, null does not have a type
349
-
>varu=x=>x+1; // Error, anonymous functions do not have a type
350
-
>varv=v++; // Error, initializer cannot refer to v itself
351
-
> ```
352
-
>
353
-
>*endexample*
309
+
Implicitly typed declarations contain the contextual keyword ([§6.4.4](lexical-structure.md#644-keywords)) `var` resulting in a syntactic ambiguity between the three categories which is resolved as follows:
Within a *local_variable_declaration*each variable is introduced by a *declarator*, which is one of *implicitly_typed_local_variable_declarator*, *explicitly_typed_local_variable_declarator* or *ref_local_variable_declarator* for impicitly typed, explicitly typed and ref local variables respectively. The declarator defines the name (*identifier*) and initial value, if any, of the introduced variable.
If there are multiple declarators in a declaration then they are processed, including any initializing expressions, in order left to right ([§9.4.4.5](variables.md#945-declaration-statements)).
360
317
361
-
> *Example*:Theexample
318
+
> *Note*: For a *local_variable_declaration* not occuring as a *for_initializer* ([§13.9.4](statements.md#1394-the-for-statement)) or *resource_acquisition* ([§13.14](statements.md#1314-the-using-statement)) this left to right order is equivalent to each declarator being within a separate *local_variable_declaration*. For example:
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 variant declares a variable with type `T` and an initial value of *expression*. The second variant declares a ref variable with type `ref T` and an initial value of `ref`*variable_reference*.
An *explicity_typed_local_variable_declaration* introduces one or more local variables with the specified *type*.
431
+
432
+
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.
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)).
451
+
452
+
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.
453
+
454
+
It is a compile-time error to declare a ref local variable, or a variable of a `ref struct` type, within a method declared with the *method_modifier*`async`, or within an iterator ([§15.14](classes.md#1514-iterators)).
455
+
415
456
### 13.6.3 Local constant declarations
416
457
417
458
A *local_constant_declaration* declares one or more local constants.
@@ -537,15 +578,15 @@ Local function bodies are always reachable. The endpoint of a local function dec
0 commit comments