Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Field-backed properties: update uses of IsAutoProperty #74798

Merged
merged 21 commits into from
Aug 27, 2024

Conversation

cston
Copy link
Member

@cston cston commented Aug 18, 2024

Relates to test plan #57012

@cston cston requested a review from a team as a code owner August 18, 2024 22:08
@dotnet-issue-labeler dotnet-issue-labeler bot added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels Aug 18, 2024
@RikkiGibson RikkiGibson self-assigned this Aug 21, 2024
src/Compilers/CSharp/Test/Emit3/FieldKeywordTests.cs Outdated Show resolved Hide resolved
src/Compilers/CSharp/Test/Emit3/FieldKeywordTests.cs Outdated Show resolved Hide resolved
src/Compilers/CSharp/Test/Emit3/FieldKeywordTests.cs Outdated Show resolved Hide resolved
comp.VerifyEmitDiagnostics(
// (3,28): error CS8080: Auto-implemented properties must override all accessors of the overridden property.
// public override object P1 { get => field; }
Diagnostic(ErrorCode.ERR_AutoPropertyMustOverrideSet, "P1").WithLocation(3, 28),
Copy link
Contributor

Choose a reason for hiding this comment

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

I always forget about this. Yes I feel fine with saying that if you use the field keyword then you must override all the accessors. It feels like if you forgot to override one and you are using that keyword then something is going wrong, a value is being dropped on the floor somewhere.

@cston cston requested a review from a team August 22, 2024 19:13
Copy link
Member

@333fred 333fred left a comment

Choose a reason for hiding this comment

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

Done review pass. Feels like there's a fundamental difference between the implementation and the spec here, so we need to clarify what the expected behavior is.

@@ -1765,7 +1765,7 @@ private static bool AccessingAutoPropertyFromConstructor(BoundExpression receive
var propertyIsStatic = propertySymbol.IsStatic;

return (object)sourceProperty != null &&
sourceProperty.IsAutoProperty &&
sourceProperty.IsAutoPropertyOrUsesFieldKeyword &&
Copy link
Member

@333fred 333fred Aug 23, 2024

Choose a reason for hiding this comment

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

I'm not so sure that this is 100% correct. There's a usage in AbstractFlowPass that visits the backing field when this returns true; are we sure we want that behavior for all flow passes? #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.

Good catch, thanks. For now, I've limited this change to the one caller that expects this method to include field cases.

{
if (!IsStatic && SetMethod is { IsInitOnly: false })
if (!IsStatic && ((_propertyFlags & Flags.HasAutoPropertySet) != 0) && SetMethod is { IsInitOnly: false })
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure why we'd condition this on having set;, as opposed to any setter.

Copy link
Member Author

Choose a reason for hiding this comment

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

Added an open question for language design: dotnet/csharplang#8389

Comment on lines +747 to +748
if ((overriddenProperty.GetMethod is { } && GetMethod is null) ||
(overriddenProperty.SetMethod is { } && SetMethod is null))
Copy link
Member

Choose a reason for hiding this comment

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

Correct me if I'm wrong, but this appears to be a fundamentally different check than was here earlier. What was reporting the error on a missing get override earlier?

Copy link
Member Author

@cston cston Aug 23, 2024

Choose a reason for hiding this comment

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

Previously, for a set-only auto-property that overrides a virtual property with a get, the compiler would report:

CS8051: Auto-implemented properties must have get accessors.

And the compiler would not report:

CS8080: Auto-implemented properties must override all accessors of the overridden property.

See sharplab.io.

src/Compilers/CSharp/Portable/CSharpResources.resx Outdated Show resolved Hide resolved
src/Compilers/CSharp/Test/Emit3/FieldKeywordTests.cs Outdated Show resolved Hide resolved
src/Compilers/CSharp/Test/Emit3/FieldKeywordTests.cs Outdated Show resolved Hide resolved
@cston
Copy link
Member Author

cston commented Aug 23, 2024

Feels like there's a fundamental difference between the implementation and the spec here, so we need to clarify what the expected behavior is.

The proposal text for initializers appears to have been based on LDM-2022-01-12 but there was a more recent decision in LDM-2022-03-02, as you found.

I'll update the proposal and implementation.

Copy link
Member

@333fred 333fred left a comment

Choose a reason for hiding this comment

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

No further questions in this commit, but I believe there's still an unanswered question or two from previous commits.

@RikkiGibson RikkiGibson self-requested a review August 27, 2024 01:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers New Feature - Field Keyword untriaged Issues and PRs which have not yet been triaged by a lead
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants