Skip to content

Commit 0994740

Browse files
committed
Address language in review comments
This commit address the comments in this review: #672 (review) except for any grammar changes. Notes on where the edit differs (slightly) from the recommendation: - The rule that a `using` statement can't declare an `out` variable applies to all forms. I added that in 13.14.1. - I added a note that ref structs can't use the form of `await using`. It's a note because it follows from the normative restriction that `ref struct` types can't implement interfaces, but `await using` requires the resource type to implement `IAsyncDisposable`. - The rules for `goto`, `break`, etc. are a note at the end of 13.14.1. They can be derived from the expanded forms of the `using` statement. - The rule for a using declaration in a switch block remains. It's specific to a using declaration.
1 parent f45c645 commit 0994740

File tree

1 file changed

+58
-66
lines changed

1 file changed

+58
-66
lines changed

standard/statements.md

Lines changed: 58 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -351,71 +351,6 @@ It is an error to refer to a local variable by name in a textual position that p
351351
352352
The ref-safe-context ([§9.7.2](variables.md#972-ref-safe-contexts)) of a ref local variable is the ref-safe-context of its initializing *variable_reference*. The ref-safe-context of non-ref local variables is *declaration-block*.
353353
354-
When *local_variable_declaration* includes `using`, the semantics described above are modified, as follows.
355-
356-
Each *local_variable_type* shall be `dynamic` or a resource type. If `await` is also present, the resource type shall not be a ref struct.
357-
358-
Each *local_variable_declarator* shall have a *local_variable_initializer*.
359-
360-
The variables declared are read-only. A compile-time error occurs if any subsequent statement attempts to modify these variables, take the address of them, or pass them as reference or output parameters.
361-
362-
An occurrence of *local_variable_declaration* containing `using` has the same semantics as, and can be rewritten as, the corresponding resource-acquisition form of the using statement ([§13.14](statements.md#1314-the-using-statement)), as follows:
363-
364-
```csharp
365-
using «local_variable_type» «local_variable_declarators»
366-
// statements
367-
```
368-
369-
is equivalent to
370-
371-
```csharp
372-
using («local_variable_type» «local_variable_declarators»)
373-
{
374-
// statements
375-
}
376-
```
377-
378-
and
379-
380-
```csharp
381-
await using «local_variable_type» «local_variable_declarators»
382-
// statements
383-
```
384-
385-
is equivalent to
386-
387-
```csharp
388-
await usinglocal_variable_type» «local_variable_declarators»)
389-
{
390-
// statements
391-
}
392-
```
393-
394-
The lifetime of the variables declared in a *local_variable_declaration* extends to the end of the scope in which they are declared. Those variables are then disposed in the reverse order in which they are declared.
395-
396-
<!-- Example: {template:"code-in-partial-class", name:"LocalVariableDecls6", additionalFiles:["SupportLocalVarDecl.cs"], replaceEllipsis:true, customEllipsisReplacements: ["\"File1.txt\", FileMode.Create", "\"File2.txt\", FileMode.Create", "\"File3.txt\", FileMode.Create"]} -->
397-
```csharp
398-
static void M()
399-
{
400-
using FileStream f1 = new FileStream(...);
401-
using FileStream f2 = new FileStream(...), f3 = new FileStream(...);
402-
...
403-
// Dispose f3
404-
// Dispose f2
405-
// Dispose f1
406-
}
407-
```
408-
409-
When jumping to a label in a statement list which contains *local_variable_declaration*s involving `using`, there must not be any such declaration between the `goto` statement and the label.```
410-
411-
Apart from wordsmithing this needs x-ref to goto, and goto probably needs this restriction listed in its description as well.
412-
413-
Also surely this is an echo of a similar statement for `using (…) {…}`, so is it needed here at all given the equivalency defined above – this is just a shorthand.
414-
415-
A *local_variable_declaration* with `using` shall not appear directly inside a `case` label, but, instead, may be within a block inside a `case` label.
416-
417-
A *local_variable_declaration* with `using` shall not appear in an `out` variable declaration.
418-
419354
#### 13.6.2.2 Implicitly typed local variable declarations
420355
421356
```ANTLR
@@ -1941,6 +1876,8 @@ While a mutual-exclusion lock is held, code executing in the same execution thre
19411876
19421877
## 13.14 The using statement
19431878
1879+
### §using_general General
1880+
19441881
The `using` statement obtains one or more resources, executes a statement, and then disposes of the resource.
19451882
19461883
```ANTLR
@@ -1956,7 +1893,9 @@ resource_acquisition
19561893
19571894
A ***resource*** is either a class or non-ref struct that implements either or both of the `System.IDisposable` or `System.`IAsync`Disposable` 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.
19581895
1959-
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`.
1896+
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. The *local_variable_declaration* cannot include the `out` modifier. 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`.
1897+
1898+
> *Note:* A `ref struct` type cannot be the resource type for a `using` statement with the `await` modifier because `ref struct` types cannot implement interfaces. *end note*
19601899
19611900
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.
19621901
@@ -2133,6 +2072,59 @@ corresponds to
21332072
21342073
When `ResourceType` is a reference type that implements `IAsyncDisposable`. Other expansions for `await using` perform similar substitutions from the synchronous `Dispose` method to the asynchronous `DisposeAsync` method.
21352074

2075+
> *Note*: Any jump statements (§13.10) in the *embedded_statement* must conform to expanded form of the `using` statement. *end note*
2076+
2077+
### §using_declarations Using declarations
2078+
2079+
A syntactic variant of the using statement is a *using declaration*. A *using declaration* has the same semantics as, and can be rewritten as, the corresponding resource-acquisition form of the using statement (§using_general), as follows:
2080+
2081+
```csharp
2082+
using «local_variable_type» «local_variable_declarators»
2083+
// statements
2084+
```
2085+
2086+
is equivalent to
2087+
2088+
```csharp
2089+
usinglocal_variable_type» «local_variable_declarators»)
2090+
{
2091+
// statements
2092+
}
2093+
```
2094+
2095+
and
2096+
2097+
```csharp
2098+
await using «local_variable_type» «local_variable_declarators»
2099+
// statements
2100+
```
2101+
2102+
is equivalent to
2103+
2104+
```csharp
2105+
await usinglocal_variable_type» «local_variable_declarators»)
2106+
{
2107+
// statements
2108+
}
2109+
```
2110+
2111+
The lifetime of the variables declared in a *local_variable_declaration* extends to the end of the scope in which they are declared. Those variables are then disposed in the reverse order in which they are declared. It is a compile time error for a `goto` statement (§13.10.4)
2112+
2113+
<!-- Example: {template:"code-in-partial-class", name:"LocalVariableDecls6", additionalFiles:["SupportLocalVarDecl.cs"], replaceEllipsis:true, customEllipsisReplacements: ["\"File1.txt\", FileMode.Create", "\"File2.txt\", FileMode.Create", "\"File3.txt\", FileMode.Create"]} -->
2114+
```csharp
2115+
static void M()
2116+
{
2117+
using FileStream f1 = new FileStream(...);
2118+
using FileStream f2 = new FileStream(...), f3 = new FileStream(...);
2119+
...
2120+
// Dispose f3
2121+
// Dispose f2
2122+
// Dispose f1
2123+
}
2124+
```
2125+
2126+
A using declaration shall not appear directly inside a `case` label, but, instead, may be within a block inside a `case` label.
2127+
21362128
## 13.15 The yield statement
21372129

21382130
The `yield` statement is used in an iterator block ([§13.3](statements.md#133-blocks)) to yield a value to the enumerator object ([§15.15.5](classes.md#15155-enumerator-objects)) or enumerable object ([§15.15.6](classes.md#15156-enumerable-objects)) of an iterator or to signal the end of the iteration.

0 commit comments

Comments
 (0)