-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Fix explicit offset of ByRefLike fields. #111584
Merged
AaronRobinsonMSFT
merged 16 commits into
dotnet:main
from
AaronRobinsonMSFT:runtime_111260
Jan 31, 2025
Merged
Changes from 15 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
948d73b
Fix explicit offset of ByRefLike fields.
AaronRobinsonMSFT b0cda63
Improve tests coverage
AaronRobinsonMSFT f87bb60
Fix mono error checking
AaronRobinsonMSFT 405b24e
Update native AOT.
AaronRobinsonMSFT d0fbad1
Feedback
AaronRobinsonMSFT f762b1d
Update native AOT tests
AaronRobinsonMSFT 3c86eb9
Feedback
AaronRobinsonMSFT c8285e9
Fix test build warning
AaronRobinsonMSFT c458d74
AOT should needs to pass along the base offset.
AaronRobinsonMSFT 3b789f2
Add property for type containing any byrefs.
AaronRobinsonMSFT 247e5e5
Feedback
AaronRobinsonMSFT 8cfee36
Feedback
AaronRobinsonMSFT 59f7ec4
Update docs/coding-guidelines/breaking-change-rules.md
AaronRobinsonMSFT ac4e3d2
Fix native AOT predicate
AaronRobinsonMSFT 47a7a13
Fix style
AaronRobinsonMSFT 7f86488
Revert changes to breaking-change-rules.md
AaronRobinsonMSFT File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 am not following what's the rationale for this. How is this different from adding/removing any fields? We have no guarantees for internal type layout compatibility, unless the guarantee is explicitly documented.
"Changing a
struct
type to aref struct
type and vice versa" is very different - it is very obvious compile time 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.
I think the point of it is that now adding a
ref
field could break someone if they were using the type in anExplicit
offset scenario. For example, the BCL has someref struct
that just has anint
field. A user consumes that type in a user defined type as anExplicit
field and the containing library is published to NuGet. In the next major version aref int
field is added. When that NuGet package is consumed on a new BCL, the library fails to load because theref int
field forces a new alignment restriction.By definition this would now break. We can argue if it matters, but it would cause a failure at type load time.
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.
It is the case for any field changes in public BCL value types. You can get the same break by adding/removing
int
orobject
fields too. There is nothing special about ref fields here.Field layout of BCL value types is not a public contract that people can depend on, unless it is explicitly documented for specific types.
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.
Between the two statements above, it looks like the distinction in this case is compile time vs run time failure. Is that the conversation we are having? In the sense that compile time failure is not acceptable, but run time failure is?
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 happens to be a compile time vs. runtime time difference between these two case, but that's just accidental. Runtime breaking changes are not acceptable either in general.
I think that the discussion that we are having here is about distinction between what we define as a breaking change vs. change that can break apps that depend on undocumented behaviors.
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 thought we already consider such things breaking as well - for example adding an object typed field to a struct makes the struct no longer meet
unmanaged
constraint. I recall Roslyn team even did work to put a dummy object field into such struct for reference assemblies because these non-contractual private implementation details actually matter.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.
If the libraries folks agree, I think it would be fine to explicitly match the current Roslyn behavior and say that adding first field of a new kind to an existing value type is disallowed change. Kind can be any of objref, byref or generic type argument, and the rule applies recursively.
Introducing new significant state in existing value types is close to impossible to do in compatible way for other reasons (e.g. it is why we have both DateTime and DateTimeOffset), so these situations do not come up in practice. I guess it is the reason why nobody bothered to mention it in the breaking changes doc up until now.
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 will create a discussion issue for this topic and loop in libraries folks. Updating the markdown is a cheaper PR than continually running the build/test legs.
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 have created #112114
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.
Opened dotnet/docs#44672