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}"
""",