Initial support for union declarations#82500
Conversation
Supporting: - ```union <name> ... ``` - ```record union <name> ... ```
|
Working group decided to not support |
|
@RikkiGibson, @333fred, @dotnet/roslyn-compiler Please review |
| // union S1(int); | ||
| Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "S1").WithArguments("System.Object").WithLocation(100, 7) | ||
| ); | ||
| } |
There was a problem hiding this comment.
Not sure if this already planned for a later PR, consider testing the various modifiers ref union, abstract union, readonly union, unsafe union, ... #Resolved
There was a problem hiding this comment.
Also various parameter modifiers for the case types.
There was a problem hiding this comment.
This PR is meant to enable the scenario, but doesn't include complete test coverage
| comp.VerifyEmitDiagnostics( | ||
| // (100,10): error CS1031: Type expected | ||
| // union S1(); | ||
| Diagnostic(ErrorCode.ERR_TypeExpected, ")").WithLocation(100, 10) |
There was a problem hiding this comment.
Why is this error reported and not CS9401? #Resolved
There was a problem hiding this comment.
Why is this error reported and not CS9401?
Grammar requires at least one type, parser reports accordingly. The CS9401 is for cases when the types list is missing in all partial declarations
There was a problem hiding this comment.
It is Ok to omit the list, but if the list is not omitted, there must be at least one type
There was a problem hiding this comment.
It feels like we should still be reporting 9401 here. It's odd that the better error text is reported in the scenario where the user typed less.
There was a problem hiding this comment.
It feels like we should still be reporting 9401 here.
I am not necessarily sharing your opinion, but I will capture it in a PROTOTYPE comment. I think that the current behavior is sufficiently good for preview
| "; | ||
| var comp = CreateCompilation([src, UnionAttributeSource]); | ||
| comp.VerifyEmitDiagnostics( | ||
| // (100,15): error CS0111: Type 'S1' already defines a member called 'S1' with the same parameter types |
There was a problem hiding this comment.
Could we perhaps report a better error here? #Resolved
There was a problem hiding this comment.
Could we perhaps report a better error here?
Probably, but it is not a priority at the moment.
| // union S1(int); | ||
| Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "S1").WithArguments("System.Object").WithLocation(100, 7) | ||
| ); | ||
| } |
There was a problem hiding this comment.
Also various parameter modifiers for the case types.
| Assert.True(members[1].IsImplicitlyDeclared); | ||
| Assert.False(members[2].IsStatic); | ||
| Assert.True(members[2].IsImplicitlyDeclared); | ||
| Assert.False(members[^3].IsStatic); |
There was a problem hiding this comment.
Is there a particular reason for accessing "from start" sometimes and "from end" other times here? #Resolved
There was a problem hiding this comment.
Is there a particular reason for accessing "from start" sometimes and "from end" other times here?
This is in artifact of support for record unions. The test was a theory covering both declaration kinds and for records there were some record specific members in the middle
|
|
||
| struct_declaration | ||
| : attribute_list* modifier* 'struct' identifier_token type_parameter_list? parameter_list? base_list? type_parameter_constraint_clause* '{'? member_declaration* '}'? ';'? | ||
| : attribute_list* modifier* ('struct' | 'union') identifier_token type_parameter_list? parameter_list? base_list? type_parameter_constraint_clause* '{'? member_declaration* '}'? ';'? |
There was a problem hiding this comment.
Passing on feedback from @CyrusNajmabadi in #82526 (comment)
This is very weird that this is part of struct_declaration when it changes that keyword. I would expect a different type-decl here.
FWIW, I had the same reaction. I found it strange to use the parameter list for the union's case list.
#Resolved
There was a problem hiding this comment.
The syntax model is a public API and, therefore will go though the standard review process. In this PR, I really don't focus on this aspect. The goal is to enable an ability to use a union declaration in code.
| // For extension declarations, there must be a parameter list | ||
| var paramList = CurrentToken.Kind == SyntaxKind.OpenParenToken || isExtension | ||
| ? ParseParenthesizedParameterList(forExtension: isExtension) : null; | ||
| ? ParseParenthesizedParameterList(forExtensionOrUnion: isExtension || isUnion) : null; |
There was a problem hiding this comment.
Passing on feedback from @CyrusNajmabadi from #82526 (comment)
Imo,this is very difficult to understand precedence here. I would parenthesize for clarity. #Resolved
There was a problem hiding this comment.
very difficult to understand precedence here. I would parenthesize for clarity.
The modified condition is already parenthesized:
(forExtensionOrUnion: isExtension || isUnion)
|
Fwiw, I only noticed this in julien' ide pr, but reusing StructDecl here with a different keyword/kind doesn't fit how I think TypeDecl is intended to be used. Like with RecordDecl, I think this should be it's own TypeDecl subclass. So keep the new UnionDecl syntaxkind, but pair withe a UnionDecl subclass. If I can be included in the API review, that would be appreciated. Thanks. @333fred fyi, tnx. |
Supporting:
union <name> ...