Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for target typed conditional expression #1071

Draft
wants to merge 2 commits into
base: draft-v9
Choose a base branch
from
Draft
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
9 changes: 9 additions & 0 deletions standard/conversions.md
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,15 @@ An implicit conversion exists from a *default_literal* ([§12.8.20](expressions.

While throw expressions do not have a type, they may be implicitly converted to any type.

### §imp-cond-expr-conv Implicit conditional expression conversions

For a *conditional_expression* `c ? e1 : e2`, when

1. there is no common type for `e1` and `e2`, or
1. for which a common type exists, but one of the expressions `e1` or `e2` has no implicit conversion to that type

an implicit ***conditional expression conversion*** exists that permits an implicit conversion from *conditional_expression* to any type `T` for which there is a conversion-from-expression from `e1` to `T` and also from `e2` to `T`. It is an error if *conditional_expression* neither has a common type between `e1` and `e2` nor is subject to a conditional expression conversion.

## 10.3 Explicit conversions

### 10.3.1 General
Expand Down
9 changes: 5 additions & 4 deletions standard/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,11 @@

> *Note*: For an example of overloading the `++` and `--` operators see [§15.10.2](classes.md#15102-unary-operators). *end note*

**Operator notation** | **Functional notation**

Check failure on line 215 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / lint

Table pipe style [Expected: leading_and_trailing; Actual: no_leading_or_trailing; Missing leading pipe]

Check failure on line 215 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / lint

Table pipe style [Expected: leading_and_trailing; Actual: no_leading_or_trailing; Missing trailing pipe]
---------------------- | -------------------------

Check failure on line 216 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / lint

Table pipe style [Expected: leading_and_trailing; Actual: no_leading_or_trailing; Missing leading pipe]

Check failure on line 216 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / lint

Table pipe style [Expected: leading_and_trailing; Actual: no_leading_or_trailing; Missing trailing pipe]
`«op» x` | `operator «op»(x)`

Check failure on line 217 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / lint

Table pipe style [Expected: leading_and_trailing; Actual: no_leading_or_trailing; Missing leading pipe]

Check failure on line 217 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / lint

Table pipe style [Expected: leading_and_trailing; Actual: no_leading_or_trailing; Missing trailing pipe]
`x «op»` | `operator «op»(x)`

Check failure on line 218 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / lint

Table pipe style [Expected: leading_and_trailing; Actual: no_leading_or_trailing; Missing leading pipe]

Check failure on line 218 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / lint

Table pipe style [Expected: leading_and_trailing; Actual: no_leading_or_trailing; Missing trailing pipe]
`x «op» y` | `operator «op»(x, y)`

Check failure on line 219 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / lint

Table pipe style [Expected: leading_and_trailing; Actual: no_leading_or_trailing; Missing leading pipe]

Check failure on line 219 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / lint

Table pipe style [Expected: leading_and_trailing; Actual: no_leading_or_trailing; Missing trailing pipe]

User-defined operator declarations always require at least one of the parameters to be of the class or struct type that contains the operator declaration.

Expand Down Expand Up @@ -1098,10 +1098,11 @@

#### 12.6.4.5 Better conversion from expression

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:
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:

- `E` exactly matches `T₁` and `E` does not exactly match `T₂` ([§12.6.4.6](expressions.md#12646-exactly-matching-expression))
- `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))
- `C₁` is not a conditional expression conversion and `C₂` is a conditional expression conversion.
- `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
- `E` is a method group ([§12.2](expressions.md#122-expression-classifications)), `T₁` is compatible ([§20.4](delegates.md#204-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₂`

#### 12.6.4.6 Exactly matching expression
Expand Down Expand Up @@ -3472,7 +3473,7 @@
;
```

A *cast_expression* of the form `(T)E`, where `T` is a type and `E` is a *unary_expression*, performs an explicit conversion ([§10.3](conversions.md#103-explicit-conversions)) of the value of `E` to type `T`. If no explicit conversion exists from `E` to `T`, a binding-time error occurs. Otherwise, the result is the value produced by the explicit conversion. The result is always classified as a value, even if `E` denotes a variable.
A *cast_expression* of the form `(T)E`, where `T` is a type and `E` is a *unary_expression*, performs an explicit conversion ([§10.3](conversions.md#103-explicit-conversions)) of the value of `E` to type `T`. In the presence of a conditional expression conversion (§imp-cond-expr-conv) there may be more than one possible conversion from `E` to `T`, in which case, the conditional expression conversion shall only be used as a last resort. If no explicit conversion exists from `E` to `T`, a binding-time error occurs. Otherwise, the result is the value produced by the explicit conversion. The result is always classified as a value, even if `E` denotes a variable.

The grammar for a *cast_expression* leads to certain syntactic ambiguities.

Expand Down Expand Up @@ -4818,7 +4819,7 @@
If `ref` is not present, the second and third operands, `x` and `y`, of the `?:` operator control the type of the conditional expression:

- If `x` has type `X` and `y` has type `Y` then,
- If an identity conversion exists between `X` and `Y`, then the result is the best common type of a set of expressions ([§12.6.3.15](expressions.md#126315-finding-the-best-common-type-of-a-set-of-expressions)). If either type is `dynamic`, type inference prefers `dynamic` ([§8.7](types.md#87-the-dynamic-type)). If either type is a tuple type ([§8.3.11](types.md#8311-tuple-types)), type inference includes the element names when the element names in the same ordinal position match in both tuples.
- If an identity conversion exists between `X` and `Y`, then the result is the best common type of a set of expressions ([§12.6.3.15](expressions.md#126315-finding-the-best-common-type-of-a-set-of-expressions)). ***placeholder for words somehow referring to “12.6.4.5 Better conversion from expression.”*** If either type is `dynamic`, type inference prefers `dynamic` ([§8.7](types.md#87-the-dynamic-type)). If either type is a tuple type ([§8.3.11](types.md#8311-tuple-types)), type inference includes the element names when the element names in the same ordinal position match in both tuples.
- Otherwise, if an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) exists from `X` to `Y`, but not from `Y` to `X`, then `Y` is the type of the conditional expression.
- Otherwise, if an implicit enumeration conversion ([§10.2.4](conversions.md#1024-implicit-enumeration-conversions)) exists from `X` to `Y`, then `Y` is the type of the conditional expression.
- Otherwise, if an implicit enumeration conversion ([§10.2.4](conversions.md#1024-implicit-enumeration-conversions)) exists from `Y` to `X`, then `X` is the type of the conditional expression.
Expand Down
Loading