Skip to content

Covariant returns part 2#43673

Merged
gafter merged 6 commits intodotnet:features/covariant-returnsfrom
gafter:covariant-returns-part2
May 4, 2020
Merged

Covariant returns part 2#43673
gafter merged 6 commits intodotnet:features/covariant-returnsfrom
gafter:covariant-returns-part2

Conversation

@gafter
Copy link
Member

@gafter gafter commented Apr 25, 2020

  • Emit language version suggestion for property overrides when applicable.
  • Add test for override properties with setters.
  • Test relaxed rules for override in source vs a metadata base type.
  • Add a number of tests requested in Covariant returns part1 #43576
  • Add testing for symbol API (when override is in source)

@gafter gafter added Area-Compilers Feature - Covariant Returns Permit an override to return a more specific reference type labels Apr 25, 2020
@gafter gafter added this to the Compiler.Net5 milestone Apr 25, 2020
@gafter gafter self-assigned this Apr 25, 2020
Neal Gafter added 2 commits April 27, 2020 12:12
…able.

- Add test for override properties with setters.
- Test relaxed rules for override in source vs a metadata base type.
@gafter gafter force-pushed the covariant-returns-part2 branch from 2f9edfa to 51e69fb Compare April 27, 2020 19:12
@gafter gafter marked this pull request as ready for review April 27, 2020 19:14
@gafter gafter requested a review from a team as a code owner April 27, 2020 19:14
@gafter gafter requested review from AlekseyTs and agocke April 27, 2020 19:14
@gafter gafter closed this Apr 27, 2020
@gafter gafter reopened this Apr 27, 2020
else if (!IsValidOverrideReturnType(overridingProperty, overridingMemberType, overriddenMemberType, diagnostics))
else if (overridingProperty.SetMethod is null ?
!IsValidOverrideReturnType(overridingProperty, overridingMemberType, overriddenMemberType, diagnostics) :
!overridingMemberType.Equals(overriddenMemberType, TypeCompareKind.AllIgnoreOptions))
Copy link
Contributor

@AlekseyTs AlekseyTs Apr 28, 2020

Choose a reason for hiding this comment

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

overriddenMemberType [](start = 61, length = 20)

It feels like this isn't always the right type to use. For example:

class A
{
     public virtual A P {get; set;}
}

class B : A
{
     public override B P {get => null;}
}

class C : B
{
     public override B P {get; set;}
}

It looks like the check will succeed for C.P, but the override is not valid because we cannot override the setter this way. #ByDesign

Copy link
Member Author

@gafter gafter Apr 28, 2020

Choose a reason for hiding this comment

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

There is a separate check for the accessors which will fail. This is the existing code for this scenario.


In reply to: 416908389 [](ancestors = 416908389)

{
var method = comp.GlobalNamespace.GetMember(methodName);
var overridden = method.GetOverriddenMember();
Assert.Equal(overriddenMethodName, overridden.ToTestDisplayString());
Copy link
Contributor

@AlekseyTs AlekseyTs Apr 28, 2020

Choose a reason for hiding this comment

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

Assert.Equal(overriddenMethodName, overridden.ToTestDisplayString()); [](start = 12, length = 69)

Consider also asserting the same for method. Makes it easier to see what type did we assume for the overriding method, strengthens the tests. #Closed

Copy link
Member Author

Choose a reason for hiding this comment

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

Did you mean adding a parameter so we can assert the display name of the method? The syntax we use for looking up a member is not compatible with the syntax generated for a display string.


In reply to: 416916024 [](ancestors = 416916024)

Copy link
Contributor

Choose a reason for hiding this comment

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

Did you mean adding a parameter so we can assert the display name of the method?

Yes


In reply to: 416985050 [](ancestors = 416985050,416916024)

}
public class Derived : Base
{
public override string M1 => null;
Copy link
Contributor

@AlekseyTs AlekseyTs Apr 28, 2020

Choose a reason for hiding this comment

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

public override string M1 => null; [](start = 4, length = 34)

When there are multiple equal lines, we usually add some distinct comments to them to make it easier to navigate the base-line #Closed

VerifyOverride(comp, "Derived2.get_P", "System.String Derived.P.get");
VerifyNoOverride(comp, "Derived2.set_P");
comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics(
// (12,53): error CS0546: 'Derived2.P.set': cannot override because 'Derived.P' does not have an overridable set accessor
Copy link
Contributor

@AlekseyTs AlekseyTs Apr 28, 2020

Choose a reason for hiding this comment

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

// (12,53): error CS0546: 'Derived2.P.set': cannot override because 'Derived.P' does not have an overridable set accessor [](start = 16, length = 121)

I think this diagnostics is confusing because it implies that either there is no setter, or it is not virtual/overridable. I think this is because we are detecting this problem in the "wrong" place. #Closed

Copy link
Member Author

Choose a reason for hiding this comment

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

This is an existing diagnostic for this identical scenario. I am not attempting to improve it in the context of this set of changes.


In reply to: 416949513 [](ancestors = 416949513)

Copy link
Contributor

@AlekseyTs AlekseyTs Apr 29, 2020

Choose a reason for hiding this comment

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

This is an existing diagnostic for this identical scenario. I am not attempting to improve it in the context of this set of changes.

I think we should improve that because before one could almost never run into this existing diagnostics and it would most likely mean what it says. For this scenario, the diagnostic should be improved to explain what is wrong in a way the people can understand. Please, either ad a PROTOTYPE comment or open an issue for this.


In reply to: 416983969 [](ancestors = 416983969,416949513)

Copy link
Member Author

Choose a reason for hiding this comment

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

Recorded as #43794


In reply to: 417027167 [](ancestors = 417027167,416983969,416949513)

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Apr 28, 2020

Done with review pass (iteration 5) #Closed

…riding method.

Ensure that the overriden-symbol API behaves the same with or without the featue.
@gafter
Copy link
Member Author

gafter commented Apr 29, 2020

@AlekseyTs I think I've responded to all of your comments. Do you have others?

@agocke Can you please review this?

@gafter
Copy link
Member Author

gafter commented Apr 29, 2020

@AlekseyTs I think I've responded to all of your comments. Do you have others?

@agocke Can you please review this?

Copy link
Contributor

@AlekseyTs AlekseyTs left a comment

Choose a reason for hiding this comment

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

LGTM (iteration 6)

Copy link
Member

@agocke agocke left a comment

Choose a reason for hiding this comment

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

LGTM aside from question about combining checks

suppressAccessors = true; //we get really unhelpful errors from the accessor if the ref kind is mismatched
}
else if (!IsValidOverrideReturnType(overridingProperty, overridingMemberType, overriddenMemberType, diagnostics))
else if (overridingProperty.SetMethod is null ?
Copy link
Member

@agocke agocke May 4, 2020

Choose a reason for hiding this comment

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

Would it be easier to simply call GetOwnOrInheritedSetMethod here? Like we do below for doing the nullable checking? #Resolved

Copy link
Member Author

@gafter gafter May 4, 2020

Choose a reason for hiding this comment

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

I will respond to this comment in #43797 #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

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

No, because we need to treat the presence of a set method declared on the property differently from the absence of one, even if one is inherited.


In reply to: 419707694 [](ancestors = 419707694)

@gafter gafter merged commit 60f7f3c into dotnet:features/covariant-returns May 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-Compilers Feature - Covariant Returns Permit an override to return a more specific reference type

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants