From 888cde23bad1da8a19adaa32dd6051c3e8c25cb9 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Sun, 12 Nov 2023 15:10:10 -0500 Subject: [PATCH 1/5] Add support for target-typed new expressions --- standard/conversions.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/standard/conversions.md b/standard/conversions.md index 0ed9932f7..e69e324d3 100644 --- a/standard/conversions.md +++ b/standard/conversions.md @@ -352,6 +352,12 @@ 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-obj-creation-conv Implicit object-creation conversions + +There is an implicit ***object-creation conversion*** from a *target_typed_new* expression ([§12.7.15.2](expressions.md#127152-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. + ## 10.3 Explicit conversions ### 10.3.1 General From 9c49e1c33bdfde7fbfa51ec72e3c46f301788cd9 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Sun, 12 Nov 2023 15:15:20 -0500 Subject: [PATCH 2/5] Add support for target-typed new expressions --- standard/expressions.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/standard/expressions.md b/standard/expressions.md index d2c0df118..92e2f279a 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -2286,6 +2286,11 @@ An *object_creation_expression* is used to create a new instance of a *class_typ object_creation_expression : 'new' type '(' argument_list? ')' object_or_collection_initializer? | 'new' type object_or_collection_initializer + | target_typed_new + ; + +target_typed_new + : 'new' '(' argument_list? ')' object_or_collection_initializer? ; object_or_collection_initializer @@ -2296,6 +2301,10 @@ object_or_collection_initializer The *type* of an *object_creation_expression* shall be a *class_type*, a *value_type*, or a *type_parameter*. The *type* cannot be a *tuple_type* or an abstract or static *class_type*. +If `type` can be inferred from usage, it can be omitted, as allowed by *target_typed_new*. It is a compile-time error to omit `type` if the type cannot be inferred. A *target_typed_new* expression has no type. However, there is an implicit object-creation conversion (§imp-obj-creation-conv) from a *target_typed_new* expression to every type. It is a compile-time error if a *target_typed_new* is used as an operand of a unary or binary operator, or if it is used where it is not subject to an object-creation conversion. + +If `type` is present, let `T` be that type; otherwise, let `T` be the implied type. + The optional *argument_list* ([§12.6.2](expressions.md#1262-argument-lists)) is permitted only if the *type* is a *class_type* or a *struct_type*. An object creation expression can omit the constructor argument list and enclosing parentheses provided it includes an object initializer or collection initializer. Omitting the constructor argument list and enclosing parentheses is equivalent to specifying an empty argument list. @@ -2304,7 +2313,7 @@ Processing of an object creation expression that includes an object initializer If any of the arguments in the optional *argument_list* has the compile-time type `dynamic` then the *object_creation_expression* is dynamically bound ([§12.3.3](expressions.md#1233-dynamic-binding)) and the following rules are applied at run-time using the run-time type of those arguments of the *argument_list* that have the compile-time type `dynamic`. However, the object creation undergoes a limited compile-time check as described in [§12.6.5](expressions.md#1265-compile-time-checking-of-dynamic-member-invocation). -The binding-time processing of an *object_creation_expression* of the form new `T(A)`, where `T` is a *class_type*, or a *value_type*, and `A` is an optional *argument_list*, consists of the following steps: +The binding-time processing of an *object_creation_expression* of the form `new T(A)`, where the specified or implied type `T` is a *class_type*, or a *value_type*, and `A` is an optional *argument_list*, consists of the following steps: - If `T` is a *value_type* and `A` is not present: - The *object_creation_expression* is a default constructor invocation. The result of the *object_creation_expression* is a value of type `T`, namely the default value for `T` as defined in [§8.3.3](types.md#833-default-constructors). @@ -2319,7 +2328,7 @@ The binding-time processing of an *object_creation_expression* of the form new ` Even if the *object_creation_expression* is dynamically bound, the compile-time type is still `T`. -The run-time processing of an *object_creation_expression* of the form new `T(A)`, where `T` is *class_type* or a *struct_type* and `A` is an optional *argument_list*, consists of the following steps: +The run-time processing of an *object_creation_expression* of the form `new T(A)`, where the specified or implied type `T` is *class_type* or a *struct_type* and `A` is an optional *argument_list*, consists of the following steps: - If `T` is a *class_type*: - A new instance of class `T` is allocated. If there is not enough memory available to allocate the new instance, a `System.OutOfMemoryException` is thrown and no further steps are executed. From 627f62febd479fadca5a122b9e3362c77a20bab7 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Sun, 12 Nov 2023 15:17:25 -0500 Subject: [PATCH 3/5] Add support for target-typed new expressions --- standard/statements.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/statements.md b/standard/statements.md index a8fc58a60..302441797 100644 --- a/standard/statements.md +++ b/standard/statements.md @@ -1538,7 +1538,7 @@ throw_statement ; ``` -A `throw` statement with an expression throws an exception produced by evaluating the expression. The expression shall be implicitly convertible to `System.Exception`, and the result of evaluating the expression is converted to `System.Exception` before being thrown. If the result of the conversion is `null`, a `System.NullReferenceException` is thrown instead. +A `throw` statement with an expression throws an exception produced by evaluating the expression. The expression shall be implicitly convertible to `System.Exception`, and the result of evaluating the expression is converted to `System.Exception` before being thrown. If *expression* is a *target_typed_new* expression ([§12.7.15.2](expressions.md#127152-object-creation-expressions)), the target type is `System.Exception`. If the result of the conversion is `null`, a `System.NullReferenceException` is thrown instead. A `throw` statement with no expression can be used only in a `catch` block, in which case, that statement re-throws the exception that is currently being handled by that `catch` block. From ab89a917a39659dbdbcd8b0552b312134bdf5823 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Sun, 12 Nov 2023 15:30:16 -0500 Subject: [PATCH 4/5] fix link --- standard/statements.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/statements.md b/standard/statements.md index 302441797..a7321afc5 100644 --- a/standard/statements.md +++ b/standard/statements.md @@ -1538,7 +1538,7 @@ throw_statement ; ``` -A `throw` statement with an expression throws an exception produced by evaluating the expression. The expression shall be implicitly convertible to `System.Exception`, and the result of evaluating the expression is converted to `System.Exception` before being thrown. If *expression* is a *target_typed_new* expression ([§12.7.15.2](expressions.md#127152-object-creation-expressions)), the target type is `System.Exception`. If the result of the conversion is `null`, a `System.NullReferenceException` is thrown instead. +A `throw` statement with an expression throws an exception produced by evaluating the expression. The expression shall be implicitly convertible to `System.Exception`, and the result of evaluating the expression is converted to `System.Exception` before being thrown. If *expression* is a *target_typed_new* expression ([§12.8.16.2](expressions.md#128162-object-creation-expressions)), the target type is `System.Exception`. If the result of the conversion is `null`, a `System.NullReferenceException` is thrown instead. A `throw` statement with no expression can be used only in a `catch` block, in which case, that statement re-throws the exception that is currently being handled by that `catch` block. From 42cd8761e42338daaae5c33f3e0113b5c99a05bd Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Sun, 12 Nov 2023 15:31:04 -0500 Subject: [PATCH 5/5] fix link --- standard/conversions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/conversions.md b/standard/conversions.md index e69e324d3..2eb7cbb2d 100644 --- a/standard/conversions.md +++ b/standard/conversions.md @@ -354,7 +354,7 @@ While throw expressions do not have a type, they may be implicitly converted to ### §imp-obj-creation-conv Implicit object-creation conversions -There is an implicit ***object-creation conversion*** from a *target_typed_new* expression ([§12.7.15.2](expressions.md#127152-object-creation-expressions)) to every type. +There is an implicit ***object-creation conversion*** from a *target_typed_new* expression ([§12.8.16.2](expressions.md#128162-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.