-
Notifications
You must be signed in to change notification settings - Fork 105
Fix type forwarding for init
/record
workaround
#895
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 type forwarding for init
/record
workaround
#895
Conversation
It is working on macOS 🥳:
|
So they don't need `IsExternalInit` defined too.
5c9f137
to
37d7594
Compare
Codecov Report
@@ Coverage Diff @@
## master #895 +/- ##
=========================================
Coverage ? 72.32%
=========================================
Files ? 255
Lines ? 12847
Branches ? 817
=========================================
Hits ? 9292
Misses ? 3555
Partials ? 0 Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
This was confusing as all get out, and I'm still not sure I understand exactly what breaks and why, but I know how to fix it 🤷 |
That issue is just about flagging this compatibility problem at build time for libraries that have it. Right now the problem is still a library issue. Libraries defined IsExternalInit locally and that "leaks" to their callers in public API. If they want to remain compatible with that public API they need to keep defining the type locally, or forward the local definition to the framework version. The only "more elegant fix" would be a hack to have the runitme's type loader ignore the assembly difference here and effectively "inject" a type forward. I don't expect the runtime will ever do that, and likely not retroactively on |
I agree with @ericstj assessment. This is one of the dangers of using new C# features on old runtimes. |
This PR fixes the magic around the
IsExternalInit
field that allowed OmniSharp to opt-in to the use ofinit
andrecord
semantics before they were available normally. This prior workaround, however, now can easily cause problems after updating to .NET 6.0, where the field is available. The primary problem manifests with anet6.0
app consumes the OmniSharp library (targetingnetstandard2.0
) and attempts to use any of therecord
structs (withinit
fields), such as PowerShell Editor Services' test suite when creatingCompletionRecord
structs. The type resolution would fail on initialization of the struct because the set method was not pointing to the right place, similar to what happened toSystem.Text.Json
(which also opted in early with that workaround) in dotnet/runtime#61737..NET may eventually find a solution (see dotnet/sdk#23319) that is more elegant than this, but for now the correct thing to do, as confirmed with @ericstj, is as seen in this PR: forward the type when targeting .NET 5.0 or greater, and otherwise define it internally (it should never be defined publicly). Then in consuming libraries, if they similarly used the same
IsExternalInit
code, the same correction should be applied (as was done to PowerShell Editor Services in PowerShell/PowerShellEditorServices#1953).I also updated the test apps and sample program just to target
net6.0
instead ofnetcoreapp3.1
for simplicity (note the prior targets had redundant frameworks, probably from a prior find/replace). This will not affect consumers.Finally, I fixed the macOS CI build by updating the build tool that was failing to install, and then re-enabled CI.