Skip to content
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

System.NullReferenceException in new task CE in F# 6 #12359

Closed
sasmithjr opened this issue Nov 9, 2021 · 27 comments · Fixed by #12374
Closed

System.NullReferenceException in new task CE in F# 6 #12359

sasmithjr opened this issue Nov 9, 2021 · 27 comments · Fixed by #12374
Assignees
Labels
Bug Impact-High (Internal MS Team use only) Describes an issue with extreme impact on existing code.

Comments

@sasmithjr
Copy link

sasmithjr commented Nov 9, 2021

In some cases where a let precedes a let! in the new task CE, an NRE is thrown. I'm not sure of the specifics for why it happens sometimes and not others, but I've got an example than can quickly be run through FSI.

dotnet --version: 6.0.100
OS: macOS 11.6.1

Repro steps

After using dotnet fsi, copy/paste the following code block into FSI to see the issue:

let z0 () =
    task {
        let w = [| 1 |] |> Array.map (fun w -> w + 1) |> Array.head
        let! x = task { return 3 }
        let finalResult = w + x + 3
        return finalResult
    }

// Throws an NRE
z0 () |> Async.AwaitTask |> Async.RunSynchronously;;

If you swap the let w... and let! x... lines, it works:

let z1 () =
    task {
        let! x = task { return 3 }
        let w = [| 1 |] |> Array.map (fun w -> w + 1) |> Array.head
        let finalResult = w + x + 3
        return finalResult
    }

// Works
z1 () |> Async.AwaitTask |> Async.RunSynchronously;;

Or a simple replacement of Array.map and Array.head works:

let increment = Array.map (fun w -> w + 1)
let head = Array.head

let z2 () =
    task {
        let w = [| 1 |] |> increment |> head
        let! x = task { return 3 }
        let finalResult = w + x + 3
        return finalResult
    }

// Works
z2 () |> Async.AwaitTask |> Async.RunSynchronously;;

Adding a second let also works:

let z3 () =
    task {
        let w0 = [| 1 |] |> Array.map (fun w -> w + 1)
        let w1 = w0 |> Array.head
        let! x = task { return 3 }
        let finalResult = w1 + x + 3
        return finalResult
    }

//Works
z3 () |> Async.AwaitTask |> Async.RunSynchronously;;

Actual behavior

System.NullReferenceException: Object reference not set to an instance of an object. at FSI_0003.z0@13.MoveNext()

Expected behavior

I'd expect the z0() call to eventually evaluate to 8 instead of throwing an exception.

Known workarounds

The problem occurs when

  1. You are in a task { ... }, and
  2. You are in a binding let v = ... where the v becomes a state variable of the task state machine, because it is used after an asynchronous point
  3. The right-hand-side of a binding uses either a while or try or for or a construct such as Array.map that is inlined to produce one of these

In short, the most common cause appears to be the use of the inlined Array.map inside task { ... }. For this case, you can either rewrite your code to avoid the use of Array.map, e.g. using Array.mapi, or define and use a non-inlined Array.map as follows:

module Array =
    let map f x = FSharp.Collections.Array.map f x
    
let f arr =
    task {
        let w = arr |> Array.map (fun w -> w + 1) |> Array.head // This uses the new non-inlined Array.map
        do!  System.Threading.Tasks.Task.Yield()
        return w + 3
    }

(f [| 1 |]).Result

Alternatively using Array.mapi:

let f arr =
    task {
        let w = arr |> Array.mapi (fun _ w -> w + 1) |> Array.head 
        do!  System.Threading.Tasks.Task.Yield()
        return w + 3
    }

(f [| 1 |]).Result

Other workarounds are shown above

@sasmithjr sasmithjr added the Bug label Nov 9, 2021
@NinoFloris
Copy link
Contributor

@sasmithjr Thanks for opening this issue, I can repro it.

@dsyme in a normal project this repro causes an AccessViolationException which usually points to invalid IL, the dynamic case seems to suffer from the same underlying issue though just manifesting as an NRE instead.

An interplay of resumable code and calls to a function with InlineIfLambda arguments before the first yield seems to be the trigger (moving it after a resumption point indeed avoids the issue).

@dsyme
Copy link
Contributor

dsyme commented Nov 9, 2021

Thank you for the bug report, we will prioritise a fix for this.

An interplay of resumable code and calls to a function with InlineIfLambda arguments before the first yield seems to be the trigger (moving it after a resumption point indeed avoids the issue).

