csharpstandard icon indicating copy to clipboard operation
csharpstandard copied to clipboard

Expression-bodied members vs. expressions that return nothing

Open Nigel-Ecma opened this issue 4 years ago • 10 comments

v6 introduces expression-bodied members, v7 will introduce expression-bodied finalisers. In the former case result of the expression of the body may be classified as nothing (§12.2.1) if the return type of the method is void; in the latter case it may be the case that the result type must be classified as nothing.

The introduction of at least the above two kinds of expression bodied members extends the places expressions whose result is classified as nothing may occur: §12.2.1 requires updating for v6 (and again for v7); it may impact how null conditionals are specified (PR #7, #251); and there could well be other places…

Let the hunt begin!

Nigel-Ecma avatar Sep 07 '21 02:09 Nigel-Ecma

Jon will poke around to try to find other examples.

jskeet avatar Oct 20 '21 21:10 jskeet

Research notes as I go...

There are 13 matches for "nothing" (case-insensitive) in the standard right now. Three of these are irrelevant - for the record, they are:

  • In standard-library.md: "otherwise, nothing is stored in that position in the output string"
  • In standard-library.md: "(nothing appears between the semicolons)"
  • In statements.md: "An empty_statement does nothing."

The remaining matches are all in expressions.md (somewhat predictably). They are:

  • 11.2.1 (Expression classifications / general): "Nothing. This occurs when the expression is an invocation of a method with a return type of void. An expression classified as nothing is only valid in the context of a statement_expression (§12.7) or as the body of a lambda_expression (§11.16)."
  • 11.2.2 (Values of expressions): "Most of the constructs that involve an expression ultimately require the expression to denote a value. In such cases, if the actual expression denotes a namespace, a type, a method group, or nothing, a compile-time error occurs."
  • 11.6.3.13 (Type inference / Inferred return type): "If F is async and the body of F is either an expression classified as nothing (§11.2), or a statement block where no return statements have expressions, the inferred return type is System.Threading.Tasks.Task."
  • 11.7.8.1 (Invocation expressions / general): "If the invocation_expression invokes a method or delegate that returns void, the result is nothing. An expression that is classified as nothing is permitted only in the context of a statement_expression (§12.7) or as the body of a lambda_expression (§11.16). Otherwise a binding-time error occurs."
  • 11.7.9 (Null Conditional Invocation Expression): "Unlike the syntactically equivalent null_conditional_member_access or null_conditional_element_access, a null_conditional_invocation_expression may be classified as nothing."
  • 11.7.9 (Null Conditional Invocation Expression): "If E is classified as nothing then its meaning is the same as the meaning of the block [...]"
  • 11.8.8.3 (Classification of await expressions): "The expression await t is classified the same way as the expression (t).GetAwaiter().GetResult(). Thus, if the return type of GetResult is void, the await_expression is classified as nothing. If it has a non-void return type T, the await_expression is classified as a value of type T."
  • 11.8.8.4 (Run-time evaluation of await expressions): "Either immediately after (if b was true), or upon later invocation of the resumption delegate (if b was false), the expression (a).GetResult() is evaluated. If it returns a value, that value is the result of the await_expression. Otherwise, the result is nothing."

All of those currently look okay to me - that is, of course, only searching for "nothing". An additional search for statement_expression may yield other places to consider, but a quick look at those didn't suggest anything immediately.

Handing back to Nigel for other suggestions, whether of places to look for problems or closing the issue (or deferring to C# 7 so that we check again then).

jskeet avatar Feb 18 '22 14:02 jskeet

Moving this to C# 7.x, when some new places expression that may be classified as nothing get introduced. Then we need to look for places where nothing is currently not an option that needs to be considered and determine if now it needs to be… could be no such places of course but determining that may take non-trivial time.

Nigel-Ecma avatar Mar 10 '22 21:03 Nigel-Ecma

These might be addressed in #213

Assigning to @jskeet to verify, or bump to C# 8

BillWagner avatar Apr 20 '23 13:04 BillWagner

Will wait until #213 is merged before looking. I suspect it won't be fixed, but we can validate it's not worse.

jskeet avatar Apr 20 '23 14:04 jskeet

Checked now, before #795 is merged, admittedly - all of the above is still true. Will change the milestone to C# 8.

jskeet avatar Jun 06 '23 10:06 jskeet