Description
FEATURE_NAME
- Proposed
- Prototype: Not Started
- Implementation: Not Started
- Specification: Not Started
Summary
Labels currently need to be part of statements but can't be statements on their own. We should consider making "Label:" a statement on its own.
Motivation
Source generators that utilize gotos and labels need to be aware when generating code whether a label being jumped to is at the end of a scope. If it is, emitting "Label:" will cause compilation failures, because the C# spec/compiler currently prohibit a label from being followed by a closing brace. e.g. if code is being generated for the equivalent of:
if (Condition())
{
Work();
}
as:
if (!Condition()) goto AfterWork;
Work();
AfterWork:
the source generator now needs to either know that there will be additional code being generated after AfterWork:
, track it to be able to output a semicolon if there isn't, or just always emit it as:
if (!Condition()) goto AfterWork;
Work();
AfterWork:;
which looks weird and makes for somewhat strange stepping behavior when debugging through the source-generated code. This is all because if it's emitted as:
{
if (!Condition()) goto AfterWork;
Work();
AfterWork:
}
that will fail to compile.
Detailed design
The C# specification currently states:
A labeled_statement permits a statement to be prefixed by a label. Labeled statements are permitted in blocks, but are not permitted as embedded statements.
labeled_statement
: identifier ':' statement
;
such that Label:
is only permitted as part of "labeled statement", i.e. there has to be a statement to put the label on. We should consider allowing Label:
to be a statement of its own.