-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Mark applicable structs as readonly and use in-modifier #13919
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
Conversation
f49168e to
a739002
Compare
|
This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days. |
| /// can only be used as a switch. | ||
| /// </summary> | ||
| public struct SwitchParameter | ||
| public readonly struct SwitchParameter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one could be an issue -- SwitchParameter is a very widely used public API
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But SwitchParameter is immutable by design, and adding the readonly-modifier doesn't cause any overload resolution changes [1], so I think this is not a breaking change.
[1] https://blog.paranoidcoding.com/2019/03/27/readonly-struct-breaking-change.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I'm fairly convinced by this
| { | ||
| [StructLayout(LayoutKind.Explicit, Size = 16)] | ||
| public struct EventDescriptor | ||
| public readonly struct EventDescriptor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about changing public structs to readonly -- existing code that relies on the previous form may be affected
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This struct is immutable by design.
| /// <param name="eventPayload"> | ||
| /// </param> | ||
| public bool WriteEvent(ref EventDescriptor eventDescriptor, params object[] eventPayload) | ||
| public bool WriteEvent(in EventDescriptor eventDescriptor, params object[] eventPayload) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing the signature on a public method like this is a breaking change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The compiler doesn't permit overloading on ref/out/in differences, so this change is non-breaking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically the issue isn't with the compiler, but with the runtime. Modules compiled against the old API surface must continue to work after any changes are made to the API.
But I tested it out with a toy project (an exe and a lib, where I built an in version of the lib and then changed it so the exe is compiled against a ref version) and it seems to work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that's still C# compiler rules, where the compiler statically decides which overload to resolve for a call. My concern was that the resolved method call in the IL might not match what the library was originally compiled against when its loaded at runtime (so even though the original program isn't broken it still requires recompilation, which is a dealbreaker for modules). It makes sense that that's not the case though.
|
@daxian-dbw can you review please? |
|
This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days. |
|
🎉 Handy links: |
Work toward #13915.
Changes touch public APIs but do not cause any overload resolution changes, so in theory are non-breaking:
See also: dotnet/coreclr#14789