It could also be the presence of an inlined loop implied by Array.map. Do you happen to have other failing examples for InlineIfLambda?

@dsyme dsyme self-assigned this Nov 9, 2021
@dsyme dsyme added the Impact-High (Internal MS Team use only) Describes an issue with extreme impact on existing code. label Nov 9, 2021
@forki
Copy link
Contributor

forki commented Nov 10, 2021

we see similar things. Sometimes NRE and sometime System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

@forki
Copy link
Contributor

forki commented Nov 10, 2021

It could also be the presence of an inlined loop implied by Array.map

all issues that I saw today were with Array.map somewhere in that code

@dsyme
Copy link
Contributor

dsyme commented Nov 11, 2021

The fix is in. I wrote up some workarounds that can be used systematically until dev 17.1 and its associated update to .NET SDK and FCS are out

@cmeeren
Copy link
Contributor

cmeeren commented Nov 23, 2021

Happy to hear this is fixed! Anyone know when it'll be out - days, weeks, months? I have some (non-critical) work that depends on this (through Giraffe).

@dsyme
Copy link
Contributor

dsyme commented Nov 23, 2021

Happy to hear this is fixed! Anyone know when it'll be out - days, weeks, months? I have some (non-critical) work that depends on this (through Giraffe).

I'd imagine it's in preview within weeks, though @KevinRansom and @brettfo may know for sure

@ninjarobot
Copy link

ninjarobot commented Dec 15, 2021

@KevinRansom @brettfo do you know if this was included in the 6.0.101 SDK that came out today or was that only for the CVE?

@vzarytovskii
Copy link
Member

@KevinRansom @brettfo do you know if this was included in the 6.0.101 SDK that came out today or was that only for the CVE?

This was a fix for CVE, tasks fix is in 6.0.200:

PS C:\Users\vlza> dotnet --version
6.0.200-preview.21573.3

image

Not sure where a non-preview version will be released exactly.

@isaacabraham
Copy link
Contributor

@KevinRansom @dsyme @KathleenDollard Any idea of when this is going to go in? We want to upgrade SAFE Stack to .NET 6 but this is kind of a blocker - it doesn't really make sense to release a .NET 6 version of SAFE Stack which doesn't use the flagship feature of F#6, but at the moment in all good conscience we can't release the latest template with a bug like this.

I appreciate that there are release windows for this sort of thing and it all has to be scheduled in, but it's been over two months since @dsyme got a fix out for this and we don't even know when this is going out.

If there is a public release plan for this, my apologies - just send me the link to that. Otherwise, could we at least have some idea as to when this is going to be released so that we can start to put in place some kind of release plan for SAFE? This is harder than it sounds, since we would need to align all the downstream dependencies e.g. Saturn, Giraffe etc. to ensure that it's all in lockstep and the dependency tree is tested out.

Thanks!

@dsyme
Copy link
Contributor

dsyme commented Jan 31, 2022

@isaacabraham SDK integrations have been continuing at their normal pace, so I think it's in the 6.0.2xx series and coming through the pipe https://github.com/dotnet/installer/blob/main/README.md#installers-and-binaries. I don't think there's any particular delay - perhaps the usual few weeks over US holiday season. @KevinRansom can confirm.

I believe you can upgrade to .NET 6 without using F# 6 tasks - just continue to use FSharp.Core 5.0.x, plus whichever task implementation you're curently using. If yo ulike set `/langversion:5.0" though I don't think you need to - F# 6 can be used just fine with FSharp.Core 5.0.x, just some features like built-in tasks will not be available.

You are right to wait until this fix is available in a public release before updating the stack to both F# 6 + FSharp.Core 6.0.x.

@isaacabraham
Copy link
Contributor

I don't think there's any particular delay - perhaps the usual few weeks over US holiday season. @KevinRansom can confirm.

Understood - wasn't really complaining that it's taking long (although IMHO this should have been released much sooner). It's more just the visibility and clarity that would help us.

I believe you can upgrade to .NET 6 without using F# 6 tasks

Yes - sure it is. But we really don't want to be doing this with our customers, it's just more work - better to just wait until the fix is out. Especially with the SAFE - there are so many moving parts, a hybrid F# 5/6 solution would really be undesirable.

@dsyme
Copy link
Contributor

dsyme commented Feb 1, 2022

I sympathise. As an aside, upgrading a stack of tech is really painful - in particular I wish there was a way to coordinate a single PR over multiple repositories (Giraffe, Saturn, SAFE) , with all of them doing CI runs, and publication of packages propagating within the overall PR. The only real way of making this efficient is to merge more and more repositories.

@rstm-sf
Copy link
Contributor

rstm-sf commented Feb 1, 2022

Release expected in a week dotnet/runtime#64529 (comment)

@cartermp
Copy link
Contributor

cartermp commented Feb 9, 2022

@dsyme I'm not sure this was fixed. Using .NET SDK 6.0.102,

Using macOS arm64, this is what I get when I try to see if it still reproduces in FSI:

Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at FSI_0002+z0@2.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[FSI_0002+z0@2, FSI-ASSEMBLY, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]](z0@2 ByRef)
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Start[[FSI_0002+z0@2, FSI-ASSEMBLY, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]](z0@2 ByRef)
   at FSI_0002.z0()
   at <StartupCode$FSI_0002>.$FSI_0002.main@()
   at System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Span`1<System.Object> ByRef, System.Signature, Boolean, Boolean)
   at System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)
   at FSharp.Compiler.AbstractIL.ILRuntimeWriter.TypeBuilder.InvokeMemberAndLog[[System.Reflection.BindingFlags, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.Reflection.Emit.TypeBuilder, System.String, System.Reflection.BindingFlags, System.Object[])
   at FSharp.Compiler.AbstractIL.ILRuntimeWriter+execEntryPtFun@2111.Invoke(System.Tuple`2<System.Reflection.Emit.TypeBuilder,System.String>, Microsoft.FSharp.Core.Unit)
   at FSharp.Compiler.Interactive.Shell.action@1-114(FsiDynamicCompiler, ErrorLogger, Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.FSharpOption`1<System.Exception>>)
   at FSharp.Compiler.Interactive.Shell.arg10@1182(FsiDynamicCompiler, ErrorLogger, Microsoft.FSharp.Collections.FSharpList`1<Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.FSharpOption`1<System.Exception>>>, Microsoft.FSharp.Core.Unit)
   at FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler.ProcessCodegenResults(Internal.Utilities.Library.CompilationThreadToken, ErrorLogger, FsiDynamicCompilerState, IncrementalOptimizationEnv, TcState, TcConfig, Microsoft.FSharp.Collections.FSharpList`1<FSharp.Compiler.Syntax.Ident>, Boolean, Boolean, System.String, Microsoft.FSharp.Collections.FSharpList`1<TypedImplFile>, IlxAssemblyGenerator, IlxGenResults)
   at FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler.ProcessInputs(Internal.Utilities.Library.CompilationThreadToken, ErrorLogger, FsiDynamicCompilerState, Microsoft.FSharp.Collections.FSharpList`1<FSharp.Compiler.Syntax.ParsedInput>, Boolean, Boolean, Boolean, Microsoft.FSharp.Collections.FSharpList`1<FSharp.Compiler.Syntax.Ident>)
   at FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler.EvalParsedDefinitions(Internal.Utilities.Library.CompilationThreadToken, ErrorLogger, FsiDynamicCompilerState, Boolean, Boolean, Microsoft.FSharp.Collections.FSharpList`1<FSharp.Compiler.Syntax.SynModuleDecl>)
   at FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor.InteractiveCatch[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](ErrorLogger, Microsoft.FSharp.Core.FSharpFunc`2<System.__Canon,System.Tuple`2<System.__Canon,FsiInteractionStepStatus>>, System.__Canon)
   at FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor.execParsedInteractions(Internal.Utilities.Library.CompilationThreadToken, TcConfig, FsiDynamicCompilerState, Microsoft.FSharp.Core.FSharpOption`1<FSharp.Compiler.Syntax.ParsedScriptInteraction>, ErrorLogger, Microsoft.FSharp.Core.FSharpOption`1<FsiInteractionStepStatus>, System.Threading.CancellationToken)
   at FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor.executeParsedInteractions(Internal.Utilities.Library.CompilationThreadToken, TcConfig, FsiDynamicCompilerState, Microsoft.FSharp.Core.FSharpOption`1<FSharp.Compiler.Syntax.ParsedScriptInteraction>, ErrorLogger, Microsoft.FSharp.Core.FSharpOption`1<FsiInteractionStepStatus>, System.Threading.CancellationToken)
   at FSharp.Compiler.Interactive.Shell+clo@2396-383.Invoke(Internal.Utilities.Library.CompilationThreadToken, TcConfig, FsiDynamicCompilerState)
   at FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor.mainThreadProcessAction[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.__Canon, Microsoft.FSharp.Core.FSharpFunc`2<System.__Canon,Microsoft.FSharp.Core.FSharpFunc`2<TcConfig,Microsoft.FSharp.Core.FSharpFunc`2<System.__Canon,System.Tuple`2<System.__Canon,FsiInteractionStepStatus>>>>, System.__Canon)
   at FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor.mainThreadProcessParsedInteractions(Internal.Utilities.Library.CompilationThreadToken, ErrorLogger, Microsoft.FSharp.Core.FSharpOption`1<FSharp.Compiler.Syntax.ParsedScriptInteraction>, FsiDynamicCompilerState, System.Threading.CancellationToken)
   at FSharp.Compiler.Interactive.Shell+res@2456-21.Invoke(Internal.Utilities.Library.CompilationThreadToken, FsiDynamicCompilerState)
   at FSharp.Compiler.Interactive.Shell+clo@2103-380[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Invoke(Microsoft.FSharp.Core.Unit)
   at <StartupCode$FSharp-Compiler-Interactive-Settings>.$Fsiaux+FSharp-Compiler-Interactive-IEventLoop-Invoke@50[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Invoke(Microsoft.FSharp.Core.Unit)
   at <StartupCode$FSharp-Compiler-Interactive-Settings>.$Fsiaux.action@1(FSharp.Compiler.Interactive.SimpleEventLoop, Microsoft.FSharp.Core.FSharpFunc`2<Microsoft.FSharp.Core.Unit,System.Object>)
   at <StartupCode$FSharp-Compiler-Interactive-Settings>.$Fsiaux.run@38(FSharp.Compiler.Interactive.SimpleEventLoop, Microsoft.FSharp.Core.Unit)
   at FSharp.Compiler.Interactive.SimpleEventLoop.FSharp.Compiler.Interactive.IEventLoop.Run()
   at System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Span`1<System.Object> ByRef, System.Signature, Boolean, Boolean)
   at System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)
   at FSharp.Compiler.Interactive.Shell+Utilities.callInstanceMethod0[[System.Boolean, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.Object, System.Type[], System.String)
   at FSharp.Compiler.Interactive.Shell+GetDefaultConfiguration@3201.EventLoopRun()
   at FSharp.Compiler.Interactive.Shell.runLoop@2704(FsiConsoleOutput, FsiEvaluationSessionHostConfig, Microsoft.FSharp.Core.Unit)
   at FSharp.Compiler.Interactive.Shell.DriveFsiEventLoop(FsiEvaluationSessionHostConfig, FsiConsoleOutput)
   at FSharp.Compiler.Interactive.Shell+FsiEvaluationSession.Run()
   at Sample.FSharp.Compiler.Interactive.Main.evaluateSession(System.String[])
   at Sample.FSharp.Compiler.Interactive.Main.MainMain(System.String[])

Same issue in a brand-new console app:

Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at Program+z0@2.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Program+z0@2, fart, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]](z0@2 ByRef)
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Start[[Program+z0@2, fart, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]](z0@2 ByRef)
   at Program.z0()
   at <StartupCode$fart>.$Program.main@()

@vzarytovskii
Copy link
Member

@cartermp I think the fix is targeting .200 sdk. 102 was fixes only afaik.

@cartermp
Copy link
Contributor

cartermp commented Feb 9, 2022

Aha. Any clue as to when that one will drop? We're pretty angsty about getting this fix in so we can update the F# web ecosystem

@vzarytovskii
Copy link
Member

Aha. Any clue as to when that one will drop? We're pretty angsty about getting this fix in so we can update the F# web ecosystem

Supposed to be 2nd Tuesday of the February, according to dotnet/runtime#64529 (comment)

Not sure whether plans changed. @brettfo do you happen to know if it's gonna be released anytime soon?

@eriawan
Copy link
Member

eriawan commented Feb 9, 2022

@vzarytovskii

FYI, .NET SDK 6.0.102 has been released yesterday, and it's included in VS 2022 17.0.6

image

After looking and trying this update, the fix I think the fix isn't included in this SDK 6.0.102 release...

@vzarytovskii
Copy link
Member

vzarytovskii commented Feb 9, 2022

@vzarytovskii

FYI, .NET SDK 6.0.102 has been released yesterday, and it's included in VS 2022 17.0.6

image

After looking and trying this update, the fix I think the fix isn't included in this SDK 6.0.102 release...

Ah I see, for some reason I thought .200 was set to release yesterday.
I'm not sure unfortunately when 6.0.200 is going to release.

@eriawan
Copy link
Member

eriawan commented Feb 9, 2022

@vzarytovskii
about the 6.0.200, I think this release will be available with VS 2022 17.1.0 release.
Afaik .NET SDK release since .NET Core 3.0 has always been using some themed "major.minor.feature", where the first number in the feature is always encoded and coupled with Visual Studio major and minor release.

Therefore, 6.0.1xx will always be available with VS 2022 17.0.x updates, whereas 6.0.2xx will always be available with VS 2022 17.1.x updates.

This weird theme has been there since .NET Core 3.x and 5.0 releases.
For example, the 5.0.4xx SDK is available with VS 2019 16.11.x updates, whereas 5.0.2xx SDK is available with VS 2019 16.9.x release: (in this case, I pasted the latest release of 5.0.14 runtime that is available in 5.0.405 and 5.0.211)

image

image

NOTE that those SDK has the same runtime version, but the SDK is for different release of VS 2019 16.11.x and 16.9.x

So I hope this helps you, @dsyme , @cartermp and others as well 🙂 🙏

@eriawan
Copy link
Member

eriawan commented Feb 9, 2022

Additional note: (based on my previous comment)

Due to the fact that VS 2022 17.1 is still in Preview 2 and there will be another next preview of 17.1.x, I think the RTM of 6.0.200 SDK will have to wait for VS 2022 17.1.0 release.

@sasmithjr
Copy link
Author

sasmithjr commented Feb 15, 2022

6.0.200 is available now, and it seems to include the fix for this issue.

@eriawan
Copy link
Member

eriawan commented Feb 16, 2022

@sasmithjr
cc @vzarytovskii

Looking at the download page of .NET 6.0 SDK, it seems we haven't got the fix released
https://dotnet.microsoft.com/en-us/download/dotnet/6.0

As we have known, the 6.0.2 runtime doesn't include this fix.
The 6.0.200 SDK unfortunately is still using the same problematic 6.0.2 runtime:

image

It is still the same as the runtime used in 6.0.101 then.

So looks like we actually have to wait for updated SDK (maybe 6.0.201 for VS 2022 17.1.x and 6.0.103 for VS 2022 17.0.x) with the updated runtime of 6.0.3.

To be honest, I'm fine with 17.1 but at the same time this 6.0.200 SDK has the same problematic 6.0.2 as described in the initial issue. FYI, I personally wait for 6.0.3 to be actually released.

@baronfel
Copy link
Member

baronfel commented Feb 16, 2022

@eriawan - This fix is in the FSharp.Core shipped with 6.0.200, which is independent from the 6.0.2 runtime.

Here's the code from the report in a 6.0.200 dotnet fsi that I just installed:

 6.0.200
> dotnet fsi

Microsoft (R) F# Interactive version 12.0.1.0 for F# 6.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

For help type #help;;

> let z0 () =
-     task {
-         let w = [| 1 |] |> Array.map (fun w -> w + 1) |> Array.head
-         let! x = task { return 3 }
-         let finalResult = w + x + 3
-         return finalResult
-     }
-
- // Throws an NRE
- z0 () |> Async.AwaitTask |> Async.RunSynchronously;;;;
val z0: unit -> System.Threading.Tasks.Task<int>
val it: int = 8

@eriawan
Copy link
Member

eriawan commented Feb 16, 2022

@baronfel

@eriawan - This fix is in the FSharp.Core shipped with 6.0.200, which is independent from the 6.0.2 runtime.

So we can have F# fix out of .NET SDK? THANKS!
I'm going to try to update to VS 2022 to 17.1.0👍

@vzarytovskii
Copy link
Member

vzarytovskii commented Feb 16, 2022

@baronfel

@eriawan - This fix is in the FSharp.Core shipped with 6.0.200, which is independent from the 6.0.2 runtime.

So we can have F# fix out of .NET SDK? THANKS!
I'm going to try to update to VS 2022 to 17.1.0👍

Yeah, most of F# fixes land in SDK (both compiler and FSharp.Core). There are some exceptions where runtime contains the change to account for F#'s codegen (for example, most recent one is some improvements for .tail calls).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Impact-High (Internal MS Team use only) Describes an issue with extreme impact on existing code.
Projects
None yet
Development

Successfully merging a pull request may close this issue.