Skip to content

Commit 6f8e826

Browse files
committed
Address existing comments.
Also, edit after moving text around.
2 parents 20f8f91 + 5429e2e commit 6f8e826

3 files changed

Lines changed: 63 additions & 57 deletions

File tree

.github/workflows/update-on-merge.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ jobs:
5656
shell: bash
5757

5858
- name: Create pull request
59-
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725
59+
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0
6060
if: ${{ steps.renumber-sections.outputs.status }} == 'success' && ${{ steps.update-grammar.outputs.status }} == 'success'
6161
with:
6262
title: "Automated Section renumber and grammar extraction"

standard/expressions.md

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1681,12 +1681,12 @@ A *deconstruction_expression* `var (e1, ..., en)` is shorthand for the *tuple_ex
16811681
16821682
A tuple expression has a type if and only if each of its element expressions `Ei` has a type `Ti`. The type shall be a tuple type of the same arity as the tuple expression, where each element is given by the following:
16831683
1684-
- If the tuple element in the corresponding position has a name `Ni`, then the tuple type element shall be `Ti Ni`.
1685-
- Otherwise, if `Ei` is of the form `Ni` or `E.Ni` or `E?.Ni` then the tuple type element shall be `Ti Ni`, *unless* any of the following holds:
1686-
- Another element of the tuple expression has the name `Ni`, or
1687-
- Another tuple element without a name has a tuple element expression of the form `Ni` or `E.Ni` or `E?.Ni`, or
1688-
- `Ni` is of the form `ItemX`, where `X` is a sequence of non-`0`-initiated decimal digits that could represent the position of a tuple element, and `X` does not represent the position of the element.
1689-
- Otherwise, the tuple type element shall be `Ti`.
1684+
- If the tuple element in the corresponding position has a name `N`, then the tuple type element shall be `TN`.
1685+
- Otherwise, if `E` is of the form `N` or `E.N` or `E?.N` then the tuple type element shall be `TN`, *unless* any of the following holds:
1686+
- Another element of the tuple expression has the name `N`, or
1687+
- Another tuple element without a name has a tuple element expression of the form `N` or `E.N` or `E?.N`, or
1688+
- `N` is of the form `ItemX`, where `X` is a sequence of non-`0`-initiated decimal digits that could represent the position of a tuple element, and `X` does not represent the position of the element.
1689+
- Otherwise, the tuple type element shall be `T`.
16901690
16911691
A tuple expression is evaluated by evaluating each of its element expressions in order from left to right.
16921692
@@ -4534,7 +4534,7 @@ equality_expression
45344534
<!-- markdownlint-disable MD028 -->
45354535

45364536
<!-- markdownlint-enable MD028 -->
4537-
> *Note*: There is a grammar ambiguity between *type* and *constant_pattern* in a `relational_expression` on the right-hand-side of `is`; either might be a valid parse of a qualified identifier. In such a case, only if it fails to bind as a type (for compatibility with previous versions of the language), is it resolved to be the first thing found (which must be either a constant or a type). This ambiguity is only present on the right-hand side of such an expression.
4537+
> *Note*: There is a grammar ambiguity between *type* and *constant_pattern* in a `relational_expression` on the right-hand-side of `is`; either might be a valid parse of a qualified identifier. In such a case, only if it fails to bind as a type (for compatibility with previous versions of the language), is it resolved to be the first thing found (which must be either a constant or a type). This ambiguity is only present on the right-hand side of such an expression. *end note*
45384538
45394539
The `is` operator is described in [§12.15.12](expressions.md#121512-the-is-operator) and the `as` operator is described in [§12.15.13](expressions.md#121513-the-as-operator).
45404540

@@ -4869,16 +4869,16 @@ The tuple equality operators are applied pairwise to the elements of the tuple o
48694869

48704870
If each operand `x` and `y` of a `==` or `!=` operator is classified either as a tuple or as a value with a tuple type ([§8.3.11](types.md#8311-tuple-types)), the operator is a *tuple equality operator*.
48714871

4872-
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`.
4872+
If an operand `e` is classified as a tuple, the elements `e₁...eₙ` 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`.
48734873

4874-
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.
4874+
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 `xᵢ` and `yᵢ`, 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.
48754875

48764876
The tuple equality operator `x == y` is evaluated as follows:
48774877

48784878
- The left side operand `x` is evaluated.
48794879
- The right side operand `y` is evaluated.
4880-
- For each pair of elements `xi` and `yi` in lexical order:
4881-
- The operator `xi == yi` is evaluated, and a result of type `bool` is obtained in the following way:
4880+
- For each pair of elements `xᵢ` and `yᵢ` in lexical order:
4881+
- The operator `xᵢ == yᵢ` is evaluated, and a result of type `bool` is obtained in the following way:
48824882
- If the comparison yielded a `bool` then that is the result.
48834883
- Otherwise if the comparison yielded a `dynamic` then the operator `false` is dynamically invoked on it, and the resulting `bool` value is negated with the logical negation operator (`!`).
48844884
- Otherwise, if the type of the comparison has an implicit conversion to `bool`, that conversion is applied.
@@ -4890,8 +4890,8 @@ The tuple equality operator `x != y` is evaluated as follows:
48904890

48914891
- The left side operand `x` is evaluated.
48924892
- The right side operand `y` is evaluated.
4893-
- For each pair of elements `xi` and `yi` in lexical order:
4894-
- The operator `xi != yi` is evaluated, and a result of type `bool` is obtained in the following way:
4893+
- For each pair of elements `xᵢ` and `yᵢ` in lexical order:
4894+
- The operator `xᵢ != yᵢ` is evaluated, and a result of type `bool` is obtained in the following way:
48954895
- If the comparison yielded a `bool` then that is the result.
48964896
- Otherwise if the comparison yielded a `dynamic` then the operator `true` is dynamically invoked on it, and the resulting `bool` value is the result.
48974897
- Otherwise, if the type of the comparison has an implicit conversion to `bool`, that conversion is applied.
@@ -6954,24 +6954,25 @@ When a property or indexer declared in a *struct_type* is the target of an assig
69546954
> ```csharp
69556955
> struct Point
69566956
> {
6957-
> int x, y;
6957+
> int x, y;
69586958
>
6959-
> public Point(int x, int y)
6960-
> {
6961-
> this.x = x;
6962-
> this.y = y;
6963-
> }
6959+
> public Point(int x, int y)
6960+
> {
6961+
> this.x = x;
6962+
> this.y = y;
6963+
> }
69646964
>
6965-
> public int X
6966-
> {
6967-
> get { return x; }
6968-
> set { x = value; }
6969-
> }
6965+
> public int X
6966+
> {
6967+
> get { return x; }
6968+
> set { x = value; }
6969+
> }
69706970
>
6971-
> public int Y {
6972-
> get { return y; }
6973-
> set { y = value; }
6974-
> }
6971+
> public int Y
6972+
> {
6973+
> get { return y; }
6974+
> set { y = value; }
6975+
> }
69756976
> }
69766977
>
69776978
> struct Rectangle
@@ -7055,17 +7056,18 @@ The ref assignment operator shall not read the storage location referenced by th
70557056
> public static ref readonly int M3() { ... }
70567057
> public static void Test()
70577058
> {
7058-
> int v = 42;
7059-
> ref int r1 = ref v; // OK, r1 refers to v, which has value 42
7060-
> r1 = ref M1(); // Error; M1 returns a value, not a reference
7061-
> r1 = ref M2(); // OK; makes an alias
7062-
> r1 = ref M2u(); // Error; lhs and rhs have different types
7063-
> r1 = ref M3(); // error; M3 returns a ref readonly, which r1 cannot honor
7064-
> ref readonly int r2 = ref v; // OK; make readonly alias to ref
7065-
> r2 = ref M2(); // OK; makes an alias, adding read-only protection
7066-
> r2 = ref M3(); // OK; makes an alias and honors the read-only
7067-
> r2 = ref (r1 = ref M2()); // OK; r1 is an alias to a writable variable,
7068-
> // r2 is an alias (with read-only access) to the same variable
7059+
> int v = 42;
7060+
> ref int r1 = ref v; // OK, r1 refers to v, which has value 42
7061+
> r1 = ref M1(); // Error; M1 returns a value, not a reference
7062+
> r1 = ref M2(); // OK; makes an alias
7063+
> r1 = ref M2u(); // Error; lhs and rhs have different types
7064+
> r1 = ref M3(); // error; M3 returns a ref readonly, which r1 cannot honor
7065+
> ref readonly int r2 = ref v; // OK; make readonly alias to ref
7066+
> r2 = ref M2(); // OK; makes an alias, adding read-only protection
7067+
> r2 = ref M3(); // OK; makes an alias and honors the read-only
7068+
> r2 = ref (r1 = ref M2()); // OK; r1 is an alias to a writable variable,
7069+
> // r2 is an alias (with read-only access)
7070+
> // to the same variable
70697071
> }
70707072
> ```
70717073
>

standard/foreword.md

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
11
# Foreword
22

3-
This specification replaces ECMA-334:2023. Changes from the previous edition include the addition of the following features:
3+
This specification replaces ECMA-334:2026. Changes from the previous edition include the addition of the following features:
44

5-
- enhanced interpolated verbatim strings
6-
- asynchronous streams
7-
- `using` declarations and `async using`
8-
- generic method override with constraints
9-
- unmanaged constructed types
10-
- default member implementations in interfaces
11-
- permit `stackalloc` in nested contexts
12-
- `notnull` constraint
13-
- null coalescing assignment
14-
- nullable reference types
15-
- positional, property, and discard patterns
16-
- ranges and indexes
17-
- readonly instance members
18-
- name shadowing in nested functions
19-
- static local functions
20-
- Disposable ref structs
5+
- Init accessors
6+
- Top-level statements
7+
- Native-sized integers
8+
- Records
9+
- Function pointers
10+
- Pattern matching enhancements
11+
- Static anonymous functions
12+
- Target-typed conditional expressions
13+
- Covariant return types
14+
- Extension `GetEnumerator` support for `foreach` loops
15+
- Lambda discard parameters
16+
- Attributes and `extern` on local functions
17+
- Module initializers
18+
- New features for partial methods
19+
- Target-typed `new` expressions
20+
- Unconstrained type parameter annotations
21+
- Variance safety for static interface members
22+
- Nullable reference types
23+
- Nullable constructor analysis
24+
- Nullable parameter default value analysis

0 commit comments

Comments
 (0)