-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Update Marshal.QueryInterface()
argument modifier
#91983
Conversation
Change "in" modifier to "ref readonly" to avoid warnings in existing interop code.
Note regarding the This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change. |
Tagging subscribers to this area: @dotnet/interop-contrib Issue DetailsFixes #91981 Change
|
/cc @stephentoub |
/backport to release/8.0 |
Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/6167832178 |
....Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/IIUnknownStrategy.cs
Show resolved
Hide resolved
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.
cc: @tannergooding
I thought that it is "by design" that the change will produce warnings in existing code. There are other APIs with the same problem. For example, this compiled fine in .NET 7 and it will produce the exact same warning in .NET 8 as the Marshal.QueryInterface case. var span = new byte[10];
int value = 42;
MemoryMarshal.Write<int>(span, ref value); If we are not happy with this change, should we roll it back in all APIs that were affected? |
I think in general I would agree that introducing new warnings should be avoided, but I do see the benefit in most of these cases. My specific concern here is the legacy nature of the My calculus is on the nature of the |
These two changes from #89736 (comment) can introduce warnings in existing code:
|
Ok, makes sense. It is unfortunate that we will end up with no consistency in how Guids are treated by various QI APIs:
|
cc @Sergio0694 |
Oh, well this is unfortunate 🥲 I was hoping starting with .NET 8 we'd be able to just pass |
If people are actually failing to build, isn't that simply because they're on an older version of Roslyn? The changes needed to properly support |
This should be fine to have as To be clear: it is my opinion that this should not be merged on any version, because the issue shouldn't exist to start with. There is something else that has gone wrong. Either it's that they've enabled WarningsAsErrors (in which case they're being told about some unideal usage of an API as a warning, which they've opted to convert into an error), they've got an out-of-date compiler (either their fault, or the latest .NET 8 build has an old compiler which doesn't support the feature properly), or there's a bug in roslyn (which would obviously need to be fixed). On a side note, this is why I suggested to the roslyn team on the issue (iirc I'm pretty sure I did anyway) that there should be no warning when using |
In general, yes. We didn't go API by API and discuss every single one being changed, though. And for things in interop, the folks responsible for interop (aka Aaron) get to weigh in (and apparently hadn't been aware of this).
Whether or not it's something we consider to be "breaking", it's still friction. And the person responsible for our interop system is saying that friction isn't warranted.
Or |
Sorry, let me rephrase that. Of course I do respect what Aaron is saying here, all I'm trying to say is just, given this PR is marked as a fix for an issue which is just a consequence of that user trying to compile with outdated tooling, and not a real break caused by the signature change when using C# 12, is it possible that the apparent need to revert this might've been influenced by that? As in, that considering the additional context (and the fact that user would not in fact see a build error as soon as they update Roslyn to latest), is there a chance undoing this might not actually be needed? 😅
This is more of a side note, but I find this to be a bit confusing. One of the main arguments for including those relaxed combinations of ref modifiers as part of the spec was specifically to allow changing the signature of APIs like this without it being a source breaking change. If se say that upgrading TFM without keeping the language version in sync is a perfectly supported scenario, doesn't that kinda just invalidate all of that? Because you'd still end up in a situation where you'd have users on an "officially supported" scenario getting (unwanted) breaking changes when migrating to .NET 8 🤔 |
No, it's just one more thing to factor in. It needs to be worth it. And Aaron is saying it's not worth it. There's a scale here and with all changes that introduce friction; this isn't something where everything is definitively 100% right or 100% wrong. |
cc: @jaredpar |
@hamarb123 @Sergio0694 Both of your arguments are sound and I tend to agree with them. There are two dimensions I am concerned with. First, consider the comment made by @jkotas at #91983 (comment). This can also introduce precisely the same error and comes with all the same UX concerns as Second, the These concerns are compounded by mucking with an API that doesn't functionally benefit from the change in any obvious way - performance or otherwise. The performance angle is on the interop boundary and any potential copy is going to be heavily out-weighted by the interop call itself and the UX has been established since .NET Framework 1.1. I just don't see the win, other than @jkotas's other comment at #91983 (comment), which I am very sympathetic to. The update in this PR means that |
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.
Seems good to me overall.
I'm not particularly a fan of avoiding new warnings, but I understand why there is a desire to do it here in particular.
It being ref readonly
notably also doesn't block typeof(T).GUID
, it just transfers the warning there instead which the people who want to explicit take advantage of this can suppress instead.
This means by changing from ref
to ref readonly
(rather than in
) here on this very old API means we maintain the status quo for existing code, we improve the experience for new code by removing the need to Unsafe.As
to strip the readonlyness, and we allow power users to still pass rvalues if they are willing to suppress a warning.
Runtime reverted the change in following PR. dotnet/runtime#91983
Updatign API call on QueryInterface Runtime reverted the change in following PR. dotnet/runtime#91983
Runtime reverted the change in following PR. dotnet/runtime#91983
Fixes #91981
Change
in
modifier toref readonly
to avoid warnings in existing interop code.