diff --git a/src/Compiler/Facilities/BuildGraph.fs b/src/Compiler/Facilities/BuildGraph.fs index 1df58c1024b..71f4d3da991 100644 --- a/src/Compiler/Facilities/BuildGraph.fs +++ b/src/Compiler/Facilities/BuildGraph.fs @@ -193,7 +193,19 @@ type NodeCode private () = } static member Parallel(computations: NodeCode<'T> seq) = - computations |> Seq.map (fun (Node x) -> x) |> Async.Parallel |> Node + let diagnosticsLogger = DiagnosticsThreadStatics.DiagnosticsLogger + let phase = DiagnosticsThreadStatics.BuildPhase + + computations + |> Seq.map (fun (Node x) -> + async { + DiagnosticsThreadStatics.DiagnosticsLogger <- diagnosticsLogger + DiagnosticsThreadStatics.BuildPhase <- phase + return! x + }) + |> Async.Parallel + |> wrapThreadStaticInfo + |> Node [] module GraphNode = diff --git a/tests/FSharp.Compiler.UnitTests/BuildGraphTests.fs b/tests/FSharp.Compiler.UnitTests/BuildGraphTests.fs index 75f53eb6e5c..556a9b5bc42 100644 --- a/tests/FSharp.Compiler.UnitTests/BuildGraphTests.fs +++ b/tests/FSharp.Compiler.UnitTests/BuildGraphTests.fs @@ -8,6 +8,7 @@ open Xunit open FSharp.Test open FSharp.Test.Compiler open FSharp.Compiler.BuildGraph +open FSharp.Compiler.DiagnosticsLogger open Internal.Utilities.Library module BuildGraphTests = @@ -233,3 +234,42 @@ module BuildGraphTests = Assert.shouldBeTrue graphNode.HasValue Assert.shouldBe (ValueSome 1) (graphNode.TryPeekValue()) + + + [] + let internal ``NodeCode preserves DiagnosticsThreadStatics`` () = + let random = + let rng = Random() + fun n -> rng.Next n + + let job phase _ = node { + do! random 10 |> Async.Sleep |> NodeCode.AwaitAsync + Assert.Equal(phase, DiagnosticsThreadStatics.BuildPhase) + } + + let work (phase: BuildPhase) = + node { + use _ = new CompilationGlobalsScope(DiscardErrorsLogger, phase) + let! _ = Seq.init 8 (job phase) |> NodeCode.Parallel + Assert.Equal(phase, DiagnosticsThreadStatics.BuildPhase) + } + + let phases = [| + BuildPhase.DefaultPhase + BuildPhase.Compile + BuildPhase.Parameter + BuildPhase.Parse + BuildPhase.TypeCheck + BuildPhase.CodeGen + BuildPhase.Optimize + BuildPhase.IlxGen + BuildPhase.IlGen + BuildPhase.Output + BuildPhase.Interactive + |] + + let pickRandomPhase _ = phases[random phases.Length] + Seq.init 100 pickRandomPhase + |> Seq.map (work >> Async.AwaitNodeCode) + |> Async.Parallel + |> Async.RunSynchronously