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

Allow init accessors in readonly contexts #47652

Merged
merged 6 commits into from
Sep 18, 2020
Merged

Conversation

333fred
Copy link
Member

@333fred 333fred commented Sep 12, 2020

This allows init properties on readonly structs, readonly properties in structs, and allows init accessors to be declared readonly themselves. Fixes #47612.

This allows `init` properties on readonly structs, readonly properties in structs, and allows `init` accessors to be declared readonly themselves. Fixes dotnet#47612.

public struct S
{
public int I { get; readonly init; }
Copy link
Contributor

@RikkiGibson RikkiGibson Sep 12, 2020

Choose a reason for hiding this comment

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

I think it is strange to allow this, and I also think it is strange to consider an 'init' accessor to be readonly--including when the containing type is 'readonly'. It's effectively saying: "The 'this' parameter to the accessor is a readonly ref, and the accessor is allowed to write to it". It can't cause any differences in behavior.

Also, due to the implementation of MethodSymbol.IsEffectivelyReadOnly, the public API will say that IMethodSymbol.IsReadOnly is false for the readonly init; accessor here. We should add a test for this accessor and a test for when the containing type is readonly. (you beat me to the punch 😉)

The more I look at this, the stranger I find it--but if you are sure that you do not want to introduce a restriction here, I won't belabor the point.

Copy link
Member Author

Choose a reason for hiding this comment

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

I just think there's no real point to introduce a restriction here. This PR makes it so you can put an init in a readonly struct, and this is legal because the initter can only be called during the construction phase, when instance readonly is allowed to be violated. Doing this makes the language more regular. It might be worth clarifying with LDM as to whether we should allow this, but I just don't think we get any real benefits to restricting it.

Copy link
Member

Choose a reason for hiding this comment

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

I agree it's a bit strange at first glance but I agree that it makes the language more regular to allow it. The mental model of readonly struct is that it's a struct where every single member has the readonly modifier. Hence if we allow init in a readonly struct then it should follow that we allow readonly init in a standard struct.

Copy link
Contributor

Choose a reason for hiding this comment

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

In a readonly struct, most of the instance members are readonly. The constructors are not readonly. The static members are not readonly. "All the members have 'readonly'" is a reasonable mental model but it is a simplification of the reality of the language.

@333fred
Copy link
Member Author

333fred commented Sep 12, 2020

Will wait to merge until we get LDM clarification on the readonly init; question.

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

LGTM Thanks (iteration 3)

@jcouv jcouv marked this pull request as draft September 15, 2020 19:42
…prevent them from being considered readonly by the language.
@333fred 333fred marked this pull request as ready for review September 17, 2020 01:31
* upstream/master: (114 commits)
  Remove langversion restriction for source generators. (dotnet#47714)
  Adjust disambiguation rules for type pattern in a switch expression. (dotnet#47756)
  Delete decommissioned benchview tool scripts (dotnet#47752)
  Emit conversions between native integers and pointers directly (dotnet#47708)
  Typeless expressions should contribute nullability to lambda return (dotnet#47581)
  Use a distinct diagnostic ID when an exhaustiveness report uses an unnamed enum value. (dotnet#47693)
  [master] Update dependencies from dotnet/arcade (dotnet#46586)
  Change `Location` of record's primary constructor to point to record's identifier. (dotnet#47715)
  Add public API test for extended partial methods (dotnet#47727)
  Rename in CheckValidNullableMethodOverride (dotnet#47718)
  Update docs
  Add more doc comments
  Add comments and doc comments for ExternalErrorDiagnosticUpdateSource
  Add documentation remarks for syntax kinds (dotnet#43646)
  Disable TestCancellation (dotnet#47725)
  Classify function pointer punctuation (dotnet#47668)
  Disable flaky optprof test
  Handle NotNullIfNotNull in delegate creation and overrides (dotnet#47572)
  Adjust QuickInfo on record BaseType syntax (dotnet#47656)
  Don't exclude events for NameOf context
  ...
@RikkiGibson RikkiGibson self-assigned this Sep 17, 2020
@333fred
Copy link
Member Author

333fred commented Sep 17, 2020

@jaredpar or @jcouv, can you please take another look?

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

LGTM Thanks (iteration 6)

@333fred 333fred merged commit 7e65d92 into dotnet:master Sep 18, 2020
@333fred 333fred deleted the readonly-init branch September 18, 2020 04:17
@ghost ghost added this to the Next milestone Sep 18, 2020
@dibarbet dibarbet modified the milestones: Next, 16.8.P4 Sep 21, 2020
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.

Enable init accessors on readonly structs
5 participants