Skip to content

Unions: Support inheritance for Value/HasValue property#82779

Merged
AlekseyTs merged 3 commits intodotnet:features/Unionsfrom
AlekseyTs:Unions_34
Mar 16, 2026
Merged

Unions: Support inheritance for Value/HasValue property#82779
AlekseyTs merged 3 commits intodotnet:features/Unionsfrom
AlekseyTs:Unions_34

Conversation

@AlekseyTs
Copy link
Contributor

@AlekseyTs AlekseyTs commented Mar 15, 2026

Microsoft Reviewers: Open in CodeFlow

@AlekseyTs
Copy link
Contributor Author

@RikkiGibson, @jjonescz, @dotnet/roslyn-compiler Please review

static bool hasUnionValueSignature(PropertySymbol property)
{
// https://github.com/dotnet/roslyn/issues/82636: Cover individual conditions with tests
// https://github.com/dotnet/roslyn/issues/82636: Cover scenaros with a setter present
Copy link
Member

@jjonescz jjonescz Mar 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(typo in word "scenarios")

Suggested change
// https://github.com/dotnet/roslyn/issues/82636: Cover scenarios with a setter present


PropertySymbol? valueProperty = null;
var useSiteInfo = CompoundUseSiteInfo<AssemblySymbol>.Discarded;
PropertySymbol? valueProperty = TryGetOwnOrInheritedUnionMember<PropertySymbol>(inputUnionType, WellKnownMemberNames.HasValuePropertyName, isSuitableProperty, ref useSiteInfo);
Copy link
Member

@jjonescz jjonescz Mar 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

valueProperty

nit: "hasValueProperty"? #Resolved

Debug.Assert(inputUnionType.IsUnionType);

PropertySymbol? valueProperty = null;
var useSiteInfo = CompoundUseSiteInfo<AssemblySymbol>.Discarded;
Copy link
Member

@jjonescz jjonescz Mar 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we discarding use site info here? #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we discarding use site info here?

It is not an error to not find matching HasValue property, therefore we don't want to report any errors or warnings.

public S1(string x) : base(x) {}
public S1(bool x) : base(x) {}

public override object Value => base.Value;
Copy link
Member

@jjonescz jjonescz Mar 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a tests for when the overridden Value returns something else than base.Value? To verify what gets actually called at runtime. #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added ValueProperty_13_Override. If that is not what you had in mind, please provide more details

@AlekseyTs AlekseyTs requested review from a team and jjonescz March 16, 2026 14:01
@AlekseyTs
Copy link
Contributor Author

@RikkiGibson, @jjonescz, @dotnet/roslyn-compiler Please review

class S1 : S0
{
public S1(string x) : base(x) {}
public override string Value => (string)_value;
Copy link
Member

@jjonescz jjonescz Mar 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I imagined we would write something to console in the override and see that it gets executed rather than the overridden property (e.g., if we called it non-virtually) but I guess that might not be really related to the changes in this PR so this looks good too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Or perhaps return the string modified from the override and output the value.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added 'throw` to base implementation

@AlekseyTs
Copy link
Contributor Author

@RikkiGibson, @dotnet/roslyn-compiler For a second review

@AlekseyTs AlekseyTs requested a review from a team March 16, 2026 14:44
Copy link
Member

@RikkiGibson RikkiGibson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still looking through tests

}
else
{
for (NamedTypeSymbol baseType1 = declaringType.BaseTypeWithDefinitionUseSiteDiagnostics(ref useSiteInfo), baseType2 = inputUnionType.BaseTypeNoUseSiteDiagnostics;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any need to defend against cycles like class MyUnion1 : MyUnion2; class MyUnion2 : MyUnion1 here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any need to defend against cycles like class MyUnion1 : MyUnion2; class MyUnion2 : MyUnion1 here?

I do not think so. I do not expect us to get here while bases are being resolved.

{
if (getMemberDeclaredInType(baseType1, memberName, isSuitableUnionMember, out member))
{
if (!inputUnionType.IsDefinition)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checking my understanding: is this just an optimization to avoid creating an unnecessary constructed member symbol?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checking my understanding: is this just an optimization to avoid creating an unnecessary constructed member symbol?

Yes, If we are dealing with a type definition, no additional substitution is needed for members from it's definition base.

@AlekseyTs AlekseyTs merged commit be80397 into dotnet:features/Unions Mar 16, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants