Skip to content
Merged
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
36 changes: 18 additions & 18 deletions standard/classes.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions standard/conversions.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
> ```csharp
> enum Color { Red, Blue, Green }
>
> // The expression 0 converts implicitly to enum types

Check warning on line 28 in standard/conversions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/conversions.md#L28

MDC032::Line length 82 > maximum 81
> Color c0 = 0;
>
> // Other int expressions need explicit conversion
Expand Down Expand Up @@ -149,7 +149,7 @@

An implicit interpolated string conversion permits an *interpolated_string_expression* ([§12.8.3](expressions.md#1283-interpolated-string-expressions)) to be converted to `System.IFormattable` or `System.FormattableString` (which implements `System.IFormattable`). When this conversion is applied, a string value is not composed from the interpolated string. Instead an instance of `System.FormattableString` is created, as further described in [§12.8.3](expressions.md#1283-interpolated-string-expressions).

For any type `T` that is an applicable interpolated string handler type ([§23.5.9.1.1](attributes.md#235911-declaring-a-custom-handler)), there exists an implicit interpolated string handler conversion to `T` from a non-constant *ISE* ([§12.8.3](expressions.md#1283-interpolated-string-expressions)). This conversion exists, regardless of whether errors are found later when attempting to lower the interpolation using the handler pattern. This ensures that there are predictable and useful errors, and that runtime behavior doesn't change based on the content of an interpolated string.
For any type `T` that is an applicable interpolated string handler type ([§23.5.9.1.1](attributes.md#235911-declaring-a-custom-handler)), there exists an implicit interpolated string handler conversion to `T` from a non-constant *ISE* ([§12.8.3](expressions.md#1283-interpolated-string-expressions)). This conversion exists, regardless of whether errors are found later when attempting to lower the interpolation using the handler pattern. This ensures that there are predictable and useful errors, and that runtime behavior doesn’t change based on the content of an interpolated string.

### 10.2.6 Implicit nullable conversions

Expand Down Expand Up @@ -406,7 +406,7 @@

There is an implicit ***object-creation conversion*** from a *target_typed_new* expression ([§12.8.17.2](expressions.md#128172-object-creation-expressions)) to every type.

Given a target type `T`, if `T` is an instance of `System.Nullable`, the type `T0` is `T`'s underlying type. Otherwise `T0` is `T`. The meaning of a *target_typed_new* expression that is converted to the type `T` is the same as the meaning of a corresponding *object_creation_expression* that specifies `T0` as the type.
Given a target type `T`, if `T` is an instance of `System.Nullable`, the type `T0` is `T`’s underlying type. Otherwise `T0` is `T`. The meaning of a *target_typed_new* expression that is converted to the type `T` is the same as the meaning of a corresponding *object_creation_expression* that specifies `T0` as the type.

### 10.2.20 Implicit conditional expression conversions

Expand Down
8 changes: 4 additions & 4 deletions standard/expressions.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# 12 Expressions

Check warning on line 1 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L1

MDC032::Line length 83 > maximum 81

Check warning on line 1 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L1

MDC032::Line length 84 > maximum 81

Check warning on line 2 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L2

MDC032::Line length 84 > maximum 81

Check warning on line 2 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L2

MDC032::Line length 85 > maximum 81
## 12.1 General

Check warning on line 3 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L3

MDC032::Line length 85 > maximum 81

Check warning on line 3 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L3

MDC032::Line length 86 > maximum 81

An expression is a sequence of operators and operands. This clause defines the syntax, order of evaluation of operands and operators, and meaning of expressions.

Check warning on line 5 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L5

MDC032::Line length 82 > maximum 81

Check warning on line 5 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L5

MDC032::Line length 102 > maximum 81

Check warning on line 6 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L6

MDC032::Line length 97 > maximum 81

Check warning on line 6 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L6

MDC032::Line length 82 > maximum 81

Check warning on line 6 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L6

MDC032::Line length 82 > maximum 81
An expression *E* is said to ***directly contain*** a subexpression *E₁* if it is not subject to a user-defined conversion [§10.5](conversions.md#105-user-defined-conversions) whose parameter is not of a non-nullable value type, and one of the following conditions holds:

Check warning on line 8 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L8

MDC032::Line length 90 > maximum 81
- *E* is *E₁*.
- If *E* is a parenthesized expression `(E₂)`, and *E₂* directly contains *E₁*.
- If *E* is a null-forgiving operator expression `E₂!`, and *E₂* directly contains *E₁*.
- If *E* is a cast expression `(T)E₂`, and the cast does not subject *E₂* to a non-lifted user-defined conversion whose parameter is not of a non-nullable value type, and *E₂* directly contains *E₁*.

Check warning on line 12 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L12

MDC032::Line length 82 > maximum 81

## 12.2 Expression classifications

Expand Down Expand Up @@ -1632,7 +1632,7 @@
- no interpolations, or
- interpolations whose *expression*s are constant expressions of type `string`, and these interpolations have no *interpolation_minimum_width*, *Regular_Interpolation_Format*, or *Verbatim_Interpolation_Format* specifiers.

For example, $"Hello", $"{cs1}, world!" (given `const string cs1 = $"Hello";`), $"{"Hello," + $"world!"}", and $"xxx{(true ? $"{"X"}" : $"{$"{"Y"}"}")}yyy" are all constant interpolated strings. However, $"{123}" and $"{"abc"}{123.45}" are not.
For example, $“Hello”, $“{cs1}, world!” (given `const string cs1 = $"Hello";`), $“{“Hello,” + $“world!"}”, and $“xxx{(true ? $“{“X”}” : $“{$“{“Y”}”}”)}yyy” are all constant interpolated strings. However, $“{123}” and $“{“abc”}{123.45}” are not.

For simplicity, the term *ISE* is used throughout this specification to mean either an *interpolated_string_expression* or an *additive_expression* composed entirely of *interpolated_string_expression*s and binary `+` operators.

Expand Down Expand Up @@ -3977,13 +3977,13 @@

The receiver type shall be non-`void` and of some record class, record struct, or non-record struct type.

*identifier* shall be an accessible instance field or property of the receiver's type.
*identifier* shall be an accessible instance field or property of the receiver’s type.

All non-positional properties being changed shall have both set and init accessors.

This expression is evaluated as follows:

- For a record class type, the receiver's clone method ([§15.16.6.4](classes.md#151664-copy-and-clone-members)) is invoked, and its result is converted to the receiver’s type.
- For a record class type, the receiver’s clone method ([§15.16.6.4](classes.md#151664-copy-and-clone-members)) is invoked, and its result is converted to the receiver’s type.
- For a record struct or non-record struct type, the receiver is copied.
- Each `member_initializer` is processed the same way as an assignment to
a field or property access of the result of the conversion. Assignments are processed in lexical order. If *member_initializer_list* is omitted, no members are changed.
Expand Down Expand Up @@ -7584,7 +7584,7 @@
> }
> ```
>
> The preceding example emits an error because the result of the expression `int.MaxValue + 1` isn't representable as `Int32`. On machines where the size of a `nint` is greater than 32 bits, the expression would succeed at runtime. *end example*
> The preceding example emits an error because the result of the expression `int.MaxValue + 1` isn’t representable as `Int32`. On machines where the size of a `nint` is greater than 32 bits, the expression would succeed at runtime. *end example*

