diff --git a/Directory.Build.props b/Directory.Build.props index 10c53909035..0fe610fc267 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -28,6 +28,8 @@ + true + true false true true diff --git a/FSharp.Benchmarks.sln b/FSharp.Benchmarks.sln index 2ace22c1515..e04c208232f 100644 --- a/FSharp.Benchmarks.sln +++ b/FSharp.Benchmarks.sln @@ -1,4 +1,5 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 + +Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.1.32113.165 MinimumVisualStudioVersion = 10.0.40219.1 @@ -26,6 +27,8 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FCSSourceFiles", "tests\ben EndProject Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Test.Utilities", "tests\FSharp.Test.Utilities\FSharp.Test.Utilities.fsproj", "{0B149238-0912-493E-8877-F831AE01B942}" EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Benchmarks.Common", "tests\benchmarks\FSharp.Benchmarks.Common\FSharp.Benchmarks.Common.fsproj", "{62DED1EA-6A33-4537-8ED2-118462D0FEE5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -109,6 +112,14 @@ Global {0B149238-0912-493E-8877-F831AE01B942}.Release|Any CPU.Build.0 = Release|Any CPU {0B149238-0912-493E-8877-F831AE01B942}.ReleaseCompressed|Any CPU.ActiveCfg = Debug|Any CPU {0B149238-0912-493E-8877-F831AE01B942}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {62DED1EA-6A33-4537-8ED2-118462D0FEE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {62DED1EA-6A33-4537-8ED2-118462D0FEE5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {62DED1EA-6A33-4537-8ED2-118462D0FEE5}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {62DED1EA-6A33-4537-8ED2-118462D0FEE5}.Proto|Any CPU.Build.0 = Debug|Any CPU + {62DED1EA-6A33-4537-8ED2-118462D0FEE5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {62DED1EA-6A33-4537-8ED2-118462D0FEE5}.Release|Any CPU.Build.0 = Release|Any CPU + {62DED1EA-6A33-4537-8ED2-118462D0FEE5}.ReleaseCompressed|Any CPU.ActiveCfg = Release|Any CPU + {62DED1EA-6A33-4537-8ED2-118462D0FEE5}.ReleaseCompressed|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/FSharp.Compiler.Service.sln b/FSharp.Compiler.Service.sln index ca14b9f9e06..45997f8a6db 100644 --- a/FSharp.Compiler.Service.sln +++ b/FSharp.Compiler.Service.sln @@ -61,6 +61,8 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Interactive EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.UnitTests", "tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj", "{0C0BDAF4-7D47-4BDA-9992-077F63D6B494}" EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Benchmarks.Common", "tests\benchmarks\FSharp.Benchmarks.Common\FSharp.Benchmarks.Common.fsproj", "{A7ACFD1F-D1B8-483A-A210-200BB6B4BD7E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -143,6 +145,10 @@ Global {0C0BDAF4-7D47-4BDA-9992-077F63D6B494}.Debug|Any CPU.Build.0 = Debug|Any CPU {0C0BDAF4-7D47-4BDA-9992-077F63D6B494}.Release|Any CPU.ActiveCfg = Release|Any CPU {0C0BDAF4-7D47-4BDA-9992-077F63D6B494}.Release|Any CPU.Build.0 = Release|Any CPU + {A7ACFD1F-D1B8-483A-A210-200BB6B4BD7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A7ACFD1F-D1B8-483A-A210-200BB6B4BD7E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A7ACFD1F-D1B8-483A-A210-200BB6B4BD7E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A7ACFD1F-D1B8-483A-A210-200BB6B4BD7E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -154,6 +160,7 @@ Global {35F5F1C5-AE4F-4B5A-8D94-1AF708724FD5} = {AF321816-B4A0-41DD-9A1D-484E8A20C6F6} {C1950E28-1CB7-4DEC-BB3A-8A0443A17282} = {AF321816-B4A0-41DD-9A1D-484E8A20C6F6} {07CD957A-3C31-4F75-A735-16CE72E1BD71} = {AF321816-B4A0-41DD-9A1D-484E8A20C6F6} + {A7ACFD1F-D1B8-483A-A210-200BB6B4BD7E} = {AF321816-B4A0-41DD-9A1D-484E8A20C6F6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F9A60F3B-D894-4C8E-BA0F-C51115B25A5A} diff --git a/FSharp.sln b/FSharp.sln index c021f7026b4..5ce2e4eeb35 100644 --- a/FSharp.sln +++ b/FSharp.sln @@ -106,6 +106,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution src\Compiler\FSCompCheck.fsx = src\Compiler\FSCompCheck.fsx EndProjectSection EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Benchmarks.Common", "tests\benchmarks\FSharp.Benchmarks.Common\FSharp.Benchmarks.Common.fsproj", "{7D482560-DF6F-46A5-B50C-20ECF7C38759}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -416,6 +418,18 @@ Global {9C7523BA-7AB2-4604-A5FD-653E82C2BAD1}.Release|Any CPU.Build.0 = Release|Any CPU {9C7523BA-7AB2-4604-A5FD-653E82C2BAD1}.Release|x86.ActiveCfg = Release|Any CPU {9C7523BA-7AB2-4604-A5FD-653E82C2BAD1}.Release|x86.Build.0 = Release|Any CPU + {7D482560-DF6F-46A5-B50C-20ECF7C38759}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7D482560-DF6F-46A5-B50C-20ECF7C38759}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7D482560-DF6F-46A5-B50C-20ECF7C38759}.Debug|x86.ActiveCfg = Debug|Any CPU + {7D482560-DF6F-46A5-B50C-20ECF7C38759}.Debug|x86.Build.0 = Debug|Any CPU + {7D482560-DF6F-46A5-B50C-20ECF7C38759}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {7D482560-DF6F-46A5-B50C-20ECF7C38759}.Proto|Any CPU.Build.0 = Debug|Any CPU + {7D482560-DF6F-46A5-B50C-20ECF7C38759}.Proto|x86.ActiveCfg = Debug|Any CPU + {7D482560-DF6F-46A5-B50C-20ECF7C38759}.Proto|x86.Build.0 = Debug|Any CPU + {7D482560-DF6F-46A5-B50C-20ECF7C38759}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7D482560-DF6F-46A5-B50C-20ECF7C38759}.Release|Any CPU.Build.0 = Release|Any CPU + {7D482560-DF6F-46A5-B50C-20ECF7C38759}.Release|x86.ActiveCfg = Release|Any CPU + {7D482560-DF6F-46A5-B50C-20ECF7C38759}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -447,6 +461,7 @@ Global {209C7D37-8C01-413C-8698-EC25F4C86976} = {B8DDA694-7939-42E3-95E5-265C2217C142} {BEC6E796-7E53-4888-AAFC-B8FD55C425DF} = {CE70D631-C5DC-417E-9CDA-B16097BEF1AC} {9C7523BA-7AB2-4604-A5FD-653E82C2BAD1} = {CE70D631-C5DC-417E-9CDA-B16097BEF1AC} + {7D482560-DF6F-46A5-B50C-20ECF7C38759} = {CE70D631-C5DC-417E-9CDA-B16097BEF1AC} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BD5177C7-1380-40E7-94D2-7768E1A8B1B8} diff --git a/VisualFSharp.sln b/VisualFSharp.sln index 485d887f3ce..486cc03a163 100644 --- a/VisualFSharp.sln +++ b/VisualFSharp.sln @@ -193,6 +193,8 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Editor.Tests", "vsin EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FSharp.Editor.IntegrationTests", "vsintegration\tests\FSharp.Editor.IntegrationTests\FSharp.Editor.IntegrationTests.csproj", "{E31F9B59-FCF1-4D04-8762-C7BB60285A7B}" EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Benchmarks.Common", "tests\benchmarks\FSharp.Benchmarks.Common\FSharp.Benchmarks.Common.fsproj", "{6734FC6F-B5F3-45E1-9A72-720378BB49C9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1019,6 +1021,18 @@ Global {E31F9B59-FCF1-4D04-8762-C7BB60285A7B}.Release|Any CPU.Build.0 = Release|Any CPU {E31F9B59-FCF1-4D04-8762-C7BB60285A7B}.Release|x86.ActiveCfg = Release|Any CPU {E31F9B59-FCF1-4D04-8762-C7BB60285A7B}.Release|x86.Build.0 = Release|Any CPU + {6734FC6F-B5F3-45E1-9A72-720378BB49C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6734FC6F-B5F3-45E1-9A72-720378BB49C9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6734FC6F-B5F3-45E1-9A72-720378BB49C9}.Debug|x86.ActiveCfg = Debug|Any CPU + {6734FC6F-B5F3-45E1-9A72-720378BB49C9}.Debug|x86.Build.0 = Debug|Any CPU + {6734FC6F-B5F3-45E1-9A72-720378BB49C9}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {6734FC6F-B5F3-45E1-9A72-720378BB49C9}.Proto|Any CPU.Build.0 = Debug|Any CPU + {6734FC6F-B5F3-45E1-9A72-720378BB49C9}.Proto|x86.ActiveCfg = Debug|Any CPU + {6734FC6F-B5F3-45E1-9A72-720378BB49C9}.Proto|x86.Build.0 = Debug|Any CPU + {6734FC6F-B5F3-45E1-9A72-720378BB49C9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6734FC6F-B5F3-45E1-9A72-720378BB49C9}.Release|Any CPU.Build.0 = Release|Any CPU + {6734FC6F-B5F3-45E1-9A72-720378BB49C9}.Release|x86.ActiveCfg = Release|Any CPU + {6734FC6F-B5F3-45E1-9A72-720378BB49C9}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1099,6 +1113,7 @@ Global {39CDF34B-FB23-49AE-AB27-0975DA379BB5} = {DFB6ADD7-3149-43D9-AFA0-FC4A818B472B} {CBC96CC7-65AB-46EA-A82E-F6A788DABF80} = {F7876C9B-FB6A-4EFB-B058-D6967DB75FB2} {E31F9B59-FCF1-4D04-8762-C7BB60285A7B} = {F7876C9B-FB6A-4EFB-B058-D6967DB75FB2} + {6734FC6F-B5F3-45E1-9A72-720378BB49C9} = {DFB6ADD7-3149-43D9-AFA0-FC4A818B472B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {48EDBBBE-C8EE-4E3C-8B19-97184A487B37} diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 6b11aca6687..81083aaf05a 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,4 +1,4 @@ -# CI and PR triggers +# CI and PR triggers trigger: branches: include: @@ -110,13 +110,10 @@ stages: demands: ImageOverride -equals windows.vs2022preview.amd64 timeoutInMinutes: 300 variables: - - group: DotNet-Blob-Feed - group: DotNet-Symbol-Server-Pats - group: DotNet-DevDiv-Insertion-Workflow-Variables - name: _SignType value: Real - - name: _DotNetPublishToBlobFeed - value: true steps: - checkout: self clean: true @@ -131,9 +128,6 @@ stages: /p:MicroBuild_SigningEnabled=true /p:OverridePackageSource=https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json /p:TeamName=$(_TeamName) - /p:DotNetPublishBlobFeedKey=$(dotnetfeed-storage-access-key-1) - /p:DotNetPublishBlobFeedUrl=https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json - /p:DotNetPublishToBlobFeed=true /p:DotNetPublishUsingPipelines=$(_PublishUsingPipelines) /p:DotNetArtifactsCategory=$(_DotNetArtifactsCategory) /p:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat) @@ -713,30 +707,19 @@ stages: continueOnError: true condition: always() - # Build benchmarks - - job: Plain_Build_Benchmarks + # Build and run fast benchmarks + - job: Benchmarks pool: name: $(DncEngPublicBuildPool) demands: ImageOverride -equals $(WindowsMachineQueueName) variables: - name: _BuildConfig - value: Debug + value: Release steps: - checkout: self clean: true - - script: dotnet --list-sdks - displayName: Report dotnet SDK versions - - task: UseDotNet@2 - displayName: install SDK - inputs: - packageType: sdk - useGlobalJson: true - includePreviewVersions: true - workingDirectory: $(Build.SourcesDirectory) - installationPath: $(Agent.ToolsDirectory)/dotnet - - script: dotnet build .\FSharp.Benchmarks.sln /bl:\"artifacts/log/$(_BuildConfig)/BenchmarkBuild.binlog\" - workingDirectory: $(Build.SourcesDirectory) - displayName: Regular rebuild of FSharp.Benchmarks.sln + - script: eng\CIBuild.cmd -testBenchmarks + displayName: Smoke test fast benchmarks continueOnError: true condition: always() diff --git a/buildtools/AssemblyCheck/SkipVerifyEmbeddedPdb.txt b/buildtools/AssemblyCheck/SkipVerifyEmbeddedPdb.txt index f823017f4a1..07ec0379282 100644 --- a/buildtools/AssemblyCheck/SkipVerifyEmbeddedPdb.txt +++ b/buildtools/AssemblyCheck/SkipVerifyEmbeddedPdb.txt @@ -1,4 +1,5 @@ FSharp.Build.UnitTests.dll +FSharp.Benchmarks.Common.dll FSharp.Compiler.Benchmarks.dll FSharp.Compiler.ComponentTests.dll FSharp.Test.Utilities.dll diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index 8fa3c363b20..f91b3e54f60 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -2,10 +2,12 @@ * Code generated files with > 64K methods and generated symbols crash when loaded. Use infered sequence points for debugging. ([Issue #16399](https://github.com/dotnet/fsharp/issues/16399), [#PR 16514](https://github.com/dotnet/fsharp/pull/16514)) * `nameof Module` expressions and patterns are processed to link files in `--test:GraphBasedChecking`. ([PR #16550](https://github.com/dotnet/fsharp/pull/16550)) -* Graph Based Checking doesn't throw on invalid parsed input so it can be used for IDE scenarios ([PR #16575](https://github.com/dotnet/fsharp/pull/16575)) +* Graph Based Checking doesn't throw on invalid parsed input so it can be used for IDE scenarios ([PR #16575](https://github.com/dotnet/fsharp/pull/16575), [PR #16588](https://github.com/dotnet/fsharp/pull/16588)) +* Keep parens for problematic exprs (`if`, `match`, etc.) in `$"{(…):N0}"`, `$"{(…),-3}"`, etc. ([PR #16578](https://github.com/dotnet/fsharp/pull/16578)) ### Added +* The stackguard depth for ILPdbWriter.unshadowScopes can be modified via the environment variable `FSHARP_ILPdb_UnshadowScopes_StackGuardDepth`([PR #16583](https://github.com/dotnet/fsharp/pull/16583)) * Parser recovers on complex primary constructor patterns, better tree representation for primary constructor patterns. ([PR #16425](https://github.com/dotnet/fsharp/pull/16425)) * Name resolution: keep type vars in subsequent checks ([PR #16456](https://github.com/dotnet/fsharp/pull/16456)) * Higher-order-function-based API for working with the untyped abstract syntax tree. ([PR #16462](https://github.com/dotnet/fsharp/pull/16462)) diff --git a/eng/Build.ps1 b/eng/Build.ps1 index b713a86effa..a971d399788 100644 --- a/eng/Build.ps1 +++ b/eng/Build.ps1 @@ -62,6 +62,7 @@ param ( [switch]$testAllButIntegration, [switch]$testpack, [switch]$testAOT, + [switch]$testBenchmarks, [string]$officialSkipTests = "false", [switch]$noVisualStudio, [switch]$sourceBuild, @@ -111,6 +112,7 @@ function Print-Usage() { Write-Host " -testVs Run F# editor unit tests" Write-Host " -testpack Verify built packages" Write-Host " -testAOT Run AOT/Trimming tests" + Write-Host " -testBenchmarks Build and Run Benchmark suite" Write-Host " -officialSkipTests Set to 'true' to skip running tests" Write-Host "" Write-Host "Advanced settings:" @@ -176,6 +178,7 @@ function Process-Arguments() { $script:testVs = $False $script:testpack = $False $script:testAOT = $False + $script:testBenchmarks = $False $script:verifypackageshipstatus = $True } @@ -211,6 +214,10 @@ function Process-Arguments() { $script:pack = $True; } + if ($testBenchmarks) { + $script:testBenchmarks = $True + } + foreach ($property in $properties) { if (!$property.StartsWith("/p:", "InvariantCultureIgnoreCase")) { Write-Host "Invalid argument: $property" @@ -339,7 +346,7 @@ function TestUsingMSBuild([string] $testProject, [string] $targetFramework, [str if ($env:RunningAsPullRequest -ne "true" -and $noTestFilter -eq $false) { $args += " --filter TestCategory!=PullRequest" - } + }` if ($asBackgroundJob) { Write-Host("Starting on the background: $args") @@ -541,12 +548,21 @@ try { } } + if ($testBenchmarks) { + $properties_storage = $properties + $properties += "/p:RuntimeIdentifier=win-x64" + $properties += "/p:Configuration=Release" # Always run in release. + BuildSolution "FSharp.Benchmarks.sln" $False + $properties = $properties_storage + } + if ($pack) { $properties_storage = $properties $properties += "/p:GenerateSbom=false" BuildSolution "Microsoft.FSharp.Compiler.sln" $True $properties = $properties_storage } + if ($build) { VerifyAssemblyVersionsAndSymbols } @@ -662,6 +678,12 @@ try { Pop-Location } + if ($testBenchmarks) { + Push-Location "$RepoRoot\tests\benchmarks" + ./SmokeTestBenchmarks.ps1 + Pop-Location + } + # verify nupkgs have access to the source code $nupkgtestFailed = $false if ($testpack) { diff --git a/src/Compiler/AbstractIL/ilwritepdb.fs b/src/Compiler/AbstractIL/ilwritepdb.fs index 24082eea2b3..fd5ffad27ac 100644 --- a/src/Compiler/AbstractIL/ilwritepdb.fs +++ b/src/Compiler/AbstractIL/ilwritepdb.fs @@ -16,6 +16,7 @@ open Internal.Utilities open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.AbstractIL.Support open Internal.Utilities.Library +open Internal.Utilities.Library.Extras open FSharp.Compiler.DiagnosticsLogger open FSharp.Compiler.IO open FSharp.Compiler.Text.Range @@ -1028,6 +1029,11 @@ let rec pushShadowedLocals (stackGuard: StackGuard) (localsToPush: PdbLocalVar[] // adding the text " (shadowed)" to the names of those with name conflicts. let unshadowScopes rootScope = // Avoid stack overflow when writing linearly nested scopes - let stackGuard = StackGuard(100, "ILPdbWriter.unshadowScopes") + let UnshadowScopesStackGuardDepth = + GetEnvInteger "FSHARP_ILPdb_UnshadowScopes_StackGuardDepth" 100 + + let stackGuard = + StackGuard(UnshadowScopesStackGuardDepth, "ILPdbWriter.unshadowScopes") + let result, _ = pushShadowedLocals stackGuard [||] rootScope result diff --git a/src/Compiler/Driver/GraphChecking/FileContentMapping.fs b/src/Compiler/Driver/GraphChecking/FileContentMapping.fs index a09b64a3584..15355de5a30 100644 --- a/src/Compiler/Driver/GraphChecking/FileContentMapping.fs +++ b/src/Compiler/Driver/GraphChecking/FileContentMapping.fs @@ -9,10 +9,9 @@ type Continuations = ((FileContentEntry list -> FileContentEntry list) -> FileCo let collectFromOption (mapping: 'T -> 'U list) (t: 'T option) : 'U list = List.collect mapping (Option.toList t) let longIdentToPath (skipLast: bool) (longId: LongIdent) : LongIdentifier = - if skipLast then - List.take (longId.Length - 1) longId - else - longId + match skipLast, longId with + | true, _ :: _ -> List.take (longId.Length - 1) longId + | _ -> longId |> List.map (fun ident -> ident.idText) let synLongIdentToPath (skipLast: bool) (synLongIdent: SynLongIdent) = diff --git a/src/Compiler/Driver/GraphChecking/GraphProcessing.fs b/src/Compiler/Driver/GraphChecking/GraphProcessing.fs index afe491b4b74..37ecc35041d 100644 --- a/src/Compiler/Driver/GraphChecking/GraphProcessing.fs +++ b/src/Compiler/Driver/GraphChecking/GraphProcessing.fs @@ -230,8 +230,12 @@ let processGraphAsync<'Item, 'Result when 'Item: equality and 'Item: comparison> let processedCount = IncrementableInt(0) - let raiseExn (item, ex: exn) = - localCts.Cancel() + let handleExn (item, ex: exn) = + try + localCts.Cancel() + with :? ObjectDisposedException -> + // If it's disposed already, it means that the processing has already finished, most likely due to cancellation or failure in another node. + () match ex with | :? OperationCanceledException -> completionSignal.TrySetCanceled() @@ -252,7 +256,7 @@ let processGraphAsync<'Item, 'Result when 'Item: equality and 'Item: comparison> match res with | Choice1Of2() -> () - | Choice2Of2 ex -> raiseExn (node.Info.Item, ex) + | Choice2Of2 ex -> handleExn (node.Info.Item, ex) }, cts.Token ) 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/src/Compiler/Service/SynExpr.fs b/src/Compiler/Service/SynExpr.fs index 0df9a1a1c17..41dbd4d4d18 100644 --- a/src/Compiler/Service/SynExpr.fs +++ b/src/Compiler/Service/SynExpr.fs @@ -423,7 +423,9 @@ module SynExpr = | SynExpr.MatchLambda(matchClauses = Last(SynMatchClause(resultExpr = expr))) | SynExpr.MatchBang(clauses = Last(SynMatchClause(resultExpr = expr))) | SynExpr.TryWith(withCases = Last(SynMatchClause(resultExpr = expr))) - | SynExpr.TryFinally(finallyExpr = expr) -> loop expr + | SynExpr.TryFinally(finallyExpr = expr) + | SynExpr.Do(expr = expr) + | SynExpr.DoBang(expr = expr) -> loop expr | _ -> ValueNone loop @@ -810,6 +812,12 @@ module SynExpr = -> true + | SynExpr.InterpolatedString(contents = contents), (SynExpr.Tuple(isStruct = false) | Dangling.Problematic _) -> + contents + |> List.exists (function + | SynInterpolatedStringPart.FillExpr(qualifiers = Some _) -> true + | _ -> false) + | SynExpr.Record(copyInfo = Some(SynExpr.Paren(expr = Is inner), _)), Dangling.Problematic _ | SynExpr.AnonRecd(copyInfo = Some(SynExpr.Paren(expr = Is inner), _)), Dangling.Problematic _ -> true diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/FileContentMappingTests.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/FileContentMappingTests.fs index 279bb55e3dc..12f171de5fa 100644 --- a/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/FileContentMappingTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/FileContentMappingTests.fs @@ -122,17 +122,36 @@ module B = C | [ TopLevelNamespace "" [ PrefixedIdentifier "C" ] ] -> Assert.Pass() | content -> Assert.Fail($"Unexpected content: {content}") -[] -let ``Invalid nested module should just be ignored`` () = - let content = - getContent - false - """ -module A -module B.C -""" +module InvalidSyntax = - match content with - | [ TopLevelNamespace "" [] ] -> Assert.Pass() - | content -> Assert.Fail($"Unexpected content: {content}") + [] + let ``Nested module`` () = + let content = + getContent + false + """ + module A + + module B.C + """ + + match content with + | [ TopLevelNamespace "" [] ] -> Assert.Pass() + | content -> Assert.Fail($"Unexpected content: {content}") + + + [] + let ``Module above namespace`` () = + let content = + getContent + false + """ + module + + namespace A.B.C + """ + + match content with + | [ TopLevelNamespace "" [] ] -> Assert.Pass() + | content -> Assert.Fail($"Unexpected content: {content}") 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 diff --git a/tests/benchmarks/FCSBenchmarks/BenchmarkComparison/HistoricalBenchmark.fsproj b/tests/benchmarks/FCSBenchmarks/BenchmarkComparison/HistoricalBenchmark.fsproj index 2534ba292b5..09ca5cb6912 100644 --- a/tests/benchmarks/FCSBenchmarks/BenchmarkComparison/HistoricalBenchmark.fsproj +++ b/tests/benchmarks/FCSBenchmarks/BenchmarkComparison/HistoricalBenchmark.fsproj @@ -59,6 +59,9 @@ $(FSharpCoreDllPath) + + + diff --git a/tests/benchmarks/FCSBenchmarks/BenchmarkComparison/Program.fs b/tests/benchmarks/FCSBenchmarks/BenchmarkComparison/Program.fs index 779a18a7709..2a4f8af4ce5 100644 --- a/tests/benchmarks/FCSBenchmarks/BenchmarkComparison/Program.fs +++ b/tests/benchmarks/FCSBenchmarks/BenchmarkComparison/Program.fs @@ -3,6 +3,7 @@ namespace HistoricalBenchmark open System.IO open BenchmarkDotNet.Attributes open BenchmarkDotNet.Running +open FSharp.Benchmarks.Common.Categories [] type SingleFileCompilerBenchmarkBase(compiler : SingleFileCompiler) = @@ -20,6 +21,7 @@ type SingleFileCompilerBenchmarkBase(compiler : SingleFileCompiler) = [] [] +[] type DecentlySizedStandAloneFileBenchmark() = inherit SingleFileCompilerBenchmarkBase( SingleFileCompiler( diff --git a/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/BackgroundCompilerBenchmarks.fs b/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/BackgroundCompilerBenchmarks.fs index d7d643ab915..2f7e3a80a5e 100644 --- a/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/BackgroundCompilerBenchmarks.fs +++ b/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/BackgroundCompilerBenchmarks.fs @@ -7,14 +7,10 @@ open FSharp.Compiler.Text open FSharp.Compiler.Diagnostics open FSharp.Test.ProjectGeneration open BenchmarkDotNet.Engines - - -[] -let FSharpCategory = "fsharp" - +open FSharp.Benchmarks.Common.Categories [] -[] +[] type BackgroundCompilerBenchmarks () = let size = 50 @@ -104,7 +100,7 @@ type BackgroundCompilerBenchmarks () = this.Benchmark.DeleteProjectDir() [] -[] +[] type ParsingBenchmark() = let mutable checker: FSharpChecker = Unchecked.defaultof<_> @@ -134,7 +130,7 @@ type ParsingBenchmark() = failwith "ParseHadErrors" [] -[] +[] type NoFileSystemCheckerBenchmark() = let size = 30 @@ -229,8 +225,8 @@ type TestProjectType = [] [] -[] [] +[] type TransparentCompilerBenchmark() = let size = 30 @@ -331,9 +327,9 @@ type TransparentCompilerBenchmark() = benchmark.DeleteProjectDir() +// needs Giraffe repo somewhere nearby, hence benchmarks disabled [] [] -[] [] type TransparentCompilerGiraffeBenchmark() = @@ -399,7 +395,7 @@ type TransparentCompilerGiraffeBenchmark() = checkFile (this.Project.SourceFiles |> List.last).Id expectOk } - [] + // [] member this.SomeWorkflow() = use _ = Activity.start "Benchmark" [ diff --git a/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/CompilerServiceBenchmarks.fs b/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/CompilerServiceBenchmarks.fs index 4910b2e19eb..2b28cdce001 100644 --- a/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/CompilerServiceBenchmarks.fs +++ b/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/CompilerServiceBenchmarks.fs @@ -12,6 +12,7 @@ open FSharp.Compiler.AbstractIL.ILBinaryReader open BenchmarkDotNet.Attributes open FSharp.Compiler.Benchmarks open Microsoft.CodeAnalysis.Text +open FSharp.Benchmarks.Common.Categories type private Config = { @@ -66,6 +67,7 @@ let function%s{moduleName} (x: %s{moduleName}) = [] +[] type CompilerServiceBenchmarks() = let mutable configOpt : Config option = None let sourcePath = Path.Combine(__SOURCE_DIRECTORY__, "../decentlySizedStandAloneFile.fs") diff --git a/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/ComputationExpressionBenchmarks.fs b/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/ComputationExpressionBenchmarks.fs index 92a7141822d..815d4818344 100644 --- a/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/ComputationExpressionBenchmarks.fs +++ b/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/ComputationExpressionBenchmarks.fs @@ -4,12 +4,10 @@ open System.IO open BenchmarkDotNet.Attributes open FSharp.Compiler.CodeAnalysis open FSharp.Test.ProjectGeneration - -[] -let FSharpCategory = "fsharp" +open FSharp.Benchmarks.Common.Categories [] -[] +[] type ComputationExpressionBenchmarks() = let mutable sourceFileName = "" diff --git a/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/DecentlySizedStandAloneFileBenchmark.fs b/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/DecentlySizedStandAloneFileBenchmark.fs index 58dcb885e50..b1926b44e66 100644 --- a/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/DecentlySizedStandAloneFileBenchmark.fs +++ b/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/DecentlySizedStandAloneFileBenchmark.fs @@ -4,6 +4,7 @@ open System.IO open FSharp.Compiler.CodeAnalysis open FSharp.Compiler.Text open BenchmarkDotNet.Attributes +open FSharp.Benchmarks.Common.Categories type private SingleFileCompilerConfig = { @@ -12,6 +13,7 @@ type private SingleFileCompilerConfig = } [] +[] type DecentlySizedStandAloneFileBenchmark() = let mutable configOpt : SingleFileCompilerConfig option = None diff --git a/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/FSharp.Compiler.Benchmarks.fsproj b/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/FSharp.Compiler.Benchmarks.fsproj index 55968edddaf..043de02d374 100644 --- a/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/FSharp.Compiler.Benchmarks.fsproj +++ b/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/FSharp.Compiler.Benchmarks.fsproj @@ -25,6 +25,7 @@ + diff --git a/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/FileCascadeBenchmarks.fs b/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/FileCascadeBenchmarks.fs index 686153577fa..6eddb5eb5b3 100644 --- a/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/FileCascadeBenchmarks.fs +++ b/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/FileCascadeBenchmarks.fs @@ -2,18 +2,13 @@ open System open System.IO -open System.Text open FSharp.Compiler.CodeAnalysis -open FSharp.Compiler.Diagnostics -open FSharp.Compiler.EditorServices open FSharp.Compiler.Text -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.ILBinaryReader open BenchmarkDotNet.Attributes open FSharp.Compiler.Benchmarks -open Microsoft.CodeAnalysis.Text open BenchmarkDotNet.Order open BenchmarkDotNet.Mathematics +open FSharp.Benchmarks.Common.Categories [] module private CascadeProjectHelpers = @@ -87,6 +82,7 @@ val processFunc{number}: x: MyType{number} -> func: MyFunctionType{number} -> As [] [] [] +[] type FileCascadeBenchmarks() = let mutable project : FSharpProjectOptions option = None let filesToCreate = 128 diff --git a/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/GraphTypeCheckingBenchmarks.fs b/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/GraphTypeCheckingBenchmarks.fs index dd16e8b13a0..3f2f170a410 100644 --- a/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/GraphTypeCheckingBenchmarks.fs +++ b/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/GraphTypeCheckingBenchmarks.fs @@ -4,12 +4,10 @@ open System.IO open BenchmarkDotNet.Attributes open FSharp.Compiler.CodeAnalysis open FSharp.Test.ProjectGeneration - -[] -let FSharpCategory = "fsharp" +open FSharp.Benchmarks.Common.Categories [] -[] +[] type GraphTypeCheckingBenchmarks() = let size = 250 diff --git a/tests/benchmarks/FCSBenchmarks/FCSSourceFiles/FCSSourceFiles.fsproj b/tests/benchmarks/FCSBenchmarks/FCSSourceFiles/FCSSourceFiles.fsproj index 3774aa87023..92255adb462 100644 --- a/tests/benchmarks/FCSBenchmarks/FCSSourceFiles/FCSSourceFiles.fsproj +++ b/tests/benchmarks/FCSBenchmarks/FCSSourceFiles/FCSSourceFiles.fsproj @@ -16,6 +16,7 @@ + diff --git a/tests/benchmarks/FCSBenchmarks/FCSSourceFiles/Program.fs b/tests/benchmarks/FCSBenchmarks/FCSSourceFiles/Program.fs index 9c8148ed4da..7b716505156 100644 --- a/tests/benchmarks/FCSBenchmarks/FCSSourceFiles/Program.fs +++ b/tests/benchmarks/FCSBenchmarks/FCSSourceFiles/Program.fs @@ -5,6 +5,7 @@ open FSharp.Compiler.CodeAnalysis open FSharp.Compiler.Text open BenchmarkDotNet.Attributes open BenchmarkDotNet.Running +open FSharp.Benchmarks.Common.Categories module Project = let nugetCache = @@ -874,6 +875,7 @@ module Project = Stamp = None } [] +[] type CompilerService() = let mutable checkerOpt = None let mutable sourceOpt : (string * ISourceText) array option = None diff --git a/tests/benchmarks/FCSBenchmarks/SmokeTestAllBenchmarks.ps1 b/tests/benchmarks/FCSBenchmarks/SmokeTestAllBenchmarks.ps1 deleted file mode 100644 index 688434a176e..00000000000 --- a/tests/benchmarks/FCSBenchmarks/SmokeTestAllBenchmarks.ps1 +++ /dev/null @@ -1,19 +0,0 @@ -# Smoke test for checking that all the benchmarks work -# The test is successful if all the benchmarks run and produce results. -# The actual numbers produced aren't accurate. -# Results can be checked in BenchmarkDotNet.Artifacts/results - -function Run { - param ( - [string[]]$path - ) - # Build the benchmark project itself but no dependencies - still fast, but reduces risk of not accounting for code changes - dotnet build -c release --no-dependencies $path - # Run the minimum the CLI API allows - ideally we would use ColdStart but that's not part of the CLI API - # For API details see https://benchmarkdotnet.org/articles/guides/console-args.html - dotnet run -c release --project $path --no-build -- --warmupCount 0 --iterationCount 1 --runOncePerIteration --filter * -} - -Run "BenchmarkComparison/HistoricalBenchmark.fsproj" -Run "CompilerServiceBenchmarks/FSharp.Compiler.Benchmarks.fsproj" -Run "FCSSourceFiles/FCSSourceFiles.fsproj" \ No newline at end of file diff --git a/tests/benchmarks/FSharp.Benchmarks.Common/Categories.fs b/tests/benchmarks/FSharp.Benchmarks.Common/Categories.fs new file mode 100644 index 00000000000..deadacbfd6e --- /dev/null +++ b/tests/benchmarks/FSharp.Benchmarks.Common/Categories.fs @@ -0,0 +1,10 @@ +namespace FSharp.Benchmarks.Common + +module Categories = + + [] + let ShortCategory = "short" + + [] + let LongCategory = "long" + diff --git a/tests/benchmarks/FSharp.Benchmarks.Common/FSharp.Benchmarks.Common.fsproj b/tests/benchmarks/FSharp.Benchmarks.Common/FSharp.Benchmarks.Common.fsproj new file mode 100644 index 00000000000..2e6b2e9ceb7 --- /dev/null +++ b/tests/benchmarks/FSharp.Benchmarks.Common/FSharp.Benchmarks.Common.fsproj @@ -0,0 +1,12 @@ + + + + net8.0 + true + + + + + + + diff --git a/tests/benchmarks/SmokeTestBenchmarks.ps1 b/tests/benchmarks/SmokeTestBenchmarks.ps1 new file mode 100644 index 00000000000..710d8c3e2ba --- /dev/null +++ b/tests/benchmarks/SmokeTestBenchmarks.ps1 @@ -0,0 +1,21 @@ +# Smoke test for checking that some (faster) benchmarks work. +# The test is successful if all the benchmarks run and produce results. +# The actual numbers produced aren't accurate. + +function Run { + param ( + [string[]]$path + ) + + dotnet run ` + --project $path ` + -c release ` + --no-build ` + --job Dry ` + --allCategories short ` + --stopOnFirstError +} + +Run "FCSBenchmarks/BenchmarkComparison/HistoricalBenchmark.fsproj" +Run "FCSBenchmarks/CompilerServiceBenchmarks/FSharp.Compiler.Benchmarks.fsproj" +Run "FCSBenchmarks/FCSSourceFiles/FCSSourceFiles.fsproj" \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/LanguageService/WorkspaceExtensions.fs b/vsintegration/src/FSharp.Editor/LanguageService/WorkspaceExtensions.fs index c0682607360..6e3de8133f1 100644 --- a/vsintegration/src/FSharp.Editor/LanguageService/WorkspaceExtensions.fs +++ b/vsintegration/src/FSharp.Editor/LanguageService/WorkspaceExtensions.fs @@ -447,7 +447,7 @@ module private CheckerExtensions = ) = cancellableTask { - if document.Project.UseTransparentCompiler then + if checker.UsesTransparentCompiler then return! checker.ParseAndCheckDocumentUsingTransparentCompiler(document, options, userOpName) else let allowStaleResults = diff --git a/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/RemoveUnnecessaryParenthesesTests.fs b/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/RemoveUnnecessaryParenthesesTests.fs index 69d6456e378..cd3bbdd2bfc 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/RemoveUnnecessaryParenthesesTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/RemoveUnnecessaryParenthesesTests.fs @@ -800,6 +800,24 @@ in x "$\"{(id 3)}\"", "$\"{id 3}\"" "$\"{(x)}\"", "$\"{x}\"" + "$\"{(if true then 1 else 0)}\"", "$\"{if true then 1 else 0}\"" + "$\"{(if true then 1 else 0):N0}\"", "$\"{(if true then 1 else 0):N0}\"" + "$\"{(if true then 1 else 0),-3}\"", "$\"{(if true then 1 else 0),-3}\"" + "$\"{(match () with () -> 1):N0}\"", "$\"{(match () with () -> 1):N0}\"" + "$\"{(match () with () -> 1),-3}\"", "$\"{(match () with () -> 1),-3}\"" + "$\"{(try () with _ -> 1):N0}\"", "$\"{(try () with _ -> 1):N0}\"" + "$\"{(try () with _ -> 1),-3}\"", "$\"{(try () with _ -> 1),-3}\"" + "$\"{(try 1 finally ()):N0}\"", "$\"{(try 1 finally ()):N0}\"" + "$\"{(try 1 finally ()),-3}\"", "$\"{(try 1 finally ()),-3}\"" + "$\"{(let x = 3 in x):N0}\"", "$\"{(let x = 3 in x):N0}\"" + "$\"{(let x = 3 in x),-3}\"", "$\"{(let x = 3 in x),-3}\"" + "$\"{(do (); 3):N0}\"", "$\"{(do (); 3):N0}\"" + "$\"{(do (); 3),-3}\"", "$\"{(do (); 3),-3}\"" + "$\"{(x <- 3):N0}\"", "$\"{(x <- 3):N0}\"" + "$\"{(x <- 3),-3}\"", "$\"{(x <- 3),-3}\"" + "$\"{(1, 2):N0}\"", "$\"{(1, 2):N0}\"" + "$\"{(1, 2),-3}\"", "$\"{(1, 2),-3}\"" + """ $"{(3 + LanguagePrimitives.GenericZero):N0}" """,