Uh oh!
There was an error while loading. Please reload this page.
Update Marshal.QueryInterface() argument modifier - #91983
Conversation
Change "in" modifier to "ref readonly" to avoid warnings in existing interop code.
ghost
commented
Sep 13, 2023
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. |
ghost
commented
Sep 13, 2023
Tagging subscribers to this area: @dotnet/interop-contrib Issue DetailsFixes #91981 Change
|
AaronRobinsonMSFT
commented
Sep 13, 2023
/cc @stephentoub |
AaronRobinsonMSFT
commented
Sep 13, 2023
/backport to release/8.0 |
Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/6167832178 |
Uh oh!
There was an error while loading. Please reload this page.
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. varspan=newbyte[10];intvalue=42;MemoryMarshal.Write<int>(span,refvalue);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 |
jkotas
commented
Sep 13, 2023
These two changes from #89736 (comment) can introduce warnings in existing code:
|
jkotas
commented
Sep 13, 2023
Ok, makes sense. It is unfortunate that we will end up with no consistency in how Guids are treated by various QI APIs:
|
jkotas
commented
Sep 13, 2023
cc @Sergio0694 |
Oh, well this is unfortunate 🥲 I was hoping starting with .NET 8 we'd be able to just pass |
Sergio0694
commented
Sep 13, 2023
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 |
Sergio0694
commented
Sep 13, 2023
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 🤔 |
stephentoub
commented
Sep 13, 2023
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. |
stephentoub
commented
Sep 13, 2023
cc: @jaredpar |
AaronRobinsonMSFT
commented
Sep 13, 2023
@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 |
tannergooding
left a comment
There was a problem hiding this comment.
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
inmodifier toref readonlyto avoid warnings in existing interop code.