Skip to content

Commit 132bae5

Browse files
committed
Review udpates
In conversions, restore the IFormattable/FormattableString conversion about the new handler paragraph. Both are valie. In expression, update Better conversion bullets to prefer the handler-preference rules, then the existing rules under a "does not exactly match" bullet. Fix typo in 12.83. Add a bullet in 12.83 to target the IFormattable/Formattable string conversion around the handler.
1 parent 25ace32 commit 132bae5

2 files changed

Lines changed: 13 additions & 8 deletions

File tree

standard/conversions.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ An implicit enumeration conversion permits a *constant_expression* ([§12.26](ex
146146
147147
### 10.2.5 Implicit interpolated string conversions
148148
149+
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 in12.8.3](expressions.md#1283-interpolated-string-expressions).
150+
149151
For any type `T` that is an applicable interpolated string handler typecustInterpStrExpCustHandling), 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.
150152
151153
### 10.2.6 Implicit nullable conversions

standard/expressions.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,14 +1150,16 @@ Given `int i = 10;`, according to [§12.6.4.2](expressions.md#12642-applicable-f
11501150
11511151
#### 12.6.4.5 Better conversion from expression
11521152
1153-
Given an implicit conversion `C₁` that converts from an expression `E` to a type `T₁`, and an implicit conversion `C₂` that converts from an expression `E` to a type `T₂`, `C₁` is a ***better conversion*** than `C₂` if `E` does not exactly match `T₂` and at least one of the following holds:
1153+
Given an implicit conversion `C₁` that converts from an expression `E` to a type `T₁`, and an implicit conversion `C₂` that converts from an expression `E` to a type `T₂`, `C₁` is a ***better conversion*** than `C₂` if one of the following holds:
11541154
1155-
- `E` exactly matches `T₁` and `E` does not exactly match `T₂` ([§12.6.4.6](expressions.md#12646-exactly-matching-expression))
1156-
- `C₁` is not a conditional expression conversion and `C₂` is a conditional expression conversion.
1157-
- `E` exactly matches both or neither of `T₁` and `T₂`, and `T₁` is a better conversion target than `T₂` ([§12.6.4.7](expressions.md#12647-better-conversion-target)) and either `C₁` and `C₂` are both conditional expression conversions or neither is a conditional expression conversion.
1158-
- `V` is a function pointer type `delegate*<V2..Vk, V1>` and `U` is a function pointer type `delegate*<U2..Uk, U1>`, and the calling convention of `V` is identical to `U`, and the refness of `Vi` is identical to `Ui`.
1159-
> *Note*: This is only applicable in unsafe code. *end note*
1160-
- `E` is a method group ([§12.2](expressions.md#122-expression-classifications)), `T₁` is compatible ([§21.4](delegates.md#214-delegate-compatibility)) with the single best method from the method group for conversion `C₁`, and `T₂` is not compatible with the single best method from the method group for conversion `C₂`
1155+
- `E` is a non-constant *interpolated_string_expression*, `C₁` is an implicit interpolated string handler conversion, `T₁` is an applicable interpolated string handler type, and `C₂` is not an implicit interpolated string handler conversion.
1156+
- `E` does not exactly match `T₂` and at least one of the following holds:
1157+
- `E` exactly matches `T₁` and `E` does not exactly match `T₂` ([§12.6.4.6](expressions.md#12646-exactly-matching-expression))
1158+
- `C₁` is not a conditional expression conversion and `C₂` is a conditional expression conversion.
1159+
- `E` exactly matches both or neither of `T₁` and `T₂`, and `T₁` is a better conversion target than `T₂` ([§12.6.4.7](expressions.md#12647-better-conversion-target)) and either `C₁` and `C₂` are both conditional expression conversions or neither is a conditional expression conversion.
1160+
- `V` is a function pointer type `delegate*<V2..Vk, V1>` and `U` is a function pointer type `delegate*<U2..Uk, U1>`, and the calling convention of `V` is identical to `U`, and the refness of `Vi` is identical to `Ui`.
1161+
> *Note*: This is only applicable in unsafe code. *end note*
1162+
- `E` is a method group ([§12.2](expressions.md#122-expression-classifications)), `T₁` is compatible ([§21.4](delegates.md#214-delegate-compatibility)) with the single best method from the method group for conversion `C₁`, and `T₂` is not compatible with the single best method from the method group for conversion `C₂`
11611163
11621164
#### 12.6.4.6 Exactly matching expression
11631165
@@ -1509,6 +1511,7 @@ but this is an implementation detail and therefore not part of this specificatio
15091511
An *interpolated_string_expression* is classified as a value, which is evaluated in one of the following ways depending on the context in which it appears:
15101512

15111513
1. If the target of an assignment or method-call argument has type `string`, the expression is processed by the default interpolated string handler, `System.Runtime.CompilerServices.DefaultInterpolatedStringHandler`, and the result has type `string`.
1514+
1. If the target of an assignment or method-call argument has type `System.IFormattable` or `System.FormattableString`, a string value is not composed from the interpolated string. Instead an instance of `System.FormattableString` is created.
15121515
1. If the target of an assignment or method-call argument has a custom interpolated string handler (§custInterpStrExpHandler) type, then
15131516

15141517
- If the interpolated string contains no interpolations, the expression is processed as if the target type was `string`.
@@ -1526,7 +1529,7 @@ M($"{val}"); // invokes M(SomeInterpolatedStringHandler)
15261529
string s1 = $"{val}"; // default handler used, as target has type string
15271530
M(s1); // invokes M(string)
15281531
SomeInterpolatedStringHandler str2 = $"{val}"; // custom handler used
1529-
M(s2); // invokes M(SomeInterpolatedStringHandler)
1532+
M(str2); // invokes M(SomeInterpolatedStringHandler)
15301533
```
15311534

15321535
The remainder of this subclause deals with the default interpolated string handler behavior only. The declaration and use of custom interpolated string handlers is described in §custInterpStrExpHandler.

0 commit comments

Comments
 (0)