Covariant returns part 2#43673
Conversation
…able. - Add test for override properties with setters. - Test relaxed rules for override in source vs a metadata base type.
2f9edfa to
51e69fb
Compare
| else if (!IsValidOverrideReturnType(overridingProperty, overridingMemberType, overriddenMemberType, diagnostics)) | ||
| else if (overridingProperty.SetMethod is null ? | ||
| !IsValidOverrideReturnType(overridingProperty, overridingMemberType, overriddenMemberType, diagnostics) : | ||
| !overridingMemberType.Equals(overriddenMemberType, TypeCompareKind.AllIgnoreOptions)) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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()); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
// (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
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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)
|
Done with review pass (iteration 5) #Closed |
…riding method. Ensure that the overriden-symbol API behaves the same with or without the featue.
|
@AlekseyTs I think I've responded to all of your comments. Do you have others? @agocke Can you please review this? |
|
@AlekseyTs I think I've responded to all of your comments. Do you have others? @agocke Can you please review this? |
agocke
left a comment
There was a problem hiding this comment.
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 ? |
There was a problem hiding this comment.
Would it be easier to simply call GetOwnOrInheritedSetMethod here? Like we do below for doing the nullable checking? #Resolved
There was a problem hiding this comment.
I will respond to this comment in #43797 #Resolved
There was a problem hiding this comment.
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)
Uh oh!
There was an error while loading. Please reload this page.