Skip to content

Commit 56f724d

Browse files
committed
Null-forgiving operator
- Fix grammar - Specify semantic restrictions - Add to precedence table - Add to MLR group
1 parent 2be6531 commit 56f724d

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed

standard/expressions.md

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ The precedence of an operator is established by the definition of its associated
147147
>
148148
> | **Subclause** | **Category** | **Operators** |
149149
> | ----------------- | ------------------------------- | -------------------------------------------------------|
150-
> | [§12.8](expressions.md#128-primary-expressions) | Primary | `x.y` `x?.y` `f(x)` `a[x]` `a?[x]` `x++` `x--` `new` `typeof` `default` `checked` `unchecked` `delegate` `stackalloc` |
150+
> | [§12.8](expressions.md#128-primary-expressions) | Primary | `x.y` `x?.y` `f(x)` `a[x]` `a?[x]` `x++` `x--` `x!` `new` `typeof` `default` `checked` `unchecked` `delegate` `stackalloc` |
151151
> | [§12.9](expressions.md#129-unary-operators) | Unary | `+` `-` `!` `~` `++x` `--x` `(T)x` `await x` |
152152
> | [§12.10](expressions.md#1210-arithmetic-operators) | Multiplicative | `*` `/` `%` |
153153
> | [§12.10](expressions.md#1210-arithmetic-operators) | Additive | `+` `-` |
@@ -1273,7 +1273,6 @@ Primary expressions include the simplest forms of expressions.
12731273
primary_expression
12741274
: primary_no_array_creation_expression
12751275
| array_creation_expression
1276-
| null_forgiving_expression
12771276
;
12781277
12791278
primary_no_array_creation_expression
@@ -1291,6 +1290,7 @@ primary_no_array_creation_expression
12911290
| base_access
12921291
| post_increment_expression
12931292
| post_decrement_expression
1293+
| null_forgiving_expression
12941294
| object_creation_expression
12951295
| delegate_creation_expression
12961296
| anonymous_object_creation_expression
@@ -1307,7 +1307,7 @@ primary_no_array_creation_expression
13071307
;
13081308
```
13091309
1310-
> *Note*: These grammar rules are not ANTLR-ready as they are part of a set of mutually left-recursive rules (`primary_expression`, `primary_no_array_creation_expression`, `member_access`, `invocation_expression`, `element_access`, `post_increment_expression`, `post_decrement_expression`, `pointer_member_access` and `pointer_element_access`) which ANTLR does not handle. Standard techniques can be used to transform the grammar to remove the mutual left-recursion. This has not been done as not all parsing strategies require it (e.g. an LALR parser would not) and doing so would obfuscate the structure and description. *end note*
1310+
> *Note*: These grammar rules are not ANTLR-ready as they are part of a set of mutually left-recursive rules (`primary_expression`, `primary_no_array_creation_expression`, `member_access`, `invocation_expression`, `element_access`, `post_increment_expression`, `post_decrement_expression`, `null_forgiving_expression`, `pointer_member_access` and `pointer_element_access`) which ANTLR does not handle. Standard techniques can be used to transform the grammar to remove the mutual left-recursion. This has not been done as not all parsing strategies require it (e.g. an LALR parser would not) and doing so would obfuscate the structure and description. *end note*
13111311
13121312
*pointer_member_access* ([§23.6.3](unsafe-code.md#2363-pointer-member-access)) and *pointer_element_access* ([§23.6.4](unsafe-code.md#2364-pointer-element-access)) are only available in unsafe code ([§23](unsafe-code.md#23-unsafe-code)).
13131313

@@ -1824,18 +1824,29 @@ A *null_conditional_projection_initializer* is a restriction of *null_conditiona
18241824

18251825
### 12.8.9 Null-forgiving expressions
18261826

1827-
This operator sets the null state ([§8.9.5](types.md#895-nullabilities-and-null-states)) of the operand tonot null”.
1827+
The null-forgiving operator sets the null state ([§8.9.5](types.md#895-nullabilities-and-null-states)) of the operand tonot null”.
18281828

18291829
```ANTLR
18301830
null_forgiving_expression
1831-
: primary_no_array_creation_expression suppression
1831+
: primary_expression null_forgiving_operator
18321832
;
18331833

1834-
suppression
1834+
null_forgiving_operator
18351835
: '!'
18361836
;
18371837
```
18381838

1839+
The *primary_expression* must not be known to have a value type.
1840+
1841+
It is an error to apply the null-forgiving operator more than once to the same expression, intervening parenetheses notwithstanding.
1842+
1843+
> *Example*: the following are all invalid:
1844+
>
1845+
> ```csharp
1846+
> var p = q!!; // error: cannot apply the null_forgiving_operator more than once
1847+
> var s = ( ( m(t) ! ) )! // error: null_forgiving_operator applied twice to m(t)
1848+
> ```
1849+
18391850
This operator has no runtime effect; it evaluates to the result of its operand, and that result retains that operands classification.
18401851
18411852
The null-forgiving operator is used to declare that an expression not known to be a value type is not null.

0 commit comments

Comments
 (0)