Unless a constant expression is explicitly placed in an `unchecked` context, overflows that occur in integral-type arithmetic operations and conversions during the compile-time evaluation of the expression always cause compile-time errors ([§12.8.20](expressions.md#12820-the-checked-and-unchecked-operators)).

Expand Down
2 changes: 1 addition & 1 deletion standard/lexical-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
Conceptually speaking, a program is compiled using three steps:

1. Transformation, which converts a file from a particular character repertoire and encoding scheme into a sequence of Unicode characters.
1. Lexical analysis, which translates a stream of Unicode input characters into a stream of tokens.

Check warning on line 10 in standard/lexical-structure.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/lexical-structure.md#L10

MDC032::Line length 85 > maximum 81
1. Syntactic analysis, which translates the stream of tokens into executable code.

Apart from accepting UTF-8 encoded input (as required by [§5](conformance.md#5-conformance), a conforming implementation may choose to accept and transform additional character encoding schemes (such as UTF-16, UTF-32, or non-Unicode character mappings).
Expand Down Expand Up @@ -1577,7 +1577,7 @@

> *Note*: Although a *PP_Compilation_Unit_Name* might contain text that looks like an escape sequence, such text is not an escape sequence; in this context a ‘`\`’ character simply designates an ordinary backslash character. *end note*

Together, the tokens *PP_Start_Line_Character* '-' *PP_End_Line_Character* specify a span of characters in the source file identified by *PP_Compilation_Unit_Name* (the ***mapped file***).
Together, the tokens *PP_Start_Line_Character* ‘-’ *PP_End_Line_Character* specify a span of characters in the source file identified by *PP_Compilation_Unit_Name* (the ***mapped file***).

*PP_Start_Line_Character* represents a start position in the mapped file, specified as a line (*PP_Start_Line*) and column (*PP_Start_Character*) pair; for example, `(1,1)`. This position corresponds to the first character on the line following the directive in the generated code.

Expand Down
6 changes: 3 additions & 3 deletions standard/patterns.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
# 11 Patterns and pattern matching

## 11.1 General

Check warning on line 3 in standard/patterns.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/patterns.md#L3

MDC032::Line length 91 > maximum 81

Check warning on line 4 in standard/patterns.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/patterns.md#L4

MDC032::Line length 94 > maximum 81
A ***pattern*** may be used with the `is` operator ([§12.15.12](expressions.md#121512-the-is-operator)), in a *switch_statement* ([§13.8.3](statements.md#1383-the-switch-statement)), and in a *switch_expression* ([§12.12](expressions.md#1212-switch-expression)) to describe the shape of data against which incoming data is to be compared. Patterns may be nested, with parts of the data being matched against ***sub-patterns***.

A pattern is tested against a value in a number of contexts:

Check warning on line 7 in standard/patterns.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/patterns.md#L7

MDC032::Line length 87 > maximum 81

Check warning on line 8 in standard/patterns.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/patterns.md#L8

MDC032::Line length 91 > maximum 81
- In a *switch_statement*, the *pattern* of a *switch_label* is tested against the *selector_expression* of the *switch_statement*.
- With an *is-pattern* operator, the *pattern* on the right-hand-side is tested against the expression on the left.

Check warning on line 10 in standard/patterns.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/patterns.md#L10

MDC032::Line length 87 > maximum 81
- In a *switch_expression*, the *pattern* of a *switch_expression_arm* is tested against the expression on the *switch_expression*’s left-hand-side.

Check warning on line 11 in standard/patterns.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/patterns.md#L11

MDC032::Line length 83 > maximum 81
- In nested contexts, the *sub-pattern* is tested against values retrieved from properties, fields, or indexed from other input values, depending on the pattern form.

The value against which a pattern is tested is called the ***pattern input value***.

Check warning on line 15 in standard/patterns.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/patterns.md#L15

MDC032::Line length 90 > maximum 81
A pattern `P` is *subsumed* by set of unguarded patterns `Q` if any input value matched by `P` is matched by one of the members of `Q`.

In a switch statement ([§13.8.3](statements.md#1383-the-switch-statement)), it is an error if a case’s pattern is *subsumed* by the preceding set of *unguarded* ([§13.8.3](statements.md#1383-the-switch-statement)) cases. In a switch expression ([§12.12](expressions.md#1212-switch-expression)), it is an error if a *switch_expression_arm*’s pattern is *subsumed* by the preceding set of *unguarded* *switch_expression_arm*s’ patterns.

A set of patterns is exhaustive if, for every possible input value, some pattern in the set is applicable. When an implementation detects that a set of patterns is not exhaustive, it shall issue a warning.

Check warning on line 20 in standard/patterns.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/patterns.md#L20

MDC032::Line length 84 > maximum 81

## 11.2 Pattern forms

### 11.2.1 General

Check warning on line 24 in standard/patterns.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/patterns.md#L24

MDC032::Line length 91 > maximum 81

A pattern may have one of the following forms:

Expand Down Expand Up @@ -650,15 +650,15 @@

In a *conjunctive_pattern*, the *input type* of the second pattern is narrowed by the *type narrowing* requirements of first pattern of the `and`. The *narrowed type* of a pattern `P` is defined as follows:

- If `P` is a type pattern, the *narrowed type* is the type of the type pattern's type.
- Otherwise, if `P` is a declaration pattern, the *narrowed type* is the type of the declaration pattern's type.
- If `P` is a type pattern, the *narrowed type* is the type of the type pattern’s type.
- Otherwise, if `P` is a declaration pattern, the *narrowed type* is the type of the declaration pattern’s type.
- Otherwise, if `P` is a recursive pattern that gives an explicit type, the *narrowed type* is that type.
- Otherwise, if `P` is matched via the rules for `ITuple` in a *positional_pattern* ([§11.2.5](patterns.md#1125-positional-pattern)), the *narrowed type* is the type `System.ITuple`.
- Otherwise, if `P` is a constant pattern where the constant is not the null constant and where the expression has no *constant expression conversion* to the *input type*, the *narrowed type* is the type of the constant.
- Otherwise, if `P` is a relational pattern where the constant expression has no *constant expression conversion* to the *input type*, the *narrowed type* is the type of the constant.
- Otherwise, if `P` is an `or` pattern, the *narrowed type* is the common type of the *narrowed type* of the subpatterns if such a common type exists. For this purpose, the common type algorithm considers only identity, boxing, and implicit reference conversions, and it considers all subpatterns of a sequence of `or` patterns (ignoring parenthesized patterns).
- Otherwise, if `P` is an `and` pattern, the *narrowed type* is the *narrowed type* of the right pattern. Moreover, the *narrowed type* of the left pattern is the *input type* of the right pattern.
- Otherwise the *narrowed type* of `P` is `P`'s input type.
- Otherwise the *narrowed type* of `P` is `P`’s input type.

> *Note*: As indicated by the grammar, `not` has precedence over `and`, which has precedence over `or`. This can be explicitly indicated or overridden by using parentheses. *end note*

Expand Down
2 changes: 1 addition & 1 deletion standard/statements.md
Original file line number Diff line number Diff line change
Expand Up @@ -1194,7 +1194,7 @@ Before the process described in [§13.9.5.1](statements.md#13951-general), the f
If the process in [§13.9.5.1](statements.md#13951-general) completes without producing a single collection type, enumerator type, and iteration type, the following steps are taken:

- If there is an implicit conversion from `X` to the `System.Collections.IEnumerable` interface, then the collection type is this interface, the enumerator type is the interface `System.Collections.IEnumerator`, and the iteration type is `object`.
- Otherwise, determine whether the type 'X' has an appropriate `GetEnumerator` extension method:
- Otherwise, determine whether the type ‘X’ has an appropriate `GetEnumerator` extension method:
- Perform extension method lookup on the type `X` with identifier `GetEnumerator`. If the member lookup does not produce a match, or it produces an ambiguity, or produces a match which is not a method group, an error is produced, and no further steps are taken. It is recommended that a warning be issued if member lookup produces anything except a method group or no match.
- Perform overload resolution using the resulting method group and a single argument of type `X`. If overload resolution produces no applicable methods, results in an ambiguity, or results in a single best method but that method is not accessible, an error is produced an no further steps are taken.
- This resolution permits the first argument to be passed by ref if `X` is a struct type, and the ref kind is `in`.
Expand Down
4 changes: 2 additions & 2 deletions standard/structs.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
## 16.2 Struct declarations

### 16.2.1 General

Check warning on line 14 in standard/structs.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/structs.md#L14

MDC032::Line length 82 > maximum 81
A *struct_declaration* is a *type_declaration* ([§14.8](namespaces.md#148-type-declarations)) that declares a new struct:

Check warning on line 15 in standard/structs.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/structs.md#L15

MDC032::Line length 91 > maximum 81

```ANTLR
struct_declaration
Expand Down Expand Up @@ -334,7 +334,7 @@

This method performs the following tasks:

1. For each of the record struct’s printable members (non-static public field and readable property members), appends that member's name followed by “` = `“ followed by the member's value separated with “`, “`,
1. For each of the record struct’s printable members (non-static public field and readable property members), appends that member’s name followed by “` = `“ followed by the member’s value separated with “`, “`,
2. Returns true if the record struct has printable members.

For a member that has a value type, its value shall be converted to a string representation.
Expand All @@ -357,7 +357,7 @@

1. Creates a `StringBuilder` instance,
2. Appends the record struct name to the builder, followed by “` { `“,
3. Invokes the record struct's `PrintMembers` method giving it the builder, followed by “` `” if it returned true,
3. Invokes the record struct’s `PrintMembers` method giving it the builder, followed by “` `” if it returned true,
4. Appends “`}`”,
5. Returns the builder’s contents with `builder.ToString()`.

Expand Down
2 changes: 1 addition & 1 deletion standard/unsafe-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ When the `unsafe` modifier is used on a partial type declaration ([§15.2.7](cla

### 24.3.1 General

A ***pointer*** is a variable that is capable of containing the address of a variable or static method, referred to as that pointer's target. A pointer with value `null` is a ***null pointer***, and does not currently point to a variable or static method. The act of attempting to access the target of a pointer is called ***dereferencing*** ([§24.6.2](unsafe-code.md#2462-pointer-indirection) and [§24.6.4](unsafe-code.md#2464-pointer-element-access)).
A ***pointer*** is a variable that is capable of containing the address of a variable or static method, referred to as that pointer’s target. A pointer with value `null` is a ***null pointer***, and does not currently point to a variable or static method. The act of attempting to access the target of a pointer is called ***dereferencing*** ([§24.6.2](unsafe-code.md#2462-pointer-indirection) and [§24.6.4](unsafe-code.md#2464-pointer-element-access)).

In an unsafe context, a *type* ([§8.1](types.md#81-general)) can be a *pointer_type*. A *pointer_type* may also be the element type of an array ([§17](arrays.md#17-arrays)). A *pointer_type* may also be used in a typeof expression ([§12.8.18](expressions.md#12818-the-typeof-operator)) outside of an unsafe context (as such usage is not unsafe).

Expand Down
22 changes: 11 additions & 11 deletions standard/variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,7 @@ let *E₀* be the expression obtained by textually removing the leading `?` from
<!-- markdownlint-enable MD028 -->
> *Note*: The concept of “directly contains” allows skipping over relatively simple “wrapper” expressions when analyzing conditional accesses that are compared to other values. For example, in general, `((a?.b(out x))!) == true` is expected to result in the same flow state as `a?.b == true`.
>
> The intent is to allow analysis to function in the presence of a number of possible conversions on a conditional access. Propagating out “state when not null” is not possible when the conversion is user-defined, though, since one can't count on user-defined conversions to honor the constraint that the output is non-null only if the input is non-null. The only exception to this is when the user-defined conversion’s input is a non-nullable value type. For example:
> The intent is to allow analysis to function in the presence of a number of possible conversions on a conditional access. Propagating out “state when not null” is not possible when the conversion is user-defined, though, since one can’t count on user-defined conversions to honor the constraint that the output is non-null only if the input is non-null. The only exception to this is when the user-defined conversion’s input is a non-nullable value type. For example:
>
> ```csharp
> public struct S1 { }
Expand Down Expand Up @@ -1090,7 +1090,7 @@ For an expression *expr*, where *expr* is a constant expression with a `bool` va
- If *expr* is a constant expression with value *true*, and the state of *v* before *expr* is “not definitely assigned,” then the state of *v* after *expr* is “definitely assigned when false.”
- If *expr* is a constant expression with value *false*, and the state of *v* before *expr* is “not definitely assigned,” then the state of *v* after *expr* is “definitely assigned when true.”

> *Note*: It is assumed that if an expression has a constant value bool `false`, that it's impossible to reach any branch that requires the expression to return `true`. Therefore, variables are assumed to be definitely assigned in such branches.
> *Note*: It is assumed that if an expression has a constant value bool `false`, that it’s impossible to reach any branch that requires the expression to return `true`. Therefore, variables are assumed to be definitely assigned in such branches.
>
> Being in a conditional state *before* visiting a constant expression, is never expected, so there is no need to account for scenarios such as “*expr* is a constant expression with value *true* and the state of *v* before *expr* is definitely assigned when true.” *end note*

Expand Down Expand Up @@ -1132,14 +1132,14 @@ All of the above rules are commutative.
>
> Some consequences of these rules are:
>
> - `if (a?.b(out var x) == true) x() else x();` will error in the 'else' branch
> - `if (a?.b(out var x) == 42) x() else x();` will error in the 'else' branch
> - `if (a?.b(out var x) == false) x() else x();` will error in the 'else' branch
> - `if (a?.b(out var x) == null) x() else x();` will error in the 'then' branch
> - `if (a?.b(out var x) != true) x() else x();` will error in the 'then' branch
> - `if (a?.b(out var x) != 42) x() else x();` will error in the 'then' branch
> - `if (a?.b(out var x) != false) x() else x();` will error in the 'then' branch
> - `if (a?.b(out var x) != null) x() else x();` will error in the 'else' branch
> - `if (a?.b(out var x) == true) x() else x();` will error in the ‘else’ branch
> - `if (a?.b(out var x) == 42) x() else x();` will error in the ‘else’ branch
> - `if (a?.b(out var x) == false) x() else x();` will error in the ‘else’ branch
> - `if (a?.b(out var x) == null) x() else x();` will error in the ‘then’ branch
> - `if (a?.b(out var x) != true) x() else x();` will error in the ‘then’ branch
> - `if (a?.b(out var x) != 42) x() else x();` will error in the ‘then’ branch
> - `if (a?.b(out var x) != false) x() else x();` will error in the ‘then’ branch
> - `if (a?.b(out var x) != null) x() else x();` will error in the ‘else’ branch
>
> *end note*

Expand All @@ -1160,7 +1160,7 @@ where *T* is any type or pattern:
- If *E* directly contains a null-conditional expression, and the state of *v* after the non-conditional counterpart *E₀* is “definitely assigned,” and `T` is a pattern that matches a `null` input, then the state of *v* after *expr* is “definitely assigned when false.”
- If *E* is of type `bool` and `T` is a pattern that only matches a `true` input, then the definite-assignment state of *v* after *expr* is the same as the definite-assignment state of *v* after *E*.
- If *E* is of type `bool` and `T` is a pattern that only matches a `false` input, then the definite-assignment state of *v* after *expr* is the same as the definite-assignment state of *v* after the logical negation expression `!`*expr*.
- Otherwise, if the definite-assignment state of *v* after *E* is "definitely assigned," then the definite-assignment state of *v* after *expr* is "definitely assigned."
- Otherwise, if the definite-assignment state of *v* after *E* is “definitely assigned,” then the definite-assignment state of *v* after *expr* is “definitely assigned.”

> *Note*: This subclause addresses similar scenarios as [§9.4.4.37](variables.md#94437--expressions). It does not, however, address recursive patterns; e.g., `(a?.b(out x), c?.d(out y)) is (object, object)`. *end note*

Expand Down
Loading