diff --git a/DEVGUIDE.md b/DEVGUIDE.md index 712ac7eb5f0..28e92adb57a 100644 --- a/DEVGUIDE.md +++ b/DEVGUIDE.md @@ -17,24 +17,24 @@ This will make management of multiple forks and your own work easier over time. We recommend the following commands to update your fork: ``` -git checkout master +git checkout main git clean -xdf git fetch upstream -git rebase upstream/master +git rebase upstream/main git push ``` Or more succinctly: ``` -git checkout master && git clean -xdf && git fetch upstream && git rebase upstream/master && git push +git checkout main && git clean -xdf && git fetch upstream && git rebase upstream/main && git push ``` This will update your fork with the latest from `dotnet/fsharp` on your machine and push those updates to your remote fork. ## Developing on Windows -Install the latest released [Visual Studio](https://www.visualstudio.com/downloads/), as that is what the `master` branch's tools are synced with. Select the following workloads: +Install the latest released [Visual Studio](https://www.visualstudio.com/downloads/), as that is what the `main` branch's tools are synced with. Select the following workloads: * .NET desktop development (also check F# desktop support, as this will install some legacy templates) * Visual Studio extension development diff --git a/Directory.Build.targets b/Directory.Build.targets index 08da3ab0966..7b7a6a7a80a 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -2,4 +2,15 @@ + + + + + + + + + + + diff --git a/INTERNAL.md b/INTERNAL.md index 15550dcedcd..3d142266e78 100644 --- a/INTERNAL.md +++ b/INTERNAL.md @@ -47,8 +47,8 @@ To see all insertions created this way (possibly including for other internal te ## Less interesting links -[Nightly VSIX (master) uploader](https://dev.azure.com/dnceng/internal/_release?_a=releases&definitionId=70). Uploads -a package from every build of `master` to the [Nightly VSIX feed](README.md#using-nightly-releases-in-visual-studio). +[Nightly VSIX (main) uploader](https://dev.azure.com/dnceng/internal/_release?_a=releases&definitionId=70). Uploads +a package from every build of `main` to the [Nightly VSIX feed](README.md#using-nightly-releases-in-visual-studio). [Nightly VSIX (preview) uploader](https://dev.azure.com/dnceng/internal/_release?_a=releases&definitionId=71). Uploads a package from every build of the branch that corresponds to the current Visual Studio preview to the diff --git a/README.md b/README.md index e2815fe484a..dd85f8a43ed 100644 --- a/README.md +++ b/README.md @@ -50,11 +50,11 @@ Even if you find a single-character typo, we're happy to take the change! Althou | Branch | Status | |:------:|:------:| -|master|[![Build Status](https://dev.azure.com/dnceng/public/_apis/build/status/dotnet/fsharp/fsharp-ci?branchName=master)](https://dev.azure.com/dnceng/public/_build/latest?definitionId=496&branchName=master)| +|main|[![Build Status](https://dev.azure.com/dnceng/public/_apis/build/status/dotnet/fsharp/fsharp-ci?branchName=main)](https://dev.azure.com/dnceng/public/_build/latest?definitionId=496&branchName=main)| ## Using nightly releases in Visual Studio -You can use the latest `master` build of the F# compiler and tools for Visual Studio via our nightly releases if you are a Visual Studio user. See details on setup here: +You can use the latest `main` build of the F# compiler and tools for Visual Studio via our nightly releases if you are a Visual Studio user. See details on setup here: https://blogs.msdn.microsoft.com/dotnet/2017/03/14/announcing-nightly-releases-for-the-visual-f-tools/ @@ -69,7 +69,7 @@ Alternatively, if you _really_ want to live on the bleeding edge, you can set up These are the branches in use: -* `master` +* `main` - Most contributions go here. - Able to be built, installed and used in the latest public Visual Studio release. - May contain updated F# features and logic. @@ -77,14 +77,14 @@ These are the branches in use: - Gets integrated into https://github.com/fsharp/fsharp to form the basis of Mono releases - Gets integrated into https://github.com/fsharp/FSharp.Compiler.Service to form the basis of FSharp.Compiler.Service releases -* `dev15.9` +* `release/dev15.9` - Long-term servicing branch for VS 2017 update 15.9.x. We do not expect to service that release, but if we do, that's where the changes will go. -* `dev16.x` +* `release/dev16.x` - Latest release branch for the particular point release of Visual Studio. - - Incorporates features and fixes from master up to a particular branch point, then selective cherry-picks. + - Incorporates features and fixes from main up to a particular branch point, then selective cherry-picks. - May contain new features that depend on new things or fixes in the corresponding forthcoming Visual Studio release. - - Gets integrated back into master once the corresponding Visual Studio release is made. + - Gets integrated back into main once the corresponding Visual Studio release is made. ## F# language and core library evolution diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 576608de1ba..a00c94d58c8 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,11 +1,11 @@ # CI and PR triggers trigger: -- master +- main - dev16.1 - feature/* - release/* pr: -- master +- main - dev16.1 - feature/* - release/* diff --git a/eng/Build.ps1 b/eng/Build.ps1 index 05349af3bba..e882f280e8a 100644 --- a/eng/Build.ps1 +++ b/eng/Build.ps1 @@ -266,13 +266,13 @@ function VerifyAssemblyVersionsAndSymbols() { } } -function TestUsingNUnit([string] $testProject, [string] $targetFramework, [boolean] $noTestFilter = $false) { +function TestUsingMSBuild([string] $testProject, [string] $targetFramework, [string]$testadapterpath, [boolean] $noTestFilter = $false) { $dotnetPath = InitializeDotNetCli $dotnetExe = Join-Path $dotnetPath "dotnet.exe" $projectName = [System.IO.Path]::GetFileNameWithoutExtension($testProject) $testLogPath = "$ArtifactsDir\TestResults\$configuration\${projectName}_$targetFramework.xml" $testBinLogPath = "$LogDir\${projectName}_$targetFramework.binlog" - $args = "test $testProject -c $configuration -f $targetFramework -v n --test-adapter-path . --logger ""nunit;LogFilePath=$testLogPath"" /bl:$testBinLogPath" + $args = "test $testProject -c $configuration -f $targetFramework -v n --test-adapter-path $testadapterpath --logger ""nunit;LogFilePath=$testLogPath"" /bl:$testBinLogPath" if (-not $noVisualStudio -or $norestore) { $args += " --no-restore" @@ -286,9 +286,18 @@ function TestUsingNUnit([string] $testProject, [string] $targetFramework, [boole $args += " --filter TestCategory!=PullRequest" } + Write-Host("$args") Exec-Console $dotnetExe $args } +function TestUsingXUnit([string] $testProject, [string] $targetFramework, [string]$testadapterpath) { + TestUsingMsBuild -testProject $testProject -targetFramework $targetFramework -testadapterpath $testadapterpath -noTestFilter $false +} + +function TestUsingNUnit([string] $testProject, [string] $targetFramework, [string]$testadapterpath) { + TestUsingMsBuild -testProject $testProject -targetFramework $targetFramework -testadapterpath $testadapterpath -noTestFilter $true +} + function BuildCompiler() { if ($bootstrapTfm -eq "netcoreapp3.1") { $dotnetPath = InitializeDotNetCli @@ -476,27 +485,27 @@ try { $desktopTargetFramework = "net472" $coreclrTargetFramework = "netcoreapp3.1" - if ($testDesktop -and -not $noVisualStudio) { - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.ComponentTests\FSharp.Compiler.ComponentTests.fsproj" -targetFramework $desktopTargetFramework -noTestFilter $true - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj" -targetFramework $desktopTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Service.Tests\FSharp.Compiler.Service.Tests.fsproj" -targetFramework $desktopTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj" -targetFramework $desktopTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Build.UnitTests\FSharp.Build.UnitTests.fsproj" -targetFramework $desktopTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Core.UnitTests\FSharp.Core.UnitTests.fsproj" -targetFramework $desktopTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\fsharp\FSharpSuite.Tests.fsproj" -targetFramework $desktopTargetFramework + if ($testDesktop) { + TestUsingXUnit -testProject "$RepoRoot\tests\FSharp.Compiler.ComponentTests\FSharp.Compiler.ComponentTests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.ComponentTests\" -noTestFilter $true + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.UnitTests\" + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Service.Tests\FSharp.Compiler.Service.Tests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.Service.Tests\" + TestUsingXUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.Private.Scripting.UnitTests\" + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Build.UnitTests\FSharp.Build.UnitTests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Build.UnitTests\" + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Core.UnitTests\FSharp.Core.UnitTests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Core.UnitTests\" + TestUsingNUnit -testProject "$RepoRoot\tests\fsharp\FSharpSuite.Tests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharpSuite.Tests\" } if ($testCoreClr) { - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.ComponentTests\FSharp.Compiler.ComponentTests.fsproj" -targetFramework $coreclrTargetFramework -noTestFilter $true - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj" -targetFramework $coreclrTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Service.Tests\FSharp.Compiler.Service.Tests.fsproj" -targetFramework $coreclrTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj" -targetFramework $coreclrTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Build.UnitTests\FSharp.Build.UnitTests.fsproj" -targetFramework $coreclrTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Core.UnitTests\FSharp.Core.UnitTests.fsproj" -targetFramework $coreclrTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\fsharp\FSharpSuite.Tests.fsproj" -targetFramework $coreclrTargetFramework + TestUsingXUnit -testProject "$RepoRoot\tests\FSharp.Compiler.ComponentTests\FSharp.Compiler.ComponentTests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.ComponentTests\" + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.UnitTests\" + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Service.Tests\FSharp.Compiler.Service.Tests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.Service.Tests\" + TestUsingXUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.Private.Scripting.UnitTests\" + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Build.UnitTests\FSharp.Build.UnitTests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Build.UnitTests\" + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Core.UnitTests\FSharp.Core.UnitTests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Core.UnitTests\" + TestUsingNUnit -testProject "$RepoRoot\tests\fsharp\FSharpSuite.Tests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharpSuite.Tests\" } - if ($testFSharpQA -and -not $noVisualStudio) { + if ($testFSharpQA) { Push-Location "$RepoRoot\tests\fsharpqa\source" $nugetPackages = Get-PackagesDir $resultsRoot = "$ArtifactsDir\TestResults\$configuration" @@ -518,45 +527,29 @@ try { } if ($testFSharpCore) { - if (-not $noVisualStudio) { - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Core.UnitTests\FSharp.Core.UnitTests.fsproj" -targetFramework $desktopTargetFramework - } - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Core.UnitTests\FSharp.Core.UnitTests.fsproj" -targetFramework $coreclrTargetFramework + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Core.UnitTests\FSharp.Core.UnitTests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Core.UnitTests\" } if ($testCompiler) { - if (-not $noVisualStudio) { - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.ComponentTests\FSharp.Compiler.ComponentTests.fsproj" -targetFramework $desktopTargetFramework -noTestFilter $true - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj" -targetFramework $desktopTargetFramework - } - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.ComponentTests\FSharp.Compiler.ComponentTests.fsproj" -targetFramework $coreclrTargetFramework -noTestFilter $true - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj" -targetFramework $coreclrTargetFramework + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.ComponentTests\FSharp.Compiler.ComponentTests.fsproj" -targetFramework $coreclrTargetFramework -noTestFilter $true -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.ComponentTests\" + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.UnitTests\" } if ($testCompilerService) { - if (-not $noVisualStudio) { - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Service.Tests\FSharp.Compiler.Service.Tests.fsproj" -targetFramework $desktopTargetFramework - } - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Service.Tests\FSharp.Compiler.Service.Tests.fsproj" -targetFramework $coreclrTargetFramework + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Service.Tests\FSharp.Compiler.Service.Tests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.Service.Tests\" } if ($testCambridge) { - if (-not $noVisualStudio) { - TestUsingNUnit -testProject "$RepoRoot\tests\fsharp\FSharpSuite.Tests.fsproj" -targetFramework $desktopTargetFramework - } - TestUsingNUnit -testProject "$RepoRoot\tests\fsharp\FSharpSuite.Tests.fsproj" -targetFramework $coreclrTargetFramework + TestUsingNUnit -testProject "$RepoRoot\tests\fsharp\FSharpSuite.Tests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharpSuite.Tests\" } if ($testScripting) { - if (-not $noVisualStudio) { - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj" -targetFramework $desktopTargetFramework - } - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj" -targetFramework $coreclrTargetFramework + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.Private.Scripting.UnitTests\" } if ($testVs -and -not $noVisualStudio) { - TestUsingNUnit -testProject "$RepoRoot\vsintegration\tests\GetTypesVS.UnitTests\GetTypesVS.UnitTests.fsproj" -targetFramework $desktopTargetFramework - TestUsingNUnit -testProject "$RepoRoot\vsintegration\tests\UnitTests\VisualFSharp.UnitTests.fsproj" -targetFramework $desktopTargetFramework + TestUsingNUnit -testProject "$RepoRoot\vsintegration\tests\GetTypesVS.UnitTests\GetTypesVS.UnitTests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\GetTypesVS.UnitTests" + TestUsingNUnit -testProject "$RepoRoot\vsintegration\tests\UnitTests\VisualFSharp.UnitTests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\VisualFSharp.UnitTests" } # verify nupkgs have access to the source code diff --git a/eng/Versions.props b/eng/Versions.props index 57554acff15..df947643389 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -76,6 +76,7 @@ $([System.IO.File]::ReadAllText('$(MSBuildThisFileDirectory)..\RoslynPackageVersion.txt').Trim()) + 4.5.1 1.5.0 4.3.0 4.3.0 @@ -85,7 +86,7 @@ 4.3.0 4.3.0 4.3.0 - 4.5.3 + 4.5.4 4.3.0 4.3.0 4.3.0 @@ -104,8 +105,6 @@ 4.3.0 4.3.0 4.5.0 - 4.5.0 - 4.5.3 $(RoslynVersion) $(RoslynVersion) diff --git a/src/absil/illex.fsl b/src/absil/illex.fsl index 149cd087b91..1516e02df4b 100644 --- a/src/absil/illex.fsl +++ b/src/absil/illex.fsl @@ -16,7 +16,8 @@ open FSharp.Compiler.AbstractIL.Internal.AsciiParser open FSharp.Compiler.AbstractIL.Internal.AsciiConstants -let lexeme (lexbuf : LexBuffer) = new System.String(lexbuf.Lexeme) +let lexeme (lexbuf : LexBuffer) = LexBuffer.LexemeString lexbuf +let lexemeChar (lexbuf : LexBuffer) n = lexbuf.LexemeChar n let unexpectedChar _lexbuf = raise Parsing.RecoverableParseError ;; @@ -79,12 +80,7 @@ let kwdInstrTable = let kwdOrInstr s = (Lazy.force kwdInstrTable).[s] (* words *) -let eval = function - | '0' -> 0 | '1' -> 1 | '2' -> 2 | '3' -> 3 | '4' -> 4 | '5' -> 5 - | '6' -> 6 | '7' -> 7 | '8' -> 8 | '9' -> 9 - | 'A' -> 10 | 'B' -> 11 | 'C' -> 12 | 'D' -> 13 | 'E' -> 14 | 'F' -> 15 - | 'a' -> 10 | 'b' -> 11 | 'c' -> 12 | 'd' -> 13 | 'e' -> 14 | 'f' -> 15 - | _ -> failwith "bad hexbyte" +let evalDigit ch = (int ch) - (int '0') let kwdOrInstrOrId s = match (Lazy.force kwdInstrTable).TryFind s with Some v -> v | _ -> VAL_ID s @@ -119,21 +115,21 @@ rule token = parse (* The problem is telling an integer-followed-by-ellipses from a floating-point-nubmer-followed-by-dots *) | ((['0'-'9']) | (['0'-'9']['0'-'9']['0'-'9']+)) "..." - { let b = lexeme lexbuf in - VAL_INT32_ELIPSES(int32(String.sub b 0 (String.length b - 3))) } + { let b = lexbuf.LexemeView in + VAL_INT32_ELIPSES(int32(b.Slice(0, (b.Length - 3)).ToString())) } | ['0'-'9' 'A'-'F' 'a'-'f' ] ['0'-'9' 'A'-'F' 'a'-'f' ] - { let c1 = String.get (lexeme lexbuf) 0 in - let c2 = String.get (lexeme lexbuf) 1 in + { let c1 = (lexemeChar lexbuf 0) in + let c2 = (lexemeChar lexbuf 1) in if c1 >= '0' && c1 <= '9' && c2 >= '0' && c2 <= '9' then - VAL_INT64(int64 (10*eval c1 + eval c2) ) + VAL_INT64(int64 (10*evalDigit c1 + evalDigit c2) ) else VAL_ID(lexeme lexbuf) } | '0' 'x' ['0'-'9' 'a'-'f' 'A'-'F']+ { VAL_INT64(int64(lexeme lexbuf)) } | "FFFFFF" ['0'-'9' 'A'-'F' 'a'-'f' ] ['0'-'9' 'A'-'F' 'a'-'f' ] - { let c1 = (lexeme lexbuf).[6] in - let c2 = (lexeme lexbuf).[7] in + { let c1 = (lexemeChar lexbuf 6) in + let c2 = (lexemeChar lexbuf 7) in if c1 >= '0' && c1 <= '9' && c2 >= '0' && c2 <= '9' then - VAL_INT64(int64 (10*eval c1 + eval c2)) + VAL_INT64(int64 (10*evalDigit c1 + evalDigit c2)) else VAL_ID(lexeme lexbuf) } | '-' ['0'-'9']+ diff --git a/src/absil/ilread.fs b/src/absil/ilread.fs index 4567d85c252..0df497850e6 100644 --- a/src/absil/ilread.fs +++ b/src/absil/ilread.fs @@ -218,10 +218,9 @@ let rec seekCountUtf8String mdv addr n = if c = 0 then n else seekCountUtf8String mdv (addr+1) (n+1) -let seekReadUTF8String mdv addr = +let seekReadUTF8String (mdv: BinaryView) addr = let n = seekCountUtf8String mdv addr 0 - let bytes = seekReadBytes mdv addr n - System.Text.Encoding.UTF8.GetString (bytes, 0, bytes.Length) + mdv.ReadUtf8String (addr, n) let seekReadBlob mdv addr = let struct (len, addr) = seekReadCompressedUInt32 mdv addr diff --git a/src/fsharp/CompileOptions.fs b/src/fsharp/CompileOptions.fs index a06169304f4..5e9959f5dfb 100644 --- a/src/fsharp/CompileOptions.fs +++ b/src/fsharp/CompileOptions.fs @@ -5,6 +5,7 @@ module internal FSharp.Compiler.CompileOptions open Internal.Utilities +open Internal.Utilities.StructuredFormat open System open System.IO open FSharp.Compiler @@ -1608,10 +1609,10 @@ let PrintWholeAssemblyImplementation g (tcConfig:TcConfig) outfile header expr = let filename = outfile + ".terms" use f = System.IO.File.CreateText (filename + "-" + string showTermFileCount + "-" + header) showTermFileCount <- showTermFileCount + 1 - Layout.outL f (Layout.squashTo 192 (DebugPrint.implFilesL g expr)) + Layout.outL f (Display.squashTo 192 (DebugPrint.implFilesL g expr)) else dprintf "\n------------------\nshowTerm: %s:\n" header - Layout.outL stderr (Layout.squashTo 192 (DebugPrint.implFilesL g expr)) + Layout.outL stderr (Display.squashTo 192 (DebugPrint.implFilesL g expr)) dprintf "\n------------------\n" //---------------------------------------------------------------------------- @@ -1706,10 +1707,10 @@ let ApplyAllOptimizations (tcConfig:TcConfig, tcGlobals, tcVal, outfile, importM PrintWholeAssemblyImplementation tcGlobals tcConfig outfile "pass-start" implFiles #if DEBUG if tcConfig.showOptimizationData then - dprintf "Expression prior to optimization:\n%s\n" (Layout.showL (Layout.squashTo 192 (DebugPrint.implFilesL tcGlobals implFiles))) + dprintf "Expression prior to optimization:\n%s\n" (Layout.showL (Display.squashTo 192 (DebugPrint.implFilesL tcGlobals implFiles))) if tcConfig.showOptimizationData then - dprintf "CCU prior to optimization:\n%s\n" (Layout.showL (Layout.squashTo 192 (DebugPrint.entityL tcGlobals ccu.Contents))) + dprintf "CCU prior to optimization:\n%s\n" (Layout.showL (Display.squashTo 192 (DebugPrint.entityL tcGlobals ccu.Contents))) #endif let optEnv0 = optEnv @@ -1738,7 +1739,7 @@ let ApplyAllOptimizations (tcConfig:TcConfig, tcGlobals, tcVal, outfile, importM let optSettings = { optSettings with abstractBigTargets = false; reportingPhase = false } #if DEBUG if tcConfig.showOptimizationData then - dprintf "Optimization implFileOptData:\n%s\n" (Layout.showL (Layout.squashTo 192 (Optimizer.moduleInfoL tcGlobals implFileOptData))) + dprintf "Optimization implFileOptData:\n%s\n" (Layout.showL (Display.squashTo 192 (Optimizer.moduleInfoL tcGlobals implFileOptData))) #endif let implFile, optEnvExtraLoop = diff --git a/src/fsharp/FSharp.Core/event.fs b/src/fsharp/FSharp.Core/event.fs index 8643b669c3e..d14eea26904 100644 --- a/src/fsharp/FSharp.Core/event.fs +++ b/src/fsharp/FSharp.Core/event.fs @@ -97,13 +97,10 @@ namespace Microsoft.FSharp.Control // CreateDelegate creates a delegate that is fast to invoke. invoker.Invoke(multicast, sender, args) |> ignore - member x.Publish = - // Note, we implement each interface explicitly: this works around a bug in the CLR - // implementation on CompactFramework 3.7, used on Windows Phone 7 + member x.Publish = { new obj() with member x.ToString() = "" - interface IEvent<'Delegate,'Args> - interface IDelegateEvent<'Delegate> with + interface IEvent<'Delegate,'Args> with member e.AddHandler(d) = multicast <- System.Delegate.Combine(multicast, d) :?> 'Delegate member e.RemoveHandler(d) = @@ -126,13 +123,10 @@ namespace Microsoft.FSharp.Control match x.multicast with | null -> () | d -> d.Invoke(null,arg) |> ignore - member x.Publish = - // Note, we implement each interface explicitly: this works around a bug in the CLR - // implementation on CompactFramework 3.7, used on Windows Phone 7 + member x.Publish = { new obj() with member x.ToString() = "" - interface IEvent<'T> - interface IDelegateEvent> with + interface IEvent<'T> with member e.AddHandler(d) = x.multicast <- (System.Delegate.Combine(x.multicast, d) :?> Handler<'T>) member e.RemoveHandler(d) = diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index d912b8f9757..9395d190056 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -784,9 +784,9 @@ namespace Microsoft.FSharp.Core let inline anyToString nullStr x = match box x with + | :? IFormattable as f -> f.ToString(null, CultureInfo.InvariantCulture) | null -> nullStr - | :? System.IFormattable as f -> f.ToString(null,System.Globalization.CultureInfo.InvariantCulture) - | obj -> obj.ToString() + | _ -> x.ToString() let anyToStringShowingNull x = anyToString "null" x @@ -3749,6 +3749,8 @@ namespace Microsoft.FSharp.Core open System.Diagnostics open System.Collections.Generic open System.Globalization + open System.Text + open System.Numerics open Microsoft.FSharp.Core open Microsoft.FSharp.Core.LanguagePrimitives open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators @@ -4456,23 +4458,53 @@ namespace Microsoft.FSharp.Core when ^T : ^T = (^T : (static member op_Explicit: ^T -> nativeint) (value)) [] - let inline string (value: ^T) = + let inline string (value: 'T) = anyToString "" value - // since we have static optimization conditionals for ints below, we need to special-case Enums. - // This way we'll print their symbolic value, as opposed to their integral one (Eg., "A", rather than "1") - when ^T struct = anyToString "" value - when ^T : float = (# "" value : float #).ToString("g",CultureInfo.InvariantCulture) - when ^T : float32 = (# "" value : float32 #).ToString("g",CultureInfo.InvariantCulture) - when ^T : int64 = (# "" value : int64 #).ToString("g",CultureInfo.InvariantCulture) - when ^T : int32 = (# "" value : int32 #).ToString("g",CultureInfo.InvariantCulture) - when ^T : int16 = (# "" value : int16 #).ToString("g",CultureInfo.InvariantCulture) - when ^T : nativeint = (# "" value : nativeint #).ToString() - when ^T : sbyte = (# "" value : sbyte #).ToString("g",CultureInfo.InvariantCulture) - when ^T : uint64 = (# "" value : uint64 #).ToString("g",CultureInfo.InvariantCulture) - when ^T : uint32 = (# "" value : uint32 #).ToString("g",CultureInfo.InvariantCulture) - when ^T : int16 = (# "" value : int16 #).ToString("g",CultureInfo.InvariantCulture) - when ^T : unativeint = (# "" value : unativeint #).ToString() - when ^T : byte = (# "" value : byte #).ToString("g",CultureInfo.InvariantCulture) + when 'T : string = (# "" value : string #) // force no-op + + // Using 'let x = (# ... #) in x.ToString()' leads to better IL, without it, an extra stloc and ldloca.s (get address-of) + // gets emitted, which are unnecessary. With it, the extra address-of-variable is not created + when 'T : float = let x = (# "" value : float #) in x.ToString(null, CultureInfo.InvariantCulture) + when 'T : float32 = let x = (# "" value : float32 #) in x.ToString(null, CultureInfo.InvariantCulture) + when 'T : decimal = let x = (# "" value : decimal #) in x.ToString(null, CultureInfo.InvariantCulture) + when 'T : BigInteger = let x = (# "" value : BigInteger #) in x.ToString(null, CultureInfo.InvariantCulture) + + // no IFormattable + when 'T : char = let x = (# "" value : 'T #) in x.ToString() // use 'T, because char can be an enum + when 'T : bool = let x = (# "" value : bool #) in x.ToString() + when 'T : nativeint = let x = (# "" value : nativeint #) in x.ToString() + when 'T : unativeint = let x = (# "" value : unativeint #) in x.ToString() + + // Integral types can be enum: + // It is not possible to distinguish statically between Enum and (any type of) int. For signed types we have + // to use IFormattable::ToString, as the minus sign can be overridden. Using boxing we'll print their symbolic + // value if it's an enum, e.g.: 'ConsoleKey.Backspace' gives "Backspace", rather than "8") + when 'T : sbyte = (box value :?> IFormattable).ToString(null, CultureInfo.InvariantCulture) + when 'T : int16 = (box value :?> IFormattable).ToString(null, CultureInfo.InvariantCulture) + when 'T : int32 = (box value :?> IFormattable).ToString(null, CultureInfo.InvariantCulture) + when 'T : int64 = (box value :?> IFormattable).ToString(null, CultureInfo.InvariantCulture) + + // unsigned integral types have equal behavior with 'T::ToString() vs IFormattable::ToString + // this allows us to issue the 'constrained' opcode with 'callvirt' + when 'T : byte = let x = (# "" value : 'T #) in x.ToString() + when 'T : uint16 = let x = (# "" value : 'T #) in x.ToString() + when 'T : uint32 = let x = (# "" value : 'T #) in x.ToString() + when 'T : uint64 = let x = (# "" value : 'T #) in x.ToString() + + + // other common mscorlib System struct types + when 'T : DateTime = let x = (# "" value : DateTime #) in x.ToString(null, CultureInfo.InvariantCulture) + when 'T : DateTimeOffset = let x = (# "" value : DateTimeOffset #) in x.ToString(null, CultureInfo.InvariantCulture) + when 'T : TimeSpan = let x = (# "" value : TimeSpan #) in x.ToString(null, CultureInfo.InvariantCulture) + when 'T : Guid = let x = (# "" value : Guid #) in x.ToString(null, CultureInfo.InvariantCulture) + when 'T struct = + match box value with + | :? IFormattable as f -> f.ToString(null, CultureInfo.InvariantCulture) + | _ -> value.ToString() + + // other commmon mscorlib reference types + when 'T : StringBuilder = let x = (# "" value : StringBuilder #) in x.ToString() + when 'T : IFormattable = let x = (# "" value : IFormattable #) in x.ToString(null, CultureInfo.InvariantCulture) [] [] diff --git a/src/fsharp/FSharp.Core/prim-types.fsi b/src/fsharp/FSharp.Core/prim-types.fsi index 398fbd0a0f3..c886299fc0a 100644 --- a/src/fsharp/FSharp.Core/prim-types.fsi +++ b/src/fsharp/FSharp.Core/prim-types.fsi @@ -3407,13 +3407,13 @@ namespace Microsoft.FSharp.Core /// Converts the argument to a string using ToString. /// - /// For standard integer and floating point values the ToString conversion - /// uses CultureInfo.InvariantCulture. + /// For standard integer and floating point values the and any type that implements IFormattable + /// ToString conversion uses CultureInfo.InvariantCulture. /// The input value. /// /// The converted string. [] - val inline string : value:^T -> string + val inline string : value:'T -> string /// Converts the argument to System.Decimal using a direct conversion for all /// primitive numeric types. For strings, the input is converted using UInt64.Parse() diff --git a/src/fsharp/FSharp.Core/seqcore.fs b/src/fsharp/FSharp.Core/seqcore.fs index bc54d01e670..663227cb4e5 100644 --- a/src/fsharp/FSharp.Core/seqcore.fs +++ b/src/fsharp/FSharp.Core/seqcore.fs @@ -335,12 +335,9 @@ namespace Microsoft.FSharp.Core.CompilerServices (FinallyEnumerable(compensation, (fun () -> source)) :> seq<_>) let CreateEvent (addHandler : 'Delegate -> unit) (removeHandler : 'Delegate -> unit) (createHandler : (obj -> 'Args -> unit) -> 'Delegate ) :IEvent<'Delegate,'Args> = - // Note, we implement each interface explicitly: this works around a bug in the CLR - // implementation on CompactFramework 3.7, used on Windows Phone 7 { new obj() with member x.ToString() = "" - interface IEvent<'Delegate,'Args> - interface IDelegateEvent<'Delegate> with + interface IEvent<'Delegate,'Args> with member x.AddHandler(h) = addHandler h member x.RemoveHandler(h) = removeHandler h interface System.IObservable<'Args> with diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index fad5d71a6ed..1252b638f0c 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -139,8 +139,9 @@ type ArgumentContainer = // let (|A|B|) x = if x < 0 then A else B // A and B are reported as results using 'Item.ActivePatternResult' // match () with | A | B -> () // A and B are reported using 'Item.ActivePatternCase' +let emptyTypeInst : TypeInst = [] type EnclosingTypeInst = TypeInst -let emptyEnclosingTypeInst : EnclosingTypeInst = [] +let emptyEnclosingTypeInst : EnclosingTypeInst = emptyTypeInst [] /// Represents an item that results from name resolution @@ -281,7 +282,7 @@ let ItemWithNoInst item = ({ Item = item; TyparInst = emptyTyparInst } : ItemWit let (|ItemWithInst|) (x: ItemWithInst) = (x.Item, x.TyparInst) /// Represents a record field resolution and the information if the usage is deprecated. -type FieldResolution = FieldResolution of RecdFieldRef * bool +type FieldResolution = FieldResolution of RecdFieldInfo * bool /// Information about an extension member held in the name resolution environment type ExtensionMember = @@ -366,6 +367,10 @@ type NameResolutionEnv = /// Bools indicate if from a record, where no warning is given on indeterminate lookup eFieldLabels: NameMultiMap + /// Record or unions that may have type instantiations associated with them + /// when record labels or union cases are used in an unqualified context. + eUnqualifiedRecordOrUnionTypeInsts: TyconRefMap + /// Tycons indexed by the various names that may be used to access them, e.g. /// "List" --> multiple TyconRef's for the various tycons accessible by this name. /// "List`1" --> TyconRef @@ -397,6 +402,7 @@ type NameResolutionEnv = eModulesAndNamespaces = Map.empty eFullyQualifiedModulesAndNamespaces = Map.empty eFieldLabels = Map.empty + eUnqualifiedRecordOrUnionTypeInsts = TyconRefMap.Empty eUnqualifiedItems = LayeredMap.Empty eUnqualifiedEnclosingTypeInsts = TyconRefMap.Empty ePatItems = Map.empty @@ -1149,13 +1155,13 @@ and private AddTyconRefsWithEnclosingTypeInstToNameEnv bulkAddMode ownDefinition AddTyconRefsToNameEnv bulkAddMode ownDefinition g amap ad m root nenv tcrefs and private AddStaticPartsOfTypeToNameEnv (amap: Import.ImportMap) m nenv ty = - match tryTcrefOfAppTy amap.g ty with - | ValueSome tcref -> - AddStaticPartsOfTyconRefToNameEnv BulkAdd.Yes false amap.g amap m nenv tcref + match tryAppTy amap.g ty with + | ValueSome (tcref, tinst) -> + AddStaticPartsOfTyconRefToNameEnv BulkAdd.Yes false amap.g amap m nenv (Some tinst) tcref | _ -> nenv -and private AddStaticPartsOfTyconRefToNameEnv bulkAddMode ownDefinition g amap m nenv (tcref: TyconRef) = +and private AddStaticPartsOfTyconRefToNameEnv bulkAddMode ownDefinition g amap m nenv tinstOpt (tcref: TyconRef) = let isIL = tcref.IsILTycon let ucrefs = if isIL then [] else tcref.UnionCasesAsList |> List.map tcref.MakeNestedUnionCaseRef let flds = if isIL then [| |] else tcref.AllFieldsArray @@ -1194,8 +1200,19 @@ and private AddStaticPartsOfTyconRefToNameEnv bulkAddMode ownDefinition g amap m // Union cases for patterns AddUnionCases1 nenv.ePatItems ucrefs + let eUnqualifiedRecordOrUnionTypeInsts = + if isILOrRequiredQualifiedAccess || not (tcref.IsRecordTycon || tcref.IsUnionTycon) then + nenv.eUnqualifiedRecordOrUnionTypeInsts + else + match tinstOpt with + | None + | Some [] -> nenv.eUnqualifiedEnclosingTypeInsts + | Some tinst -> + nenv.eUnqualifiedRecordOrUnionTypeInsts.Add tcref tinst + { nenv with eFieldLabels = eFieldLabels + eUnqualifiedRecordOrUnionTypeInsts = eUnqualifiedRecordOrUnionTypeInsts eUnqualifiedItems = eUnqualifiedItems ePatItems = ePatItems eIndexedExtensionMembers = eIndexedExtensionMembers @@ -1238,7 +1255,7 @@ and private AddPartsOfTyconRefToNameEnv bulkAddMode ownDefinition (g: TcGlobals) { nenv with eUnqualifiedItems = tab } - let nenv = AddStaticPartsOfTyconRefToNameEnv bulkAddMode ownDefinition g amap m nenv tcref + let nenv = AddStaticPartsOfTyconRefToNameEnv bulkAddMode ownDefinition g amap m nenv None tcref let nenv = if CanAutoOpenTyconRef g m tcref then let ty = generalizedTyconRef tcref @@ -1427,17 +1444,26 @@ let FreshenTyconWithEnclosingTypeInst (ncenv: NameResolver) m (tinstEnclosing: T /// Convert a reference to a union case into a UnionCaseInfo that includes /// a fresh set of inference type variables for the type parameters of the union type. -let FreshenUnionCaseRef (ncenv: NameResolver) m (ucref: UnionCaseRef) = +let FreshenUnionCaseRef (ncenv: NameResolver) m (ucref: UnionCaseRef) = let tinst = ncenv.InstantiationGenerator m (ucref.TyconRef.Typars m) UnionCaseInfo(tinst, ucref) -/// This must be called after fetching unqualified items that may need to be freshened -let FreshenUnqualifiedItem (ncenv: NameResolver) m res = +/// Generate a new reference to a record field with a fresh type instantiation +let FreshenRecdFieldRef (ncenv: NameResolver) m (rfref: RecdFieldRef) = + RecdFieldInfo(ncenv.InstantiationGenerator m (rfref.Tycon.Typars m), rfref) + +/// This must be called after fetching unqualified items that may need to be freshened +/// or have type instantiations +let ResolveUnqualifiedItem (ncenv: NameResolver) nenv m res = match res with - | Item.UnionCase(UnionCaseInfo(_, ucref), _) -> Item.UnionCase(FreshenUnionCaseRef ncenv m ucref, false) + | Item.UnionCase(UnionCaseInfo(_, ucref), _) -> + match nenv.eUnqualifiedRecordOrUnionTypeInsts.TryFind ucref.TyconRef with + | Some tinst -> + Item.UnionCase(UnionCaseInfo(tinst, ucref), false) + | _ -> + Item.UnionCase(FreshenUnionCaseRef ncenv m ucref, false) | _ -> res - //------------------------------------------------------------------------- // Resolve module paths, value, field etc. lookups. Doing this involves // searching through many possibilities and disambiguating. Hence first @@ -2777,7 +2803,7 @@ let rec ResolveExprLongIdentPrim sink (ncenv: NameResolver) first fullyQualified None | true, res -> - let fresh = FreshenUnqualifiedItem ncenv m res + let fresh = ResolveUnqualifiedItem ncenv nenv m res match fresh with | Item.Value value -> let isNameOfOperator = valRefEq ncenv.g ncenv.g.nameof_vref value @@ -2896,7 +2922,7 @@ let rec ResolveExprLongIdentPrim sink (ncenv: NameResolver) first fullyQualified match nenv.eUnqualifiedItems.TryGetValue id.idText with | true, Item.UnqualifiedType _ | false, _ -> NoResultsOrUsefulErrors - | true, res -> OneSuccess (ResolutionInfo.Empty, FreshenUnqualifiedItem ncenv m res, rest) + | true, res -> OneSuccess (ResolutionInfo.Empty, ResolveUnqualifiedItem ncenv nenv m res, rest) moduleSearch ad () +++ tyconSearch ad +++ envSearch @@ -3041,7 +3067,7 @@ let rec ResolvePatternLongIdentPrim sink (ncenv: NameResolver) fullyQualified wa // For the special case of // let C = x match nenv.ePatItems.TryGetValue id.idText with - | true, res when not newDef -> FreshenUnqualifiedItem ncenv m res + | true, res when not newDef -> ResolveUnqualifiedItem ncenv nenv m res | _ -> // Single identifiers in patterns - variable bindings if not newDef && @@ -3347,7 +3373,7 @@ let rec ResolveFieldInModuleOrNamespace (ncenv: NameResolver) nenv ad (resInfo: match TryFindTypeWithRecdField modref id with | Some tycon when IsEntityAccessible ncenv.amap m ad (modref.NestedTyconRef tycon) -> let showDeprecated = HasFSharpAttribute ncenv.g ncenv.g.attrib_RequireQualifiedAccessAttribute tycon.Attribs - success [resInfo, FieldResolution(modref.RecdFieldRefInNestedTycon tycon id, showDeprecated), rest] + success [resInfo, FieldResolution(FreshenRecdFieldRef ncenv m (modref.RecdFieldRefInNestedTycon tycon id), showDeprecated), rest] | _ -> raze (UndefinedName(depth, FSComp.SR.undefinedNameRecordLabelOrNamespace, id, NoSuggestions)) // search for type-qualified names, e.g. { Microsoft.FSharp.Core.Ref.contents = 1 } @@ -3359,7 +3385,7 @@ let rec ResolveFieldInModuleOrNamespace (ncenv: NameResolver) nenv ad (resInfo: let tcrefs = tcrefs |> List.map (fun tcref -> (ResolutionInfo.Empty, tcref)) let tyconSearch = ResolveLongIdentInTyconRefs ResultCollectionSettings.AllResults ncenv nenv LookupKind.RecdField (depth+1) m ad id2 rest2 typeNameResInfo id.idRange tcrefs // choose only fields - let tyconSearch = tyconSearch |?> List.choose (function (resInfo, Item.RecdField(RecdFieldInfo(_, rfref)), rest) -> Some(resInfo, FieldResolution(rfref, false), rest) | _ -> None) + let tyconSearch = tyconSearch |?> List.choose (function (resInfo, Item.RecdField(RecdFieldInfo(_, rfref)), rest) -> Some(resInfo, FieldResolution(FreshenRecdFieldRef ncenv m rfref, false), rest) | _ -> None) tyconSearch | _ -> NoResultsOrUsefulErrors @@ -3453,12 +3479,17 @@ let ResolveFieldPrim sink (ncenv: NameResolver) nenv ad ty (mp, id: Ident) allFi // Eliminate duplicates arising from multiple 'open' frefs |> ListSet.setify (fun fref1 fref2 -> tyconRefEq g fref1.TyconRef fref2.TyconRef) - |> List.map (fun x -> ResolutionInfo.Empty, FieldResolution(x, false)) + |> List.map (fun x -> + let rfinfo = + match nenv.eUnqualifiedRecordOrUnionTypeInsts.TryFind x.TyconRef with + | Some tinst -> RecdFieldInfo(tinst, x) + | _ -> FreshenRecdFieldRef ncenv m x + ResolutionInfo.Empty, FieldResolution(rfinfo, false)) match tryTcrefOfAppTy g ty with | ValueSome tcref -> match ncenv.InfoReader.TryFindRecdOrClassFieldInfoOfType(id.idText, m, ty) with - | ValueSome (RecdFieldInfo(_, rfref)) -> [ResolutionInfo.Empty, FieldResolution(rfref, false)] + | ValueSome (RecdFieldInfo(_, rfref)) -> [ResolutionInfo.Empty, FieldResolution(FreshenRecdFieldRef ncenv m rfref, false)] | _ -> if tcref.IsRecordTycon then // record label doesn't belong to record type -> suggest other labels of same record @@ -3484,7 +3515,7 @@ let ResolveFieldPrim sink (ncenv: NameResolver) nenv ad ty (mp, id: Ident) allFi let tcrefs = tcrefs |> List.map (fun tcref -> (ResolutionInfo.Empty, tcref)) let tyconSearch = ResolveLongIdentInTyconRefs ResultCollectionSettings.AllResults ncenv nenv LookupKind.RecdField 1 m ad id2 rest2 typeNameResInfo tn.idRange tcrefs // choose only fields - let tyconSearch = tyconSearch |?> List.choose (function (resInfo, Item.RecdField(RecdFieldInfo(_, rfref)), rest) -> Some(resInfo, FieldResolution(rfref, false), rest) | _ -> None) + let tyconSearch = tyconSearch |?> List.choose (function (resInfo, Item.RecdField(RecdFieldInfo(_, rfref)), rest) -> Some(resInfo, FieldResolution(FreshenRecdFieldRef ncenv m rfref, false), rest) | _ -> None) tyconSearch | _ -> NoResultsOrUsefulErrors @@ -3515,11 +3546,6 @@ let ResolveField sink ncenv nenv ad ty (mp, id) allFields = ResolutionInfo.SendEntityPathToSink(sink, ncenv, nenv, ItemOccurence.UseInType, ad, resInfo, checker) rfref) -/// Generate a new reference to a record field with a fresh type instantiation -let FreshenRecdFieldRef (ncenv: NameResolver) m (rfref: RecdFieldRef) = - Item.RecdField(RecdFieldInfo(ncenv.InstantiationGenerator m (rfref.Tycon.Typars m), rfref)) - - /// Resolve F#/IL "." syntax in expressions (2). /// /// We have an expr. on the left, and we do an access, e.g. @@ -3544,7 +3570,7 @@ let private ResolveExprDotLongIdent (ncenv: NameResolver) m ad nenv ty (id: Iden | true, rfref :: _ -> // NOTE (instantiationGenerator cleanup): we need to freshen here because we don't know the type. // But perhaps the caller should freshen?? - let item = FreshenRecdFieldRef ncenv m rfref + let item = Item.RecdField(FreshenRecdFieldRef ncenv m rfref) OneSuccess (ResolutionInfo.Empty, item, rest) | _ -> NoResultsOrUsefulErrors diff --git a/src/fsharp/NameResolution.fsi b/src/fsharp/NameResolution.fsi index da55f262828..d71def02718 100755 --- a/src/fsharp/NameResolution.fsi +++ b/src/fsharp/NameResolution.fsi @@ -137,7 +137,7 @@ val (|ItemWithInst|) : ItemWithInst -> Item * TyparInst val ItemWithNoInst : Item -> ItemWithInst /// Represents a record field resolution and the information if the usage is deprecated. -type FieldResolution = FieldResolution of RecdFieldRef * bool +type FieldResolution = FieldResolution of RecdFieldInfo * bool /// Information about an extension member held in the name resolution environment type ExtensionMember = @@ -181,6 +181,10 @@ type NameResolutionEnv = /// Bools indicate if from a record, where no warning is given on indeterminate lookup eFieldLabels: NameMultiMap + /// Record or unions that may have type instantiations associated with them + /// when record labels or union cases are used in an unqualified context. + eUnqualifiedRecordOrUnionTypeInsts: TyconRefMap + /// Tycons indexed by the various names that may be used to access them, e.g. /// "List" --> multiple TyconRef's for the various tycons accessible by this name. /// "List`1" --> TyconRef @@ -510,7 +514,7 @@ exception internal IndeterminateType of range exception internal UpperCaseIdentifierInPattern of range /// Generate a new reference to a record field with a fresh type instantiation -val FreshenRecdFieldRef :NameResolver -> Range.range -> RecdFieldRef -> Item +val FreshenRecdFieldRef :NameResolver -> Range.range -> RecdFieldRef -> RecdFieldInfo /// Indicates the kind of lookup being performed. Note, this type should be made private to nameres.fs. [] diff --git a/src/fsharp/NicePrint.fs b/src/fsharp/NicePrint.fs index e84a5ebcd2b..cdfbf1ee89a 100755 --- a/src/fsharp/NicePrint.fs +++ b/src/fsharp/NicePrint.fs @@ -2182,9 +2182,9 @@ let layoutExnDef denv x = x |> TastDefinitionPrinting.layoutExnDefn denv let stringOfTyparConstraints denv x = x |> PrintTypes.layoutConstraintsWithInfo denv SimplifyTypes.typeSimplificationInfo0 |> showL -let outputTycon denv infoReader ad m (* width *) os x = TastDefinitionPrinting.layoutTycon denv infoReader ad m true WordL.keywordType x (* |> Layout.squashTo width *) |> bufferL os +let outputTycon denv infoReader ad m (* width *) os x = TastDefinitionPrinting.layoutTycon denv infoReader ad m true WordL.keywordType x (* |> Display.squashTo width *) |> bufferL os -let layoutTycon denv infoReader ad m (* width *) x = TastDefinitionPrinting.layoutTycon denv infoReader ad m true WordL.keywordType x (* |> Layout.squashTo width *) +let layoutTycon denv infoReader ad m (* width *) x = TastDefinitionPrinting.layoutTycon denv infoReader ad m true WordL.keywordType x (* |> Display.squashTo width *) let layoutUnionCases denv x = x |> TastDefinitionPrinting.layoutUnionCaseFields denv true diff --git a/src/fsharp/Optimizer.fs b/src/fsharp/Optimizer.fs index 1c8e4928b0d..1d25344b0fc 100644 --- a/src/fsharp/Optimizer.fs +++ b/src/fsharp/Optimizer.fs @@ -6,6 +6,7 @@ module internal FSharp.Compiler.Optimizer open Internal.Utilities +open Internal.Utilities.StructuredFormat open FSharp.Compiler open FSharp.Compiler.AbstractIL.Diagnostics @@ -1250,17 +1251,17 @@ let RemapOptimizationInfo g tmenv = let AbstractAndRemapModulInfo msg g m (repackage, hidden) info = let mrpi = mkRepackageRemapping repackage #if DEBUG - if verboseOptimizationInfo then dprintf "%s - %a - Optimization data prior to trim: \n%s\n" msg outputRange m (Layout.showL (Layout.squashTo 192 (moduleInfoL g info))) + if verboseOptimizationInfo then dprintf "%s - %a - Optimization data prior to trim: \n%s\n" msg outputRange m (Layout.showL (Display.squashTo 192 (moduleInfoL g info))) #else ignore (msg, m) #endif let info = info |> AbstractLazyModulInfoByHiding false hidden #if DEBUG - if verboseOptimizationInfo then dprintf "%s - %a - Optimization data after trim:\n%s\n" msg outputRange m (Layout.showL (Layout.squashTo 192 (moduleInfoL g info))) + if verboseOptimizationInfo then dprintf "%s - %a - Optimization data after trim:\n%s\n" msg outputRange m (Layout.showL (Display.squashTo 192 (moduleInfoL g info))) #endif let info = info |> RemapOptimizationInfo g mrpi #if DEBUG - if verboseOptimizationInfo then dprintf "%s - %a - Optimization data after remap:\n%s\n" msg outputRange m (Layout.showL (Layout.squashTo 192 (moduleInfoL g info))) + if verboseOptimizationInfo then dprintf "%s - %a - Optimization data after remap:\n%s\n" msg outputRange m (Layout.showL (Display.squashTo 192 (moduleInfoL g info))) #endif info diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index 563b001f4e1..985317ffe62 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -2005,35 +2005,36 @@ let BuildFieldMap cenv env isPartial ty flds m = fld, frefSet, fldExpr) let relevantTypeSets = - frefSets |> List.map (fun (_, frefSet, _) -> frefSet |> List.map (fun (FieldResolution(rfref, _)) -> rfref.TyconRef)) + frefSets |> List.map (fun (_, frefSet, _) -> frefSet |> List.map (fun (FieldResolution(rfinfo, _)) -> rfinfo.TypeInst, rfinfo.TyconRef)) - let tcref = - match List.fold (ListSet.intersect (tyconRefEq cenv.g)) (List.head relevantTypeSets) (List.tail relevantTypeSets) with - | [tcref] -> tcref + let tinst, tcref = + match List.fold (ListSet.intersect (fun (_, tcref1) (_, tcref2) -> tyconRefEq cenv.g tcref1 tcref2)) (List.head relevantTypeSets) (List.tail relevantTypeSets) with + | [tinst, tcref] -> tinst, tcref | tcrefs -> if isPartial then warning (Error(FSComp.SR.tcFieldsDoNotDetermineUniqueRecordType(), m)) // try finding a record type with the same number of fields as the ones that are given. - match tcrefs |> List.tryFind (fun tc -> tc.TrueFieldsAsList.Length = fldCount) with - | Some tcref -> tcref + match tcrefs |> List.tryFind (fun (_, tc) -> tc.TrueFieldsAsList.Length = fldCount) with + | Some (tinst, tcref) -> tinst, tcref | _ -> // OK, there isn't a unique, good type dictated by the intersection for the field refs. // We're going to get an error of some kind below. // Just choose one field ref and let the error come later let (_, frefSet1, _) = List.head frefSets - let (FieldResolution(fref1, _)) = List.head frefSet1 - fref1.TyconRef + let (FieldResolution(rfinfo1, _)) = List.head frefSet1 + rfinfo1.TypeInst, rfinfo1.TyconRef let fldsmap, rfldsList = ((Map.empty, []), frefSets) ||> List.fold (fun (fs, rfldsList) (fld, frefs, fldExpr) -> - match frefs |> List.filter (fun (FieldResolution(fref2, _)) -> tyconRefEq cenv.g tcref fref2.TyconRef) with - | [FieldResolution(fref2, showDeprecated)] -> + match frefs |> List.filter (fun (FieldResolution(rfinfo2, _)) -> tyconRefEq cenv.g tcref rfinfo2.TyconRef) with + | [FieldResolution(rfinfo2, showDeprecated)] -> // Record the precise resolution of the field for intellisense - let item = FreshenRecdFieldRef cenv.nameResolver m fref2 + let item = Item.RecdField(rfinfo2) CallNameResolutionSink cenv.tcSink ((snd fld).idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, ad) + let fref2 = rfinfo2.RecdFieldRef CheckRecdFieldAccessible cenv.amap m env.eAccessRights fref2 |> ignore CheckFSharpAttributes cenv.g fref2.PropertyAttribs m |> CommitOperationResult if Map.containsKey fref2.FieldName fs then @@ -2043,14 +2044,14 @@ let BuildFieldMap cenv env isPartial ty flds m = if not (tyconRefEq cenv.g tcref fref2.TyconRef) then let (_, frefSet1, _) = List.head frefSets - let (FieldResolution(fref1, _)) = List.head frefSet1 - errorR (FieldsFromDifferentTypes(env.DisplayEnv, fref1, fref2, m)) + let (FieldResolution(rfinfo1, _)) = List.head frefSet1 + errorR (FieldsFromDifferentTypes(env.DisplayEnv, rfinfo1.RecdFieldRef, fref2, m)) fs, rfldsList else Map.add fref2.FieldName fldExpr fs, (fref2.FieldName, fldExpr) :: rfldsList | _ -> error(Error(FSComp.SR.tcRecordFieldInconsistentTypes(), m))) - tcref, fldsmap, List.rev rfldsList + tinst, tcref, fldsmap, List.rev rfldsList let rec ApplyUnionCaseOrExn (makerForUnionCase, makerForExnTag) m cenv env overallTy item = let ad = env.eAccessRights @@ -4253,6 +4254,12 @@ type TyconBindingDefn = TyconBindingDefn of ContainerInfo * NewSlotsOK * DeclKin type ValSpecResult = ValSpecResult of ParentRef * ValMemberInfoTransient option * Ident * Typars * Typars * TType * PartialValReprInfo * DeclKind +/// Used to flag if this is the first or a sebsequent translation pass through a computation expression +type CompExprTranslationPass = Initial | Subsequent + +/// Used to flag if computation expression custom operations are allowed in a given context +type CustomOperationsMode = Allowed | Denied + //------------------------------------------------------------------------- // Additional data structures used by checking recursive bindings //------------------------------------------------------------------------- @@ -5685,9 +5692,10 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty p else List.foldBack (mkConsListPat cenv.g argty) args' (mkNilListPat cenv.g m argty)), acc | SynPat.Record (flds, m) -> - let tcref, fldsmap, _fldsList = BuildFieldMap cenv env true ty flds m + let tinst, tcref, fldsmap, _fldsList = BuildFieldMap cenv env true ty flds m // REVIEW: use _fldsList to type check pattern in code order not field defn order - let _, inst, tinst, gtyp = FreshenTyconRef2 m tcref + let gtyp = mkAppTy tcref tinst + let inst = List.zip (tcref.Typars m) tinst UnifyTypes cenv env m ty gtyp let fields = tcref.TrueInstanceFieldsAsList let ftys = fields |> List.map (fun fsp -> actualTyOfRecdField inst fsp, fsp) @@ -7455,8 +7463,8 @@ and TcRecdExpr cenv overallTy env tpenv (inherits, optOrigExpr, flds, mWholeExpr match flds with | [] -> [] | _ -> - let tcref, _, fldsList = BuildFieldMap cenv env hasOrigExpr overallTy flds mWholeExpr - let _, _, _, gtyp = FreshenTyconRef2 mWholeExpr tcref + let tinst, tcref, _, fldsList = BuildFieldMap cenv env hasOrigExpr overallTy flds mWholeExpr + let gtyp = mkAppTy tcref tinst UnifyTypes cenv env mWholeExpr overallTy gtyp [ for n, v in fldsList do @@ -7950,7 +7958,7 @@ and TcComputationExpression cenv env overallTy mWhole (interpExpr: Expr) builder | _ -> None /// Decide if the identifier represents a use of a custom query operator - let hasCustomOperations () = not (isNil customOperationMethods) + let hasCustomOperations () = if isNil customOperationMethods then CustomOperationsMode.Denied else CustomOperationsMode.Allowed let isCustomOperation nm = tryGetDataForCustomOperation nm |> Option.isSome @@ -8333,7 +8341,7 @@ and TcComputationExpression cenv env overallTy mWhole (interpExpr: Expr) builder | ForEachThenJoinOrGroupJoinOrZipClause (isFromSource, firstSourcePat, firstSource, nm, secondSourcePat, secondSource, keySelectorsOpt, secondResultPatOpt, mOpCore, innerComp) -> - if not q then error(Error(FSComp.SR.tcCustomOperationMayNotBeUsedHere(), nm.idRange)) + if q = CustomOperationsMode.Denied then error(Error(FSComp.SR.tcCustomOperationMayNotBeUsedHere(), nm.idRange)) let firstSource = mkSourceExprConditional isFromSource firstSource let secondSource = mkSourceExpr secondSource @@ -8474,7 +8482,7 @@ and TcComputationExpression cenv env overallTy mWhole (interpExpr: Expr) builder let varSpaceExpr = mkExprForVarSpace mOpCore valsInner let varSpacePat = mkPatForVarSpace mOpCore valsInner let joinExpr = mkOverallExprGivenVarSpaceExpr varSpaceExpr - Some (trans true q varSpaceInner (SynExpr.ForEach (DebugPointAtFor.No, SeqExprOnly false, false, varSpacePat, joinExpr, innerComp, mOpCore)) translatedCtxt) + Some (trans CompExprTranslationPass.Initial q varSpaceInner (SynExpr.ForEach (DebugPointAtFor.No, SeqExprOnly false, false, varSpacePat, joinExpr, innerComp, mOpCore)) translatedCtxt) | SynExpr.ForEach (spForLoop, SeqExprOnly _seqExprOnly, isFromSource, pat, sourceExpr, innerComp, _) -> @@ -8492,14 +8500,14 @@ and TcComputationExpression cenv env overallTy mWhole (interpExpr: Expr) builder let _, _, vspecs, envinner, _ = TcMatchPattern cenv (NewInferenceType()) env tpenv (pat, None) vspecs, envinner) - Some (trans true q varSpace innerComp + Some (trans CompExprTranslationPass.Initial q varSpace innerComp (fun holeFill -> translatedCtxt (mkSynCall "For" mFor [wrappedSourceExpr; SynExpr.MatchLambda (false, sourceExpr.Range, [Clause(pat, None, holeFill, mPat, DebugPointForTarget.Yes)], spBind, mFor) ])) ) | SynExpr.For (spBind, id, start, dir, finish, innerComp, m) -> let mFor = match spBind with DebugPointAtFor.Yes m -> m | _ -> m if isQuery then errorR(Error(FSComp.SR.tcNoIntegerForLoopInQuery(), mFor)) - Some (trans true q varSpace (elimFastIntegerForLoop (spBind, id, start, dir, finish, innerComp, m)) translatedCtxt ) + Some (trans CompExprTranslationPass.Initial q varSpace (elimFastIntegerForLoop (spBind, id, start, dir, finish, innerComp, m)) translatedCtxt ) | SynExpr.While (spWhile, guardExpr, innerComp, _) -> let mGuard = guardExpr.Range @@ -8509,7 +8517,7 @@ and TcComputationExpression cenv env overallTy mWhole (interpExpr: Expr) builder error(Error(FSComp.SR.tcRequireBuilderMethod("While"), mWhile)) if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mWhile ad "Delay" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Delay"), mWhile)) - Some(trans true q varSpace innerComp (fun holeFill -> translatedCtxt (mkSynCall "While" mWhile [mkSynDelay2 guardExpr; mkSynCall "Delay" mWhile [mkSynDelay innerComp.Range holeFill]])) ) + Some(trans CompExprTranslationPass.Initial q varSpace innerComp (fun holeFill -> translatedCtxt (mkSynCall "While" mWhile [mkSynDelay2 guardExpr; mkSynCall "Delay" mWhile [mkSynDelay innerComp.Range holeFill]])) ) | SynExpr.TryFinally (innerComp, unwindExpr, mTryToLast, spTry, _spFinally) -> @@ -8529,7 +8537,7 @@ and TcComputationExpression cenv env overallTy mWhole (interpExpr: Expr) builder Some (translatedCtxt (mkSynCall "Zero" m [])) | OptionalSequential (JoinOrGroupJoinOrZipClause (_, _, _, _, _, mClause), _) - when firstTry -> + when firstTry = CompExprTranslationPass.Initial -> // 'join' clauses preceded by 'let' and other constructs get processed by repackaging with a 'for' loop. let patvs, _env = varSpace.Force comp.Range @@ -8544,12 +8552,12 @@ and TcComputationExpression cenv env overallTy mWhole (interpExpr: Expr) builder SynExpr.ForEach (DebugPointAtFor.No, SeqExprOnly false, false, varSpacePat, dataCompPrior, comp, comp.Range) // Retry with the 'for' loop packaging. Set firstTry=false just in case 'join' processing fails - tryTrans false q varSpace rebind id + tryTrans CompExprTranslationPass.Subsequent q varSpace rebind id | OptionalSequential (CustomOperationClause (nm, _, opExpr, mClause, _), _) -> - if not q then error(Error(FSComp.SR.tcCustomOperationMayNotBeUsedHere(), opExpr.Range)) + if q = CustomOperationsMode.Denied then error(Error(FSComp.SR.tcCustomOperationMayNotBeUsedHere(), opExpr.Range)) let patvs, _env = varSpace.Force comp.Range let varSpaceExpr = mkExprForVarSpace mClause patvs @@ -8566,7 +8574,7 @@ and TcComputationExpression cenv env overallTy mWhole (interpExpr: Expr) builder // Check for 'where x > y' and other mis-applications of infix operators. If detected, give a good error message, and just ignore innerComp1 if isQuery && checkForBinaryApp innerComp1 then - Some (trans true q varSpace innerComp2 translatedCtxt) + Some (trans CompExprTranslationPass.Initial q varSpace innerComp2 translatedCtxt) else @@ -8575,7 +8583,7 @@ and TcComputationExpression cenv env overallTy mWhole (interpExpr: Expr) builder | SynExpr.JoinIn _ -> () // an error will be reported later when we process innerComp1 as a sequential | _ -> errorR(Error(FSComp.SR.tcUnrecognizedQueryOperator(), innerComp1.RangeOfFirstPortion)) - match tryTrans true false varSpace innerComp1 id with + match tryTrans CompExprTranslationPass.Initial CustomOperationsMode.Denied varSpace innerComp1 id with | Some c -> // "cexpr; cexpr" is treated as builder.Combine(cexpr1, cexpr1) // This is not pretty - we have to decide which range markers we use for the calls to Combine and Delay @@ -8595,11 +8603,11 @@ and TcComputationExpression cenv env overallTy mWhole (interpExpr: Expr) builder | DebugPointAtSequential.ExprOnly -> DebugPointAtBinding m | DebugPointAtSequential.StmtOnly -> NoDebugPointAtDoBinding | DebugPointAtSequential.Both -> DebugPointAtBinding m - Some(trans true q varSpace (SynExpr.LetOrUseBang (sp, false, true, SynPat.Const(SynConst.Unit, rhsExpr.Range), rhsExpr, [], innerComp2, m)) translatedCtxt) + Some(trans CompExprTranslationPass.Initial q varSpace (SynExpr.LetOrUseBang (sp, false, true, SynPat.Const(SynConst.Unit, rhsExpr.Range), rhsExpr, [], innerComp2, m)) translatedCtxt) // "expr; cexpr" is treated as sequential execution | _ -> - Some (trans true q varSpace innerComp2 (fun holeFill -> + Some (trans CompExprTranslationPass.Initial q varSpace innerComp2 (fun holeFill -> let fillExpr = if enableImplicitYield then // When implicit yields are enabled, then if the 'innerComp1' checks as type @@ -8624,7 +8632,7 @@ and TcComputationExpression cenv env overallTy mWhole (interpExpr: Expr) builder if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mIfToThen ad "Zero" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Zero"), mIfToThen)) mkSynCall "Zero" mIfToThen [] - Some (trans true q varSpace thenComp (fun holeFill -> translatedCtxt (SynExpr.IfThenElse (guardExpr, holeFill, Some elseComp, spIfToThen, isRecovery, mIfToThen, mIfToEndOfElseBranch)))) + Some (trans CompExprTranslationPass.Initial q varSpace thenComp (fun holeFill -> translatedCtxt (SynExpr.IfThenElse (guardExpr, holeFill, Some elseComp, spIfToThen, isRecovery, mIfToThen, mIfToEndOfElseBranch)))) // 'let binds in expr' | SynExpr.LetOrUse (isRec, false, binds, innerComp, m) -> @@ -8654,7 +8662,7 @@ and TcComputationExpression cenv env overallTy mWhole (interpExpr: Expr) builder // error case error(Error(FSComp.SR.tcCustomOperationMayNotBeUsedInConjunctionWithNonSimpleLetBindings(), mQueryOp))) - Some (trans true q varSpace innerComp (fun holeFill -> translatedCtxt (SynExpr.LetOrUse (isRec, false, binds, holeFill, m)))) + Some (trans CompExprTranslationPass.Initial q varSpace innerComp (fun holeFill -> translatedCtxt (SynExpr.LetOrUse (isRec, false, binds, holeFill, m)))) // 'use x = expr in expr' | SynExpr.LetOrUse (_, true, [Binding (_, NormalBinding, _, _, _, _, _, pat, _, rhsExpr, _, spBind)], innerComp, _) -> @@ -8958,7 +8966,7 @@ and TcComputationExpression cenv env overallTy mWhole (interpExpr: Expr) builder else SynExpr.ForEach (DebugPointAtFor.No, SeqExprOnly false, false, intoPat, dataCompAfterOp, contExpr, intoPat.Range) - trans true q emptyVarSpace rebind id + trans CompExprTranslationPass.Initial q emptyVarSpace rebind id // select a.Name; ... // distinct; ... @@ -8980,9 +8988,9 @@ and TcComputationExpression cenv env overallTy mWhole (interpExpr: Expr) builder else SynExpr.ForEach (DebugPointAtFor.No, SeqExprOnly false, false, varSpacePat, dataCompPrior, compClausesExpr, compClausesExpr.Range) - trans true q varSpace rebind id + trans CompExprTranslationPass.Initial q varSpace rebind id and transNoQueryOps comp = - trans true false emptyVarSpace comp id + trans CompExprTranslationPass.Initial CustomOperationsMode.Denied emptyVarSpace comp id and trans firstTry q varSpace comp translatedCtxt = match tryTrans firstTry q varSpace comp translatedCtxt with @@ -9000,20 +9008,20 @@ and TcComputationExpression cenv env overallTy mWhole (interpExpr: Expr) builder SynExpr.ImplicitZero m else SynExpr.YieldOrReturn((false, true), SynExpr.Const(SynConst.Unit, m), m) - trans true q varSpace (SynExpr.LetOrUseBang (NoDebugPointAtDoBinding, false, false, SynPat.Const(SynConst.Unit, mUnit), rhsExpr, [], bodyExpr, m)) translatedCtxt + trans CompExprTranslationPass.Initial q varSpace (SynExpr.LetOrUseBang (NoDebugPointAtDoBinding, false, false, SynPat.Const(SynConst.Unit, mUnit), rhsExpr, [], bodyExpr, m)) translatedCtxt // "expr;" in final position is treated as { expr; zero } // Suppress the sequence point on the "zero" | _ -> // Check for 'where x > y' and other mis-applications of infix operators. If detected, give a good error message, and just ignore comp if isQuery && checkForBinaryApp comp then - trans true q varSpace (SynExpr.ImplicitZero comp.Range) translatedCtxt + trans CompExprTranslationPass.Initial q varSpace (SynExpr.ImplicitZero comp.Range) translatedCtxt else if isQuery && not comp.IsArbExprAndThusAlreadyReportedError then match comp with | SynExpr.JoinIn _ -> () // an error will be reported later when we process innerComp1 as a sequential | _ -> errorR(Error(FSComp.SR.tcUnrecognizedQueryOperator(), comp.RangeOfFirstPortion)) - trans true q varSpace (SynExpr.ImplicitZero comp.Range) (fun holeFill -> + trans CompExprTranslationPass.Initial q varSpace (SynExpr.ImplicitZero comp.Range) (fun holeFill -> let fillExpr = if enableImplicitYield then let implicitYieldExpr = mkSynCall "Yield" comp.Range [comp] @@ -9055,7 +9063,7 @@ and TcComputationExpression cenv env overallTy mWhole (interpExpr: Expr) builder error(Error(FSComp.SR.tcRequireBuilderMethod(bindName), bindRange)) // Build the `Bind` call - trans true q varSpace innerComp (fun holeFill -> + trans CompExprTranslationPass.Initial q varSpace innerComp (fun holeFill -> let consumeExpr = SynExpr.MatchLambda(false, consumePat.Range, [Clause(consumePat, None, holeFill, innerRange, DebugPointForTarget.Yes)], spBind, innerRange) translatedCtxt (mkSynCall bindName bindRange (bindArgs @ [consumeExpr]))) @@ -9146,7 +9154,7 @@ and TcComputationExpression cenv env overallTy mWhole (interpExpr: Expr) builder | _ -> true let basicSynExpr = - trans true (hasCustomOperations ()) (LazyWithContext.NotLazy ([], env)) comp (fun holeFill -> holeFill) + trans CompExprTranslationPass.Initial (hasCustomOperations ()) (LazyWithContext.NotLazy ([], env)) comp (fun holeFill -> holeFill) let delayedExpr = match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mBuilderVal ad "Delay" builderTy with @@ -16452,7 +16460,7 @@ module EstablishTypeDefinitionCores = let info = RecdFieldInfo(thisTyInst, thisTyconRef.MakeNestedRecdFieldRef fspec) let nenv' = AddFakeNameToNameEnv fspec.Name nenv (Item.RecdField info) // Name resolution gives better info for tooltips - let item = FreshenRecdFieldRef cenv.nameResolver m (thisTyconRef.MakeNestedRecdFieldRef fspec) + let item = Item.RecdField(FreshenRecdFieldRef cenv.nameResolver m (thisTyconRef.MakeNestedRecdFieldRef fspec)) CallNameResolutionSink cenv.tcSink (fspec.Range, nenv, item, emptyTyparInst, ItemOccurence.Binding, ad) // Environment is needed for completions CallEnvSink cenv.tcSink (fspec.Range, nenv', ad) diff --git a/src/fsharp/TypedTreeBasics.fs b/src/fsharp/TypedTreeBasics.fs index 7f35d57a865..8c74d6bdbeb 100644 --- a/src/fsharp/TypedTreeBasics.fs +++ b/src/fsharp/TypedTreeBasics.fs @@ -412,17 +412,14 @@ let primUnionCaseRefEq compilingFslib fslibCcu (UnionCaseRef(tcr1, c1) as uc1) ( /// /// Note this routine doesn't take type forwarding into account let primValRefEq compilingFslib fslibCcu (x: ValRef) (y: ValRef) = - x === y || - if (x.IsResolved && y.IsResolved && x.ResolvedTarget === y.ResolvedTarget) || - (x.IsLocalRef && y.IsLocalRef && valEq x.ResolvedTarget y.ResolvedTarget) then - true - else - (// Use TryDeref to guard against the platforms/times when certain F# language features aren't available, - // e.g. CompactFramework doesn't have support for quotations. - match x.TryDeref with - | ValueSome v1 -> match y.TryDeref with ValueSome v2 -> v1 === v2 | _ -> false - | _ -> match y.TryDeref with ValueNone -> true | _ -> false) - || (if compilingFslib then fslibValRefEq fslibCcu x y else false) + x === y + || (x.IsResolved && y.IsResolved && x.ResolvedTarget === y.ResolvedTarget) + || (x.IsLocalRef && y.IsLocalRef && valEq x.ResolvedTarget y.ResolvedTarget) + || // Use TryDeref to guard against the platforms/times when certain F# language features aren't available + match x.TryDeref with + | ValueSome v1 -> match y.TryDeref with ValueSome v2 -> v1 === v2 | ValueNone -> false + | ValueNone -> match y.TryDeref with ValueNone -> true | ValueSome _ -> false + || (compilingFslib && fslibValRefEq fslibCcu x y) //--------------------------------------------------------------------------- // pubpath/cpath mess diff --git a/src/fsharp/fsc.fs b/src/fsharp/fsc.fs index d4fc5019e6f..68e768acbf6 100644 --- a/src/fsharp/fsc.fs +++ b/src/fsharp/fsc.fs @@ -24,6 +24,7 @@ open System.Threading open Internal.Utilities open Internal.Utilities.Collections open Internal.Utilities.Filename +open Internal.Utilities.StructuredFormat open FSharp.Compiler open FSharp.Compiler.AbstractIL @@ -321,7 +322,7 @@ module InterfaceFileWriter = for (TImplFile (_, _, mexpr, _, _, _)) in declaredImpls do let denv = BuildInitialDisplayEnvForSigFileGeneration tcGlobals writeViaBuffer os (fun os s -> Printf.bprintf os "%s\n\n" s) - (NicePrint.layoutInferredSigOfModuleExpr true denv infoReader AccessibleFromSomewhere range0 mexpr |> Layout.squashTo 80 |> Layout.showL) + (NicePrint.layoutInferredSigOfModuleExpr true denv infoReader AccessibleFromSomewhere range0 mexpr |> Display.squashTo 80 |> Layout.showL) if tcConfig.printSignatureFile <> "" then os.Dispose() diff --git a/src/fsharp/layout.fs b/src/fsharp/layout.fs index 04ec4989256..22c92e56acf 100644 --- a/src/fsharp/layout.fs +++ b/src/fsharp/layout.fs @@ -16,42 +16,21 @@ type TaggedText = Internal.Utilities.StructuredFormat.TaggedText type NavigableTaggedText(taggedText: TaggedText, range: Range.range) = member val Range = range interface TaggedText with - member x.Tag = taggedText.Tag - member x.Text = taggedText.Text + member _.Tag = taggedText.Tag + member _.Text = taggedText.Text let mkNav r t = NavigableTaggedText(t, r) :> TaggedText let spaces n = new String(' ', n) - -//-------------------------------------------------------------------------- -// INDEX: support -//-------------------------------------------------------------------------- - -let rec juxtLeft = function - | ObjLeaf (jl, _text, _jr) -> jl - | Leaf (jl, _text, _jr) -> jl - | Node (jl, _l, _jm, _r, _jr, _joint) -> jl - | Attr (_tag, _attrs, l) -> juxtLeft l - -let rec juxtRight = function - | ObjLeaf (_jl, _text, jr) -> jr - | Leaf (_jl, _text, jr) -> jr - | Node (_jl, _l, _jm, _r, jr, _joint) -> jr - | Attr (_tag, _attrs, l) -> juxtRight l - // NOTE: emptyL might be better represented as a constructor, so then (Sep"") would have true meaning -let emptyL = Leaf (true, Internal.Utilities.StructuredFormat.TaggedTextOps.tag LayoutTag.Text "", true) +let emptyL = Leaf (true, TaggedTextOps.mkTag LayoutTag.Text "", true) let isEmptyL = function Leaf(true, tag, true) when tag.Text = "" -> true | _ -> false let mkNode l r joint = if isEmptyL l then r else if isEmptyL r then l else - let jl = juxtLeft l - let jm = juxtRight l || juxtLeft r - let jr = juxtRight r - Node(jl, l, jm, r, jr, joint) - + Node(l, r, joint) //-------------------------------------------------------------------------- //INDEX: constructors @@ -63,57 +42,57 @@ let rightL (str:TaggedText) = Leaf (true, str, false) let leftL (str:TaggedText) = Leaf (false, str, true) module TaggedTextOps = - let tagActivePatternCase = Internal.Utilities.StructuredFormat.TaggedTextOps.tag LayoutTag.ActivePatternCase - let tagActivePatternResult = Internal.Utilities.StructuredFormat.TaggedTextOps.tag LayoutTag.ActivePatternResult - let tagAlias = Internal.Utilities.StructuredFormat.TaggedTextOps.tagAlias - let tagClass = Internal.Utilities.StructuredFormat.TaggedTextOps.tagClass - let tagUnion = Internal.Utilities.StructuredFormat.TaggedTextOps.tag LayoutTag.Union - let tagUnionCase = Internal.Utilities.StructuredFormat.TaggedTextOps.tagUnionCase - let tagDelegate = Internal.Utilities.StructuredFormat.TaggedTextOps.tagDelegate - let tagEnum = Internal.Utilities.StructuredFormat.TaggedTextOps.tagEnum - let tagEvent = Internal.Utilities.StructuredFormat.TaggedTextOps.tagEvent - let tagField = Internal.Utilities.StructuredFormat.TaggedTextOps.tagField - let tagInterface = Internal.Utilities.StructuredFormat.TaggedTextOps.tagInterface - let tagKeyword = Internal.Utilities.StructuredFormat.TaggedTextOps.tagKeyword - let tagLineBreak = Internal.Utilities.StructuredFormat.TaggedTextOps.tagLineBreak - let tagLocal = Internal.Utilities.StructuredFormat.TaggedTextOps.tagLocal - let tagRecord = Internal.Utilities.StructuredFormat.TaggedTextOps.tagRecord - let tagRecordField = Internal.Utilities.StructuredFormat.TaggedTextOps.tagRecordField - let tagMethod = Internal.Utilities.StructuredFormat.TaggedTextOps.tagMethod - let tagMember = Internal.Utilities.StructuredFormat.TaggedTextOps.tag LayoutTag.Member - let tagModule = Internal.Utilities.StructuredFormat.TaggedTextOps.tagModule - let tagModuleBinding = Internal.Utilities.StructuredFormat.TaggedTextOps.tagModuleBinding - let tagNamespace = Internal.Utilities.StructuredFormat.TaggedTextOps.tagNamespace - let tagNumericLiteral = Internal.Utilities.StructuredFormat.TaggedTextOps.tagNumericLiteral - let tagOperator = Internal.Utilities.StructuredFormat.TaggedTextOps.tagOperator - let tagParameter = Internal.Utilities.StructuredFormat.TaggedTextOps.tagParameter - let tagProperty = Internal.Utilities.StructuredFormat.TaggedTextOps.tagProperty - let tagSpace = Internal.Utilities.StructuredFormat.TaggedTextOps.tagSpace - let tagStringLiteral = Internal.Utilities.StructuredFormat.TaggedTextOps.tagStringLiteral - let tagStruct = Internal.Utilities.StructuredFormat.TaggedTextOps.tagStruct - let tagTypeParameter = Internal.Utilities.StructuredFormat.TaggedTextOps.tagTypeParameter - let tagText = Internal.Utilities.StructuredFormat.TaggedTextOps.tagText - let tagPunctuation = Internal.Utilities.StructuredFormat.TaggedTextOps.tagPunctuation - let tagUnknownEntity = Internal.Utilities.StructuredFormat.TaggedTextOps.tag LayoutTag.UnknownEntity - let tagUnknownType = Internal.Utilities.StructuredFormat.TaggedTextOps.tag LayoutTag.UnknownType + let tagActivePatternCase = TaggedTextOps.mkTag LayoutTag.ActivePatternCase + let tagActivePatternResult = TaggedTextOps.mkTag LayoutTag.ActivePatternResult + let tagAlias = TaggedTextOps.tagAlias + let tagClass = TaggedTextOps.tagClass + let tagUnion = TaggedTextOps.mkTag LayoutTag.Union + let tagUnionCase = TaggedTextOps.tagUnionCase + let tagDelegate = TaggedTextOps.tagDelegate + let tagEnum = TaggedTextOps.tagEnum + let tagEvent = TaggedTextOps.tagEvent + let tagField = TaggedTextOps.tagField + let tagInterface = TaggedTextOps.tagInterface + let tagKeyword = TaggedTextOps.tagKeyword + let tagLineBreak = TaggedTextOps.tagLineBreak + let tagLocal = TaggedTextOps.tagLocal + let tagRecord = TaggedTextOps.tagRecord + let tagRecordField = TaggedTextOps.tagRecordField + let tagMethod = TaggedTextOps.tagMethod + let tagMember = TaggedTextOps.mkTag LayoutTag.Member + let tagModule = TaggedTextOps.tagModule + let tagModuleBinding = TaggedTextOps.tagModuleBinding + let tagNamespace = TaggedTextOps.tagNamespace + let tagNumericLiteral = TaggedTextOps.tagNumericLiteral + let tagOperator = TaggedTextOps.tagOperator + let tagParameter = TaggedTextOps.tagParameter + let tagProperty = TaggedTextOps.tagProperty + let tagSpace = TaggedTextOps.tagSpace + let tagStringLiteral = TaggedTextOps.tagStringLiteral + let tagStruct = TaggedTextOps.tagStruct + let tagTypeParameter = TaggedTextOps.tagTypeParameter + let tagText = TaggedTextOps.tagText + let tagPunctuation = TaggedTextOps.tagPunctuation + let tagUnknownEntity = TaggedTextOps.mkTag LayoutTag.UnknownEntity + let tagUnknownType = TaggedTextOps.mkTag LayoutTag.UnknownType module Literals = // common tagged literals - let lineBreak = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.lineBreak - let space = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.space - let comma = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.comma - let semicolon = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.semicolon - let leftParen = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.leftParen - let rightParen = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.rightParen - let leftBracket = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.leftBracket - let rightBracket = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.rightBracket - let leftBrace = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.leftBrace - let rightBrace = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.rightBrace - let leftBraceBar = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.leftBraceBar - let rightBraceBar = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.rightBraceBar - let equals = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.equals - let arrow = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.arrow - let questionMark = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.questionMark + let lineBreak = TaggedTextOps.Literals.lineBreak + let space = TaggedTextOps.Literals.space + let comma = TaggedTextOps.Literals.comma + let semicolon = TaggedTextOps.Literals.semicolon + let leftParen = TaggedTextOps.Literals.leftParen + let rightParen = TaggedTextOps.Literals.rightParen + let leftBracket = TaggedTextOps.Literals.leftBracket + let rightBracket = TaggedTextOps.Literals.rightBracket + let leftBrace = TaggedTextOps.Literals.leftBrace + let rightBrace = TaggedTextOps.Literals.rightBrace + let leftBraceBar = TaggedTextOps.Literals.leftBraceBar + let rightBraceBar = TaggedTextOps.Literals.rightBraceBar + let equals = TaggedTextOps.Literals.equals + let arrow = TaggedTextOps.Literals.arrow + let questionMark = TaggedTextOps.Literals.questionMark let dot = tagPunctuation "." let leftAngle = tagPunctuation "<" let rightAngle = tagPunctuation ">" @@ -245,12 +224,17 @@ let tagListL tagger = function process' x xs let commaListL x = tagListL (fun prefixL -> prefixL ^^ rightL Literals.comma) x + let semiListL x = tagListL (fun prefixL -> prefixL ^^ rightL Literals.semicolon) x + let spaceListL x = tagListL (fun prefixL -> prefixL) x + let sepListL x y = tagListL (fun prefixL -> prefixL ^^ x) y let bracketL l = leftL Literals.leftParen ^^ l ^^ rightL Literals.rightParen + let tupleL xs = bracketL (sepListL (sepL Literals.comma) xs) + let aboveListL = function | [] -> emptyL | [x] -> x @@ -262,119 +246,6 @@ let optionL xL = function let listL xL xs = leftL Literals.leftBracket ^^ sepListL (sepL Literals.semicolon) (List.map xL xs) ^^ rightL Literals.rightBracket - -//-------------------------------------------------------------------------- -//INDEX: breaks v2 -//-------------------------------------------------------------------------- - -// A very quick implementation of break stack. -type breaks = Breaks of - /// pos of next free slot - int * - /// pos of next possible "outer" break - OR - outer=next if none possible - int * - /// stack of savings, -ve means it has been broken - int array - -// next is next slot to push into - aka size of current occupied stack. -// outer counts up from 0, and is next slot to break if break forced. -// - if all breaks forced, then outer=next. -// - popping under these conditions needs to reduce outer and next. -let chunkN = 400 -let breaks0 () = Breaks(0, 0, Array.create chunkN 0) -let pushBreak saving (Breaks(next, outer, stack)) = - let stack = if next = stack.Length then - Array.append stack (Array.create chunkN 0) (* expand if full *) - else - stack - stack.[next] <- saving - Breaks(next+1, outer, stack) - -let popBreak (Breaks(next, outer, stack)) = - if next=0 then raise (Failure "popBreak: underflow") - let topBroke = stack.[next-1] < 0 - let outer = if outer=next then outer-1 else outer (* if all broken, unwind *) - let next = next - 1 - Breaks(next, outer, stack), topBroke - -let forceBreak (Breaks(next, outer, stack)) = - if outer=next then - (* all broken *) - None - else - let saving = stack.[outer] - stack.[outer] <- -stack.[outer] - let outer = outer+1 - Some (Breaks(next, outer, stack), saving) - -let squashTo maxWidth layout = - // breaks = break context, can force to get indentation savings. - // pos = current position in line - // layout = to fit - //------ - // returns: - // breaks - // layout - with breaks put in to fit it. - // pos - current pos in line = rightmost position of last line of block. - // offset - width of last line of block - // NOTE: offset <= pos -- depending on tabbing of last block - let rec fit breaks (pos, layout) = - (*printf "\n\nCalling pos=%d layout=[%s]\n" pos (showL layout)*) - let breaks, layout, pos, offset = - match layout with - | ObjLeaf _ -> failwith "ObjLeaf should not appear here" - | Attr (tag, attrs, l) -> - let breaks, layout, pos, offset = fit breaks (pos, l) - let layout = Attr (tag, attrs, layout) - breaks, layout, pos, offset - | Leaf (_jl, taggedText, _jr) -> - let textWidth = taggedText.Text.Length - let rec fitLeaf breaks pos = - if pos + textWidth <= maxWidth then - breaks, layout, pos + textWidth, textWidth (* great, it fits *) - else - match forceBreak breaks with - None -> (breaks, layout, pos + textWidth, textWidth (* tough, no more breaks *)) - | Some (breaks, saving) -> (let pos = pos - saving in fitLeaf breaks pos) - fitLeaf breaks pos - - | Node (jl, l, jm, r, jr, joint) -> - let mid = if jm then 0 else 1 - match joint with - | Unbreakable -> - let breaks, l, pos, offsetl = fit breaks (pos, l) (* fit left *) - let pos = pos + mid (* fit space if juxt says so *) - let breaks, r, pos, offsetr = fit breaks (pos, r) (* fit right *) - breaks, Node (jl, l, jm, r, jr, Unbreakable), pos, offsetl + mid + offsetr - | Broken indent -> - let breaks, l, pos, offsetl = fit breaks (pos, l) (* fit left *) - let pos = pos - offsetl + indent (* broken so - offset left + indent *) - let breaks, r, pos, offsetr = fit breaks (pos, r) (* fit right *) - breaks, Node (jl, l, jm, r, jr, Broken indent), pos, indent + offsetr - | Breakable indent -> - let breaks, l, pos, offsetl = fit breaks (pos, l) (* fit left *) - (* have a break possibility, with saving *) - let saving = offsetl + mid - indent - let pos = pos + mid - if saving>0 then - let breaks = pushBreak saving breaks - let breaks, r, pos, offsetr = fit breaks (pos, r) - let breaks, broken = popBreak breaks - if broken then - breaks, Node (jl, l, jm, r, jr, Broken indent), pos, indent + offsetr - else - breaks, Node (jl, l, jm, r, jr, Breakable indent), pos, offsetl + mid + offsetr - else - (* actually no saving so no break *) - let breaks, r, pos, offsetr = fit breaks (pos, r) - breaks, Node (jl, l, jm, r, jr, Breakable indent), pos, offsetl + mid + offsetr - (*printf "\nDone: pos=%d offset=%d" pos offset*) - breaks, layout, pos, offset - let breaks = breaks0 () - let pos = 0 - let _breaks, layout, _pos, _offset = fit breaks (pos, layout) - layout - //-------------------------------------------------------------------------- //INDEX: LayoutRenderer //-------------------------------------------------------------------------- @@ -393,12 +264,13 @@ let renderL (rr: LayoutRenderer<_, _>) layout = (* pos is tab level *) | Leaf (_, text, _) -> k(rr.AddText z text, i + text.Text.Length) - | Node (_, l, _, r, _, Broken indent) -> + | Node (l, r, Broken indent) -> addL z pos i l <| fun (z, _i) -> let z, i = rr.AddBreak z (pos+indent), (pos+indent) addL z (pos+indent) i r k - | Node (_, l, jm, r, _, _) -> + | Node (l, r, _) -> + let jm = Layout.JuxtapositionMiddle (l, r) addL z pos i l <| fun (z, i) -> let z, i = if jm then z, i else rr.AddText z Literals.space, i+1 @@ -418,11 +290,11 @@ let renderL (rr: LayoutRenderer<_, _>) layout = /// string render let stringR = { new LayoutRenderer with - member x.Start () = [] - member x.AddText rstrs taggedText = taggedText.Text :: rstrs - member x.AddBreak rstrs n = (spaces n) :: "\n" :: rstrs - member x.AddTag z (_, _, _) = z - member x.Finish rstrs = String.Join("", Array.ofList (List.rev rstrs)) } + member _.Start () = [] + member _.AddText rstrs taggedText = taggedText.Text :: rstrs + member _.AddBreak rstrs n = (spaces n) :: "\n" :: rstrs + member _.AddTag z (_, _, _) = z + member _.Finish rstrs = String.Join("", Array.ofList (List.rev rstrs)) } type NoState = NoState type NoResult = NoResult @@ -430,11 +302,11 @@ type NoResult = NoResult /// string render let taggedTextListR collector = { new LayoutRenderer with - member x.Start () = NoState - member x.AddText z text = collector text; z - member x.AddBreak rstrs n = collector Literals.lineBreak; collector (tagSpace(spaces n)); rstrs - member x.AddTag z (_, _, _) = z - member x.Finish rstrs = NoResult } + member _.Start () = NoState + member _.AddText z text = collector text; z + member _.AddBreak rstrs n = collector Literals.lineBreak; collector (tagSpace(spaces n)); rstrs + member _.AddTag z (_, _, _) = z + member _.Finish rstrs = NoResult } /// channel LayoutRenderer diff --git a/src/fsharp/layout.fsi b/src/fsharp/layout.fsi index 88aa8eb35c2..95f81f6cf83 100644 --- a/src/fsharp/layout.fsi +++ b/src/fsharp/layout.fsi @@ -77,8 +77,6 @@ val optionL : ('a -> Layout) -> 'a option -> Layout val listL : ('a -> Layout) -> 'a list -> Layout -val squashTo : int -> Layout -> Layout - val showL : Layout -> string val outL : TextWriter -> Layout -> unit diff --git a/src/fsharp/lex.fsl b/src/fsharp/lex.fsl index f5679b2f585..bbfe3c3c933 100644 --- a/src/fsharp/lex.fsl +++ b/src/fsharp/lex.fsl @@ -46,11 +46,10 @@ module Ranges = /// Get string from lexbuf let lexeme (lexbuf : UnicodeLexing.Lexbuf) = UnicodeLexing.Lexbuf.LexemeString lexbuf -/// Trim n chars from both side of a string -let trimBoth (s:string) n m = s.Substring(n, s.Length - (n+m)) - /// Trim n chars from both sides of lexbuf, return string -let lexemeTrimBoth lexbuf n m = trimBoth (lexeme lexbuf) n m +let lexemeTrimBoth (lexbuf : UnicodeLexing.Lexbuf) (n:int) (m:int) = + let s = lexbuf.LexemeView + s.Slice(n, s.Length - (n+m)).ToString() /// Trim n chars from the right of lexbuf, return string let lexemeTrimRight lexbuf n = lexemeTrimBoth lexbuf 0 n @@ -122,9 +121,9 @@ let lexemeTrimRightToInt32 args lexbuf n = // Checks let checkExprOp (lexbuf:UnicodeLexing.Lexbuf) = - if String.contains (lexeme lexbuf) ':' then + if lexbuf.LexemeContains ':' then deprecatedWithError (FSComp.SR.lexCharNotAllowedInOperatorNames(":")) lexbuf.LexemeRange - if String.contains (lexeme lexbuf) '$' then + if lexbuf.LexemeContains '$' then deprecatedWithError (FSComp.SR.lexCharNotAllowedInOperatorNames("$")) lexbuf.LexemeRange let unexpectedChar lexbuf = diff --git a/src/utils/prim-lexing.fs b/src/utils/prim-lexing.fs index 151052b5f80..401c9852fe0 100644 --- a/src/utils/prim-lexing.fs +++ b/src/utils/prim-lexing.fs @@ -194,13 +194,11 @@ namespace Internal.Utilities.Text.Lexing let mutable startPos = Position.Empty let mutable endPos = Position.Empty - // Throw away all the input besides the lexeme + // Throw away all the input besides the lexeme, which is placed at start of buffer let discardInput () = - let keep = Array.sub buffer bufferScanStart bufferScanLength - let nkeep = keep.Length - Array.blit keep 0 buffer 0 nkeep + Array.blit buffer bufferScanStart buffer 0 bufferScanLength bufferScanStart <- 0 - bufferMaxScanLength <- nkeep + bufferMaxScanLength <- bufferScanLength member lexbuf.EndOfScan () : int = //Printf.eprintf "endOfScan, lexBuffer.lexemeLength = %d\n" lexBuffer.lexemeLength; @@ -221,7 +219,9 @@ namespace Internal.Utilities.Text.Lexing with get() = endPos and set b = endPos <- b - member lexbuf.Lexeme = Array.sub buffer bufferScanStart lexemeLength + member lexbuf.LexemeView = System.ReadOnlySpan<'Char>(buffer, bufferScanStart, lexemeLength) + member lexbuf.LexemeChar n = buffer.[n+bufferScanStart] + member lexbuf.LexemeContains (c:'Char) = array.IndexOf(buffer, c, bufferScanStart, lexemeLength) >= 0 member lexbuf.BufferLocalStore = (context :> IDictionary<_,_>) member lexbuf.LexemeLength with get() : int = lexemeLength and set v = lexemeLength <- v member lexbuf.Buffer with get() : 'Char[] = buffer and set v = buffer <- v diff --git a/src/utils/prim-lexing.fsi b/src/utils/prim-lexing.fsi index b0579d71e2f..957fb698cb3 100644 --- a/src/utils/prim-lexing.fsi +++ b/src/utils/prim-lexing.fsi @@ -96,12 +96,18 @@ type internal LexBuffer<'Char> = /// The end position for the lexeme. member EndPos: Position with get,set - /// The matched string. - member Lexeme: 'Char [] + /// The currently matched text as a Span, it is only valid until the lexer is advanced + member LexemeView: System.ReadOnlySpan<'Char> + + /// Get single character of matched string + member LexemeChar: int -> 'Char + + /// Determine if Lexeme contains a specific character + member LexemeContains: 'Char -> bool /// Fast helper to turn the matched characters into a string, avoiding an intermediate array. static member LexemeString : LexBuffer -> string - + /// Dynamically typed, non-lexically scoped parameter table. member BufferLocalStore : IDictionary diff --git a/src/utils/sformat.fs b/src/utils/sformat.fs index 2c40158c370..ae397492934 100644 --- a/src/utils/sformat.fs +++ b/src/utils/sformat.fs @@ -1,16 +1,12 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -// This file is compiled 3(!) times in the codebase +// This file is compiled twice in the codebase // - as the internal implementation of printf '%A' formatting in FSharp.Core -// - as the internal implementation of structured formatting in the compiler and F# Interactive -// defines: COMPILER +// - as the implementation of structured formatting in the compiler, F# Interactive and FSharp.Compiler.Service. // -// The one implementation file is used because we very much want to keep the implementations of -// structured formatting the same for fsi.exe and '%A' printing. However fsi.exe may have +// The one implementation file is used because we keep the implementations of +// structured formatting the same for fsi.exe and '%A' printing. However F# Interactive has // a richer feature set. -// -// Note no layout objects are ever transferred between the above implementations, and in -// all 4 cases the layout types are really different types. #nowarn "52" // The value has been copied to ensure the original is not mutated by this operation @@ -21,1266 +17,1327 @@ namespace Internal.Utilities.StructuredFormat namespace Microsoft.FSharp.Text.StructuredPrintfImpl #endif - // Breakable block layout implementation. - // This is a fresh implementation of pre-existing ideas. +// Breakable block layout implementation. +// This is a fresh implementation of pre-existing ideas. + +open System +open System.IO +open System.Reflection +open System.Globalization +open System.Collections.Generic +open Microsoft.FSharp.Core +open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators +open Microsoft.FSharp.Reflection +open Microsoft.FSharp.Collections + +[] +type LayoutTag = + | ActivePatternCase + | ActivePatternResult + | Alias + | Class + | Union + | UnionCase + | Delegate + | Enum + | Event + | Field + | Interface + | Keyword + | LineBreak + | Local + | Record + | RecordField + | Method + | Member + | ModuleBinding + | Module + | Namespace + | NumericLiteral + | Operator + | Parameter + | Property + | Space + | StringLiteral + | Struct + | TypeParameter + | Text + | Punctuation + | UnknownType + | UnknownEntity + +type TaggedText = + abstract Tag: LayoutTag + abstract Text: string + +type TaggedTextWriter = + abstract Write: t: TaggedText -> unit + abstract WriteLine: unit -> unit + +/// A joint, between 2 layouts, is either: +/// - unbreakable, or +/// - breakable, and if broken the second block has a given indentation. +[] +type Joint = + | Unbreakable + | Breakable of indentation: int + | Broken of indentation: int + +/// If either juxtaposition flag is true, then no space between words. +[] +type Layout = + | ObjLeaf of juxtLeft: bool * object: obj * juxtRight: bool + | Leaf of juxtLeft: bool * text: TaggedText * justRight: bool + | Node of leftLayout: Layout * rightLayout: Layout * joint: Joint + | Attr of text: string * attributes: (string * string) list * layout: Layout + + member layout.JuxtapositionLeft = + match layout with + | ObjLeaf (jl, _, _) -> jl + | Leaf (jl, _, _) -> jl + | Node (left, _, _) -> left.JuxtapositionLeft + | Attr (_, _, subLayout) -> subLayout.JuxtapositionLeft + + static member JuxtapositionMiddle (left: Layout, right: Layout) = + left.JuxtapositionRight || right.JuxtapositionLeft + + member layout.JuxtapositionRight = + match layout with + | ObjLeaf (_, _, jr) -> jr + | Leaf (_, _, jr) -> jr + | Node (_, right, _) -> right.JuxtapositionRight + | Attr (_, _, subLayout) -> subLayout.JuxtapositionRight + +[] +type IEnvironment = + abstract GetLayout: obj -> Layout + abstract MaxColumns: int + abstract MaxRows: int + +module TaggedTextOps = + let mkTag tag text = + { new TaggedText with + member _.Tag = tag + member _.Text = text } + + let length (tt: TaggedText) = tt.Text.Length + let toText (tt: TaggedText) = tt.Text + + let tagAlias t = mkTag LayoutTag.Alias t + let keywordFunctions = Set ["raise"; "reraise"; "typeof"; "typedefof"; "sizeof"; "nameof"] + let keywordTypes = + [ + "array" + "bigint" + "bool" + "byref" + "byte" + "char" + "decimal" + "double" + "float" + "float32" + "int" + "int8" + "int16" + "int32" + "int64" + "list" + "nativeint" + "obj" + "sbyte" + "seq" + "single" + "string" + "unit" + "uint" + "uint8" + "uint16" + "uint32" + "uint64" + "unativeint" + ] |> Set.ofList + let tagClass name = if Set.contains name keywordTypes then mkTag LayoutTag.Keyword name else mkTag LayoutTag.Class name + let tagUnionCase t = mkTag LayoutTag.UnionCase t + let tagDelegate t = mkTag LayoutTag.Delegate t + let tagEnum t = mkTag LayoutTag.Enum t + let tagEvent t = mkTag LayoutTag.Event t + let tagField t = mkTag LayoutTag.Field t + let tagInterface t = mkTag LayoutTag.Interface t + let tagKeyword t = mkTag LayoutTag.Keyword t + let tagLineBreak t = mkTag LayoutTag.LineBreak t + let tagLocal t = mkTag LayoutTag.Local t + let tagRecord t = mkTag LayoutTag.Record t + let tagRecordField t = mkTag LayoutTag.RecordField t + let tagMethod t = mkTag LayoutTag.Method t + let tagModule t = mkTag LayoutTag.Module t + let tagModuleBinding name = if keywordFunctions.Contains name then mkTag LayoutTag.Keyword name else mkTag LayoutTag.ModuleBinding name + let tagNamespace t = mkTag LayoutTag.Namespace t + let tagNumericLiteral t = mkTag LayoutTag.NumericLiteral t + let tagOperator t = mkTag LayoutTag.Operator t + let tagParameter t = mkTag LayoutTag.Parameter t + let tagProperty t = mkTag LayoutTag.Property t + let tagSpace t = mkTag LayoutTag.Space t + let tagStringLiteral t = mkTag LayoutTag.StringLiteral t + let tagStruct t = mkTag LayoutTag.Struct t + let tagTypeParameter t = mkTag LayoutTag.TypeParameter t + let tagText t = mkTag LayoutTag.Text t + let tagPunctuation t = mkTag LayoutTag.Punctuation t + + module Literals = + // common tagged literals + let lineBreak = tagLineBreak "\n" + let space = tagSpace " " + let comma = tagPunctuation "," + let semicolon = tagPunctuation ";" + let leftParen = tagPunctuation "(" + let rightParen = tagPunctuation ")" + let leftBracket = tagPunctuation "[" + let rightBracket = tagPunctuation "]" + let leftBrace= tagPunctuation "{" + let rightBrace = tagPunctuation "}" + let leftBraceBar = tagPunctuation "{|" + let rightBraceBar = tagPunctuation "|}" + let equals = tagOperator "=" + let arrow = tagPunctuation "->" + let questionMark = tagPunctuation "?" + +module LayoutOps = + open TaggedTextOps - open System - open System.IO - open System.Reflection - open System.Globalization - open System.Collections.Generic - open Microsoft.FSharp.Core - open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators - open Microsoft.FSharp.Reflection - open Microsoft.FSharp.Collections + let mkNode l r joint = + Node(l, r, joint) - [] - type LayoutTag = - | ActivePatternCase - | ActivePatternResult - | Alias - | Class - | Union - | UnionCase - | Delegate - | Enum - | Event - | Field - | Interface - | Keyword - | LineBreak - | Local - | Record - | RecordField - | Method - | Member - | ModuleBinding - | Module - | Namespace - | NumericLiteral - | Operator - | Parameter - | Property - | Space - | StringLiteral - | Struct - | TypeParameter - | Text - | Punctuation - | UnknownType - | UnknownEntity - - type TaggedText = - abstract Tag: LayoutTag - abstract Text: string - - type TaggedTextWriter = - abstract Write: t: TaggedText -> unit - abstract WriteLine: unit -> unit - - /// A joint, between 2 layouts, is either: - /// - unbreakable, or - /// - breakable, and if broken the second block has a given indentation. - [] - type Joint = - | Unbreakable - | Breakable of int - | Broken of int - - /// Leaf juxt,data,juxt - /// Node juxt,left,juxt,right,juxt and joint - /// - /// If either juxt flag is true, then no space between words. - [] - type Layout = - | ObjLeaf of bool * obj * bool - | Leaf of bool * TaggedText * bool - | Node of bool * layout * bool * layout * bool * joint - | Attr of string * (string * string) list * layout + // constructors + let objL (value:obj) = + match value with + | :? string as s -> Leaf (false, mkTag LayoutTag.Text s, false) + | o -> ObjLeaf (false, o, false) - and layout = Layout + let sLeaf (l, t, r) = Leaf (l, t, r) - and joint = Joint + let wordL text = sLeaf (false, text, false) - [] - type IEnvironment = - abstract GetLayout : obj -> layout - abstract MaxColumns : int - abstract MaxRows : int - - module TaggedTextOps = - let tag tag text = - { new TaggedText with - member x.Tag = tag - member x.Text = text } - - let length (tt: TaggedText) = tt.Text.Length - let toText (tt: TaggedText) = tt.Text - - let tagAlias t = tag LayoutTag.Alias t - let keywordFunctions = Set ["raise"; "reraise"; "typeof"; "typedefof"; "sizeof"; "nameof"] - let keywordTypes = - [ - "array" - "bigint" - "bool" - "byref" - "byte" - "char" - "decimal" - "double" - "float" - "float32" - "int" - "int8" - "int16" - "int32" - "int64" - "list" - "nativeint" - "obj" - "sbyte" - "seq" - "single" - "string" - "unit" - "uint" - "uint8" - "uint16" - "uint32" - "uint64" - "unativeint" - ] |> Set.ofList - let tagClass name = if Set.contains name keywordTypes then tag LayoutTag.Keyword name else tag LayoutTag.Class name - let tagUnionCase t = tag LayoutTag.UnionCase t - let tagDelegate t = tag LayoutTag.Delegate t - let tagEnum t = tag LayoutTag.Enum t - let tagEvent t = tag LayoutTag.Event t - let tagField t = tag LayoutTag.Field t - let tagInterface t = tag LayoutTag.Interface t - let tagKeyword t = tag LayoutTag.Keyword t - let tagLineBreak t = tag LayoutTag.LineBreak t - let tagLocal t = tag LayoutTag.Local t - let tagRecord t = tag LayoutTag.Record t - let tagRecordField t = tag LayoutTag.RecordField t - let tagMethod t = tag LayoutTag.Method t - let tagModule t = tag LayoutTag.Module t - let tagModuleBinding name = if keywordFunctions.Contains name then tag LayoutTag.Keyword name else tag LayoutTag.ModuleBinding name - let tagNamespace t = tag LayoutTag.Namespace t - let tagNumericLiteral t = tag LayoutTag.NumericLiteral t - let tagOperator t = tag LayoutTag.Operator t - let tagParameter t = tag LayoutTag.Parameter t - let tagProperty t = tag LayoutTag.Property t - let tagSpace t = tag LayoutTag.Space t - let tagStringLiteral t = tag LayoutTag.StringLiteral t - let tagStruct t = tag LayoutTag.Struct t - let tagTypeParameter t = tag LayoutTag.TypeParameter t - let tagText t = tag LayoutTag.Text t - let tagPunctuation t = tag LayoutTag.Punctuation t - - module Literals = - // common tagged literals - let lineBreak = tagLineBreak "\n" - let space = tagSpace " " - let comma = tagPunctuation "," - let semicolon = tagPunctuation ";" - let leftParen = tagPunctuation "(" - let rightParen = tagPunctuation ")" - let leftBracket = tagPunctuation "[" - let rightBracket = tagPunctuation "]" - let leftBrace= tagPunctuation "{" - let rightBrace = tagPunctuation "}" - let leftBraceBar = tagPunctuation "{|" - let rightBraceBar = tagPunctuation "|}" - let equals = tagOperator "=" - let arrow = tagPunctuation "->" - let questionMark = tagPunctuation "?" - - module LayoutOps = - open TaggedTextOps + let sepL text = sLeaf (true , text, true) - let rec juxtLeft = function - | ObjLeaf (jl,_,_) -> jl - | Leaf (jl,_,_) -> jl - | Node (jl,_,_,_,_,_) -> jl - | Attr (_,_,l) -> juxtLeft l + let rightL text = sLeaf (true , text, false) - let rec juxtRight = function - | ObjLeaf (_,_,jr) -> jr - | Leaf (_,_,jr) -> jr - | Node (_,_,_,_,jr,_) -> jr - | Attr (_,_,l) -> juxtRight l + let leftL text = sLeaf (false, text, true) - let mkNode l r joint = - let jl = juxtLeft l - let jm = juxtRight l || juxtLeft r - let jr = juxtRight r - Node(jl,l,jm,r,jr,joint) + let emptyL = sLeaf (true, mkTag LayoutTag.Text "", true) + let isEmptyL layout = + match layout with + | Leaf(true, s, true) -> s.Text = "" + | _ -> false - // constructors + let aboveL layout1 layout2 = mkNode layout1 layout2 (Broken 0) + let tagAttrL text maps layout = Attr(text, maps, layout) - let objL (value:obj) = - match value with - | :? string as s -> Leaf (false, tag LayoutTag.Text s, false) - | o -> ObjLeaf (false, o, false) + let apply2 f l r = + if isEmptyL l then r + elif isEmptyL r then l + else f l r - let sLeaf (l, t, r) = Leaf (l, t, r) + let (^^) layout1 layout2 = mkNode layout1 layout2 (Unbreakable) - let wordL text = sLeaf (false,text,false) - let sepL text = sLeaf (true ,text,true) - let rightL text = sLeaf (true ,text,false) - let leftL text = sLeaf (false,text,true) + let (++) layout1 layout2 = mkNode layout1 layout2 (Breakable 0) - let emptyL = sLeaf (true, tag LayoutTag.Text "",true) + let (--) layout1 layout2 = mkNode layout1 layout2 (Breakable 1) - let isEmptyL layout = - match layout with - | Leaf(true, s, true) -> s.Text = "" - | _ -> false - - let aboveL layout1 layout2 = mkNode layout1 layout2 (Broken 0) - - let tagAttrL text maps layout = Attr(text,maps,layout) - - let apply2 f l r = if isEmptyL l then r else - if isEmptyL r then l else f l r - - let (^^) layout1 layout2 = mkNode layout1 layout2 (Unbreakable) - let (++) layout1 layout2 = mkNode layout1 layout2 (Breakable 0) - let (--) layout1 layout2 = mkNode layout1 layout2 (Breakable 1) - let (---) layout1 layout2 = mkNode layout1 layout2 (Breakable 2) - let (@@) layout1 layout2 = apply2 (fun l r -> mkNode l r (Broken 0)) layout1 layout2 - let (@@-) layout1 layout2 = apply2 (fun l r -> mkNode l r (Broken 1)) layout1 layout2 - let (@@--) layout1 layout2 = apply2 (fun l r -> mkNode l r (Broken 2)) layout1 layout2 - let tagListL tagger = function - | [] -> emptyL - | [x] -> x - | x :: xs -> - let rec process' prefixL = function - | [] -> prefixL - | y :: ys -> process' ((tagger prefixL) ++ y) ys - process' x xs + let (---) layout1 layout2 = mkNode layout1 layout2 (Breakable 2) + + let (@@) layout1 layout2 = apply2 (fun l r -> mkNode l r (Broken 0)) layout1 layout2 + + let (@@-) layout1 layout2 = apply2 (fun l r -> mkNode l r (Broken 1)) layout1 layout2 + + let (@@--) layout1 layout2 = apply2 (fun l r -> mkNode l r (Broken 2)) layout1 layout2 + + let tagListL tagger els = + match els with + | [] -> emptyL + | [x] -> x + | x :: xs -> + let rec process' prefixL yl = + match yl with + | [] -> prefixL + | y :: ys -> process' (tagger prefixL ++ y) ys + process' x xs - let commaListL layouts = tagListL (fun prefixL -> prefixL ^^ rightL (Literals.comma)) layouts - let semiListL layouts = tagListL (fun prefixL -> prefixL ^^ rightL (Literals.semicolon)) layouts - let spaceListL layouts = tagListL (fun prefixL -> prefixL) layouts - let sepListL layout1 layouts = tagListL (fun prefixL -> prefixL ^^ layout1) layouts - let bracketL layout = leftL Literals.leftParen ^^ layout ^^ rightL Literals.rightParen - let tupleL layouts = bracketL (sepListL (sepL Literals.comma) layouts) - let aboveListL layouts = - match layouts with - | [] -> emptyL - | [x] -> x - | x :: ys -> List.fold (fun pre y -> pre @@ y) x ys - - let optionL selector value = - match value with - | None -> wordL (tagUnionCase "None") - | Some x -> wordL (tagUnionCase "Some") -- (selector x) - - let listL selector value = leftL Literals.leftBracket ^^ sepListL (sepL Literals.semicolon) (List.map selector value) ^^ rightL Literals.rightBracket - - let squareBracketL layout = leftL Literals.leftBracket ^^ layout ^^ rightL Literals.rightBracket - - let braceL layout = leftL Literals.leftBrace ^^ layout ^^ rightL Literals.rightBrace - - let boundedUnfoldL - (itemL : 'a -> layout) - (project : 'z -> ('a * 'z) option) - (stopShort : 'z -> bool) - (z : 'z) - maxLength = - let rec consume n z = + let commaListL layouts = tagListL (fun prefixL -> prefixL ^^ rightL Literals.comma) layouts + + let semiListL layouts = tagListL (fun prefixL -> prefixL ^^ rightL Literals.semicolon) layouts + + let spaceListL layouts = tagListL (fun prefixL -> prefixL) layouts + + let sepListL layout1 layouts = tagListL (fun prefixL -> prefixL ^^ layout1) layouts + + let bracketL layout = leftL Literals.leftParen ^^ layout ^^ rightL Literals.rightParen + + let tupleL layouts = bracketL (sepListL (sepL Literals.comma) layouts) + + let aboveListL layouts = + match layouts with + | [] -> emptyL + | [x] -> x + | x :: ys -> List.fold (fun pre y -> pre @@ y) x ys + + let optionL selector value = + match value with + | None -> wordL (tagUnionCase "None") + | Some x -> wordL (tagUnionCase "Some") -- (selector x) + + let listL selector value = + leftL Literals.leftBracket ^^ sepListL (sepL Literals.semicolon) (List.map selector value) ^^ rightL Literals.rightBracket + + let squareBracketL layout = + leftL Literals.leftBracket ^^ layout ^^ rightL Literals.rightBracket + + let braceL layout = + leftL Literals.leftBrace ^^ layout ^^ rightL Literals.rightBrace + + let boundedUnfoldL + (itemL: 'a -> Layout) + (project: 'z -> ('a * 'z) option) + (stopShort: 'z -> bool) + (z: 'z) + maxLength = + + let rec consume n z = if stopShort z then [wordL (tagPunctuation "...")] else match project z with - | None -> [] // exhausted input - | Some (x,z) -> if n<=0 then [wordL (tagPunctuation "...")] // hit print_length limit - else itemL x :: consume (n-1) z // cons recursive... - consume maxLength z + | None -> [] // exhausted input + | Some (x, z) -> if n<=0 then [wordL (tagPunctuation "...")] // hit print_length limit + else itemL x :: consume (n-1) z // cons recursive... + consume maxLength z - let unfoldL selector folder state count = boundedUnfoldL selector folder (fun _ -> false) state count + let unfoldL selector folder state count = + boundedUnfoldL selector folder (fun _ -> false) state count - /// These are a typical set of options used to control structured formatting. - [] - type FormatOptions = - { FloatingPointFormat: string; - AttributeProcessor: (string -> (string * string) list -> bool -> unit); +/// These are a typical set of options used to control structured formatting. +[] +type FormatOptions = + { FloatingPointFormat: string + AttributeProcessor: (string -> (string * string) list -> bool -> unit) #if COMPILER // This is the PrintIntercepts extensibility point currently revealed by fsi.exe's AddPrinter - PrintIntercepts: (IEnvironment -> obj -> Layout option) list; - StringLimit : int; + PrintIntercepts: (IEnvironment -> obj -> Layout option) list + StringLimit: int #endif - FormatProvider: System.IFormatProvider; - BindingFlags: System.Reflection.BindingFlags - PrintWidth : int; - PrintDepth : int; - PrintLength : int; - PrintSize : int; - ShowProperties : bool; - ShowIEnumerable: bool; } - static member Default = - { FormatProvider = (System.Globalization.CultureInfo.InvariantCulture :> System.IFormatProvider); + FormatProvider: IFormatProvider + BindingFlags: BindingFlags + PrintWidth: int + PrintDepth: int + PrintLength: int + PrintSize: int + ShowProperties: bool + ShowIEnumerable: bool + } + + static member Default = + { FormatProvider = (CultureInfo.InvariantCulture :> IFormatProvider) #if COMPILER // This is the PrintIntercepts extensibility point currently revealed by fsi.exe's AddPrinter - PrintIntercepts = []; - StringLimit = System.Int32.MaxValue; + PrintIntercepts = [] + StringLimit = Int32.MaxValue #endif - AttributeProcessor= (fun _ _ _ -> ()); - BindingFlags = System.Reflection.BindingFlags.Public; - FloatingPointFormat = "g10"; - PrintWidth = 80 ; - PrintDepth = 100 ; - PrintLength = 100; - PrintSize = 10000; - ShowProperties = false; - ShowIEnumerable = true; } - - - - module ReflectUtils = - - [] - type TypeInfo = - | TupleType of Type list - | FunctionType of Type * Type - | RecordType of (string * Type) list - | SumType of (string * (string * Type) list) list - | UnitType - | ObjectType of Type - - let isNamedType (ty:Type) = not (ty.IsArray || ty.IsByRef || ty.IsPointer) - let equivHeadTypes (ty1:Type) (ty2:Type) = - isNamedType(ty1) && - if ty1.IsGenericType then - ty2.IsGenericType && (ty1.GetGenericTypeDefinition()).Equals(ty2.GetGenericTypeDefinition()) - else - ty1.Equals(ty2) - - let option = typedefof - let func = typedefof<(obj -> obj)> - - let isOptionTy ty = equivHeadTypes ty (typeof) - let isUnitType ty = equivHeadTypes ty (typeof) - let isListType ty = - FSharpType.IsUnion ty && - (let cases = FSharpType.GetUnionCases ty - cases.Length > 0 && equivHeadTypes (typedefof>) cases.[0].DeclaringType) - - [] - type TupleType = - | Value - | Reference - - [] - type ValueInfo = - | TupleValue of TupleType * (obj * Type) list - | FunctionClosureValue of System.Type - | RecordValue of (string * obj * Type) list - | ConstructorValue of declaringType: Type option * string * (string * (obj * Type)) list - | ExceptionValue of System.Type * (string * (obj * Type)) list - | UnitValue - | ObjectValue of obj - - module Value = - - // Returns true if a given type has the RequireQualifiedAccess attribute - let private requiresQualifiedAccess (declaringType:Type) = - let rqaAttr = declaringType.GetCustomAttribute(typeof, false) - isNull rqaAttr |> not - - // Analyze an object to see if it the representation - // of an F# value. - let GetValueInfoOfObject (bindingFlags:BindingFlags) (obj : obj) = - match obj with - | null -> ObjectValue(obj) - | _ -> - let reprty = obj.GetType() - - // First a bunch of special rules for tuples - // Because of the way F# currently compiles tuple values - // of size > 7 we can only reliably reflect on sizes up - // to 7. - - if FSharpType.IsTuple reprty then - let tyArgs = FSharpType.GetTupleElements(reprty) - let fields = FSharpValue.GetTupleFields obj |> Array.mapi (fun i v -> (v, tyArgs.[i])) |> Array.toList - let tupleType = - if reprty.Name.StartsWith "ValueTuple" then TupleType.Value - else TupleType.Reference - TupleValue (tupleType, fields) - elif FSharpType.IsFunction reprty then - FunctionClosureValue reprty + AttributeProcessor= (fun _ _ _ -> ()) + BindingFlags = BindingFlags.Public + FloatingPointFormat = "g10" + PrintWidth = 80 + PrintDepth = 100 + PrintLength = 100 + PrintSize = 10000 + ShowProperties = false + ShowIEnumerable = true + } + +module ReflectUtils = + + [] + type TypeInfo = + | TupleType of Type list + | FunctionType of Type * Type + | RecordType of (string * Type) list + | SumType of (string * (string * Type) list) list + | UnitType + | ObjectType of Type + + let isNamedType (ty:Type) = not (ty.IsArray || ty.IsByRef || ty.IsPointer) + + let equivHeadTypes (ty1:Type) (ty2:Type) = + isNamedType(ty1) && + if ty1.IsGenericType then + ty2.IsGenericType && (ty1.GetGenericTypeDefinition()).Equals(ty2.GetGenericTypeDefinition()) + else + ty1.Equals(ty2) + + let option = typedefof + + let func = typedefof<(obj -> obj)> + + let isOptionTy ty = equivHeadTypes ty (typeof) + + let isUnitType ty = equivHeadTypes ty (typeof) + + let isListType ty = + FSharpType.IsUnion ty && + (let cases = FSharpType.GetUnionCases ty + cases.Length > 0 && equivHeadTypes (typedefof>) cases.[0].DeclaringType) + + [] + type TupleType = + | Value + | Reference + + [] + type ValueInfo = + | TupleValue of TupleType * (obj * Type)[] + | FunctionClosureValue of Type + | RecordValue of (string * obj * Type)[] + | UnionCaseValue of declaringType: Type option * string * (string * (obj * Type))[] + | ExceptionValue of Type * (string * (obj * Type))[] + | NullValue + | UnitValue + | ObjectValue of obj + + module Value = + + // Returns true if a given type has the RequireQualifiedAccess attribute + let private requiresQualifiedAccess (declaringType: Type) = + let rqaAttr = declaringType.GetCustomAttribute(typeof, false) + isNull rqaAttr |> not + + // Analyze an object to see if it the representation + // of an F# value. + let GetValueInfoOfObject (bindingFlags: BindingFlags) (obj: obj) = + match obj with + | null -> NullValue + | _ -> + let reprty = obj.GetType() + + // First a bunch of special rules for tuples + // Because of the way F# currently compiles tuple values + // of size > 7 we can only reliably reflect on sizes up + // to 7. + + if FSharpType.IsTuple reprty then + let tyArgs = FSharpType.GetTupleElements(reprty) + let fields = FSharpValue.GetTupleFields obj |> Array.mapi (fun i v -> (v, tyArgs.[i])) + let tupleType = + if reprty.Name.StartsWith "ValueTuple" then TupleType.Value + else TupleType.Reference + TupleValue (tupleType, fields) + + elif FSharpType.IsFunction reprty then + FunctionClosureValue reprty - // It must be exception, abstract, record or union. - // Either way we assume the only properties defined on - // the type are the actual fields of the type. Again, - // we should be reading attributes here that indicate the - // true structure of the type, e.g. the order of the fields. - elif FSharpType.IsUnion(reprty,bindingFlags) then - let tag,vals = FSharpValue.GetUnionFields (obj,reprty,bindingFlags) - let props = tag.GetFields() - let pvals = (props,vals) ||> Array.map2 (fun prop v -> prop.Name,(v, prop.PropertyType)) + // It must be exception, abstract, record or union. + // Either way we assume the only properties defined on + // the type are the actual fields of the type. Again, + // we should be reading attributes here that indicate the + // true structure of the type, e.g. the order of the fields. + elif FSharpType.IsUnion(reprty, bindingFlags) then + let tag, vals = FSharpValue.GetUnionFields (obj, reprty, bindingFlags) + let props = tag.GetFields() + let pvals = (props, vals) ||> Array.map2 (fun prop v -> prop.Name, (v, prop.PropertyType)) + let declaringType = + if requiresQualifiedAccess tag.DeclaringType then Some tag.DeclaringType + else None + UnionCaseValue(declaringType, tag.Name, pvals) + + elif FSharpType.IsExceptionRepresentation(reprty, bindingFlags) then + let props = FSharpType.GetExceptionFields(reprty, bindingFlags) + let vals = FSharpValue.GetExceptionFields(obj, bindingFlags) + let pvals = (props, vals) ||> Array.map2 (fun prop v -> prop.Name, (v, prop.PropertyType)) + ExceptionValue(reprty, pvals) + + elif FSharpType.IsRecord(reprty, bindingFlags) then + let props = FSharpType.GetRecordFields(reprty, bindingFlags) + RecordValue(props |> Array.map (fun prop -> prop.Name, prop.GetValue (obj, null), prop.PropertyType)) + else + ObjectValue(obj) + + // This one is like the above but can make use of additional + // statically-known type information to aid in the + // analysis of null values. + + let GetValueInfo bindingFlags (x: 'a, ty: Type) (* x could be null *) = + let obj = (box x) + match obj with + | null -> + let isNullaryUnion = + match ty.GetCustomAttributes(typeof, false) with + | [|:? CompilationRepresentationAttribute as attr|] -> + (attr.Flags &&& CompilationRepresentationFlags.UseNullAsTrueValue) = CompilationRepresentationFlags.UseNullAsTrueValue + | _ -> false + if isNullaryUnion then + let nullaryCase = FSharpType.GetUnionCases ty |> Array.filter (fun uc -> uc.GetFields().Length = 0) |> Array.item 0 let declaringType = - if requiresQualifiedAccess tag.DeclaringType then Some tag.DeclaringType + if requiresQualifiedAccess ty then Some ty else None - ConstructorValue(declaringType, tag.Name, Array.toList pvals) - elif FSharpType.IsExceptionRepresentation(reprty,bindingFlags) then - let props = FSharpType.GetExceptionFields(reprty,bindingFlags) - let vals = FSharpValue.GetExceptionFields(obj,bindingFlags) - let pvals = (props,vals) ||> Array.map2 (fun prop v -> prop.Name,(v, prop.PropertyType)) - ExceptionValue(reprty, pvals |> Array.toList) - elif FSharpType.IsRecord(reprty,bindingFlags) then - let props = FSharpType.GetRecordFields(reprty,bindingFlags) - RecordValue(props |> Array.map (fun prop -> prop.Name, prop.GetValue(obj,null), prop.PropertyType) |> Array.toList) - else - ObjectValue(obj) + UnionCaseValue(declaringType, nullaryCase.Name, [| |]) + elif isUnitType ty then UnitValue + else NullValue + | _ -> + GetValueInfoOfObject bindingFlags (obj) - // This one is like the above but can make use of additional - // statically-known type information to aid in the - // analysis of null values. +module Display = - let GetValueInfo bindingFlags (x : 'a, ty : Type) (* x could be null *) = - let obj = (box x) - match obj with - | null -> - let isNullaryUnion = - match ty.GetCustomAttributes(typeof, false) with - | [|:? CompilationRepresentationAttribute as attr|] -> - (attr.Flags &&& CompilationRepresentationFlags.UseNullAsTrueValue) = CompilationRepresentationFlags.UseNullAsTrueValue - | _ -> false - if isNullaryUnion then - let nullaryCase = FSharpType.GetUnionCases ty |> Array.filter (fun uc -> uc.GetFields().Length = 0) |> Array.item 0 - let declaringType = - if requiresQualifiedAccess ty then Some ty - else None - ConstructorValue(declaringType, nullaryCase.Name, []) - elif isUnitType ty then UnitValue - else ObjectValue(obj) - | _ -> - GetValueInfoOfObject bindingFlags (obj) - - module Display = - - open ReflectUtils - open LayoutOps - open TaggedTextOps - - let string_of_int (i:int) = i.ToString() - - let typeUsesSystemObjectToString (ty:System.Type) = - try - let methInfo = ty.GetMethod("ToString",BindingFlags.Public ||| BindingFlags.Instance,null,[| |],null) - methInfo.DeclaringType = typeof - with e -> false - /// If "str" ends with "ending" then remove it from "str", otherwise no change. - let trimEnding (ending:string) (str:string) = - if str.EndsWith(ending,StringComparison.Ordinal) then - str.Substring(0,str.Length - ending.Length) - else str - - let catchExn f = try Choice1Of2 (f ()) with e -> Choice2Of2 e - - // An implementation of break stack. - // Uses mutable state, relying on linear threading of the state. - - [] - type Breaks = - Breaks of - int * // pos of next free slot - int * // pos of next possible "outer" break - OR - outer=next if none possible - int array // stack of savings, -ve means it has been broken - - // next is next slot to push into - aka size of current occupied stack. - // outer counts up from 0, and is next slot to break if break forced. - // - if all breaks forced, then outer=next. - // - popping under these conditions needs to reduce outer and next. + open ReflectUtils + open LayoutOps + open TaggedTextOps + + let string_of_int (i:int) = i.ToString() + + let typeUsesSystemObjectToString (ty:System.Type) = + try + let methInfo = ty.GetMethod("ToString", BindingFlags.Public ||| BindingFlags.Instance, null, [| |], null) + methInfo.DeclaringType = typeof + with _e -> false + + /// If "str" ends with "ending" then remove it from "str", otherwise no change. + let trimEnding (ending:string) (str:string) = + if str.EndsWith(ending, StringComparison.Ordinal) then + str.Substring(0, str.Length - ending.Length) + else str + + let catchExn f = try Choice1Of2 (f ()) with e -> Choice2Of2 e + + // An implementation of break stack. + // Uses mutable state, relying on linear threading of the state. + + [] + type Breaks = + Breaks of + /// pos of next free slot + nextFreeSlot: int * + /// pos of next possible "outer" break - OR - outer=next if none possible + nextOuterBreak: int * + /// stack of savings, -ve means it has been broken + savingsStack: int[] + + // next is next slot to push into - aka size of current occupied stack. + // outer counts up from 0, and is next slot to break if break forced. + // - if all breaks forced, then outer=next. + // - popping under these conditions needs to reduce outer and next. + let chunkN = 400 + let breaks0 () = Breaks(0, 0, Array.create chunkN 0) - //let dumpBreaks prefix (Breaks(next,outer,stack)) = () - // printf "%s: next=%d outer=%d stack.Length=%d\n" prefix next outer stack.Length; - // stdout.Flush() - - let chunkN = 400 - let breaks0 () = Breaks(0,0,Array.create chunkN 0) - - let pushBreak saving (Breaks(next,outer,stack)) = - //dumpBreaks "pushBreak" (next,outer,stack); - let stack = - if next = stack.Length then - Array.init (next + chunkN) (fun i -> if i < next then stack.[i] else 0) // expand if full - else - stack - - stack.[next] <- saving; - Breaks(next+1,outer,stack) - - let popBreak (Breaks(next,outer,stack)) = - //dumpBreaks "popBreak" (next,outer,stack); - if next=0 then raise (Failure "popBreak: underflow"); - let topBroke = stack.[next-1] < 0 - let outer = if outer=next then outer-1 else outer // if all broken, unwind - let next = next - 1 - Breaks(next,outer,stack),topBroke - - let forceBreak (Breaks(next,outer,stack)) = - //dumpBreaks "forceBreak" (next,outer,stack); - if outer=next then - // all broken - None + let pushBreak saving (Breaks(next, outer, stack)) = + let stack = + if next = stack.Length then + Array.init (next + chunkN) (fun i -> if i < next then stack.[i] else 0) // expand if full else - let saving = stack.[outer] - stack.[outer] <- -stack.[outer]; - let outer = outer+1 - Some (Breaks(next,outer,stack),saving) - - // ------------------------------------------------------------------------- - // fitting - // ------------------------------------------------------------------------ - - let squashTo (maxWidth,leafFormatter : _ -> TaggedText) layout = - let (|ObjToTaggedText|) = leafFormatter - if maxWidth <= 0 then layout else - let rec fit breaks (pos,layout) = - // breaks = break context, can force to get indentation savings. - // pos = current position in line - // layout = to fit - //------ - // returns: - // breaks - // layout - with breaks put in to fit it. - // pos - current pos in line = rightmost position of last line of block. - // offset - width of last line of block - // NOTE: offset <= pos -- depending on tabbing of last block + stack + + stack.[next] <- saving; + Breaks(next+1, outer, stack) + + let popBreak (Breaks(next, outer, stack)) = + if next=0 then raise (Failure "popBreak: underflow"); + let topBroke = stack.[next-1] < 0 + let outer = if outer=next then outer-1 else outer // if all broken, unwind + let next = next - 1 + Breaks(next, outer, stack), topBroke + + let forceBreak (Breaks(next, outer, stack)) = + if outer=next then + // all broken + None + else + let saving = stack.[outer] + stack.[outer] <- -stack.[outer]; + let outer = outer+1 + Some (Breaks(next, outer, stack), saving) + + /// fitting + let squashToAux (maxWidth, leafFormatter: _ -> TaggedText) layout = + let (|ObjToTaggedText|) = leafFormatter + if maxWidth <= 0 then layout else + let rec fit breaks (pos, layout) = + // breaks = break context, can force to get indentation savings. + // pos = current position in line + // layout = to fit + //------ + // returns: + // breaks + // layout - with breaks put in to fit it. + // pos - current pos in line = rightmost position of last line of block. + // offset - width of last line of block + // NOTE: offset <= pos -- depending on tabbing of last block - let breaks,layout,pos,offset = - match layout with - | Attr (tag,attrs,l) -> - let breaks,layout,pos,offset = fit breaks (pos,l) - let layout = Attr (tag,attrs,layout) - breaks,layout,pos,offset - | Leaf (jl, text, jr) - | ObjLeaf (jl, ObjToTaggedText text, jr) -> - // save the formatted text from the squash - let layout = Leaf(jl, text, jr) - let textWidth = length text - let rec fitLeaf breaks pos = - if pos + textWidth <= maxWidth then - breaks,layout,pos + textWidth,textWidth // great, it fits - else - match forceBreak breaks with - | None -> - breaks,layout,pos + textWidth,textWidth // tough, no more breaks - | Some (breaks,saving) -> - let pos = pos - saving - fitLeaf breaks pos + let breaks, layout, pos, offset = + match layout with + | Attr (tag, attrs, l) -> + let breaks, layout, pos, offset = fit breaks (pos, l) + let layout = Attr (tag, attrs, layout) + breaks, layout, pos, offset + + | Leaf (jl, text, jr) + | ObjLeaf (jl, ObjToTaggedText text, jr) -> + // save the formatted text from the squash + let layout = Leaf(jl, text, jr) + let textWidth = length text + let rec fitLeaf breaks pos = + if pos + textWidth <= maxWidth then + breaks, layout, pos + textWidth, textWidth // great, it fits + else + match forceBreak breaks with + | None -> + breaks, layout, pos + textWidth, textWidth // tough, no more breaks + | Some (breaks, saving) -> + let pos = pos - saving + fitLeaf breaks pos - fitLeaf breaks pos - | Node (jl,l,jm,r,jr,joint) -> - let mid = if jm then 0 else 1 - match joint with - | Unbreakable -> - let breaks,l,pos,offsetl = fit breaks (pos,l) // fit left - let pos = pos + mid // fit space if juxt says so - let breaks,r,pos,offsetr = fit breaks (pos,r) // fit right - breaks,Node (jl,l,jm,r,jr,Unbreakable),pos,offsetl + mid + offsetr - | Broken indent -> - let breaks,l,pos,offsetl = fit breaks (pos,l) // fit left - let pos = pos - offsetl + indent // broken so - offset left + ident - let breaks,r,pos,offsetr = fit breaks (pos,r) // fit right - breaks,Node (jl,l,jm,r,jr,Broken indent),pos,indent + offsetr - | Breakable indent -> - let breaks,l,pos,offsetl = fit breaks (pos,l) // fit left - // have a break possibility, with saving - let saving = offsetl + mid - indent - let pos = pos + mid - if saving>0 then - let breaks = pushBreak saving breaks - let breaks,r,pos,offsetr = fit breaks (pos,r) - let breaks,broken = popBreak breaks - if broken then - breaks,Node (jl,l,jm,r,jr,Broken indent) ,pos,indent + offsetr - else - breaks,Node (jl,l,jm,r,jr,Breakable indent),pos,offsetl + mid + offsetr + fitLeaf breaks pos + + | Node (l, r, joint) -> + let jm = Layout.JuxtapositionMiddle (l, r) + let mid = if jm then 0 else 1 + match joint with + | Unbreakable -> + let breaks, l, pos, offsetl = fit breaks (pos, l) // fit left + let pos = pos + mid // fit space if juxt says so + let breaks, r, pos, offsetr = fit breaks (pos, r) // fit right + breaks, Node (l, r, Unbreakable), pos, offsetl + mid + offsetr + + | Broken indent -> + let breaks, l, pos, offsetl = fit breaks (pos, l) // fit left + let pos = pos - offsetl + indent // broken so - offset left + ident + let breaks, r, pos, offsetr = fit breaks (pos, r) // fit right + breaks, Node (l, r, Broken indent), pos, indent + offsetr + + | Breakable indent -> + let breaks, l, pos, offsetl = fit breaks (pos, l) // fit left + // have a break possibility, with saving + let saving = offsetl + mid - indent + let pos = pos + mid + if saving>0 then + let breaks = pushBreak saving breaks + let breaks, r, pos, offsetr = fit breaks (pos, r) + let breaks, broken = popBreak breaks + if broken then + breaks, Node (l, r, Broken indent) , pos, indent + offsetr else - // actually no saving so no break - let breaks,r,pos,offsetr = fit breaks (pos,r) - breaks,Node (jl,l,jm,r,jr,Breakable indent) ,pos,offsetl + mid + offsetr + breaks, Node (l, r, Breakable indent), pos, offsetl + mid + offsetr + else + // actually no saving so no break + let breaks, r, pos, offsetr = fit breaks (pos, r) + breaks, Node (l, r, Breakable indent) , pos, offsetl + mid + offsetr - //printf "\nDone: pos=%d offset=%d" pos offset; - breaks,layout,pos,offset + //printf "\nDone: pos=%d offset=%d" pos offset; + breaks, layout, pos, offset - let breaks = breaks0 () - let pos = 0 - let _,layout,_,_ = fit breaks (pos,layout) - layout - - // ------------------------------------------------------------------------- - // showL - // ------------------------------------------------------------------------ - - let combine (strs: string list) = System.String.Concat strs - let showL opts leafFormatter layout = - let push x rstrs = x :: rstrs - let z0 = [],0 - let addText (rstrs,i) (text:string) = push text rstrs,i + text.Length - let index (_,i) = i - let extract rstrs = combine(List.rev rstrs) - let newLine (rstrs,_) n = // \n then spaces... - let indent = new System.String(' ', n) - let rstrs = push "\n" rstrs - let rstrs = push indent rstrs - rstrs,n - - // addL: pos is tab level - let rec addL z pos layout = - match layout with - | ObjLeaf (_,obj,_) -> - let text = leafFormatter obj - addText z text - | Leaf (_,obj,_) -> - addText z obj.Text - | Node (_,l,_,r,_,Broken indent) - // Print width = 0 implies 1D layout, no squash - when not (opts.PrintWidth = 0) -> - let z = addL z pos l - let z = newLine z (pos+indent) - let z = addL z (pos+indent) r - z - | Node (_,l,jm,r,_,_) -> - let z = addL z pos l - let z = if jm then z else addText z " " - let pos = index z - let z = addL z pos r - z - | Attr (_,_,l) -> - addL z pos l + let breaks = breaks0 () + let pos = 0 + let _, layout, _, _ = fit breaks (pos, layout) + layout + + let combine (strs: string list) = String.Concat strs + + let showL opts leafFormatter layout = + let push x rstrs = x :: rstrs + let z0 = [], 0 + let addText (rstrs, i) (text:string) = push text rstrs, i + text.Length + let index (_, i) = i + let extract rstrs = combine(List.rev rstrs) + let newLine (rstrs, _) n = // \n then spaces... + let indent = new String(' ', n) + let rstrs = push "\n" rstrs + let rstrs = push indent rstrs + rstrs, n + + // addL: pos is tab level + let rec addL z pos layout = + match layout with + | ObjLeaf (_, obj, _) -> + let text = leafFormatter obj + addText z text + + | Leaf (_, obj, _) -> + addText z obj.Text + + | Node (l, r, Broken indent) + // Print width = 0 implies 1D layout, no squash + when not (opts.PrintWidth = 0) -> + let z = addL z pos l + let z = newLine z (pos+indent) + let z = addL z (pos+indent) r + z + + | Node (l, r, _) -> + let jm = Layout.JuxtapositionMiddle (l, r) + let z = addL z pos l + let z = if jm then z else addText z " " + let pos = index z + let z = addL z pos r + z + + | Attr (_, _, l) -> + addL z pos l - let rstrs,_ = addL z0 0 layout - extract rstrs - - - // ------------------------------------------------------------------------- - // outL - // ------------------------------------------------------------------------ - - let outL outAttribute leafFormatter (chan : TaggedTextWriter) layout = - // write layout to output chan directly - let write s = chan.Write(s) - // z is just current indent - let z0 = 0 - let index i = i - let addText z text = write text; (z + length text) - let newLine _ n = // \n then spaces... - let indent = new System.String(' ',n) - chan.WriteLine(); - write (tagText indent); - n + let rstrs, _ = addL z0 0 layout + extract rstrs + + let outL outAttribute leafFormatter (chan: TaggedTextWriter) layout = + // write layout to output chan directly + let write s = chan.Write(s) + // z is just current indent + let z0 = 0 + let index i = i + let addText z text = write text; (z + length text) + let newLine _ n = // \n then spaces... + let indent = new String(' ', n) + chan.WriteLine(); + write (tagText indent); + n - // addL: pos is tab level - let rec addL z pos layout = - match layout with - | ObjLeaf (_,obj,_) -> - let text = leafFormatter obj - addText z text - | Leaf (_,obj,_) -> - addText z obj - | Node (_,l,_,r,_,Broken indent) -> - let z = addL z pos l - let z = newLine z (pos+indent) - let z = addL z (pos+indent) r - z - | Node (_,l,jm,r,_,_) -> - let z = addL z pos l - let z = if jm then z else addText z Literals.space - let pos = index z - let z = addL z pos r - z - | Attr (tag,attrs,l) -> + // addL: pos is tab level + let rec addL z pos layout = + match layout with + | ObjLeaf (_, obj, _) -> + let text = leafFormatter obj + addText z text + | Leaf (_, obj, _) -> + addText z obj + | Node (l, r, Broken indent) -> + let z = addL z pos l + let z = newLine z (pos+indent) + let z = addL z (pos+indent) r + z + | Node (l, r, _) -> + let jm = Layout.JuxtapositionMiddle (l, r) + let z = addL z pos l + let z = if jm then z else addText z Literals.space + let pos = index z + let z = addL z pos r + z + | Attr (tag, attrs, l) -> let _ = outAttribute tag attrs true let z = addL z pos l let _ = outAttribute tag attrs false z - let _ = addL z0 0 layout - () + let _ = addL z0 0 layout + () - // -------------------------------------------------------------------- - // pprinter: using general-purpose reflection... - // -------------------------------------------------------------------- - - let getValueInfo bindingFlags (x:'a, ty:Type) = Value.GetValueInfo bindingFlags (x, ty) + let unpackCons recd = + match recd with + | [|(_, h);(_, t)|] -> (h, t) + | _ -> failwith "unpackCons" - let unpackCons recd = - match recd with - | [(_,h);(_,t)] -> (h,t) - | _ -> failwith "unpackCons" + let getListValueInfo bindingFlags (x:obj, ty:Type) = + match x with + | null -> None + | _ -> + match Value.GetValueInfo bindingFlags (x, ty) with + | UnionCaseValue (_, "Cons", recd) -> Some (unpackCons recd) + | UnionCaseValue (_, "Empty", [| |]) -> None + | _ -> failwith "List value had unexpected ValueInfo" - let getListValueInfo bindingFlags (x:obj, ty:Type) = - match x with - | null -> None - | _ -> - match getValueInfo bindingFlags (x, ty) with - | ConstructorValue (_,"Cons",recd) -> Some (unpackCons recd) - | ConstructorValue (_,"Empty",[]) -> None - | _ -> failwith "List value had unexpected ValueInfo" - - let structL = wordL (tagKeyword "struct") - let nullL = wordL (tagKeyword "null") - let measureL = wordL (tagPunctuation "()") - - // -------------------------------------------------------------------- - // pprinter: attributes - // -------------------------------------------------------------------- + let structL = wordL (tagKeyword "struct") - let makeRecordL nameXs = - let itemL (name,xL) = wordL name ^^ wordL Literals.equals -- xL - let braceL xs = (wordL Literals.leftBrace) ^^ xs ^^ (wordL Literals.rightBrace) + let nullL = wordL (tagKeyword "null") + + let unitL = wordL (tagPunctuation "()") + + let makeRecordL nameXs = + let itemL (name, xL) = wordL name ^^ wordL Literals.equals -- xL + let braceL xs = (wordL Literals.leftBrace) ^^ xs ^^ (wordL Literals.rightBrace) - nameXs - |> List.map itemL - |> aboveListL - |> braceL - - let makePropertiesL nameXs = - let itemL (name,v) = - let labelL = wordL name - (labelL ^^ wordL Literals.equals) - ^^ (match v with - | None -> wordL Literals.questionMark - | Some xL -> xL) - ^^ (rightL Literals.semicolon) - let braceL xs = (leftL Literals.leftBrace) ^^ xs ^^ (rightL Literals.rightBrace) - braceL (aboveListL (List.map itemL nameXs)) - - let makeListL itemLs = - (leftL Literals.leftBracket) - ^^ sepListL (rightL Literals.semicolon) itemLs - ^^ (rightL Literals.rightBracket) - - let makeArrayL xs = - (leftL (tagPunctuation "[|")) - ^^ sepListL (rightL Literals.semicolon) xs - ^^ (rightL (tagPunctuation "|]")) - - let makeArray2L xs = leftL Literals.leftBracket ^^ aboveListL xs ^^ rightL Literals.rightBracket - - // -------------------------------------------------------------------- - // pprinter: anyL - support functions - // -------------------------------------------------------------------- - - let getProperty (ty: Type) (obj: obj) name = - ty.InvokeMember(name, (BindingFlags.GetProperty ||| BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic), null, obj, [| |],CultureInfo.InvariantCulture) - - let getField obj (fieldInfo: FieldInfo) = - fieldInfo.GetValue(obj) - - let formatChar isChar c = - match c with - | '\'' when isChar -> "\\\'" - | '\"' when not isChar -> "\\\"" - //| '\n' -> "\\n" - //| '\r' -> "\\r" - //| '\t' -> "\\t" - | '\\' -> "\\\\" - | '\b' -> "\\b" - | _ when System.Char.IsControl(c) -> - let d1 = (int c / 100) % 10 - let d2 = (int c / 10) % 10 - let d3 = int c % 10 - "\\" + d1.ToString() + d2.ToString() + d3.ToString() - | _ -> c.ToString() + nameXs + |> List.map itemL + |> aboveListL + |> braceL + + let makePropertiesL nameXs = + let itemL (name, v) = + let labelL = wordL name + (labelL ^^ wordL Literals.equals) + ^^ (match v with + | None -> wordL Literals.questionMark + | Some xL -> xL) + ^^ (rightL Literals.semicolon) + let braceL xs = (leftL Literals.leftBrace) ^^ xs ^^ (rightL Literals.rightBrace) + braceL (aboveListL (List.map itemL nameXs)) + + let makeListL itemLs = + (leftL Literals.leftBracket) + ^^ sepListL (rightL Literals.semicolon) itemLs + ^^ (rightL Literals.rightBracket) + + let makeArrayL xs = + (leftL (tagPunctuation "[|")) + ^^ sepListL (rightL Literals.semicolon) xs + ^^ (rightL (tagPunctuation "|]")) + + let makeArray2L xs = leftL Literals.leftBracket ^^ aboveListL xs ^^ rightL Literals.rightBracket + + let getProperty (ty: Type) (obj: obj) name = + ty.InvokeMember(name, (BindingFlags.GetProperty ||| BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic), null, obj, [| |],CultureInfo.InvariantCulture) + + let getField obj (fieldInfo: FieldInfo) = + fieldInfo.GetValue(obj) + + let formatChar isChar c = + match c with + | '\'' when isChar -> "\\\'" + | '\"' when not isChar -> "\\\"" + | '\\' -> "\\\\" + | '\b' -> "\\b" + | _ when System.Char.IsControl(c) -> + let d1 = (int c / 100) % 10 + let d2 = (int c / 10) % 10 + let d3 = int c % 10 + "\\" + d1.ToString() + d2.ToString() + d3.ToString() + | _ -> c.ToString() - let formatString (s:string) = - let rec check i = i < s.Length && not (System.Char.IsControl(s,i)) && s.[i] <> '\"' && check (i+1) - let rec conv i acc = if i = s.Length then combine (List.rev acc) else conv (i+1) (formatChar false s.[i] :: acc) - "\"" + s + "\"" - // REVIEW: should we check for the common case of no control characters? Reinstate the following? - //"\"" + (if check 0 then s else conv 0 []) + "\"" - - let formatStringInWidth (width:int) (str:string) = - // Return a truncated version of the string, e.g. - // "This is the initial text, which has been truncated"+[12 chars] - // - // Note: The layout code forces breaks based on leaf size and possible break points. - // It does not force leaf size based on width. - // So long leaf-string width can not depend on their printing context... - // - // The suffix like "+[dd chars]" is 11 chars. - // 12345678901 - let suffixLength = 11 // turning point suffix length - let prefixMinLength = 12 // arbitrary. If print width is reduced, want to print a minimum of information on strings... - let prefixLength = max (width - 2 (*quotes*) - suffixLength) prefixMinLength - "\"" + (str.Substring(0,prefixLength)) + "\"" + "+[" + (str.Length - prefixLength).ToString() + " chars]" - - // -------------------------------------------------------------------- - // pprinter: anyL - // -------------------------------------------------------------------- + let formatString (s:string) = + let rec check i = i < s.Length && not (System.Char.IsControl(s,i)) && s.[i] <> '\"' && check (i+1) + let rec conv i acc = if i = s.Length then combine (List.rev acc) else conv (i+1) (formatChar false s.[i] :: acc) + "\"" + s + "\"" + + // Return a truncated version of the string, e.g. + // "This is the initial text, which has been truncated"+[12 chars] + // + // Note: The layout code forces breaks based on leaf size and possible break points. + // It does not force leaf size based on width. + // So long leaf-string width can not depend on their printing context... + // + // The suffix like "+[dd chars]" is 11 chars. + // 12345678901 + let formatStringInWidth (width:int) (str:string) = + let suffixLength = 11 // turning point suffix length + let prefixMinLength = 12 // arbitrary. If print width is reduced, want to print a minimum of information on strings... + let prefixLength = max (width - 2 (*quotes*) - suffixLength) prefixMinLength + "\"" + (str.Substring(0,prefixLength)) + "\"" + "+[" + (str.Length - prefixLength).ToString() + " chars]" - type Precedence = - | BracketIfTupleOrNotAtomic = 2 - | BracketIfTuple = 3 - | NeverBracket = 4 - - // In fsi.exe, certain objects are not printed for top-level bindings. - [] - type ShowMode = - | ShowAll - | ShowTopLevelBinding - - // polymorphic and inner recursion limitations prevent us defining polyL in the recursive loop - let polyL bindingFlags (objL: ShowMode -> int -> Precedence -> ValueInfo -> obj -> Layout) showMode i prec (x:'a ,ty : Type) (* x could be null *) = - objL showMode i prec (getValueInfo bindingFlags (x, ty)) (box x) - - let anyL showMode bindingFlags (opts:FormatOptions) (x:'a, ty:Type) = - // showMode = ShowTopLevelBinding on the outermost expression when called from fsi.exe, - // This allows certain outputs, e.g. objects that would print as to be suppressed, etc. See 4343. - // Calls to layout proper sub-objects should pass showMode = ShowAll. - - // Precedences to ensure we add brackets in the right places + type Precedence = + | BracketIfTupleOrNotAtomic = 2 + | BracketIfTuple = 3 + | NeverBracket = 4 + + // In fsi.exe, certain objects are not printed for top-level bindings. + [] + type ShowMode = + | ShowAll + | ShowTopLevelBinding + + let isSetOrMapType (ty:Type) = + ty.IsGenericType && + (ty.GetGenericTypeDefinition() = typedefof> + || ty.GetGenericTypeDefinition() = typedefof>) + + // showMode = ShowTopLevelBinding on the outermost expression when called from fsi.exe, + // This allows certain outputs, e.g. objects that would print as to be suppressed, etc. See 4343. + // Calls to layout proper sub-objects should pass showMode = ShowAll. + // + // Precedences to ensure we add brackets in the right places + type ObjectGraphFormatter(opts: FormatOptions, bindingFlags) = - // Keep a record of objects encountered along the way - let path = Dictionary(10,HashIdentity.Reference) - - // Roughly count the "nodes" printed, e.g. leaf items and inner nodes, but not every bracket and comma. - let mutable size = opts.PrintSize - let exceededPrintSize() = size<=0 - let countNodes n = if size > 0 then size <- size - n else () // no need to keep decrementing (and avoid wrap around) - let stopShort _ = exceededPrintSize() // for unfoldL - - // Recursive descent - let rec objL depthLim prec (x:obj, ty:Type) = polyL bindingFlags objWithReprL ShowAll depthLim prec (x, ty) // showMode for inner expr - and sameObjL depthLim prec (x:obj, ty:Type) = polyL bindingFlags objWithReprL showMode depthLim prec (x, ty) // showMode preserved - - and objWithReprL showMode depthLim prec (info:ValueInfo) (x:obj) (* x could be null *) = - try - if depthLim<=0 || exceededPrintSize() then wordL (tagPunctuation "...") else - match x with - | null -> + // Keep a record of objects encountered along the way + let path = Dictionary(10,HashIdentity.Reference) + + // Roughly count the "nodes" printed, e.g. leaf items and inner nodes, but not every bracket and comma. + let mutable size = opts.PrintSize + let exceededPrintSize() = size<=0 + let countNodes n = if size > 0 then size <- size - n else () // no need to keep decrementing (and avoid wrap around) + let stopShort _ = exceededPrintSize() // for unfoldL + + // Recursive descent + let rec nestedObjL depthLim prec (x:obj, ty:Type) = + objL ShowAll depthLim prec (x, ty) + + and objL showMode depthLim prec (x:obj, ty:Type) = + let info = Value.GetValueInfo bindingFlags (x, ty) + try + if depthLim<=0 || exceededPrintSize() then wordL (tagPunctuation "...") else + match x with + | null -> reprL showMode (depthLim-1) prec info x - | _ -> + | _ -> if (path.ContainsKey(x)) then - wordL (tagPunctuation "...") + wordL (tagPunctuation "...") else - path.Add(x,0); + path.Add(x,0) + let res = - // Lazy values. VS2008 used StructuredFormatDisplayAttribute to show via ToString. Dev10 (no attr) needs a special case. - let ty = x.GetType() - if ty.IsGenericType && ty.GetGenericTypeDefinition() = typedefof> then - Some (wordL (tagText(x.ToString()))) - else - // Try the StructuredFormatDisplayAttribute extensibility attribute - match ty.GetCustomAttributes (typeof, true) with - | null | [| |] -> None - | res -> - let attr = (res.[0] :?> StructuredFormatDisplayAttribute) - let txt = attr.Value - if isNull txt || txt.Length <= 1 then - None - else - let messageRegexPattern = @"^(?
.*?)(?.*?)(?.*)$"
-                                  let illFormedBracketPattern = @"(?  
-                                        // there isn't a match on the regex looking for a property, so now let's make sure we don't have an ill-formed format string (i.e. mismatched/stray brackets)
-                                        let illFormedMatch = System.Text.RegularExpressions.Regex.IsMatch(txt, illFormedBracketPattern)
-                                        match illFormedMatch with
-                                        | true -> None // there are mismatched brackets, bail out
-                                        | false when layouts.Length > 1 -> Some (spaceListL (List.rev ((wordL (tagText(replaceEscapedBrackets(txt))) :: layouts))))
-                                        | false -> Some (wordL (tagText(replaceEscapedBrackets(txt))))
-                                      | true ->
-                                        // we have a hit on a property reference
-                                        let preText = replaceEscapedBrackets(m.Groups.["pre"].Value) // everything before the first opening bracket
-                                        let postText = m.Groups.["post"].Value // Everything after the closing bracket
-                                        let prop = replaceEscapedBrackets(m.Groups.["prop"].Value) // Unescape everything between the opening and closing brackets
-
-                                        match catchExn (fun () -> getProperty ty x prop) with
-                                          | Choice2Of2 e -> Some (wordL (tagText("")))
-                                          | Choice1Of2 alternativeObj ->
-                                              try 
-                                                  let alternativeObjL = 
-                                                    match alternativeObj with 
-                                                        // A particular rule is that if the alternative property
-                                                        // returns a string, we turn off auto-quoting and escaping of
-                                                        // the string, i.e. just treat the string as display text.
-                                                        // This allows simple implementations of 
-                                                        // such as
-                                                        //
-                                                        //    []
-                                                        //    type BigInt(signInt:int, v : BigNat) =
-                                                        //        member x.StructuredDisplayString = x.ToString()
-                                                        //
-                                                        | :? string as s -> sepL (tagText s)
-                                                        | _ -> 
-                                                          // recursing like this can be expensive, so let's throttle it severely
-                                                          sameObjL (depthLim/10) Precedence.BracketIfTuple (alternativeObj, alternativeObj.GetType())
-                                                  countNodes 0 // 0 means we do not count the preText and postText 
-
-                                                  let postTextMatch = System.Text.RegularExpressions.Regex.Match(postText, messageRegexPattern)
-                                                  // the postText for this node will be everything up to the next occurrence of an opening brace, if one exists
-                                                  let currentPostText =
-                                                    match postTextMatch.Success with
-                                                      | false -> postText 
-                                                      | true -> postTextMatch.Groups.["pre"].Value
-
-                                                  let newLayouts = (sepL (tagText preText) ^^ alternativeObjL ^^ sepL (tagText currentPostText)) :: layouts
-                                                  match postText with
-                                                    | "" ->
-                                                      //We are done, build a space-delimited layout from the collection of layouts we've accumulated
-                                                      Some (spaceListL (List.rev newLayouts))
-                                                    | remainingPropertyText when postTextMatch.Success ->
-                                                      
-                                                      // look for stray brackets in the text before the next opening bracket
-                                                      let strayClosingMatch = System.Text.RegularExpressions.Regex.IsMatch(postTextMatch.Groups.["pre"].Value, illFormedBracketPattern)
-                                                      match strayClosingMatch with
-                                                      | true -> None
-                                                      | false -> 
-                                                        // More to process, keep going, using the postText starting at the next instance of a '{'
-                                                        let openingBracketIndex = postTextMatch.Groups.["prop"].Index-1
-                                                        buildObjMessageL remainingPropertyText.[openingBracketIndex..] newLayouts
-                                                    | remaingPropertyText ->
-                                                      // make sure we don't have any stray brackets
-                                                      let strayClosingMatch = System.Text.RegularExpressions.Regex.IsMatch(remaingPropertyText, illFormedBracketPattern)
-                                                      match strayClosingMatch with
-                                                      | true -> None
-                                                      | false ->
-                                                        // We are done, there's more text but it doesn't contain any more properties, we need to remove escaped brackets now though
-                                                        // since that wasn't done when creating currentPostText
-                                                        Some (spaceListL (List.rev ((sepL (tagText preText) ^^ alternativeObjL ^^ sepL (tagText(replaceEscapedBrackets(remaingPropertyText)))) :: layouts)))
-                                              with _ -> 
-                                                None
-                                  // Seed with an empty layout with a space to the left for formatting purposes
-                                  buildObjMessageL txt [leftL (tagText "")] 
-#if COMPILER    // This is the PrintIntercepts extensibility point currently revealed by fsi.exe's AddPrinter
+                            // Lazy values. VS2008 used StructuredFormatDisplayAttribute to show via ToString. Dev10 (no attr) needs a special case.
+                            let ty = x.GetType()
+                            if ty.IsGenericType && ty.GetGenericTypeDefinition() = typedefof> then
+                                Some (wordL (tagText(x.ToString())))
+                            else
+                                // Try the StructuredFormatDisplayAttribute extensibility attribute
+                                match ty.GetCustomAttributes (typeof, true) with
+                                | null | [| |] -> None
+                                | res -> 
+                                structuredFormatObjectL showMode ty depthLim (res.[0] :?> StructuredFormatDisplayAttribute) x
+
+#if COMPILER
+                        // This is the PrintIntercepts extensibility point currently revealed by fsi.exe's AddPrinter
                         let res = 
                             match res with 
                             | Some _ -> res
                             | None -> 
-                                let env = { new IEnvironment with
-                                                member env.GetLayout(y) = objL (depthLim-1) Precedence.BracketIfTuple (y, y.GetType()) 
-                                                member env.MaxColumns = opts.PrintLength
-                                                member env.MaxRows = opts.PrintLength }
+                                let env = 
+                                    { new IEnvironment with
+                                        member _.GetLayout(y) = nestedObjL (depthLim-1) Precedence.BracketIfTuple (y, y.GetType()) 
+                                        member _.MaxColumns = opts.PrintLength
+                                        member _.MaxRows = opts.PrintLength }
                                 opts.PrintIntercepts |> List.tryPick (fun intercept -> intercept env x)
 #endif
                         let res = 
                             match res with 
                             | Some res -> res
-                            | None     -> reprL showMode (depthLim-1) prec info x
-                        path .Remove(x) |> ignore;
+                            | None -> reprL showMode (depthLim-1) prec info x
+
+                        path.Remove(x) |> ignore
                         res
-                with
-                  e ->
-                    countNodes 1
-                    wordL (tagText("Error: " + e.Message))
-
-            and recdAtomicTupleL depthLim recd =
-                // tuples up args to UnionConstruction or ExceptionConstructor. no node count.
-                match recd with 
-                | [(_,x)] -> objL depthLim Precedence.BracketIfTupleOrNotAtomic x 
-                | txs     -> leftL Literals.leftParen ^^ commaListL (List.map (snd >> objL depthLim Precedence.BracketIfTuple) txs) ^^ rightL Literals.rightParen
-
-            and bracketIfL b basicL =
-                if b then (leftL Literals.leftParen) ^^ basicL ^^ (rightL Literals.rightParen) else basicL
-
-            and reprL showMode depthLim prec repr x (* x could be null *) =
-                let showModeFilter lay = match showMode with ShowAll -> lay | ShowTopLevelBinding -> emptyL                                                             
-                match repr with
-                | TupleValue (tupleType, vals) ->
-                    let basicL = sepListL (rightL Literals.comma) (List.map (objL depthLim Precedence.BracketIfTuple ) vals)
-                    let fields = bracketIfL (prec <= Precedence.BracketIfTuple) basicL
-                    match tupleType with
-                    | TupleType.Value -> structL ^^ fields
-                    | TupleType.Reference -> fields
-
-                | RecordValue items -> 
-                    let itemL (name,x,ty) =
-                      countNodes 1 // record labels are counted as nodes. [REVIEW: discussion under 4090].
-                      (tagRecordField name,objL depthLim Precedence.BracketIfTuple (x, ty))
-                    makeRecordL (List.map itemL items)
-
-                | ConstructorValue (_,constr,recd) when // x is List. Note: "null" is never a valid list value. 
-                                                      x<>null && isListType (x.GetType()) ->
-                    match constr with 
-                    | "Cons" -> 
-                        let (x,xs) = unpackCons recd
-                        let project xs = getListValueInfo bindingFlags xs
-                        let itemLs = objL depthLim Precedence.BracketIfTuple x :: boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) project stopShort xs (opts.PrintLength - 1)
-                        makeListL itemLs
-                    | _ ->
-                        countNodes 1
-                        wordL (tagPunctuation "[]")
-
-                | ConstructorValue(declaringType,nm,recd)   ->
-                    countNodes 1
-                    let caseName =
-                        match declaringType with
-                        | None ->
-                            wordL (tagMethod nm)
-                        | Some declaringType ->
-                            wordL (tagClass declaringType.Name) ^^ sepL (tagPunctuation ".") ^^ wordL (tagMethod nm)
-                    match recd with
-                    | [] -> caseName
-                    | recd -> (caseName --- recdAtomicTupleL depthLim recd) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
-
-                | ExceptionValue(ty,recd) ->
-                    countNodes 1
-                    let name = ty.Name 
-                    match recd with
-                      | []   -> (wordL (tagClass name))
-                      | recd -> (wordL (tagClass name) --- recdAtomicTupleL depthLim recd) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
+            with
+                e ->
+                countNodes 1
+                wordL (tagText("Error: " + e.Message))
+
+        // Format an object that has a layout specified by StructuredFormatAttribute
+        and structuredFormatObjectL showMode ty depthLim (attr: StructuredFormatDisplayAttribute) (obj: obj) =
+            let txt = attr.Value
+            if isNull txt || txt.Length <= 1 then  
+                None
+            else
+            let messageRegexPattern = @"^(?
.*?)(?.*?)(?.*)$"
+            let illFormedBracketPattern = @"(?
-                    // Q: should function printing include the ty.Name? It does not convey much useful info to most users, e.g. "clo@0_123".    
-                    countNodes 1
-                    wordL (tagText("")) |> showModeFilter
-
-                | ObjectValue(obj)  ->
-                    match obj with 
-                    | null ->
-                        countNodes 1
-                        // If this is the root element, wrap the null with angle brackets
-                        if depthLim = opts.PrintDepth - 1 then
-                            wordL (tagText "")
-                        else nullL
-                    | _ -> 
-                    let ty = obj.GetType()
-                    match obj with 
-                    | :? string as s ->
-                        countNodes 1
+            let rec buildObjMessageL (txt:string) (layouts:Layout list) =
+                                    
+                let replaceEscapedBrackets (txt:string) =
+                    txt.Replace("\{", "{").Replace("\}", "}")
+                                      
+                // to simplify support for escaped brackets, switch to using a Regex to simply parse the text as the following regex groups:
+                //  1) Everything up to the first opening bracket not preceded by a "\", lazily
+                //  2) Everything between that opening bracket and a closing bracket not preceded by a "\", lazily
+                //  3) Everything after that closing bracket
+                let m = System.Text.RegularExpressions.Regex.Match(txt, messageRegexPattern)
+                if not m.Success then 
+                    // there isn't a match on the regex looking for a property, so now let's make sure we don't have an ill-formed format string (i.e. mismatched/stray brackets)
+                    let illFormedMatch = System.Text.RegularExpressions.Regex.IsMatch(txt, illFormedBracketPattern)
+                    if illFormedMatch then 
+                        None // there are mismatched brackets, bail out
+                    elif layouts.Length > 1 then Some (spaceListL (List.rev ((wordL (tagText(replaceEscapedBrackets(txt))) :: layouts))))
+                    else Some (wordL (tagText(replaceEscapedBrackets(txt))))
+                else
+                    // we have a hit on a property reference
+                    let preText = replaceEscapedBrackets(m.Groups.["pre"].Value) // everything before the first opening bracket
+                    let postText = m.Groups.["post"].Value // Everything after the closing bracket
+                    let prop = replaceEscapedBrackets(m.Groups.["prop"].Value) // Unescape everything between the opening and closing brackets
+
+                    match catchExn (fun () -> getProperty ty obj prop) with
+                    | Choice2Of2 e -> Some (wordL (tagText("")))
+                    | Choice1Of2 alternativeObj ->
+                        try 
+                            let alternativeObjL = 
+                                match alternativeObj with 
+                                // A particular rule is that if the alternative property
+                                // returns a string, we turn off auto-quoting and escaping of
+                                // the string, i.e. just treat the string as display text.
+                                // This allows simple implementations of 
+                                // such as
+                                //
+                                //    []
+                                //    type BigInt(signInt:int, v: BigNat) =
+                                //        member x.StructuredDisplayString = x.ToString()
+                                //
+                                | :? string as s -> sepL (tagText s)
+                                | _ -> 
+                                    // recursing like this can be expensive, so let's throttle it severely
+                                    objL showMode (depthLim/10) Precedence.BracketIfTuple (alternativeObj, alternativeObj.GetType())
+                            countNodes 0 // 0 means we do not count the preText and postText 
+
+                            let postTextMatch = System.Text.RegularExpressions.Regex.Match(postText, messageRegexPattern)
+                            // the postText for this node will be everything up to the next occurrence of an opening brace, if one exists
+                            let currentPostText =
+                                match postTextMatch.Success with
+                                | false -> postText 
+                                | true -> postTextMatch.Groups.["pre"].Value
+
+                            let newLayouts = (sepL (tagText preText) ^^ alternativeObjL ^^ sepL (tagText currentPostText)) :: layouts
+                            match postText with
+                            | "" ->
+                                //We are done, build a space-delimited layout from the collection of layouts we've accumulated
+                                Some (spaceListL (List.rev newLayouts))
+
+                            | remainingPropertyText when postTextMatch.Success ->
+                                                      
+                                // look for stray brackets in the text before the next opening bracket
+                                let strayClosingMatch = System.Text.RegularExpressions.Regex.IsMatch(postTextMatch.Groups.["pre"].Value, illFormedBracketPattern)
+                                if strayClosingMatch then
+                                    None
+                                else 
+                                    // More to process, keep going, using the postText starting at the next instance of a '{'
+                                    let openingBracketIndex = postTextMatch.Groups.["prop"].Index-1
+                                    buildObjMessageL remainingPropertyText.[openingBracketIndex..] newLayouts
+
+                            | remaingPropertyText ->
+                                // make sure we don't have any stray brackets
+                                let strayClosingMatch = System.Text.RegularExpressions.Regex.IsMatch(remaingPropertyText, illFormedBracketPattern)
+                                if strayClosingMatch then
+                                    None
+                                else
+                                    // We are done, there's more text but it doesn't contain any more properties, we need to remove escaped brackets now though
+                                    // since that wasn't done when creating currentPostText
+                                    Some (spaceListL (List.rev ((sepL (tagText preText) ^^ alternativeObjL ^^ sepL (tagText(replaceEscapedBrackets(remaingPropertyText)))) :: layouts)))
+                        with _ -> 
+                            None
+
+            // Seed with an empty layout with a space to the left for formatting purposes
+            buildObjMessageL txt [leftL (tagText "")] 
+
+        and recdAtomicTupleL depthLim recd =
+            // tuples up args to UnionConstruction or ExceptionConstructor. no node count.
+            match recd with 
+            | [(_,x)] -> nestedObjL depthLim Precedence.BracketIfTupleOrNotAtomic x 
+            | txs -> leftL Literals.leftParen ^^ commaListL (List.map (snd >> nestedObjL depthLim Precedence.BracketIfTuple) txs) ^^ rightL Literals.rightParen
+
+        and bracketIfL flag basicL =
+            if flag then (leftL Literals.leftParen) ^^ basicL ^^ (rightL Literals.rightParen) else basicL
+
+        and tupleValueL depthLim prec vals tupleType =
+            let basicL = sepListL (rightL Literals.comma) (List.map (nestedObjL depthLim Precedence.BracketIfTuple ) (Array.toList vals))
+            let fields = bracketIfL (prec <= Precedence.BracketIfTuple) basicL
+            match tupleType with
+            | TupleType.Value -> structL ^^ fields
+            | TupleType.Reference -> fields
+
+        and recordValueL depthLim items =
+            let itemL (name, x, ty) =
+                countNodes 1
+                tagRecordField name,nestedObjL depthLim Precedence.BracketIfTuple (x, ty)
+            makeRecordL (List.map itemL items)
+
+        and listValueL depthLim constr recd =
+            match constr with 
+            | "Cons" -> 
+                let (x,xs) = unpackCons recd
+                let project xs = getListValueInfo bindingFlags xs
+                let itemLs = nestedObjL depthLim Precedence.BracketIfTuple x :: boundedUnfoldL (nestedObjL depthLim Precedence.BracketIfTuple) project stopShort xs (opts.PrintLength - 1)
+                makeListL itemLs
+            | _ ->
+                countNodes 1
+                wordL (tagPunctuation "[]")
+
+        and unionCaseValueL depthLim prec (declaringType: Type option) unionCaseName recd =
+            countNodes 1
+            let caseName =
+                match declaringType with
+                | None ->
+                    wordL (tagMethod unionCaseName)
+                | Some declaringType ->
+                    wordL (tagClass declaringType.Name) ^^ sepL (tagPunctuation ".") ^^ wordL (tagMethod unionCaseName)
+            match recd with
+            | [] -> caseName
+            | recd -> (caseName --- recdAtomicTupleL depthLim recd) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
+
+        and fsharpExceptionL depthLim prec (exceptionType: Type) recd =
+            countNodes 1
+            let name = exceptionType.Name 
+            match recd with
+            | [] -> (wordL (tagClass name))
+            | recd -> (wordL (tagClass name) --- recdAtomicTupleL depthLim recd) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
+
+        and showModeFilter showMode layout =
+            match showMode with
+            | ShowAll -> layout
+            | ShowTopLevelBinding -> emptyL                                                             
+
+        and functionClosureL showMode (closureType: Type) =
+            // Q: should function printing include the ty.Name? It does not convey much useful info to most users, e.g. "clo@0_123".    
+            countNodes 1
+            wordL (tagText("")) |> showModeFilter showMode
+
+        and stringValueL (s: string) =
+            countNodes 1
 #if COMPILER  
-                        if s.Length + 2(*quotes*) <= opts.StringLimit then
-                           // With the quotes, it fits within the limit.
-                           wordL (tagStringLiteral(formatString s))
-                        else
-                           // When a string is considered too long to print, there is a choice: what to print?
-                           // a)             -- follows 
-                           // b)      -- follows  and gives just the length
-                           // c) "abcdefg"+[n chars] -- gives a prefix and the remaining chars
-                           wordL (tagStringLiteral(formatStringInWidth opts.StringLimit s))
+            if s.Length + 2(*quotes*) <= opts.StringLimit then
+                // With the quotes, it fits within the limit.
+                wordL (tagStringLiteral(formatString s))
+            else
+                // When a string is considered too long to print, there is a choice: what to print?
+                // a)             -- follows 
+                // b)      -- follows  and gives just the length
+                // c) "abcdefg"+[n chars] -- gives a prefix and the remaining chars
+                wordL (tagStringLiteral(formatStringInWidth opts.StringLimit s))
 #else
-                        wordL (tagStringLiteral (formatString s))  
-#endif                        
-                    | :? Array as arr -> 
-                        let ty = arr.GetType().GetElementType()
-                        match arr.Rank with
-                        | 1 -> 
-                             let n = arr.Length
-                             let b1 = arr.GetLowerBound(0) 
-                             let project depthLim = if depthLim=(b1+n) then None else Some ((box (arr.GetValue(depthLim)), ty),depthLim+1)
-                             let itemLs = boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) project stopShort b1 opts.PrintLength
-                             makeArrayL (if b1 = 0 then itemLs else wordL (tagText("bound1="+string_of_int b1)) :: itemLs)
-                        | 2 -> 
-                             let n1 = arr.GetLength(0)
-                             let n2 = arr.GetLength(1)
-                             let b1 = arr.GetLowerBound(0) 
-                             let b2 = arr.GetLowerBound(1) 
-                             let project2 x y =
-                               if x>=(b1+n1) || y>=(b2+n2) then None
-                               else Some ((box (arr.GetValue(x,y)), ty),y+1)
-                             let rowL x = boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) (project2 x) stopShort b2 opts.PrintLength |> makeListL
-                             let project1 x = if x>=(b1+n1) then None else Some (x,x+1)
-                             let rowsL  = boundedUnfoldL rowL project1 stopShort b1 opts.PrintLength
-                             makeArray2L (if b1=0 && b2 = 0 then rowsL else wordL (tagText("bound1=" + string_of_int b1)) :: wordL(tagText("bound2=" + string_of_int b2)) :: rowsL)
-                          | n -> 
-                             makeArrayL [wordL (tagText("rank=" + string_of_int n))]
+            wordL (tagStringLiteral (formatString s))  
+#endif                   
+
+        and arrayValueL depthLim (arr: Array) =
+            let ty = arr.GetType().GetElementType()
+            match arr.Rank with
+            | 1 -> 
+                let n = arr.Length
+                let b1 = arr.GetLowerBound(0) 
+                let project depthLim = if depthLim=(b1+n) then None else Some ((box (arr.GetValue(depthLim)), ty),depthLim+1)
+                let itemLs = boundedUnfoldL (nestedObjL depthLim Precedence.BracketIfTuple) project stopShort b1 opts.PrintLength
+                makeArrayL (if b1 = 0 then itemLs else wordL (tagText("bound1="+string_of_int b1)) :: itemLs)
+            | 2 -> 
+                let n1 = arr.GetLength(0)
+                let n2 = arr.GetLength(1)
+                let b1 = arr.GetLowerBound(0) 
+                let b2 = arr.GetLowerBound(1) 
+                let project2 x y =
+                    if x>=(b1+n1) || y>=(b2+n2) then None
+                    else Some ((box (arr.GetValue(x,y)), ty),y+1)
+                let rowL x = boundedUnfoldL (nestedObjL depthLim Precedence.BracketIfTuple) (project2 x) stopShort b2 opts.PrintLength |> makeListL
+                let project1 x = if x>=(b1+n1) then None else Some (x,x+1)
+                let rowsL = boundedUnfoldL rowL project1 stopShort b1 opts.PrintLength
+                makeArray2L (if b1=0 && b2 = 0 then rowsL else wordL (tagText("bound1=" + string_of_int b1)) :: wordL(tagText("bound2=" + string_of_int b2)) :: rowsL)
+            | n -> 
+                makeArrayL [wordL (tagText("rank=" + string_of_int n))]
                         
-                    // Format 'set' and 'map' nicely
-                    | _ when  
-                          (ty.IsGenericType && (ty.GetGenericTypeDefinition() = typedefof> 
-                                                || ty.GetGenericTypeDefinition() = typedefof>) ) ->
-                         let word = if ty.GetGenericTypeDefinition() = typedefof> then "map" else "set"
-                         let possibleKeyValueL v = 
-                             let tyv = v.GetType()
-                             if word = "map" &&
-                                (match v with null -> false | _ -> true) && 
-                                tyv.IsGenericType && 
-                                tyv.GetGenericTypeDefinition() = typedefof> then
-                                  objL depthLim Precedence.BracketIfTuple ((tyv.GetProperty("Key").GetValue(v, [| |]), 
-                                                                            tyv.GetProperty("Value").GetValue(v, [| |])), tyv)
-                             else
-                                  objL depthLim Precedence.BracketIfTuple (v, tyv)
-                         let it = (obj :?>  System.Collections.IEnumerable).GetEnumerator() 
-                         try 
-                           let itemLs = boundedUnfoldL possibleKeyValueL (fun () -> if it.MoveNext() then Some(it.Current,()) else None) stopShort () (1+opts.PrintLength/12)
-                           (wordL (tagClass word) --- makeListL itemLs) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
-                         finally 
-                            match it with 
-                            | :? System.IDisposable as e -> e.Dispose()
-                            | _ -> ()
-
-                    | :? System.Collections.IEnumerable as ie ->
-                         let showContent = 
-                            // do not display content of IQueryable since its execution may take significant time
-                            opts.ShowIEnumerable && (ie.GetType().GetInterfaces() |> Array.exists(fun ty -> ty.FullName = "System.Linq.IQueryable") |> not)
-
-                         if showContent then
-                           let word = "seq"
-                           let it = ie.GetEnumerator() 
-                           let ty = ie.GetType().GetInterfaces() |> Array.filter (fun ty -> ty.IsGenericType && ty.Name = "IEnumerable`1") |> Array.tryItem 0
-                           let ty = Option.map (fun (ty:Type) -> ty.GetGenericArguments().[0]) ty
-                           try 
-                             let itemLs = boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) (fun () -> if it.MoveNext() then Some((it.Current, match ty with | None -> it.Current.GetType() | Some ty -> ty),()) else None) stopShort () (1+opts.PrintLength/30)
-                             (wordL (tagClass word) --- makeListL itemLs) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
-                           finally 
-                              match it with 
-                              | :? System.IDisposable as e -> e.Dispose()
-                              | _ -> ()
+        and mapSetValueL depthLim prec (ty: Type) (obj: obj) =
+            let word = if ty.GetGenericTypeDefinition() = typedefof> then "map" else "set"
+            let possibleKeyValueL v = 
+                let tyv = v.GetType()
+                if word = "map" &&
+                    (match v with null -> false | _ -> true) && 
+                    tyv.IsGenericType && 
+                    tyv.GetGenericTypeDefinition() = typedefof> then
+                    nestedObjL depthLim Precedence.BracketIfTuple ((tyv.GetProperty("Key").GetValue(v, [| |]), 
+                                                                    tyv.GetProperty("Value").GetValue(v, [| |])), tyv)
+                else
+                    nestedObjL depthLim Precedence.BracketIfTuple (v, tyv)
+            let it = (obj :?>  System.Collections.IEnumerable).GetEnumerator() 
+            try 
+                let itemLs = boundedUnfoldL possibleKeyValueL (fun () -> if it.MoveNext() then Some(it.Current,()) else None) stopShort () (1+opts.PrintLength/12)
+                (wordL (tagClass word) --- makeListL itemLs) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
+            finally 
+                match it with 
+                | :? System.IDisposable as e -> e.Dispose()
+                | _ -> ()
+
+        and sequenceValueL showMode depthLim prec (ie: System.Collections.IEnumerable) =
+            let showContent = 
+                // do not display content of IQueryable since its execution may take significant time
+                opts.ShowIEnumerable && (ie.GetType().GetInterfaces() |> Array.exists(fun ty -> ty.FullName = "System.Linq.IQueryable") |> not)
+
+            if showContent then
+                let word = "seq"
+                let it = ie.GetEnumerator() 
+                let ty = ie.GetType().GetInterfaces() |> Array.filter (fun ty -> ty.IsGenericType && ty.Name = "IEnumerable`1") |> Array.tryItem 0
+                let ty = Option.map (fun (ty:Type) -> ty.GetGenericArguments().[0]) ty
+                try 
+                    let itemLs = boundedUnfoldL (nestedObjL depthLim Precedence.BracketIfTuple) (fun () -> if it.MoveNext() then Some((it.Current, match ty with | None -> it.Current.GetType() | Some ty -> ty),()) else None) stopShort () (1+opts.PrintLength/30)
+                    (wordL (tagClass word) --- makeListL itemLs) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
+                finally 
+                    match it with 
+                    | :? System.IDisposable as e -> e.Dispose()
+                    | _ -> ()
                              
-                         else
-                           // Sequence printing is turned off for declared-values, and maybe be disabled to users.
-                           // There is choice here, what to print?  or ... or ?
-                           // Also, in the declared values case, if the sequence is actually a known non-lazy type (list, array etc etc) we could print it.  
-                           wordL (tagText "") |> showModeFilter
-                    | _ ->
-                         if showMode = ShowTopLevelBinding && typeUsesSystemObjectToString ty then
-                           emptyL
-                         else
-                           countNodes 1
-                           let basicL = LayoutOps.objL obj  // This buries an obj in the layout, rendered at squash time via a leafFormatter.
-                                                            // If the leafFormatter was directly here, then layout leaves could store strings.
-                           match obj with 
-                           | _ when opts.ShowProperties ->
-                              let props = ty.GetProperties(BindingFlags.GetField ||| BindingFlags.Instance ||| BindingFlags.Public)
-                              let fields = ty.GetFields(BindingFlags.Instance ||| BindingFlags.Public) |> Array.map (fun i -> i :> MemberInfo)
-                              let propsAndFields = 
-                                props |> Array.map (fun i -> i :> MemberInfo)
-                                      |> Array.append fields
-                                      |> Array.filter (fun pi ->
-                                    // check if property is annotated with System.Diagnostics.DebuggerBrowsable(Never). 
-                                    // Its evaluation may have unexpected side effects and\or block printing.
-                                    match Seq.toArray (pi.GetCustomAttributes(typeof, false)) with
-                                    | [|:? System.Diagnostics.DebuggerBrowsableAttribute as attr |] -> attr.State <> System.Diagnostics.DebuggerBrowsableState.Never
-                                    | _ -> true
-                                )
-
-                              // massively reign in deep printing of properties 
-                              let nDepth = depthLim/10
+            else
+                // Sequence printing is turned off for declared-values, and maybe be disabled to users.
+                // There is choice here, what to print?  or ... or ?
+                // Also, in the declared values case, if the sequence is actually a known non-lazy type (list, array etc etc) we could print it.  
+                wordL (tagText "") |> showModeFilter showMode
+
+        and objectValueWithPropertiesL depthLim (ty: Type) (obj: obj) =
+
+            // This buries an obj in the layout, rendered at squash time via a leafFormatter.
+            let basicL = LayoutOps.objL obj
+            let props = ty.GetProperties(BindingFlags.GetField ||| BindingFlags.Instance ||| BindingFlags.Public)
+            let fields = ty.GetFields(BindingFlags.Instance ||| BindingFlags.Public) |> Array.map (fun i -> i :> MemberInfo)
+            let propsAndFields = 
+                props |> Array.map (fun i -> i :> MemberInfo)
+                        |> Array.append fields
+                        |> Array.filter (fun pi ->
+                    // check if property is annotated with System.Diagnostics.DebuggerBrowsable(Never). 
+                    // Its evaluation may have unexpected side effects and\or block printing.
+                    match Seq.toArray (pi.GetCustomAttributes(typeof, false)) with
+                    | [|:? System.Diagnostics.DebuggerBrowsableAttribute as attr |] -> attr.State <> System.Diagnostics.DebuggerBrowsableState.Never
+                    | _ -> true
+                )
+
+            // massively reign in deep printing of properties 
+            let nDepth = depthLim/10
 #if NETSTANDARD
-                              Array.Sort((propsAndFields),{ new IComparer with member this.Compare(p1,p2) = compare (p1.Name) (p2.Name) } )
+            Array.Sort((propsAndFields),{ new IComparer with member this.Compare(p1,p2) = compare (p1.Name) (p2.Name) } )
 #else
-                              Array.Sort((propsAndFields :> Array),{ new System.Collections.IComparer with member this.Compare(p1,p2) = compare ((p1 :?> MemberInfo).Name) ((p2 :?> MemberInfo).Name) } )
+            Array.Sort((propsAndFields :> Array),{ new System.Collections.IComparer with member this.Compare(p1,p2) = compare ((p1 :?> MemberInfo).Name) ((p2 :?> MemberInfo).Name) } )
 #endif
 
-                              if propsAndFields.Length = 0 || (nDepth <= 0) then basicL 
-                              else basicL --- 
-                                     (propsAndFields 
-                                      |> Array.map 
-                                        (fun m -> 
-                                            ((if m :? FieldInfo then tagField m.Name else tagProperty m.Name),
-                                                (try Some (objL nDepth Precedence.BracketIfTuple ((getProperty ty obj m.Name), ty)) 
-                                                 with _ -> try Some (objL nDepth Precedence.BracketIfTuple ((getField obj (m :?> FieldInfo)), ty)) 
-                                                           with _ -> None)))
-                                      |> Array.toList 
-                                      |> makePropertiesL)
-                           | _ -> basicL 
-                | UnitValue -> countNodes 1; measureL
-
-            polyL bindingFlags objWithReprL showMode opts.PrintDepth Precedence.BracketIfTuple (x, ty)
-
-        // --------------------------------------------------------------------
-        // pprinter: leafFormatter
-        // --------------------------------------------------------------------
-
-        let leafFormatter (opts:FormatOptions) (obj :obj) =
-            match obj with 
-            | null -> tagKeyword "null"
-            | :? double as d -> 
-                let s = d.ToString(opts.FloatingPointFormat,opts.FormatProvider)
-                let t = 
-                    if System.Double.IsNaN(d) then "nan"
-                    elif System.Double.IsNegativeInfinity(d) then "-infinity"
-                    elif System.Double.IsPositiveInfinity(d) then "infinity"
-                    elif opts.FloatingPointFormat.[0] = 'g'  && String.forall(fun c -> System.Char.IsDigit(c) || c = '-')  s
-                    then s + ".0" 
-                    else s
-                tagNumericLiteral t
-            | :? single as d -> 
-                let t =
-                    (if System.Single.IsNaN(d) then "nan"
-                     elif System.Single.IsNegativeInfinity(d) then "-infinity"
-                     elif System.Single.IsPositiveInfinity(d) then "infinity"
-                     elif opts.FloatingPointFormat.Length >= 1 && opts.FloatingPointFormat.[0] = 'g' 
-                      && float32(System.Int32.MinValue) < d && d < float32(System.Int32.MaxValue) 
-                      && float32(int32(d)) = d 
-                     then (System.Convert.ToInt32 d).ToString(opts.FormatProvider) + ".0"
-                     else d.ToString(opts.FloatingPointFormat,opts.FormatProvider)) 
-                    + "f"
-                tagNumericLiteral t
-            | :? System.Decimal as d -> d.ToString("g",opts.FormatProvider) + "M" |> tagNumericLiteral
-            | :? uint64 as d -> d.ToString(opts.FormatProvider) + "UL" |> tagNumericLiteral
-            | :? int64  as d -> d.ToString(opts.FormatProvider) + "L" |> tagNumericLiteral
-            | :? int32  as d -> d.ToString(opts.FormatProvider) |> tagNumericLiteral
-            | :? uint32 as d -> d.ToString(opts.FormatProvider) + "u" |> tagNumericLiteral
-            | :? int16  as d -> d.ToString(opts.FormatProvider) + "s" |> tagNumericLiteral
-            | :? uint16 as d -> d.ToString(opts.FormatProvider) + "us" |> tagNumericLiteral
-            | :? sbyte  as d -> d.ToString(opts.FormatProvider) + "y" |> tagNumericLiteral
-            | :? byte   as d -> d.ToString(opts.FormatProvider) + "uy" |> tagNumericLiteral
-            | :? nativeint as d -> d.ToString() + "n" |> tagNumericLiteral
-            | :? unativeint  as d -> d.ToString() + "un" |> tagNumericLiteral
-            | :? bool   as b -> (if b then "true" else "false") |> tagKeyword
-            | :? char   as c -> "\'" + formatChar true c + "\'" |> tagStringLiteral
-            | _ -> 
-                let t = 
-                    try 
-                        let text = obj.ToString()
-                        match text with
-                        | null -> ""
-                        | _ -> text
-                    with e ->
-                     // If a .ToString() call throws an exception, catch it and use the message as the result.
-                     // This may be informative, e.g. division by zero etc...
-                     "" 
-                tagText t
-
-        let any_to_layout opts x = anyL ShowAll BindingFlags.Public opts x
-
-        let squash_layout opts l = 
-            // Print width = 0 implies 1D layout, no squash
-            if opts.PrintWidth = 0 then 
-                l 
-            else 
-                l |> squashTo (opts.PrintWidth,leafFormatter opts)
-
-        let asTaggedTextWriter (tw: TextWriter) =
-            { new TaggedTextWriter with
-                member __.Write(t) = tw.Write t.Text
-                member __.WriteLine() = tw.WriteLine() }
-
-        let output_layout_tagged opts oc l = 
-            l |> squash_layout opts 
-              |> outL opts.AttributeProcessor (leafFormatter opts) oc
+            if propsAndFields.Length = 0 || (nDepth <= 0) then basicL 
+            else basicL --- 
+                    (propsAndFields 
+                    |> Array.map 
+                    (fun m -> 
+                        ((if m :? FieldInfo then tagField m.Name else tagProperty m.Name),
+                            (try Some (nestedObjL nDepth Precedence.BracketIfTuple ((getProperty ty obj m.Name), ty)) 
+                                with _ -> 
+                                try Some (nestedObjL nDepth Precedence.BracketIfTuple ((getField obj (m :?> FieldInfo)), ty)) 
+                                with _ -> None)))
+                    |> Array.toList 
+                    |> makePropertiesL)
+
+        and reprL showMode depthLim prec repr x (* x could be null *) =
+            match repr with
+            | TupleValue (tupleType, vals) ->
+                tupleValueL depthLim prec vals tupleType
+
+            | RecordValue items -> 
+                recordValueL depthLim (Array.toList items)
+
+            | UnionCaseValue (_,constr,recd) when // x is List. Note: "null" is never a valid list value. 
+                                                    x<>null && isListType (x.GetType()) ->
+                listValueL depthLim constr recd
+
+            | UnionCaseValue(declaringType, unionCaseName, recd) ->
+                unionCaseValueL depthLim prec declaringType unionCaseName (Array.toList recd)
+
+            | ExceptionValue(exceptionType, recd) ->
+                fsharpExceptionL depthLim prec exceptionType (Array.toList recd)
+
+            | FunctionClosureValue closureType ->
+                functionClosureL showMode closureType
+
+            | UnitValue ->
+                countNodes 1
+                unitL
+
+            | NullValue ->
+                countNodes 1
+                // If this is the root element, wrap the null with angle brackets
+                if depthLim = opts.PrintDepth - 1 then
+                    wordL (tagText "")
+                else nullL
+
+            | ObjectValue obj ->
+                let ty = obj.GetType()
+                match obj with 
+                | :? string as s ->
+                    stringValueL s
 
-        let output_layout opts oc l = 
-            output_layout_tagged opts (asTaggedTextWriter oc) l
+                | :? Array as arr ->
+                    arrayValueL depthLim arr
 
-        let layout_to_string options layout = 
-            layout |> squash_layout options 
-              |> showL options ((leafFormatter options) >> toText)
+                | _ when isSetOrMapType ty ->
+                    mapSetValueL depthLim prec ty obj
 
-        let output_any_ex opts oc x = x |> any_to_layout opts |> output_layout opts oc
+                | :? System.Collections.IEnumerable as ie ->
+                    sequenceValueL showMode depthLim prec ie
 
-        let output_any writer x = output_any_ex FormatOptions.Default writer x
+                | _ when showMode = ShowTopLevelBinding && typeUsesSystemObjectToString ty ->
+                    emptyL 
 
-        let layout_as_string opts x = x |> any_to_layout opts |> layout_to_string opts
+                | _ when opts.ShowProperties -> 
+                    countNodes 1
+                    objectValueWithPropertiesL depthLim (ty: Type) (obj: obj)
 
-        let any_to_string x = layout_as_string FormatOptions.Default x
+                | _ ->
+                    countNodes 1
+                    // This buries an obj in the layout, rendered at squash time via a leafFormatter.
+                    LayoutOps.objL obj
+
+        member _.Format(showMode, x:'a, xty:Type) =
+            objL showMode opts.PrintDepth  Precedence.BracketIfTuple (x, xty)
+
+    let leafFormatter (opts:FormatOptions) (obj :obj) =
+        match obj with 
+        | null -> tagKeyword "null"
+        | :? double as d -> 
+            let s = d.ToString(opts.FloatingPointFormat,opts.FormatProvider)
+            let t = 
+                if System.Double.IsNaN(d) then "nan"
+                elif System.Double.IsNegativeInfinity(d) then "-infinity"
+                elif System.Double.IsPositiveInfinity(d) then "infinity"
+                elif opts.FloatingPointFormat.[0] = 'g'  && String.forall(fun c -> System.Char.IsDigit(c) || c = '-')  s
+                then s + ".0" 
+                else s
+            tagNumericLiteral t
+
+        | :? single as d -> 
+            let t =
+                (if System.Single.IsNaN(d) then "nan"
+                    elif System.Single.IsNegativeInfinity(d) then "-infinity"
+                    elif System.Single.IsPositiveInfinity(d) then "infinity"
+                    elif opts.FloatingPointFormat.Length >= 1 && opts.FloatingPointFormat.[0] = 'g' 
+                    && float32(System.Int32.MinValue) < d && d < float32(System.Int32.MaxValue) 
+                    && float32(int32(d)) = d 
+                    then (System.Convert.ToInt32 d).ToString(opts.FormatProvider) + ".0"
+                    else d.ToString(opts.FloatingPointFormat,opts.FormatProvider)) 
+                + "f"
+            tagNumericLiteral t
+
+        | :? decimal as d -> d.ToString("g",opts.FormatProvider) + "M" |> tagNumericLiteral
+        | :? uint64 as d -> d.ToString(opts.FormatProvider) + "UL" |> tagNumericLiteral
+        | :? int64  as d -> d.ToString(opts.FormatProvider) + "L" |> tagNumericLiteral
+        | :? int32  as d -> d.ToString(opts.FormatProvider) |> tagNumericLiteral
+        | :? uint32 as d -> d.ToString(opts.FormatProvider) + "u" |> tagNumericLiteral
+        | :? int16  as d -> d.ToString(opts.FormatProvider) + "s" |> tagNumericLiteral
+        | :? uint16 as d -> d.ToString(opts.FormatProvider) + "us" |> tagNumericLiteral
+        | :? sbyte  as d -> d.ToString(opts.FormatProvider) + "y" |> tagNumericLiteral
+        | :? byte   as d -> d.ToString(opts.FormatProvider) + "uy" |> tagNumericLiteral
+        | :? nativeint as d -> d.ToString() + "n" |> tagNumericLiteral
+        | :? unativeint  as d -> d.ToString() + "un" |> tagNumericLiteral
+        | :? bool   as b -> (if b then "true" else "false") |> tagKeyword
+        | :? char   as c -> "\'" + formatChar true c + "\'" |> tagStringLiteral
+
+        | _ -> 
+            let t = 
+                try 
+                    let text = obj.ToString()
+                    match text with
+                    | null -> ""
+                    | _ -> text
+                with e ->
+                    // If a .ToString() call throws an exception, catch it and use the message as the result.
+                    // This may be informative, e.g. division by zero etc...
+                    "" 
+            tagText t
+
+    let any_to_layout opts (x, xty) =
+        let formatter = ObjectGraphFormatter(opts, BindingFlags.Public) 
+        formatter.Format(ShowAll, x, xty)
+
+    let squashTo maxWidth layout = 
+       layout |> squashToAux (maxWidth, leafFormatter FormatOptions.Default)
+
+    let squash_layout opts l = 
+        // Print width = 0 implies 1D layout, no squash
+        if opts.PrintWidth = 0 then 
+            l 
+        else 
+            l |> squashToAux (opts.PrintWidth,leafFormatter opts)
+
+    let asTaggedTextWriter (tw: TextWriter) =
+        { new TaggedTextWriter with
+            member __.Write(t) = tw.Write t.Text
+            member __.WriteLine() = tw.WriteLine() }
+
+    let output_layout_tagged opts oc l = 
+        l |> squash_layout opts 
+            |> outL opts.AttributeProcessor (leafFormatter opts) oc
+
+    let output_layout opts oc l = 
+        output_layout_tagged opts (asTaggedTextWriter oc) l
+
+    let layout_to_string options layout = 
+        layout |> squash_layout options 
+            |> showL options ((leafFormatter options) >> toText)
+
+    let output_any_ex opts oc x = x |> any_to_layout opts |> output_layout opts oc
+
+    let output_any writer x = output_any_ex FormatOptions.Default writer x
+
+    let layout_as_string opts x = x |> any_to_layout opts |> layout_to_string opts
+
+    let any_to_string x = layout_as_string FormatOptions.Default x
 
 #if COMPILER
-        /// Called 
-        let fsi_any_to_layout opts x = anyL ShowTopLevelBinding BindingFlags.Public opts x
+    let fsi_any_to_layout opts (x, xty) =
+        let formatter = ObjectGraphFormatter(opts, BindingFlags.Public) 
+        formatter.Format (ShowTopLevelBinding, x, xty)
 #else
-// FSharp.Core
-        let internal anyToStringForPrintf options (bindingFlags:BindingFlags) x = 
-            x |> anyL ShowAll bindingFlags options |> layout_to_string options
+    let internal anyToStringForPrintf options (bindingFlags:BindingFlags) (x, xty) = 
+        let formatter = ObjectGraphFormatter(options, bindingFlags) 
+        formatter.Format (ShowAll, x, xty) |> layout_to_string options
 #endif
 
diff --git a/src/utils/sformat.fsi b/src/utils/sformat.fsi
index e6ff9762bb5..da5b4219fb5 100644
--- a/src/utils/sformat.fsi
+++ b/src/utils/sformat.fsi
@@ -29,10 +29,13 @@ namespace Microsoft.FSharp.Text.StructuredPrintfImpl
     open Microsoft.FSharp.Collections
     open Microsoft.FSharp.Primitives.Basics
 
+#if FSHARP_CORE
     /// Data representing structured layouts of terms.  
-#if FSHARP_CORE  // FSharp.Core.dll makes things internal and hides representations
+    // FSharp.Core.dll makes things internal and hides representations
     type internal Layout
+
     type internal LayoutTag
+
     type internal TaggedText =
         abstract Tag: LayoutTag
         abstract Text: string
@@ -43,8 +46,8 @@ namespace Microsoft.FSharp.Text.StructuredPrintfImpl
     []
     type public Joint =
         | Unbreakable
-        | Breakable of int
-        | Broken of int
+        | Breakable of indentation: int
+        | Broken of indentation: int
     
     []
     type public LayoutTag =
@@ -83,8 +86,8 @@ namespace Microsoft.FSharp.Text.StructuredPrintfImpl
         | UnknownEntity
 
     type public TaggedText =
-        abstract Tag : LayoutTag
-        abstract Text : string
+        abstract Tag: LayoutTag
+        abstract Text: string
 
     
     type public TaggedTextWriter =
@@ -95,10 +98,12 @@ namespace Microsoft.FSharp.Text.StructuredPrintfImpl
     /// of this data type is only for the consumption of formatting engines.
     []
     type public Layout =
-     | ObjLeaf of bool * obj * bool
-     | Leaf of bool * TaggedText * bool
-     | Node of bool * Layout * bool * Layout * bool * Joint
-     | Attr of string * (string * string) list * Layout
+        | ObjLeaf of juxtLeft: bool * object: obj * juxtRight: bool
+        | Leaf of juxtLeft: bool * text: TaggedText * justRight: bool
+        | Node of leftLayout: Layout * rightLayout: Layout * joint: Joint
+        | Attr of text: string * attributes: (string * string) list * layout: Layout
+
+        static member JuxtapositionMiddle: left: Layout * right: Layout -> bool
 #endif
 
 #if COMPILER
@@ -106,66 +111,68 @@ namespace Microsoft.FSharp.Text.StructuredPrintfImpl
 #else
     module internal TaggedTextOps =
 #endif
-        val tag : LayoutTag -> string -> TaggedText
-        val keywordFunctions : Set
-        val tagAlias : string -> TaggedText
-        val tagClass : string -> TaggedText
-        val tagUnionCase : string -> TaggedText
-        val tagDelegate : string -> TaggedText
-        val tagEnum : string -> TaggedText
-        val tagEvent : string -> TaggedText
-        val tagField : string -> TaggedText
-        val tagInterface : string -> TaggedText
-        val tagKeyword : string -> TaggedText
-        val tagLineBreak : string -> TaggedText
-        val tagMethod : string -> TaggedText
-        val tagModuleBinding : string -> TaggedText
-        val tagLocal : string -> TaggedText
-        val tagRecord : string -> TaggedText
-        val tagRecordField : string -> TaggedText
-        val tagModule : string -> TaggedText
-        val tagNamespace : string -> TaggedText
-        val tagNumericLiteral : string -> TaggedText
-        val tagOperator : string -> TaggedText
-        val tagParameter : string -> TaggedText
-        val tagProperty : string -> TaggedText
-        val tagSpace : string -> TaggedText
-        val tagStringLiteral : string -> TaggedText
-        val tagStruct : string -> TaggedText
-        val tagTypeParameter : string -> TaggedText
-        val tagText : string -> TaggedText
-        val tagPunctuation : string -> TaggedText
+        val mkTag: LayoutTag -> string -> TaggedText
+        val keywordFunctions: Set
+        val tagAlias: string -> TaggedText
+        val tagClass: string -> TaggedText
+        val tagUnionCase: string -> TaggedText
+        val tagDelegate: string -> TaggedText
+        val tagEnum: string -> TaggedText
+        val tagEvent: string -> TaggedText
+        val tagField: string -> TaggedText
+        val tagInterface: string -> TaggedText
+        val tagKeyword: string -> TaggedText
+        val tagLineBreak: string -> TaggedText
+        val tagMethod: string -> TaggedText
+        val tagModuleBinding: string -> TaggedText
+        val tagLocal: string -> TaggedText
+        val tagRecord: string -> TaggedText
+        val tagRecordField: string -> TaggedText
+        val tagModule: string -> TaggedText
+        val tagNamespace: string -> TaggedText
+        val tagNumericLiteral: string -> TaggedText
+        val tagOperator: string -> TaggedText
+        val tagParameter: string -> TaggedText
+        val tagProperty: string -> TaggedText
+        val tagSpace: string -> TaggedText
+        val tagStringLiteral: string -> TaggedText
+        val tagStruct: string -> TaggedText
+        val tagTypeParameter: string -> TaggedText
+        val tagText: string -> TaggedText
+        val tagPunctuation: string -> TaggedText
 
         module Literals =
             // common tagged literals
-            val lineBreak : TaggedText
-            val space : TaggedText
-            val comma : TaggedText
-            val semicolon : TaggedText
-            val leftParen : TaggedText
-            val rightParen : TaggedText
-            val leftBracket : TaggedText
-            val rightBracket : TaggedText
+            val lineBreak: TaggedText
+            val space: TaggedText
+            val comma: TaggedText
+            val semicolon: TaggedText
+            val leftParen: TaggedText
+            val rightParen: TaggedText
+            val leftBracket: TaggedText
+            val rightBracket: TaggedText
             val leftBrace: TaggedText
-            val rightBrace : TaggedText
+            val rightBrace: TaggedText
             val leftBraceBar: TaggedText
-            val rightBraceBar : TaggedText
-            val equals : TaggedText
-            val arrow : TaggedText
-            val questionMark : TaggedText
+            val rightBraceBar: TaggedText
+            val equals: TaggedText
+            val arrow: TaggedText
+            val questionMark: TaggedText
 
 #if COMPILER
     type public IEnvironment = 
         /// Return to the layout-generation 
         /// environment to layout any otherwise uninterpreted object
-        abstract GetLayout : obj -> Layout
+        abstract GetLayout: obj -> Layout
+
         /// The maximum number of elements for which to generate layout for 
         /// list-like structures, or columns in table-like 
         /// structures.  -1 if no maximum.
-        abstract MaxColumns : int
+        abstract MaxColumns: int
+
         /// The maximum number of rows for which to generate layout for table-like 
         /// structures.  -1 if no maximum.
-        abstract MaxRows : int
+        abstract MaxRows: int
 #endif
       
     /// A layout is a sequence of strings which have been joined together.
@@ -181,92 +188,92 @@ namespace Microsoft.FSharp.Text.StructuredPrintfImpl
 #endif
 
         /// The empty layout
-        val emptyL     : Layout
+        val emptyL : Layout
 
         /// Is it the empty layout?
-        val isEmptyL   : layout:Layout -> bool
+        val isEmptyL: layout:Layout -> bool
 
         /// An uninterpreted leaf, to be interpreted into a string
         /// by the layout engine. This allows leaf layouts for numbers, strings and
         /// other atoms to be customized according to culture.
-        val objL       : value:obj -> Layout
+        val objL   : value:obj -> Layout
 
         /// An string leaf 
-        val wordL      : text:TaggedText -> Layout
+        val wordL  : text:TaggedText -> Layout
 
         /// An string which requires no spaces either side.
-        val sepL       : text:TaggedText -> Layout
+        val sepL   : text:TaggedText -> Layout
 
         /// An string which is right parenthesis (no space on the left).
-        val rightL     : text:TaggedText -> Layout
+        val rightL : text:TaggedText -> Layout
 
         /// An string which is left  parenthesis (no space on the right).
-        val leftL      : text:TaggedText -> Layout
+        val leftL  : text:TaggedText -> Layout
 
         /// Join, unbreakable. 
-        val ( ^^ )     : layout1:Layout -> layout2:Layout -> Layout   
+        val ( ^^ ) : layout1:Layout -> layout2:Layout -> Layout   
 
         /// Join, possible break with indent=0
-        val ( ++ )     : layout1:Layout -> layout2:Layout -> Layout   
+        val ( ++ ) : layout1:Layout -> layout2:Layout -> Layout   
 
         /// Join, possible break with indent=1
-        val ( -- )     : layout1:Layout -> layout2:Layout -> Layout   
+        val ( -- ) : layout1:Layout -> layout2:Layout -> Layout   
 
         /// Join, possible break with indent=2 
-        val ( --- )    : layout1:Layout -> layout2:Layout -> Layout   
+        val ( --- ): layout1:Layout -> layout2:Layout -> Layout   
 
         /// Join broken with ident=0
-        val ( @@ )     : layout1:Layout -> layout2:Layout -> Layout   
+        val ( @@ ) : layout1:Layout -> layout2:Layout -> Layout   
 
         /// Join broken with ident=1 
-        val ( @@- )    : layout1:Layout -> layout2:Layout -> Layout   
+        val ( @@- ): layout1:Layout -> layout2:Layout -> Layout   
 
         /// Join broken with ident=2 
-        val ( @@-- )   : layout1:Layout -> layout2:Layout -> Layout   
+        val ( @@-- ): layout1:Layout -> layout2:Layout -> Layout   
 
         /// Join layouts into a comma separated list.
-        val commaListL : layouts:Layout list -> Layout
+        val commaListL: layouts:Layout list -> Layout
           
         /// Join layouts into a space separated list.    
-        val spaceListL : layouts:Layout list -> Layout
+        val spaceListL: layouts:Layout list -> Layout
           
         /// Join layouts into a semi-colon separated list.
-        val semiListL  : layouts:Layout list -> Layout
+        val semiListL: layouts:Layout list -> Layout
 
         /// Join layouts into a list separated using the given Layout.
-        val sepListL   : layout1:Layout -> layouts:Layout list -> Layout
+        val sepListL: layout1:Layout -> layouts:Layout list -> Layout
 
         /// Wrap round brackets around Layout.
-        val bracketL   : layout:Layout -> Layout
+        val bracketL: layout:Layout -> Layout
 
         /// Wrap square brackets around layout.    
-        val squareBracketL   : layout:Layout -> Layout
+        val squareBracketL: layout:Layout -> Layout
 
         /// Wrap braces around layout.        
-        val braceL     : layout:Layout -> Layout
+        val braceL : layout:Layout -> Layout
 
         /// Form tuple of layouts.            
-        val tupleL     : layouts:Layout list -> Layout
+        val tupleL : layouts:Layout list -> Layout
 
         /// Layout two vertically.
-        val aboveL     : layout1:Layout -> layout2:Layout -> Layout
+        val aboveL : layout1:Layout -> layout2:Layout -> Layout
 
         /// Layout list vertically.    
-        val aboveListL : layouts:Layout list -> Layout
+        val aboveListL: layouts:Layout list -> Layout
 
         /// Layout like an F# option.
-        val optionL    : selector:('T -> Layout) -> value:'T option -> Layout
+        val optionL: selector:('T -> Layout) -> value:'T option -> Layout
 
         /// Layout like an F# list.    
-        val listL      : selector:('T -> Layout) -> value:'T list   -> Layout
+        val listL  : selector:('T -> Layout) -> value:'T list   -> Layout
 
         /// See tagL
-        val tagAttrL : text:string -> maps:(string * string) list -> layout:Layout -> Layout
+        val tagAttrL: text:string -> maps:(string * string) list -> layout:Layout -> Layout
 
         /// For limiting layout of list-like sequences (lists,arrays,etc).
         /// unfold a list of items using (project and z) making layout list via itemL.
         /// If reach maxLength (before exhausting) then truncate.
-        val unfoldL : selector:('T -> Layout) -> folder:('State -> ('T * 'State) option) -> state:'State -> count:int -> Layout list
+        val unfoldL: selector:('T -> Layout) -> folder:('State -> ('T * 'State) option) -> state:'State -> count:int -> Layout list
 
     /// A record of options to control structural formatting.
     /// For F# Interactive properties matching those of this value can be accessed via the 'fsi'
@@ -296,20 +303,21 @@ namespace Microsoft.FSharp.Text.StructuredPrintfImpl
     type internal FormatOptions =
 #endif
         { FloatingPointFormat: string
-          AttributeProcessor: (string -> (string * string) list -> bool -> unit);
+          AttributeProcessor: (string -> (string * string) list -> bool -> unit)
 #if COMPILER  // FSharp.Core.dll: PrintIntercepts aren't used there
-          PrintIntercepts: (IEnvironment -> obj -> Layout option) list;
-          StringLimit: int;
+          PrintIntercepts: (IEnvironment -> obj -> Layout option) list
+          StringLimit: int
 #endif
           FormatProvider: System.IFormatProvider
           BindingFlags: System.Reflection.BindingFlags
-          PrintWidth : int 
-          PrintDepth : int 
-          PrintLength : int
-          PrintSize : int  
-          ShowProperties : bool
+          PrintWidth: int 
+          PrintDepth: int 
+          PrintLength: int
+          PrintSize: int  
+          ShowProperties: bool
           ShowIEnumerable: bool  }
-        static member Default : FormatOptions
+
+        static member Default: FormatOptions
 
 #if COMPILER
     module public Display =
@@ -317,33 +325,24 @@ namespace Microsoft.FSharp.Text.StructuredPrintfImpl
     module internal Display =
 #endif
 
-        /// Convert any value to a string using a standard formatter
-        /// Data is typically formatted in a structured format, e.g.
-        /// lists are formatted using the "[1;2]" notation.
-        /// The details of the format are not specified and may change
-        /// from version to version and according to the flags given
-        /// to the F# compiler.  The format is intended to be human-readable,
-        /// not machine readable.  If alternative generic formats are required
-        /// you should develop your own formatter, using the code in the
-        /// implementation of this file as a starting point.
-        ///
-        /// Data from other .NET languages is formatted using a virtual
-        /// call to Object.ToString() on the boxed version of the input.
-        val any_to_string: value:'T * Type -> string
-
-        /// Output any value to a channel using the same set of formatting rules
-        /// as any_to_string
-        val output_any: writer:TextWriter -> value:'T * Type -> unit
-
-#if FSHARP_CORE   // FSharp.Core.dll: Most functions aren't needed in FSharp.Core.dll, but we add one entry for printf
+#if FSHARP_CORE
 
+        // Most functions aren't needed in FSharp.Core.dll, but we add one inernal entry for printf
         val anyToStringForPrintf: options:FormatOptions -> bindingFlags:System.Reflection.BindingFlags -> value:'T * Type -> string
 #else
+
         val asTaggedTextWriter: writer: TextWriter -> TaggedTextWriter
-        val any_to_layout   : options:FormatOptions -> value:'T * Type -> Layout
-        val squash_layout   : options:FormatOptions -> layout:Layout -> Layout
-        val output_layout_tagged   : options:FormatOptions -> writer:TaggedTextWriter -> layout:Layout -> unit
-        val output_layout   : options:FormatOptions -> writer:TextWriter -> layout:Layout -> unit
+
+        val any_to_layout: options:FormatOptions -> value:'T * Type -> Layout
+
+        val squashTo: width: int -> layout: Layout -> Layout
+
+        val squash_layout: options:FormatOptions -> layout:Layout -> Layout
+
+        val output_layout_tagged: options:FormatOptions -> writer:TaggedTextWriter -> layout:Layout -> unit
+
+        val output_layout: options:FormatOptions -> writer:TextWriter -> layout:Layout -> unit
+
         val layout_as_string: options:FormatOptions -> value:'T * Type -> string
 #endif
 
@@ -353,7 +352,6 @@ namespace Microsoft.FSharp.Text.StructuredPrintfImpl
         /// built using any_to_layout with default format options.
         val layout_to_string: options:FormatOptions -> layout:Layout -> string
 
-
 #if COMPILER
-        val fsi_any_to_layout : options:FormatOptions -> value:'T * Type -> Layout
+        val fsi_any_to_layout: options:FormatOptions -> value:'T * Type -> Layout
 #endif  
diff --git a/tests/Directory.Build.targets b/tests/Directory.Build.targets
index 1108759d4a2..14437118703 100644
--- a/tests/Directory.Build.targets
+++ b/tests/Directory.Build.targets
@@ -1,16 +1,3 @@
 
-
   
-
-  
-    
-    
-    
-  
-  
-    
-    
-    
-  
-
 
diff --git a/tests/FSharp.Compiler.ComponentTests/xunit.runner.json b/tests/FSharp.Compiler.ComponentTests/xunit.runner.json
index aa4e627f2b8..d60e5705290 100644
--- a/tests/FSharp.Compiler.ComponentTests/xunit.runner.json
+++ b/tests/FSharp.Compiler.ComponentTests/xunit.runner.json
@@ -1,4 +1,5 @@
 {
     "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
+    "appDomain": "denied",
     "shadowCopy": false
 }
diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/CompletionTests.fs b/tests/FSharp.Compiler.Private.Scripting.UnitTests/CompletionTests.fs
index 03935ee77f0..89c4cc20116 100644
--- a/tests/FSharp.Compiler.Private.Scripting.UnitTests/CompletionTests.fs
+++ b/tests/FSharp.Compiler.Private.Scripting.UnitTests/CompletionTests.fs
@@ -5,12 +5,11 @@ namespace FSharp.Compiler.Scripting.UnitTests
 open System
 open System.Threading.Tasks
 open FSharp.Compiler.Scripting
-open NUnit.Framework
+open Xunit
 
-[]
 type CompletionTests() =
 
-    []
+    []
     member _.``Instance completions in the same submission``() =
         async {
             use script = new FSharpScript()
@@ -18,20 +17,20 @@ type CompletionTests() =
                           "x." ]
             let! completions = script.GetCompletionItems(String.Join("\n", lines), 2, 2)
             let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "CompareTo")
-            Assert.AreEqual(1, matchingCompletions.Length)
+            Assert.Equal(1, matchingCompletions.Length)
         } |> Async.StartAsTask :> Task
 
-    []
+    []
     member _.``Instance completions from a previous submission``() =
         async {
             use script = new FSharpScript()
             script.Eval("let x = 1") |> ignoreValue
             let! completions = script.GetCompletionItems("x.", 1, 2)
             let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "CompareTo")
-            Assert.AreEqual(1, matchingCompletions.Length)
+            Assert.Equal(1, matchingCompletions.Length)
         } |> Async.StartAsTask :> Task
 
-    []
+    []
     member _.``Completions from types that try to pull in Windows runtime extensions``() =
         async {
             use script = new FSharpScript()
@@ -39,37 +38,37 @@ type CompletionTests() =
             script.Eval("let t = TimeSpan.FromHours(1.0)") |> ignoreValue
             let! completions = script.GetCompletionItems("t.", 1, 2)
             let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "TotalHours")
-            Assert.AreEqual(1, matchingCompletions.Length)
+            Assert.Equal(1, matchingCompletions.Length)
         } |> Async.StartAsTask :> Task
 
-    []
+    []
     member _.``Static member completions``() =
         async {
             use script = new FSharpScript()
             let! completions = script.GetCompletionItems("System.String.", 1, 14)
             let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "Join")
-            Assert.GreaterOrEqual(matchingCompletions.Length, 1)
+            Assert.True(matchingCompletions.Length >= 1)
         } |> Async.StartAsTask :> Task
 
-    []
+    []
     member _.``Type completions from namespace``() =
         async {
             use script = new FSharpScript()
             let! completions = script.GetCompletionItems("System.", 1, 7)
             let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "String")
-            Assert.GreaterOrEqual(matchingCompletions.Length, 1)
+            Assert.True(matchingCompletions.Length >= 1)
         } |> Async.StartAsTask :> Task
 
-    []
+    []
     member _.``Namespace completions``() =
         async {
             use script = new FSharpScript()
             let! completions = script.GetCompletionItems("System.", 1, 7)
             let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "Collections")
-            Assert.AreEqual(1, matchingCompletions.Length)
+            Assert.Equal(1, matchingCompletions.Length)
         } |> Async.StartAsTask :> Task
 
-    []
+    []
     member _.``Extension method completions``() =
         async {
             use script = new FSharpScript()
@@ -78,5 +77,5 @@ type CompletionTests() =
                           "list." ]
             let! completions = script.GetCompletionItems(String.Join("\n", lines), 3, 5)
             let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "Select")
-            Assert.AreEqual(1, matchingCompletions.Length)
+            Assert.Equal(1, matchingCompletions.Length)
         } |> Async.StartAsTask :> Task
diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/DependencyManagerInteractiveTests.fs b/tests/FSharp.Compiler.Private.Scripting.UnitTests/DependencyManagerInteractiveTests.fs
index 02b03e9b4b8..a2659d1dcbd 100644
--- a/tests/FSharp.Compiler.Private.Scripting.UnitTests/DependencyManagerInteractiveTests.fs
+++ b/tests/FSharp.Compiler.Private.Scripting.UnitTests/DependencyManagerInteractiveTests.fs
@@ -7,20 +7,20 @@ open System.Collections.Generic
 open System.IO
 open System.Reflection
 open System.Runtime.InteropServices
+open System.Threading
+
 open FSharp.Compiler.Interactive.Shell
 open FSharp.Compiler.Scripting
 open FSharp.Compiler.SourceCodeServices
-open System.Runtime.InteropServices
-open NUnit.Framework
-open Microsoft.DotNet.DependencyManager
 open FSharp.Compiler.Scripting.UnitTests
-open System.Threading
+open Microsoft.DotNet.DependencyManager
+
+open Xunit
 
 module Native =
     []
     extern int NoneSuch()
 
-[]
 type DependencyManagerInteractiveTests() =
 
     let getValue ((value: Result), (errors: FSharpErrorInfo[])) =
@@ -34,7 +34,7 @@ type DependencyManagerInteractiveTests() =
 
     let scriptHost () = new FSharpScript(additionalArgs=[|"/langversion:preview"|])
 
-    []
+    []
     member __.``SmokeTest - #r nuget``() =
         let text = """
 #r @"nuget:Newtonsoft.Json, Version=9.0.1"
@@ -42,10 +42,10 @@ type DependencyManagerInteractiveTests() =
         use script = scriptHost()
         let opt = script.Eval(text) |> getValue
         let value = opt.Value
-        Assert.AreEqual(typeof, value.ReflectionType)
-        Assert.AreEqual(0, value.ReflectionValue :?> int)
+        Assert.Equal(typeof, value.ReflectionType)
+        Assert.Equal(0, value.ReflectionValue :?> int)
 
-    []
+    []
     member __.``SmokeTest - #r nuget package not found``() =
         let text = """
 #r @"nuget:System.Collections.Immutable.DoesNotExist, version=1.5.0"
@@ -53,10 +53,10 @@ type DependencyManagerInteractiveTests() =
         use script = scriptHost()
         let opt = script.Eval(text) |> getValue
         let value = opt.Value
-        Assert.AreEqual(typeof, value.ReflectionType)
-        Assert.AreEqual(0, value.ReflectionValue :?> int)
+        Assert.Equal(typeof, value.ReflectionType)
+        Assert.Equal(0, value.ReflectionValue :?> int)
 
-    []
+    []
     member __.``Use Dependency Manager to resolve dependency FSharp.Data``() =
 
         let nativeProbingRoots () = Seq.empty
@@ -73,20 +73,20 @@ type DependencyManagerInteractiveTests() =
 
         if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then
             let result = dp.Resolve(idm, ".fsx", [|"FSharp.Data"|], reportError, "net472")
-            Assert.AreEqual(true, result.Success)
-            Assert.AreEqual(1, result.Resolutions |> Seq.length)
-            Assert.AreEqual(1, result.SourceFiles |> Seq.length)
-            Assert.AreEqual(1, result.Roots |> Seq.length)
+            Assert.Equal(true, result.Success)
+            Assert.Equal(1, result.Resolutions |> Seq.length)
+            Assert.Equal(1, result.SourceFiles |> Seq.length)
+            Assert.Equal(1, result.Roots |> Seq.length)
 
         let result = dp.Resolve(idm, ".fsx", [|"FSharp.Data"|], reportError, "netcoreapp3.1")
-        Assert.AreEqual(true, result.Success)
-        Assert.AreEqual(1, result.Resolutions |> Seq.length)
-        Assert.AreEqual(1, result.SourceFiles |> Seq.length)
-        Assert.AreEqual(1, result.Roots |> Seq.length)
+        Assert.Equal(true, result.Success)
+        Assert.Equal(1, result.Resolutions |> Seq.length)
+        Assert.Equal(1, result.SourceFiles |> Seq.length)
+        Assert.Equal(1, result.Roots |> Seq.length)
         ()
 
 
-    []
+    []
     member __.``Dependency add with nonexistent package should fail``() =
 
         let nativeProbingRoots () = Seq.empty
@@ -103,20 +103,20 @@ type DependencyManagerInteractiveTests() =
 
         if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then
             let result = dp.Resolve(idm, ".fsx", [|"System.Collections.Immutable.DoesNotExist"|], reportError, "net472")
-            Assert.AreEqual(false, result.Success)
-            Assert.AreEqual(0, result.Resolutions |> Seq.length)
-            Assert.AreEqual(0, result.SourceFiles |> Seq.length)
-            Assert.AreEqual(0, result.Roots |> Seq.length)
+            Assert.Equal(false, result.Success)
+            Assert.Equal(0, result.Resolutions |> Seq.length)
+            Assert.Equal(0, result.SourceFiles |> Seq.length)
+            Assert.Equal(0, result.Roots |> Seq.length)
 
         let result = dp.Resolve(idm, ".fsx", [|"System.Collections.Immutable.DoesNotExist"|], reportError, "netcoreapp3.1")
-        Assert.AreEqual(false, result.Success)
-        Assert.AreEqual(0, result.Resolutions |> Seq.length)
-        Assert.AreEqual(0, result.SourceFiles |> Seq.length)
-        Assert.AreEqual(0, result.Roots |> Seq.length)
+        Assert.Equal(false, result.Success)
+        Assert.Equal(0, result.Resolutions |> Seq.length)
+        Assert.Equal(0, result.SourceFiles |> Seq.length)
+        Assert.Equal(0, result.Roots |> Seq.length)
         ()
 
 
-    []
+    []
     member __.``Multiple Instances of DependencyProvider should be isolated``() =
 
         let assemblyProbingPaths () = Seq.empty
@@ -133,53 +133,53 @@ type DependencyManagerInteractiveTests() =
         let idm1 = dp1.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget")
         if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then
             let result1 = dp1.Resolve(idm1, ".fsx", [|"FSharp.Data"|], reportError, "net472")
-            Assert.AreEqual(true, result1.Success)
-            Assert.AreEqual(1, result1.Resolutions |> Seq.length)
-            Assert.IsTrue((result1.Resolutions |> Seq.head).Contains("\\net45\\"))
-            Assert.AreEqual(1, result1.SourceFiles |> Seq.length)
-            Assert.AreEqual(1, result1.Roots |> Seq.length)
-            Assert.IsTrue((result1.Roots |> Seq.head).EndsWith("/fsharp.data/3.3.3/"))
+            Assert.Equal(true, result1.Success)
+            Assert.Equal(1, result1.Resolutions |> Seq.length)
+            Assert.True((result1.Resolutions |> Seq.head).Contains("\\net45\\"))
+            Assert.Equal(1, result1.SourceFiles |> Seq.length)
+            Assert.Equal(1, result1.Roots |> Seq.length)
+            Assert.True((result1.Roots |> Seq.head).EndsWith("/fsharp.data/3.3.3/"))
 
         let result2 = dp1.Resolve(idm1, ".fsx", [|"FSharp.Data, 3.3.3"|], reportError, "netcoreapp3.1")
-        Assert.AreEqual(true, result2.Success)
-        Assert.AreEqual(1, result2.Resolutions |> Seq.length)
+        Assert.Equal(true, result2.Success)
+        Assert.Equal(1, result2.Resolutions |> Seq.length)
         let expected2 =
             if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then
                 "\\netstandard2.0\\"
             else
                 "/netstandard2.0/"
-        Assert.IsTrue((result2.Resolutions |> Seq.head).Contains(expected2))
-        Assert.AreEqual(1, result2.SourceFiles |> Seq.length)
-        Assert.AreEqual(1, result2.Roots |> Seq.length)
-        Assert.IsTrue((result2.Roots |> Seq.head).EndsWith("/fsharp.data/3.3.3/"))
+        Assert.True((result2.Resolutions |> Seq.head).Contains(expected2))
+        Assert.Equal(1, result2.SourceFiles |> Seq.length)
+        Assert.Equal(1, result2.Roots |> Seq.length)
+        Assert.True((result2.Roots |> Seq.head).EndsWith("/fsharp.data/3.3.3/"))
 
         use dp2 = new DependencyProvider(NativeResolutionProbe(nativeProbingRoots))
         let idm2 = dp2.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget")
 
         if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then
             let result3 = dp2.Resolve(idm2, ".fsx", [|"System.Json, Version=4.6.0"|], reportError, "net472")
-            Assert.AreEqual(true, result3.Success)
-            Assert.AreEqual(1, result3.Resolutions |> Seq.length)
-            Assert.IsTrue((result3.Resolutions |> Seq.head).Contains("\\netstandard2.0\\"))
-            Assert.AreEqual(1, result3.SourceFiles |> Seq.length)
-            Assert.AreEqual(1, result3.SourceFiles |> Seq.length)
-            Assert.IsTrue((result3.Roots |> Seq.head).EndsWith("/system.json/4.6.0/"))
+            Assert.Equal(true, result3.Success)
+            Assert.Equal(1, result3.Resolutions |> Seq.length)
+            Assert.True((result3.Resolutions |> Seq.head).Contains("\\netstandard2.0\\"))
+            Assert.Equal(1, result3.SourceFiles |> Seq.length)
+            Assert.Equal(1, result3.SourceFiles |> Seq.length)
+            Assert.True((result3.Roots |> Seq.head).EndsWith("/system.json/4.6.0/"))
 
         let result4 = dp2.Resolve(idm2, ".fsx", [|"System.Json, Version=4.6.0"|], reportError, "netcoreapp3.1")
-        Assert.AreEqual(true, result4.Success)
-        Assert.AreEqual(1, result4.Resolutions |> Seq.length)
+        Assert.Equal(true, result4.Success)
+        Assert.Equal(1, result4.Resolutions |> Seq.length)
         let expected4 =
             if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then
                 "\\netstandard2.0\\"
             else
                 "/netstandard2.0/"
-        Assert.IsTrue((result4.Resolutions |> Seq.head).Contains(expected4))
-        Assert.AreEqual(1, result4.SourceFiles |> Seq.length)
-        Assert.AreEqual(1, result4.Roots |> Seq.length)
-        Assert.IsTrue((result4.Roots |> Seq.head).EndsWith("/system.json/4.6.0/"))
+        Assert.True((result4.Resolutions |> Seq.head).Contains(expected4))
+        Assert.Equal(1, result4.SourceFiles |> Seq.length)
+        Assert.Equal(1, result4.Roots |> Seq.length)
+        Assert.True((result4.Roots |> Seq.head).EndsWith("/system.json/4.6.0/"))
         ()
 
-    []
+    []
     member __.``Nuget Reference package with dependencies we should get package roots and dependent references``() =
 
         let nativeProbingRoots () = Seq.empty
@@ -196,32 +196,32 @@ type DependencyManagerInteractiveTests() =
 
         if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then
             let result1 = dp1.Resolve(idm1, ".fsx", [|"Microsoft.Extensions.Configuration.Abstractions, 3.1.1"|], reportError, "net472")
-            Assert.AreEqual(true, result1.Success)
-            Assert.AreEqual(6, result1.Resolutions |> Seq.length)
-            Assert.IsTrue((result1.Resolutions |> Seq.head).Contains("\\netstandard2.0\\"))
-            Assert.AreEqual(1, result1.SourceFiles |> Seq.length)
-            Assert.AreEqual(6, result1.Roots |> Seq.length)
-            Assert.IsTrue((result1.Roots |> Seq.head).EndsWith("/microsoft.extensions.configuration.abstractions/3.1.1/"))
+            Assert.Equal(true, result1.Success)
+            Assert.Equal(6, result1.Resolutions |> Seq.length)
+            Assert.True((result1.Resolutions |> Seq.head).Contains("\\netstandard2.0\\"))
+            Assert.Equal(1, result1.SourceFiles |> Seq.length)
+            Assert.Equal(6, result1.Roots |> Seq.length)
+            Assert.True((result1.Roots |> Seq.head).EndsWith("/microsoft.extensions.configuration.abstractions/3.1.1/"))
 
         // Netstandard gets fewer dependencies than desktop, because desktop framework doesn't contain assemblies like System.Memory
         // Those assemblies must be delivered by nuget for desktop apps
         let result2 = dp1.Resolve(idm1, ".fsx", [|"Microsoft.Extensions.Configuration.Abstractions, 3.1.1"|], reportError, "netcoreapp3.1")
-        Assert.AreEqual(true, result2.Success)
-        Assert.AreEqual(2, result2.Resolutions |> Seq.length)
+        Assert.Equal(true, result2.Success)
+        Assert.Equal(2, result2.Resolutions |> Seq.length)
         let expected =
             if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then
                 "\\netcoreapp3.1\\"
             else
                 "/netcoreapp3.1/"
-        Assert.IsTrue((result2.Resolutions |> Seq.head).Contains(expected))
-        Assert.AreEqual(1, result2.SourceFiles |> Seq.length)
-        Assert.AreEqual(2, result2.Roots |> Seq.length)
-        Assert.IsTrue((result2.Roots |> Seq.head).EndsWith("/microsoft.extensions.configuration.abstractions/3.1.1/"))
+        Assert.True((result2.Resolutions |> Seq.head).Contains(expected))
+        Assert.Equal(1, result2.SourceFiles |> Seq.length)
+        Assert.Equal(2, result2.Roots |> Seq.length)
+        Assert.True((result2.Roots |> Seq.head).EndsWith("/microsoft.extensions.configuration.abstractions/3.1.1/"))
         ()
 
 /// Native dll resolution is not implemented on desktop
 #if NETCOREAPP
-    []
+    []
     member __.``Script using TorchSharp``() =
         let text = """
 #r "nuget:RestoreSources=https://donsyme.pkgs.visualstudio.com/TorchSharp/_packaging/packages2/nuget/v3/index.json"
@@ -235,12 +235,12 @@ TorchSharp.Tensor.LongTensor.From([| 0L .. 100L |]).Device
             use script = scriptHost()
             let opt = script.Eval(text) |> getValue
             let value = opt.Value
-            Assert.AreEqual(typeof, value.ReflectionType)
-            Assert.AreEqual("cpu", value.ReflectionValue :?> string)
+            Assert.Equal(typeof, value.ReflectionType)
+            Assert.Equal("cpu", value.ReflectionValue :?> string)
         ()
 
 
-    []
+    []
     member __.``Use Dependency Manager to restore packages with native dependencies, build and run script that depends on the results``() =
         let packagemanagerlines = [|
             "RestoreSources=https://dotnet.myget.org/F/dotnet-corefxlab/api/v3/index.json"
@@ -269,7 +269,7 @@ TorchSharp.Tensor.LongTensor.From([| 0L .. 100L |]).Device
             let idm = dp.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget")
             dp.Resolve(idm, ".fsx", packagemanagerlines, reportError, "netcoreapp3.1")
 
-        Assert.IsTrue(result.Success, "resolve failed")
+        Assert.True(result.Success, "resolve failed")
 
         resolverPackageRoots <- result.Roots
         resolverReferences <- result.Resolutions
@@ -335,9 +335,9 @@ printfn ""%A"" result
         use script = new FSharpScript()
         let opt = script.Eval(scriptText)  |> getValue
         let value = opt.Value
-        Assert.AreEqual(123, value.ReflectionValue :?> int32)
+        Assert.Equal(123, value.ReflectionValue :?> int32)
 
-    []
+    []
     member __.``Use NativeResolver to resolve native dlls.``() =
         let packagemanagerlines = [|
             "RestoreSources=https://dotnet.myget.org/F/dotnet-corefxlab/api/v3/index.json"
@@ -366,7 +366,7 @@ printfn ""%A"" result
             let idm = dp.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget")
             dp.Resolve(idm, ".fsx", packagemanagerlines, reportError, "netcoreapp3.1")
 
-        Assert.IsTrue(result.Success, "resolve failed")
+        Assert.True(result.Success, "resolve failed")
 
         resolverPackageRoots <- result.Roots
         resolverReferences <- result.Resolutions
@@ -418,9 +418,9 @@ printfn ""%A"" result
         use script = new FSharpScript()
         let opt = script.Eval(scriptText)  |> getValue
         let value = opt.Value
-        Assert.AreEqual(123, value.ReflectionValue :?> int32)
+        Assert.Equal(123, value.ReflectionValue :?> int32)
 
-    []
+    []
     member __.``Use AssemblyResolver to resolve assemblies``() =
         let packagemanagerlines = [|
             "RestoreSources=https://dotnet.myget.org/F/dotnet-corefxlab/api/v3/index.json"
@@ -448,7 +448,7 @@ printfn ""%A"" result
             let idm = dp.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget")
             dp.Resolve(idm, ".fsx", packagemanagerlines, reportError, "netcoreapp3.1")
 
-        Assert.IsTrue(result.Success, "resolve failed")
+        Assert.True(result.Success, "resolve failed")
 
         resolverPackageRoots <- result.Roots
         resolverReferences <- result.Resolutions
@@ -480,9 +480,9 @@ x |> Seq.iter(fun r ->
         use script = new FSharpScript()
         let opt = script.Eval(scriptText)  |> getValue
         let value = opt.Value
-        Assert.AreEqual(123, value.ReflectionValue :?> int32)
+        Assert.Equal(123, value.ReflectionValue :?> int32)
 
-    []
+    []
     member __.``Verify that referencing FSharp.Core fails with FSharp Scripts``() =
         let packagemanagerlines = [| "FSharp.Core,version=4.7.1" |]
 
@@ -506,9 +506,9 @@ x |> Seq.iter(fun r ->
             dp.Resolve(idm, ".fsx", packagemanagerlines, reportError, "netcoreapp3.1")
 
         // Expected: error FS3217: PackageManager can not reference the System Package 'FSharp.Core'
-        Assert.IsFalse(result.Success, "resolve succeeded but should have failed")
+        Assert.False(result.Success, "resolve succeeded but should have failed")
 
-    []
+    []
     member __.``Verify that referencing FSharp.Core succeeds with CSharp Scripts``() =
         let packagemanagerlines = [| "FSharp.Core,version=4.7.1" |]
 
@@ -531,10 +531,10 @@ x |> Seq.iter(fun r ->
             let idm = dp.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget")
             dp.Resolve(idm, ".csx", packagemanagerlines, reportError, "netcoreapp3.1")
 
-        Assert.IsTrue(result.Success, "resolve failed but should have succeeded")
+        Assert.True(result.Success, "resolve failed but should have succeeded")
 
 
-    []
+    []
     member __.``Verify that Dispose on DependencyProvider unhooks ResolvingUnmanagedDll event handler``() =
 
         let mutable found = false
@@ -555,32 +555,32 @@ x |> Seq.iter(fun r ->
 
             // Invoking a non-existent dll via pinvoke cause a probe. which should invoke the call back
             try Native.NoneSuch() |> ignore with _ -> ()
-            Assert.IsTrue (found, "Failed to invoke the nativeProbingRoots callback")
+            Assert.True (found, "Failed to invoke the nativeProbingRoots callback")
 
         // Here the dispose was invoked which should clear the ResolvingUnmanagedDll handler
         found <- false
         try Native.NoneSuch() |> ignore with _ -> ()
-        Assert.IsFalse (found, "Invoke the nativeProbingRoots callback -- Error the ResolvingUnmanagedDll still fired ")
+        Assert.False (found, "Invoke the nativeProbingRoots callback -- Error the ResolvingUnmanagedDll still fired ")
 
         use dp = new DependencyProvider(NativeResolutionProbe(nativeProbingRoots))
         let idm = dp.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget")
 
         if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then
             let result = dp.Resolve(idm, ".fsx", [|"FSharp.Data"|], reportError, "net472")
-            Assert.AreEqual(true, result.Success)
-            Assert.AreEqual(1, result.Resolutions |> Seq.length)
-            Assert.AreEqual(1, result.SourceFiles |> Seq.length)
-            Assert.AreEqual(1, result.Roots |> Seq.length)
+            Assert.Equal(true, result.Success)
+            Assert.Equal(1, result.Resolutions |> Seq.length)
+            Assert.Equal(1, result.SourceFiles |> Seq.length)
+            Assert.Equal(1, result.Roots |> Seq.length)
 
         let result = dp.Resolve(idm, ".fsx", [|"FSharp.Data"|], reportError, "netcoreapp3.1")
-        Assert.AreEqual(true, result.Success)
-        Assert.AreEqual(1, result.Resolutions |> Seq.length)
-        Assert.AreEqual(1, result.SourceFiles |> Seq.length)
-        Assert.AreEqual(1, result.Roots |> Seq.length)
+        Assert.Equal(true, result.Success)
+        Assert.Equal(1, result.Resolutions |> Seq.length)
+        Assert.Equal(1, result.SourceFiles |> Seq.length)
+        Assert.Equal(1, result.Roots |> Seq.length)
         ()
 
 
-    []
+    []
     member __.``Verify that Dispose on DependencyProvider unhooks ResolvingUnmanagedDll and AssemblyResolver event handler``() =
 
         let mutable assemblyFound = false
@@ -599,24 +599,24 @@ x |> Seq.iter(fun r ->
 
             // Invoking a non-existent dll via pinvoke cause a probe. which should invoke the call back
             try Native.NoneSuch() |> ignore with _ -> ()
-            Assert.IsTrue (nativeFound, "Failed to invoke the nativeProbingRoots callback")
+            Assert.True (nativeFound, "Failed to invoke the nativeProbingRoots callback")
 
             // Invoking a non-existent assembly causes a probe. which should invoke the call back
             try Assembly.Load("NoneSuchAssembly") |> ignore with _ -> ()
-            Assert.IsTrue (assemblyFound, "Failed to invoke the AssemblyResolve handler")
+            Assert.True (assemblyFound, "Failed to invoke the AssemblyResolve handler")
 
         // Here the dispose was invoked which should clear the ResolvingUnmanagedDll handler
         nativeFound <- false
         assemblyFound <- false
 
         try Native.NoneSuch() |> ignore with _ -> ()
-        Assert.IsFalse (nativeFound, "Invoke the nativeProbingRoots callback -- Error the ResolvingUnmanagedDll still fired ")
+        Assert.False (nativeFound, "Invoke the nativeProbingRoots callback -- Error the ResolvingUnmanagedDll still fired ")
 
         try Assembly.Load("NoneSuchAssembly") |> ignore with _ -> ()
-        Assert.IsFalse (assemblyFound, "Invoke the assemblyProbingRoots callback -- Error the AssemblyResolve still fired ")
+        Assert.False (assemblyFound, "Invoke the assemblyProbingRoots callback -- Error the AssemblyResolve still fired ")
 #endif
 
-    []
+    []
     member __.``Verify that Dispose on AssemblyResolveHandler unhooks AssemblyResolve event handler``() =
 
         let mutable assemblyFound = false
@@ -630,16 +630,16 @@ x |> Seq.iter(fun r ->
 
             // Invoking a non-existent assembly causes a probe. which should invoke the call back
             try Assembly.Load("NoneSuchAssembly") |> ignore with _ -> ()
-            Assert.IsTrue (assemblyFound, "Failed to invoke the AssemblyResolve handler")
+            Assert.True (assemblyFound, "Failed to invoke the AssemblyResolve handler")
 
         // Here the dispose was invoked which should clear the ResolvingUnmanagedDll handler
         assemblyFound <- false
 
         try Assembly.Load("NoneSuchAssembly") |> ignore with _ -> ()
-        Assert.IsFalse (assemblyFound, "Invoke the assemblyProbingRoots callback -- Error the AssemblyResolve still fired ")
+        Assert.False (assemblyFound, "Invoke the assemblyProbingRoots callback -- Error the AssemblyResolve still fired ")
 
 
-    []
+    []
     member __.``Verify that #help produces help text for fsi + dependency manager``() =
         let expected = [|
             """  F# Interactive directives:"""
@@ -685,7 +685,7 @@ x |> Seq.iter(fun r ->
         Assert.True(sawExpectedOutput.WaitOne(TimeSpan.FromSeconds(5.0)), sprintf "Expected to see error sentinel value written\nexpected:%A\nactual:%A" expected lines)
 
 
-    []
+    []
     member __.``Verify that #help produces help text for fsi + dependency manager language version preview``() =
         let expected = [|
             """  F# Interactive directives:"""
diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/DependencyManagerLineParserTests.fs b/tests/FSharp.Compiler.Private.Scripting.UnitTests/DependencyManagerLineParserTests.fs
index 98377faa09b..7f053975a76 100644
--- a/tests/FSharp.Compiler.Private.Scripting.UnitTests/DependencyManagerLineParserTests.fs
+++ b/tests/FSharp.Compiler.Private.Scripting.UnitTests/DependencyManagerLineParserTests.fs
@@ -4,9 +4,9 @@ namespace FSharp.DependencyManager.UnitTests
 
 open System.Linq
 open FSharp.DependencyManager.Nuget
-open NUnit.Framework
 
-[]
+open Xunit
+
 type DependencyManagerLineParserTests() =
 
     let parseBinLogPath text =
@@ -17,98 +17,98 @@ type DependencyManagerLineParserTests() =
         let packageReferences, _ = FSharpDependencyManager.parsePackageReference ".fsx" [text]
         packageReferences.Single()
 
-    []
+    []
     member __.``Binary logging defaults to disabled``() =
         let _, binLogPath = FSharpDependencyManager.parsePackageReference ".fsx" []
-        Assert.AreEqual(None, binLogPath)
+        Assert.Equal(None, binLogPath)
 
-    []
+    []
     member __.``Binary logging can be set to default path``() =
         let binLogPath = parseBinLogPath "bl=true"
-        Assert.AreEqual(Some (None: string option), binLogPath)
+        Assert.Equal(Some (None: string option), binLogPath)
 
-    []
+    []
     member __.``Binary logging can be disabled``() =
         let binLogPath = parseBinLogPath "bl=false"
-        Assert.AreEqual(None, binLogPath)
+        Assert.Equal(None, binLogPath)
 
-    []
+    []
     member __.``Binary logging can be set to specific location``() =
         let binLogPath = parseBinLogPath "bl=path/to/file.binlog"
-        Assert.AreEqual(Some(Some "path/to/file.binlog"), binLogPath)
+        Assert.Equal(Some(Some "path/to/file.binlog"), binLogPath)
 
-    []
+    []
     member __.``Bare binary log argument isn't parsed as a package name: before``() =
         let packageReferences, binLogPath = FSharpDependencyManager.parsePackageReference ".fsx" ["bl, MyPackage"]
-        Assert.AreEqual("MyPackage", packageReferences.Single().Include)
-        Assert.AreEqual(Some (None: string option), binLogPath)
+        Assert.Equal("MyPackage", packageReferences.Single().Include)
+        Assert.Equal(Some (None: string option), binLogPath)
 
-    []
+    []
     member __.``Bare binary log argument isn't parsed as a package name: middle``() =
         let packageReferences, binLogPath = FSharpDependencyManager.parsePackageReference ".fsx" ["MyPackage, bl, 1.2.3.4"]
-        Assert.AreEqual("MyPackage", packageReferences.Single().Include)
-        Assert.AreEqual("1.2.3.4", packageReferences.Single().Version)
-        Assert.AreEqual(Some (None: string option), binLogPath)
+        Assert.Equal("MyPackage", packageReferences.Single().Include)
+        Assert.Equal("1.2.3.4", packageReferences.Single().Version)
+        Assert.Equal(Some (None: string option), binLogPath)
 
-    []
+    []
     member __.``Bare binary log argument isn't parsed as a package name: after``() =
         let packageReferences, binLogPath = FSharpDependencyManager.parsePackageReference ".fsx" ["MyPackage, bl"]
-        Assert.AreEqual("MyPackage", packageReferences.Single().Include)
-        Assert.AreEqual(Some (None: string option), binLogPath)
+        Assert.Equal("MyPackage", packageReferences.Single().Include)
+        Assert.Equal(Some (None: string option), binLogPath)
 
-    []
+    []
     member __.``Package named 'bl' can be explicitly referenced``() =
         let packageReferences, binLogPath = FSharpDependencyManager.parsePackageReference ".fsx" ["Include=bl"]
-        Assert.AreEqual("bl", packageReferences.Single().Include)
-        Assert.AreEqual(None, binLogPath)
+        Assert.Equal("bl", packageReferences.Single().Include)
+        Assert.Equal(None, binLogPath)
 
-    []
+    []
     member __.``Package named 'bl' can be explicitly referenced with binary logging``() =
         let packageReferences, binLogPath = FSharpDependencyManager.parsePackageReference ".fsx" ["Include=bl,bl"]
-        Assert.AreEqual("bl", packageReferences.Single().Include)
-        Assert.AreEqual(Some (None: string option), binLogPath)
+        Assert.Equal("bl", packageReferences.Single().Include)
+        Assert.Equal(Some (None: string option), binLogPath)
 
-    []
+    []
     member __.``Parse explicitly specified package name``() =
         let pr = parseSingleReference "Include=MyPackage"
-        Assert.AreEqual("MyPackage", pr.Include)
+        Assert.Equal("MyPackage", pr.Include)
 
-    []
+    []
     member __.``Parse implicitly specified package name``() =
         let pr = parseSingleReference "MyPackage"
-        Assert.AreEqual("MyPackage", pr.Include)
+        Assert.Equal("MyPackage", pr.Include)
 
-    []
+    []
     member __.``Parse version number``() =
         let pr = parseSingleReference "MyPackage, Version=1.2.3.4"
-        Assert.AreEqual("1.2.3.4", pr.Version)
+        Assert.Equal("1.2.3.4", pr.Version)
 
-    []
+    []
     member __.``Parse implicitly specified package name and implicitly specified version number``() =
         let pr = parseSingleReference "MyPackage, 1.2.3.4"
-        Assert.AreEqual("MyPackage", pr.Include)
-        Assert.AreEqual("1.2.3.4", pr.Version)
+        Assert.Equal("MyPackage", pr.Include)
+        Assert.Equal("1.2.3.4", pr.Version)
 
-    []
+    []
     member __.``Parse single restore source``() =
         let pr = parseSingleReference "MyPackage, RestoreSources=MyRestoreSource"
-        Assert.AreEqual("MyRestoreSource", pr.RestoreSources)
+        Assert.Equal("MyRestoreSource", pr.RestoreSources)
 
-    []
+    []
     member __.``Parse multiple restore sources``() =
         let pr = parseSingleReference "MyPackage, RestoreSources=MyRestoreSource1, RestoreSources=MyRestoreSource2"
-        Assert.AreEqual("MyRestoreSource1;MyRestoreSource2", pr.RestoreSources)
+        Assert.Equal("MyRestoreSource1;MyRestoreSource2", pr.RestoreSources)
 
-    []
+    []
     member __.``Parse script``() =
         let pr = parseSingleReference "MyPackage, Script=SomeScript"
-        Assert.AreEqual("SomeScript", pr.Script)
+        Assert.Equal("SomeScript", pr.Script)
 
-    []
+    []
     member __.``Include strings that look different but parse the same are reduced to a single item``() =
         let prs, _ =
             [ "MyPackage, Version=1.2.3.4"
               "Include=MyPackage, Version=1.2.3.4" ]
             |> FSharpDependencyManager.parsePackageReference ".fsx" 
         let pr = prs.Single()
-        Assert.AreEqual("MyPackage", pr.Include)
+        Assert.Equal("MyPackage", pr.Include)
diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharp.Compiler.Private.Scripting.UnitTests.fsproj b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharp.Compiler.Private.Scripting.UnitTests.fsproj
index f7213d78671..2c159142462 100644
--- a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharp.Compiler.Private.Scripting.UnitTests.fsproj
+++ b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharp.Compiler.Private.Scripting.UnitTests.fsproj
@@ -6,7 +6,7 @@
     netcoreapp3.1
     Library
     true
-    nunit
+    xunit
     true
   
 
@@ -16,10 +16,14 @@
     
     
     
-    
     
   
 
+  
+    
+    
+  
+
   
     
     
diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs
index a437b95283d..2c7be153960 100644
--- a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs
+++ b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs
@@ -11,38 +11,38 @@ open System.Threading
 open System.Threading.Tasks
 open FSharp.Compiler.Interactive.Shell
 open FSharp.Compiler.Scripting
-open NUnit.Framework
 
-[]
+open Xunit
+
 type InteractiveTests() =
 
-    []
+    []
     member __.``Eval object value``() =
         use script = new FSharpScript()
         let opt = script.Eval("1+1") |> getValue
         let value = opt.Value
-        Assert.AreEqual(typeof, value.ReflectionType)
-        Assert.AreEqual(2, value.ReflectionValue :?> int)
+        Assert.Equal(typeof, value.ReflectionType)
+        Assert.Equal(2, value.ReflectionValue :?> int)
 
-    []
+    []
     member __.``Declare and eval object value``() =
         use script = new FSharpScript()
         let opt = script.Eval("let x = 1 + 2\r\nx") |> getValue
         let value = opt.Value
-        Assert.AreEqual(typeof, value.ReflectionType)
-        Assert.AreEqual(3, value.ReflectionValue :?> int)
+        Assert.Equal(typeof, value.ReflectionType)
+        Assert.Equal(3, value.ReflectionValue :?> int)
 
-    []
+    []
     member __.``Capture console input``() =
         use input = new RedirectConsoleInput()
         use script = new FSharpScript()
         input.ProvideInput "stdin:1234\r\n"
         let opt = script.Eval("System.Console.ReadLine()") |> getValue
         let value = opt.Value
-        Assert.AreEqual(typeof, value.ReflectionType)
-        Assert.AreEqual("stdin:1234", value.ReflectionValue)
+        Assert.Equal(typeof, value.ReflectionType)
+        Assert.Equal("stdin:1234", downcast value.ReflectionValue)
 
-    []
+    []
     member __.``Capture console output/error``() =
         use output = new RedirectConsoleOutput()
         use script = new FSharpScript()
@@ -54,16 +54,16 @@ type InteractiveTests() =
         Assert.True(sawOutputSentinel.WaitOne(TimeSpan.FromSeconds(5.0)), "Expected to see output sentinel value written")
         Assert.True(sawErrorSentinel.WaitOne(TimeSpan.FromSeconds(5.0)), "Expected to see error sentinel value written")
 
-    []
+    []
     member __.``Maintain state between submissions``() =
         use script = new FSharpScript()
         script.Eval("let add x y = x + y") |> ignoreValue
         let opt = script.Eval("add 2 3") |> getValue
         let value = opt.Value
-        Assert.AreEqual(typeof, value.ReflectionType)
-        Assert.AreEqual(5, value.ReflectionValue :?> int)
+        Assert.Equal(typeof, value.ReflectionType)
+        Assert.Equal(5, downcast value.ReflectionValue)
 
-    []
+    []
     member __.``Assembly reference event successful``() =
         use script = new FSharpScript()
         let testCode = """
@@ -73,53 +73,53 @@ stacktype.Name = "Stack"
 """
         let opt = script.Eval(testCode) |> getValue
         let value = opt.Value
-        Assert.AreEqual(true, value.ReflectionValue :?> bool)
+        Assert.Equal(true, downcast value.ReflectionValue)
 
-    []
+    []
     member __.``Assembly reference unsuccessful``() =
         use script = new FSharpScript()
         let testAssembly = "not-an-assembly-that-can-be-found.dll"
         let _result, errors = script.Eval(sprintf "#r \"%s\"" testAssembly)
-        Assert.AreEqual(1, errors.Length)
+        Assert.Equal(1, errors.Length)
 
-    []
+    []
     member _.``Compilation errors report a specific exception``() =
         use script = new FSharpScript()
         let result, _errors = script.Eval("abc")
         match result with
-        | Ok(_) -> Assert.Fail("expected a failure")
-        | Error(ex) -> Assert.IsInstanceOf(ex)
+        | Ok(_) -> Assert.False(true, "expected a failure")
+        | Error(ex) -> Assert.IsAssignableFrom(typeof, ex)
 
-    []
+    []
     member _.``Runtime exceptions are propagated``() =
         use script = new FSharpScript()
         let result, errors = script.Eval("System.IO.File.ReadAllText(\"not-a-file-path-that-can-be-found-on-disk.txt\")")
-        Assert.IsEmpty(errors)
+        Assert.Empty(errors)
         match result with
-        | Ok(_) -> Assert.Fail("expected a failure")
-        | Error(ex) -> Assert.IsInstanceOf(ex)
+        | Ok(_) -> Assert.True(false, "expected a failure")
+        | Error(ex) -> Assert.IsAssignableFrom(typeof, ex)
 
-    []
+    []
     member _.``Script with #r "" errors``() =
         use script = new FSharpScript()
         let result, errors = script.Eval("#r \"\"")
-        Assert.IsNotEmpty(errors)
+        Assert.NotEmpty(errors)
         match result with
-        | Ok(_) -> Assert.Fail("expected a failure")
-        | Error(ex) -> Assert.IsInstanceOf(ex)
+        | Ok(_) -> Assert.False(true, "expected a failure")
+        | Error(ex) -> Assert.IsAssignableFrom(typeof, ex)
 
-    []
+    []
     member _.``Script with #r "    " errors``() =
         use script = new FSharpScript()
         let result, errors = script.Eval("#r \"    \"")
-        Assert.IsNotEmpty(errors)
+        Assert.NotEmpty(errors)
         match result with
-        | Ok(_) -> Assert.Fail("expected a failure")
-        | Error(ex) -> Assert.IsInstanceOf(ex)
+        | Ok(_) -> Assert.False(true, "expected a failure")
+        | Error(ex) -> Assert.IsAssignableFrom(typeof, ex)
 
 /// Native dll resolution is not implemented on desktop
 #if NETSTANDARD
-    []
+    []
     member __.``ML - use assembly with native dependencies``() =
         let code = @"
 #r ""nuget:RestoreSources=https://dotnet.myget.org/F/dotnet-corefxlab/api/v3/index.json""
@@ -163,18 +163,18 @@ printfn ""%A"" result
         use script = new FSharpScript(additionalArgs=[|"/langversion:preview"|])
         let opt = script.Eval(code)  |> getValue
         let value = opt.Value
-        Assert.AreEqual(123, value.ReflectionValue :?> int32)
+        Assert.Equal(123, value.ReflectionValue :?> int32)
 #endif
 
-    []
+    []
     member __.``Eval script with package manager invalid key``() =
         use script = new FSharpScript(additionalArgs=[|"/langversion:preview"|])
         let result, _errors = script.Eval(@"#r ""nugt:FSharp.Data""")
         match result with
-        | Ok(_) -> Assert.Fail("expected a failure")
-        | Error(ex) -> Assert.IsInstanceOf(ex)
+        | Ok(_) -> Assert.False(true, "expected a failure")
+        | Error(ex) -> Assert.IsAssignableFrom(typeof, ex)
 
-    []
+    []
     member __.``Eval script with invalid PackageName should fail immediately``() =
         use output = new RedirectConsoleOutput()
         use script = new FSharpScript(additionalArgs=[|"/langversion:preview"|])
@@ -188,7 +188,7 @@ printfn ""%A"" result
         let _result, _errors = script.Eval("""#r "nuget:FSharp.Really.Not.A.Package" """)
         Assert.True( (found = 1), "Expected to see output contains 'error NU1101:' and 'FSharp.Really.Not.A.Package'")
 
-    []
+    []
     member __.``Eval script with invalid PackageName should fail immediately and resolve one time only``() =
         use output = new RedirectConsoleOutput()
         use script = new FSharpScript(additionalArgs=[|"/langversion:preview"|])
@@ -201,24 +201,24 @@ printfn ""%A"" result
                 """)
         Assert.True( (foundResolve = 1), (sprintf "Expected to see 'Microsoft (R) Build Engine version' only once actually resolved %d times" foundResolve))
 
-    []
+    []
     member __.``ML - use assembly with ref dependencies``() =
-        let code = @"
-#r ""nuget:Microsoft.ML.OnnxTransformer,1.4.0""
+        let code = """
+#r "nuget:Microsoft.ML.OnnxTransformer,1.4.0"
+#r "nuget:System.Memory,4.5.4"
 
 open System
 open System.Numerics.Tensors
 let inputValues = [| 12.0; 10.0; 17.0; 5.0 |]
 let tInput = new DenseTensor(inputValues.AsMemory(), new ReadOnlySpan([|4|]))
 tInput.Length
-"
+"""
         use script = new FSharpScript(additionalArgs=[|"/langversion:preview"|])
         let opt = script.Eval(code)  |> getValue
         let value = opt.Value
-        Assert.AreEqual(4L, value.ReflectionValue :?> int64)
-
+        Assert.Equal(4L, downcast value.ReflectionValue)
 
-    []
+    []
     member __.``System.Device.Gpio - Ensure we reference the runtime version of the assembly``() =
         let code = """
 #r "nuget:System.Device.Gpio"
@@ -229,14 +229,14 @@ typeof.Assembly.Location
         let value = opt.Value
 
         if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then
-            Assert.IsTrue( (value.ReflectionValue :?> string).EndsWith(@"runtimes\win\lib\netstandard2.0\System.Device.Gpio.dll") )
+            Assert.True( (value.ReflectionValue :?> string).EndsWith(@"runtimes\win\lib\netstandard2.0\System.Device.Gpio.dll") )
         else if RuntimeInformation.IsOSPlatform(OSPlatform.Linux) then
-            Assert.IsTrue( (value.ReflectionValue :?> string).EndsWith(@"runtimes/linux/lib/netstandard2.0/System.Device.Gpio.dll") )
+            Assert.True( (value.ReflectionValue :?> string).EndsWith(@"runtimes/linux/lib/netstandard2.0/System.Device.Gpio.dll") )
         else
             // Only Windows/Linux supported.
             ()
 
-    []
+    []
     member __.``Simple pinvoke should not be impacted by native resolver``() =
         let code = @"
 open System
@@ -259,12 +259,12 @@ else
         use script = new FSharpScript(additionalArgs=[|"/langversion:preview"|])
         let opt = script.Eval(code)  |> getValue
         let value = opt.Value
-        Assert.AreEqual(123, value.ReflectionValue :?> int32)
+        Assert.Equal(123, value.ReflectionValue :?> int32)
 
-    []
+    []
     member _.``Evaluation can be cancelled``() =
         use script = new FSharpScript()
-        let sleepTime = 10000
+        let sleepTime = 10000L
         let mutable result = None
         let mutable wasCancelled = false
         use tokenSource = new CancellationTokenSource()
@@ -281,10 +281,10 @@ else
         evalTask.GetAwaiter().GetResult()
         // ensure we cancelled and didn't complete the sleep or evaluation
         Assert.True(wasCancelled)
-        Assert.LessOrEqual(sw.ElapsedMilliseconds, sleepTime)
-        Assert.AreEqual(None, result)
+        Assert.Equal(sw.ElapsedMilliseconds, sleepTime)
+        Assert.Equal(None, result)
 
-    []
+    []
     member _.``Values bound at the root trigger an event``() =
         let mutable foundX = false
         let mutable foundY = false
@@ -302,9 +302,9 @@ let y = 2
         script.Eval(code) |> ignoreValue
         Assert.True(foundX)
         Assert.True(foundY)
-        Assert.AreEqual(2, foundCount)
+        Assert.Equal(2, foundCount)
 
-    []
+    []
     member _.``Values re-bound trigger an event``() =
         let mutable foundXCount = 0
         use script = new FSharpScript()
@@ -313,9 +313,9 @@ let y = 2
             if name = "x" && typ = typeof then foundXCount <- foundXCount + 1)
         script.Eval("let x = 1") |> ignoreValue
         script.Eval("let x = 2") |> ignoreValue
-        Assert.AreEqual(2, foundXCount)
+        Assert.Equal(2, foundXCount)
 
-    []
+    []
     member _.``Nested let bindings don't trigger event``() =
         let mutable foundInner = false
         use script = new FSharpScript()
@@ -330,10 +330,9 @@ let x =
         script.Eval(code) |> ignoreValue
         Assert.False(foundInner)
 
-    []
+    []
     member _.``Script with nuget package that yields out of order dependencies works correctly``() =
         // regression test for: https://github.com/dotnet/fsharp/issues/9217
-
         let code = """
 #r "nuget: FParsec,1.1.1"
 
@@ -352,4 +351,4 @@ test pfloat "1.234"
         use script = new FSharpScript(additionalArgs=[|"/langversion:preview"|])
         let opt = script.Eval(code)  |> getValue
         let value = opt.Value
-        Assert.AreEqual(true, value.ReflectionValue :?> bool)
+        Assert.True(true = downcast value.ReflectionValue)
diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/xunit.runner.json b/tests/FSharp.Compiler.Private.Scripting.UnitTests/xunit.runner.json
new file mode 100644
index 00000000000..ff6ac3098c1
--- /dev/null
+++ b/tests/FSharp.Compiler.Private.Scripting.UnitTests/xunit.runner.json
@@ -0,0 +1,7 @@
+{
+  "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
+    "appDomain": "denied",
+    "shadowCopy": false,
+    "parallelizeTestCollections": false,
+    "maxParallelThreads": 1
+}
diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
index 63dc0d0f729..a8c93d63ea9 100644
--- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
+++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
@@ -15,6 +15,7 @@
     false
     true
     true
+    nunit
   
 
   
@@ -83,9 +84,6 @@
 
   
     
-    
-    
-    
     
   
 
diff --git a/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj b/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj
index b2da868585d..996ee46b4a3 100644
--- a/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj
+++ b/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj
@@ -12,11 +12,11 @@
     $(NoWarn);3186;1104
   
 
-	
-		
-	
+    
+        
+    
 
-	
+    
     
     
     
diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs
index 49f25574437..c5ab4c36e70 100644
--- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs
+++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs
@@ -8,6 +8,19 @@ namespace FSharp.Core.UnitTests.Operators
 open System
 open FSharp.Core.UnitTests.LibraryTestFx
 open NUnit.Framework
+open System.Globalization
+open System.Threading
+
+/// If this type compiles without error it is correct
+/// Wrong if you see: FS0670 This code is not sufficiently generic. The type variable ^T could not be generalized because it would escape its scope.
+type TestFs0670Error<'T> =
+    | TestFs0670Error of 'T
+    override this.ToString() =
+        match this with
+        | TestFs0670Error x -> 
+            // This used to raise FS0670 because the type is generic, and 'string' was inline
+            // See: https://github.com/dotnet/fsharp/issues/7958
+            Operators.string x
 
 []
 type OperatorsModule2() =
@@ -732,6 +745,53 @@ type OperatorsModule2() =
         // reference type
         let result = Operators.string "ABC"
         Assert.AreEqual("ABC", result)
+
+        // reference type without a `ToString()` overload
+        let result = Operators.string (obj())
+        Assert.AreEqual("System.Object", result)
+
+        let result = Operators.string 1un
+        Assert.AreEqual("1", result)
+
+        let result = Operators.string (obj())
+        Assert.AreEqual("System.Object", result)
+
+        let result = Operators.string 123.456M
+        Assert.AreEqual("123.456", result)
+
+        // Following tests ensure that InvariantCulture is used if type implements IFormattable
+        
+        // safe current culture, then switch culture
+        let currentCI = Thread.CurrentThread.CurrentCulture
+        Thread.CurrentThread.CurrentCulture <- CultureInfo.GetCultureInfo("de-DE")
+
+        // make sure the culture switch happened, and verify
+        let wrongResult = 123.456M.ToString()
+        Assert.AreEqual("123,456", wrongResult)
+
+        // test that culture has no influence on decimals with `string`
+        let correctResult = Operators.string 123.456M
+        Assert.AreEqual("123.456", correctResult)
+
+        // make sure that the German culture is indeed selected for DateTime
+        let dttm = DateTime(2020, 6, 23)
+        let wrongResult = dttm.ToString()
+        Assert.AreEqual("23.06.2020 00:00:00", wrongResult)
+
+        // test that culture has no influence on DateTime types when used with `string`
+        let correctResult = Operators.string dttm
+        Assert.AreEqual("06/23/2020 00:00:00", correctResult)
+
+        // reset the culture
+        Thread.CurrentThread.CurrentCulture <- currentCI
+
+    []
+    member _.``string: don't raise FS0670 anymore``() =
+        // The type used here, when compiled, should not raise this error:
+        // "FS0670 This code is not sufficiently generic. The type variable ^T could not be generalized because it would escape its scope."
+        // See: https://github.com/dotnet/fsharp/issues/7958
+        let result = TestFs0670Error 32uy |> Operators.string
+        Assert.AreEqual("32", result)
         
     []
     member _.tan() =
diff --git a/tests/fsharp/Compiler/Language/DefaultInterfaceMemberTests.fs b/tests/fsharp/Compiler/Language/DefaultInterfaceMemberTests.fs
index 0dc7b3a71e8..ff0abf3091e 100644
--- a/tests/fsharp/Compiler/Language/DefaultInterfaceMemberTests.fs
+++ b/tests/fsharp/Compiler/Language/DefaultInterfaceMemberTests.fs
@@ -810,7 +810,7 @@ type Test () =
         member __.M(_x: int) = Console.Write("InTest")
 
         member __.M<'Item> (x: int, y: 'Item) = 
-            Console.Write(string x)
+            Console.Write(x.ToString())
             Console.Write(y.ToString ())
 
         member __.M<'TTT> (x: 'TTT) =
@@ -818,7 +818,7 @@ type Test () =
 
         member __.M (x: int, text: string) =
             Console.Write("ABC")
-            Console.Write(string x)
+            Console.Write(x.ToString())
             Console.Write(text)
 
         member __.M<'U> (_x: 'U, _y: int) = ()
@@ -1166,7 +1166,8 @@ type Test () =
 let main _ =
     let x = Test () :> I1
     let y = Test () :> I2
-    Console.Write(string (x + y))
+    let result = x + y
+    Console.Write(result.ToString())
     0
             """
 
@@ -4229,7 +4230,7 @@ type Test () =
         member __.M(_x: int) = Console.Write("InTest")
 
         member __.M<'Item> (x: int, y: 'Item) = 
-            Console.Write(string x)
+            Console.Write(x.ToString())
             Console.Write(y.ToString ())
 
         member __.M<'TTT> (x: 'TTT) =
@@ -4237,7 +4238,7 @@ type Test () =
 
         member __.M (x: int, text: string) =
             Console.Write("ABC")
-            Console.Write(string x)
+            Console.Write(x.ToString())
             Console.Write(text)
 
 type Test2 () =
diff --git a/tests/fsharp/Compiler/Language/OpenTypeDeclarationTests.fs b/tests/fsharp/Compiler/Language/OpenTypeDeclarationTests.fs
index a605b3723f6..e265a16a8ae 100644
--- a/tests/fsharp/Compiler/Language/OpenTypeDeclarationTests.fs
+++ b/tests/fsharp/Compiler/Language/OpenTypeDeclarationTests.fs
@@ -994,7 +994,7 @@ module Test2 =
         |> shouldSucceed
         |> ignore
 
-    []
+    []
     let ``Open generic union should have access to union cases with the enclosing type instantiations`` () =
         FSharp """
 namespace FSharpTest
@@ -1017,7 +1017,30 @@ module Test2 =
         """
         |> withLangVersionPreview
         |> compile
-        |> shouldFail
+        |> withErrorCode 1
+        |> ignore
+
+    []
+    let ``Open generic union should have access to pattern union cases with the enclosing type instantiations - Errors`` () =
+        FSharp """
+namespace FSharpTest
+
+module Test =
+
+    type TestUnion<'T> =
+        | UCase1 of 'T
+
+open type Test.TestUnion
+
+module Test2 =
+
+    let f x : string =
+        match x with
+        | UCase1 x -> x
+        """
+        |> withLangVersionPreview
+        |> compile
+        |> withErrorCode 1
         |> ignore
 
     []
@@ -1044,7 +1067,7 @@ module Test2 =
         |> shouldSucceed
         |> ignore
 
-    []
+    []
     let ``Open generic record should have access to construct record via labels with enclosing type instantiations`` () =
         FSharp """
 namespace FSharpTest
@@ -1055,17 +1078,53 @@ module Test =
 
         static member M() = ()
 
-open type Test.TestRecord
+open Test
 
 module Test2 =
 
     let x = { X = "" }
 
+open type Test.TestRecord
+
+module Test3 =
+
+    let x = { X = "" }
+
     let y = M()
         """
         |> withLangVersionPreview
         |> compile
-        |> shouldFail
+        |> withErrorCode 1
+        |> ignore
+
+    []
+    let ``Open generic record should have access to pattern record via labels with enclosing type instantiations - Errors`` () =
+        FSharp """
+namespace FSharpTest
+
+module Test =
+
+    type TestRecord<'T> = { X: 'T }
+
+open Test
+
+module Test2 =
+
+    let f x : string =
+        match x with
+        | { X = x } -> x
+
+open type Test.TestRecord
+
+module Test3 =
+
+    let f x : string =
+        match x with
+        | { X = x } -> x
+        """
+        |> withLangVersionPreview
+        |> compile
+        |> withErrorCode 1
         |> ignore
 
     []
@@ -2207,7 +2266,7 @@ let main _ =
             |> withName "provider"
             |> ignoreWarnings
             |> withLangVersionPreview
-
+            
         let provided =
             Fsx (sprintf """
 #load @"%s"
@@ -2289,6 +2348,7 @@ if StaticProperty1 <> "You got a static property" then
             |> withName "provider"
             |> withLangVersionPreview
             |> ignoreWarnings
+            |> withLangVersionPreview
 
         let provided =
             Fsx (sprintf """
@@ -2297,6 +2357,7 @@ if StaticProperty1 <> "You got a static property" then
             |> withName "provided"
             |> withLangVersionPreview
             |> ignoreWarnings
+            |> withLangVersionPreview
 
         let test =
             Fsx """
@@ -2324,6 +2385,7 @@ if StaticProperty1 <> "You got a static property" then
             |> withName "provider"
             |> withLangVersionPreview
             |> ignoreWarnings
+            |> withLangVersionPreview
 
         let provided =
             Fsx (sprintf """
@@ -2332,6 +2394,7 @@ if StaticProperty1 <> "You got a static property" then
             |> withName "provided"
             |> withLangVersionPreview
             |> ignoreWarnings
+            |> withLangVersionPreview
 
         let test =
             Fsx """
@@ -2360,6 +2423,7 @@ let _ : TheNestedGeneratedType = Unchecked.defaultof<_>
             |> withName "provider"
             |> withLangVersionPreview
             |> ignoreWarnings
+            |> withLangVersionPreview
 
         let provided =
             Fsx (sprintf """
@@ -2368,6 +2432,7 @@ let _ : TheNestedGeneratedType = Unchecked.defaultof<_>
             |> withName "provided"
             |> withLangVersionPreview
             |> ignoreWarnings
+            |> withLangVersionPreview
 
         let test =
             Fsx """
diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs
index b2198e71748..0838d447c8e 100644
--- a/tests/service/ExprTests.fs
+++ b/tests/service/ExprTests.fs
@@ -22,6 +22,17 @@ open FSharp.Compiler.Service.Tests.Common
 
 let internal exprChecker = FSharpChecker.Create(keepAssemblyContents=true)
 
+type FSharpCore = 
+    | FC45 
+    | FC46 
+    | FC47
+
+    static member fsharpVersion fc =
+        match fc with
+        | FC45 -> "FSharp.Core 4.5"
+        | FC46 -> "FSharp.Core 4.6"
+        | FC47 -> "FSharp.Core 4.7"
+
 
 []
 module internal Utils = 
@@ -1002,8 +1013,17 @@ let testOperators dnName fsName excludedTests expectedUnoptimized expectedOptimi
         let options =  checker.GetProjectOptionsFromCommandLineArgs (projFilePath, args)
 
         let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunSynchronously
-
-        for r in wholeProjectResults.ProjectContext.GetReferencedAssemblies() do
+        let referencedAssemblies = wholeProjectResults.ProjectContext.GetReferencedAssemblies()
+        let currentAssemblyToken =
+            let fsCore = referencedAssemblies |> List.tryFind (fun asm -> asm.SimpleName = "FSharp.Core")
+            match fsCore with
+            | Some core -> 
+                if core.QualifiedName.StartsWith("FSharp.Core, Version=4.7") then  FC47
+                elif core.QualifiedName.StartsWith("FSharp.Core, Version=4.6") then FC46
+                else FC45
+            | None -> FC45
+
+        for r in referencedAssemblies do
             printfn "Referenced assembly %s: %O" r.QualifiedName r.FileName
 
         let errors = StringBuilder()
@@ -1014,16 +1034,60 @@ let testOperators dnName fsName excludedTests expectedUnoptimized expectedOptimi
         errors.ToString() |> shouldEqual ""
         wholeProjectResults.Errors.Length |> shouldEqual 0
 
-        let fileUnoptimized = wholeProjectResults.AssemblyContents.ImplementationFiles.[0]
-        let fileOptimized = wholeProjectResults.GetOptimizedAssemblyContents().ImplementationFiles.[0]
+        let resultUnoptimized = 
+            wholeProjectResults.AssemblyContents.ImplementationFiles.[0].Declarations 
+            |> printDeclarations None
+            |> Seq.toList
+
+        let resultOptimized = 
+            wholeProjectResults.GetOptimizedAssemblyContents().ImplementationFiles.[0].Declarations 
+            |> printDeclarations None
+            |> Seq.toList
+
+        let mutable countFC45 = 0
+        let mutable countFC46 = 0
+        let mutable countFC47 = 0
+
+        /// Filter for allowed FSharp.Core definition. Optimizations can differ between Core versions
+        let filterTests result expected =
+            List.zip result expected
+            |> List.choose (fun (result, (when', s)) ->
+                if List.isEmpty when' then 
+                    countFC45 <- countFC45 + 1
+                    countFC46 <- countFC46 + 1
+                    countFC47 <- countFC47 + 1
+                    Some(result, s)
+                else
+                    if when' |> List.contains FC45 then countFC45 <- countFC45 + 1
+                    if when' |> List.contains FC46 then countFC46 <- countFC46 + 1
+                    if when' |> List.contains FC47 then countFC47 <- countFC47 + 1
+                    if when' |> List.contains currentAssemblyToken then
+                        Some(result, s)
+                    else 
+                        None)
+            |> List.unzip
+
+        printfn ""
+        printfn "Running in %O mode (%s)" currentAssemblyToken (FSharpCore.fsharpVersion currentAssemblyToken)
+
+        let resultUnoptFiltered, expectedUnoptFiltered = filterTests resultUnoptimized expectedUnoptimized
+        printfn "Unoptimized FC45 tests: %i, FC46 tests: %i, FC47 tests: %i" countFC45 countFC46 countFC47
+        printfn "Unfiltered unoptimized: %i, filtered: %i" (List.length expectedUnoptimized) (List.length expectedUnoptFiltered)
+
+        countFC45 <- 0
+        countFC46 <- 0
+        countFC47 <- 0
+        let resultOptFiltered, expectedOptFiltered = filterTests resultOptimized expectedOptimized
+        printfn "Optimized FC45 tests: %i, FC46 tests: %i, FC47 tests: %i" countFC45 countFC46 countFC47
+        printfn "Unfiltered optimized: %i, filtered: %i" (List.length expectedOptimized) (List.length expectedOptFiltered)
 
         // fail test on first line that fails, show difference in output window
-        printDeclarations None (List.ofSeq fileUnoptimized.Declarations)
-        |> shouldPairwiseEqual expectedUnoptimized
+        resultUnoptFiltered
+        |> shouldPairwiseEqual expectedUnoptFiltered
 
         // fail test on first line that fails, show difference in output window
-        printDeclarations None (List.ofSeq fileOptimized.Declarations)
-        |> shouldPairwiseEqual expectedOptimized
+        resultOptFiltered
+        |> shouldPairwiseEqual expectedOptFiltered
 
     finally
         Utils.cleanupTempFiles [filePath; dllPath; projFilePath]
@@ -1038,107 +1102,103 @@ let ``Test Operator Declarations for Byte`` () =
       ]
     
     let expectedUnoptimized = [
-        "type OperatorTestsByte";
-        "let testByteEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,63--4,72)";
-        "let testByteNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,63--5,73)";
-        "let testByteLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,63--6,72)";
-        "let testByteLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,63--7,73)";
-        "let testByteGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,63--8,72)";
-        "let testByteGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,63--9,73)";
-        "let testByteAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,55--11,64)";
-        "let testByteSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,55--12,64)";
-        "let testByteMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,55--13,64)";
-        "let testByteDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,55--14,64)";
-        "let testByteModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,55--15,64)";
-        "let testByteBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,55--16,66)";
-        "let testByteBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,55--17,66)";
-        "let testByteBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,55--18,66)";
-        "let testByteShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,54--19,65)";
-        "let testByteShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,54--20,65)";
-        "let testByteAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,53--24,70)";
-        "let testByteSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,53--25,70)";
-        "let testByteMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,53--26,70)";
-        "let testByteToByteChecked(e1) = Checked.ToByte (e1) @ (29,43--29,58)";
-        "let testByteToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,43--30,59)";
-        "let testByteToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,43--31,59)";
-        "let testByteToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,43--32,60)";
-        "let testByteToIntChecked(e1) = Checked.ToInt (e1) @ (33,43--33,57)";
-        "let testByteToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,43--34,59)";
-        "let testByteToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,43--35,60)";
-        "let testByteToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,43--36,59)";
-        "let testByteToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,43--37,60)";
-        "let testByteToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,43--38,63)";
-        "let testByteToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,43--39,64)";
-        "let testByteToByteOperator(e1) = Operators.ToByte (e1) @ (41,43--41,50)";
-        "let testByteToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,43--42,51)";
-        "let testByteToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,43--43,51)";
-        "let testByteToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,43--44,52)";
-        "let testByteToIntOperator(e1) = Operators.ToInt (e1) @ (45,43--45,49)";
-        "let testByteToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,43--46,51)";
-        "let testByteToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,43--47,52)";
-        "let testByteToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,43--48,51)";
-        "let testByteToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,43--49,52)";
-        "let testByteToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,43--50,55)";
-        "let testByteToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,43--51,56)";
-        "let testByteToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,43--52,53)";
-        "let testByteToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,43--53,51)";
-        "let testByteToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,43--54,53)";
-        "let testByteToCharOperator(e1) = Operators.ToChar (e1) @ (55,43--55,50)";
-        "let testByteToStringOperator(e1) = Operators.ToString (e1) @ (56,43--56,52)";
+        [], "type OperatorTestsByte";
+        [], "let testByteEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,63--4,72)";
+        [], "let testByteNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,63--5,73)";
+        [], "let testByteLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,63--6,72)";
+        [], "let testByteLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,63--7,73)";
+        [], "let testByteGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,63--8,72)";
+        [], "let testByteGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,63--9,73)";
+        [], "let testByteAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,55--11,64)";
+        [], "let testByteSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,55--12,64)";
+        [], "let testByteMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,55--13,64)";
+        [], "let testByteDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,55--14,64)";
+        [], "let testByteModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,55--15,64)";
+        [], "let testByteBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,55--16,66)";
+        [], "let testByteBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,55--17,66)";
+        [], "let testByteBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,55--18,66)";
+        [], "let testByteShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,54--19,65)";
+        [], "let testByteShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,54--20,65)";
+        [], "let testByteAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,53--24,70)";
+        [], "let testByteSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,53--25,70)";
+        [], "let testByteMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,53--26,70)";
+        [], "let testByteToByteChecked(e1) = Checked.ToByte (e1) @ (29,43--29,58)";
+        [], "let testByteToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,43--30,59)";
+        [], "let testByteToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,43--31,59)";
+        [], "let testByteToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,43--32,60)";
+        [], "let testByteToIntChecked(e1) = Checked.ToInt (e1) @ (33,43--33,57)";
+        [], "let testByteToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,43--34,59)";
+        [], "let testByteToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,43--35,60)";
+        [], "let testByteToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,43--36,59)";
+        [], "let testByteToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,43--37,60)";
+        [], "let testByteToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,43--38,63)";
+        [], "let testByteToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,43--39,64)";
+        [], "let testByteToByteOperator(e1) = Operators.ToByte (e1) @ (41,43--41,50)";
+        [], "let testByteToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,43--42,51)";
+        [], "let testByteToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,43--43,51)";
+        [], "let testByteToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,43--44,52)";
+        [], "let testByteToIntOperator(e1) = Operators.ToInt (e1) @ (45,43--45,49)";
+        [], "let testByteToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,43--46,51)";
+        [], "let testByteToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,43--47,52)";
+        [], "let testByteToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,43--48,51)";
+        [], "let testByteToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,43--49,52)";
+        [], "let testByteToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,43--50,55)";
+        [], "let testByteToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,43--51,56)";
+        [], "let testByteToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,43--52,53)";
+        [], "let testByteToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,43--53,51)";
+        [], "let testByteToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,43--54,53)";
+        [], "let testByteToCharOperator(e1) = Operators.ToChar (e1) @ (55,43--55,50)";
+        [], "let testByteToStringOperator(e1) = Operators.ToString (e1) @ (56,43--56,52)";
       ]
 
     let expectedOptimized = [
-        "type OperatorTestsByte";
-        "let testByteEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,63--4,72)";
-        "let testByteNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,63--5,73)";
-        "let testByteLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,63--6,72)";
-        "let testByteLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,63--7,73)";
-        "let testByteGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,63--8,72)";
-        "let testByteGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,63--9,73)";
-        "let testByteAdditionOperator(e1) (e2) = Operators.ToByte (Operators.op_Addition (e1,e2)) @ (11,55--11,64)";
-        "let testByteSubtractionOperator(e1) (e2) = Operators.ToByte (Operators.op_Subtraction (e1,e2)) @ (12,55--12,64)";
-        "let testByteMultiplyOperator(e1) (e2) = Operators.ToByte (Operators.op_Multiply (e1,e2)) @ (13,55--13,64)";
-        "let testByteDivisionOperator(e1) (e2) = Operators.ToByte (Operators.op_Division (e1,e2)) @ (14,55--14,64)";
-        "let testByteModulusOperator(e1) (e2) = Operators.ToByte (Operators.op_Modulus (e1,e2)) @ (15,55--15,64)";
-        "let testByteBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,55--16,66)";
-        "let testByteBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,55--17,66)";
-        "let testByteBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,55--18,66)";
-        "let testByteShiftLeftOperator(e1) (e2) = Operators.ToByte (Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,7))) @ (19,54--19,65)";
-        "let testByteShiftRightOperator(e1) (e2) = Operators.ToByte (Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,7))) @ (20,54--20,65)";
-        "let testByteAdditionChecked(e1) (e2) = Checked.ToByte (Checked.op_Addition (e1,e2)) @ (24,53--24,70)";
-        "let testByteSubtractionChecked(e1) (e2) = Checked.ToByte (Checked.op_Subtraction (e1,e2)) @ (25,53--25,70)";
-        "let testByteMultiplyChecked(e1) (e2) = Checked.ToByte (Checked.op_Multiply (e1,e2)) @ (26,53--26,70)";
-        "let testByteToByteChecked(e1) = Checked.ToByte (e1) @ (29,43--29,58)";
-        "let testByteToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,43--30,59)";
-        "let testByteToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,43--31,59)";
-        "let testByteToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,43--32,60)";
-        "let testByteToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,43--33,57)";
-        "let testByteToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,43--34,59)";
-        "let testByteToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,43--35,60)";
-        "let testByteToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,43--36,59)";
-        "let testByteToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,43--37,60)";
-        "let testByteToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,43--38,63)";
-        "let testByteToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,43--39,64)";
-        "let testByteToByteOperator(e1) = Operators.ToByte (e1) @ (41,43--41,50)";
-        "let testByteToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,43--42,51)";
-        "let testByteToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,43--43,51)";
-        "let testByteToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,43--44,52)";
-        "let testByteToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,43--45,49)";
-        "let testByteToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,43--46,51)";
-        "let testByteToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,43--47,52)";
-        "let testByteToInt64Operator(e1) = Operators.ToUInt64 (e1) @ (48,43--48,51)";
-        "let testByteToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,43--49,52)";
-        "let testByteToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,43--50,55)";
-        "let testByteToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,43--51,56)";
-        "let testByteToSingleOperator(e1) = Operators.ToSingle (Operators.ToDouble (e1)) @ (52,43--52,53)";
-        "let testByteToDoubleOperator(e1) = Operators.ToDouble (Operators.ToDouble (e1)) @ (53,43--53,51)";
-        "let testByteToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,43--54,53)";
-        "let testByteToCharOperator(e1) = Operators.ToChar (e1) @ (55,43--55,50)";
-#if DEBUG
-        @"let testByteToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,43--56,52)";
-#else
-        "let testByteToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,43--56,52)";
-#endif
+        [], "type OperatorTestsByte";
+        [], "let testByteEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,63--4,72)";
+        [], "let testByteNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,63--5,73)";
+        [], "let testByteLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,63--6,72)";
+        [], "let testByteLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,63--7,73)";
+        [], "let testByteGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,63--8,72)";
+        [], "let testByteGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,63--9,73)";
+        [], "let testByteAdditionOperator(e1) (e2) = Operators.ToByte (Operators.op_Addition (e1,e2)) @ (11,55--11,64)";
+        [], "let testByteSubtractionOperator(e1) (e2) = Operators.ToByte (Operators.op_Subtraction (e1,e2)) @ (12,55--12,64)";
+        [], "let testByteMultiplyOperator(e1) (e2) = Operators.ToByte (Operators.op_Multiply (e1,e2)) @ (13,55--13,64)";
+        [], "let testByteDivisionOperator(e1) (e2) = Operators.ToByte (Operators.op_Division (e1,e2)) @ (14,55--14,64)";
+        [], "let testByteModulusOperator(e1) (e2) = Operators.ToByte (Operators.op_Modulus (e1,e2)) @ (15,55--15,64)";
+        [], "let testByteBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,55--16,66)";
+        [], "let testByteBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,55--17,66)";
+        [], "let testByteBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,55--18,66)";
+        [], "let testByteShiftLeftOperator(e1) (e2) = Operators.ToByte (Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,7))) @ (19,54--19,65)";
+        [], "let testByteShiftRightOperator(e1) (e2) = Operators.ToByte (Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,7))) @ (20,54--20,65)";
+        [], "let testByteAdditionChecked(e1) (e2) = Checked.ToByte (Checked.op_Addition (e1,e2)) @ (24,53--24,70)";
+        [], "let testByteSubtractionChecked(e1) (e2) = Checked.ToByte (Checked.op_Subtraction (e1,e2)) @ (25,53--25,70)";
+        [], "let testByteMultiplyChecked(e1) (e2) = Checked.ToByte (Checked.op_Multiply (e1,e2)) @ (26,53--26,70)";
+        [], "let testByteToByteChecked(e1) = Checked.ToByte (e1) @ (29,43--29,58)";
+        [], "let testByteToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,43--30,59)";
+        [], "let testByteToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,43--31,59)";
+        [], "let testByteToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,43--32,60)";
+        [], "let testByteToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,43--33,57)";
+        [], "let testByteToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,43--34,59)";
+        [], "let testByteToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,43--35,60)";
+        [], "let testByteToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,43--36,59)";
+        [], "let testByteToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,43--37,60)";
+        [], "let testByteToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,43--38,63)";
+        [], "let testByteToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,43--39,64)";
+        [], "let testByteToByteOperator(e1) = Operators.ToByte (e1) @ (41,43--41,50)";
+        [], "let testByteToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,43--42,51)";
+        [], "let testByteToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,43--43,51)";
+        [], "let testByteToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,43--44,52)";
+        [], "let testByteToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,43--45,49)";
+        [], "let testByteToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,43--46,51)";
+        [], "let testByteToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,43--47,52)";
+        [], "let testByteToInt64Operator(e1) = Operators.ToUInt64 (e1) @ (48,43--48,51)";
+        [], "let testByteToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,43--49,52)";
+        [], "let testByteToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,43--50,55)";
+        [], "let testByteToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,43--51,56)";
+        [], "let testByteToSingleOperator(e1) = Operators.ToSingle (Operators.ToDouble (e1)) @ (52,43--52,53)";
+        [], "let testByteToDoubleOperator(e1) = Operators.ToDouble (Operators.ToDouble (e1)) @ (53,43--53,51)";
+        [], "let testByteToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,43--54,53)";
+        [], "let testByteToCharOperator(e1) = Operators.ToChar (e1) @ (55,43--55,50)";
+        [FC47], "let testByteToStringOperator(e1) = let mutable copyOfStruct: Microsoft.FSharp.Core.byte = e1 in copyOfStruct.ToString() @ (56,43--56,52)"
     ]
 
     testOperators "Byte" "byte" excludedTests expectedUnoptimized expectedOptimized
@@ -1149,111 +1209,107 @@ let ``Test Operator Declarations for SByte`` () =
     let excludedTests = [ ]
     
     let expectedUnoptimized = [
-        "type OperatorTestsSByte";
-        "let testSByteEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)";
-        "let testSByteNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,66--5,76)";
-        "let testSByteLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)";
-        "let testSByteLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,66--7,76)";
-        "let testSByteGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)";
-        "let testSByteGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,66--9,76)";
-        "let testSByteAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,58--11,67)";
-        "let testSByteSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,58--12,67)";
-        "let testSByteMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,58--13,67)";
-        "let testSByteDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,58--14,67)";
-        "let testSByteModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,58--15,67)";
-        "let testSByteBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,58--16,69)";
-        "let testSByteBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,58--17,69)";
-        "let testSByteBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,58--18,69)";
-        "let testSByteShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,56--19,67)";
-        "let testSByteShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,56--20,67)";
-        "let testSByteUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,45--22,52)";
-        "let testSByteAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,56--24,73)";
-        "let testSByteSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,56--25,73)";
-        "let testSByteMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,56--26,73)";
-        "let testSByteUnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,45--27,60)";
-        "let testSByteToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)";
-        "let testSByteToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)";
-        "let testSByteToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)";
-        "let testSByteToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)";
-        "let testSByteToIntChecked(e1) = Checked.ToInt (e1) @ (33,45--33,59)";
-        "let testSByteToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)";
-        "let testSByteToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)";
-        "let testSByteToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)";
-        "let testSByteToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)";
-        "let testSByteToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)";
-        "let testSByteToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)";
-        "let testSByteToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)";
-        "let testSByteToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)";
-        "let testSByteToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)";
-        "let testSByteToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)";
-        "let testSByteToIntOperator(e1) = Operators.ToInt (e1) @ (45,45--45,51)";
-        "let testSByteToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)";
-        "let testSByteToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)";
-        "let testSByteToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)";
-        "let testSByteToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,45--49,54)";
-        "let testSByteToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)";
-        "let testSByteToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,45--51,58)";
-        "let testSByteToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)";
-        "let testSByteToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)";
-        "let testSByteToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,45--54,55)";
-        "let testSByteToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)";
-        "let testSByteToStringOperator(e1) = Operators.ToString (e1) @ (56,45--56,54)";
+        [], "type OperatorTestsSByte";
+        [], "let testSByteEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)";
+        [], "let testSByteNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,66--5,76)";
+        [], "let testSByteLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)";
+        [], "let testSByteLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,66--7,76)";
+        [], "let testSByteGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)";
+        [], "let testSByteGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,66--9,76)";
+        [], "let testSByteAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,58--11,67)";
+        [], "let testSByteSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,58--12,67)";
+        [], "let testSByteMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,58--13,67)";
+        [], "let testSByteDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,58--14,67)";
+        [], "let testSByteModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,58--15,67)";
+        [], "let testSByteBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,58--16,69)";
+        [], "let testSByteBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,58--17,69)";
+        [], "let testSByteBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,58--18,69)";
+        [], "let testSByteShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,56--19,67)";
+        [], "let testSByteShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,56--20,67)";
+        [], "let testSByteUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,45--22,52)";
+        [], "let testSByteAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,56--24,73)";
+        [], "let testSByteSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,56--25,73)";
+        [], "let testSByteMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,56--26,73)";
+        [], "let testSByteUnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,45--27,60)";
+        [], "let testSByteToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)";
+        [], "let testSByteToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)";
+        [], "let testSByteToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)";
+        [], "let testSByteToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)";
+        [], "let testSByteToIntChecked(e1) = Checked.ToInt (e1) @ (33,45--33,59)";
+        [], "let testSByteToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)";
+        [], "let testSByteToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)";
+        [], "let testSByteToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)";
+        [], "let testSByteToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)";
+        [], "let testSByteToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)";
+        [], "let testSByteToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)";
+        [], "let testSByteToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)";
+        [], "let testSByteToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)";
+        [], "let testSByteToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)";
+        [], "let testSByteToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)";
+        [], "let testSByteToIntOperator(e1) = Operators.ToInt (e1) @ (45,45--45,51)";
+        [], "let testSByteToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)";
+        [], "let testSByteToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)";
+        [], "let testSByteToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)";
+        [], "let testSByteToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,45--49,54)";
+        [], "let testSByteToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)";
+        [], "let testSByteToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,45--51,58)";
+        [], "let testSByteToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)";
+        [], "let testSByteToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)";
+        [], "let testSByteToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,45--54,55)";
+        [], "let testSByteToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)";
+        [], "let testSByteToStringOperator(e1) = Operators.ToString (e1) @ (56,45--56,54)";
       ]
 
     let expectedOptimized = [
-        "type OperatorTestsSByte";
-        "let testSByteEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)";
-        "let testSByteNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,66--5,76)";
-        "let testSByteLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)";
-        "let testSByteLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,66--7,76)";
-        "let testSByteGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)";
-        "let testSByteGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,66--9,76)";
-        "let testSByteAdditionOperator(e1) (e2) = Operators.ToSByte (Operators.op_Addition (e1,e2)) @ (11,58--11,67)";
-        "let testSByteSubtractionOperator(e1) (e2) = Operators.ToSByte (Operators.op_Subtraction (e1,e2)) @ (12,58--12,67)";
-        "let testSByteMultiplyOperator(e1) (e2) = Operators.ToSByte (Operators.op_Multiply (e1,e2)) @ (13,58--13,67)";
-        "let testSByteDivisionOperator(e1) (e2) = Operators.ToSByte (Operators.op_Division (e1,e2)) @ (14,58--14,67)";
-        "let testSByteModulusOperator(e1) (e2) = Operators.ToSByte (Operators.op_Modulus (e1,e2)) @ (15,58--15,67)";
-        "let testSByteBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,58--16,69)";
-        "let testSByteBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,58--17,69)";
-        "let testSByteBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,58--18,69)";
-        "let testSByteShiftLeftOperator(e1) (e2) = Operators.ToSByte (Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,7))) @ (19,56--19,67)";
-        "let testSByteShiftRightOperator(e1) (e2) = Operators.ToSByte (Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,7))) @ (20,56--20,67)";
-        "let testSByteUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,45--22,52)";
-        "let testSByteAdditionChecked(e1) (e2) = Checked.ToSByte (Checked.op_Addition (e1,e2)) @ (24,56--24,73)";
-        "let testSByteSubtractionChecked(e1) (e2) = Checked.ToSByte (Checked.op_Subtraction (e1,e2)) @ (25,56--25,73)";
-        "let testSByteMultiplyChecked(e1) (e2) = Checked.ToSByte (Checked.op_Multiply (e1,e2)) @ (26,56--26,73)";
-        "let testSByteUnaryNegChecked(e1) = Checked.op_Subtraction (0,e1) @ (27,45--27,60)";
-        "let testSByteToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)";
-        "let testSByteToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)";
-        "let testSByteToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)";
-        "let testSByteToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)";
-        "let testSByteToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,45--33,59)";
-        "let testSByteToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)";
-        "let testSByteToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)";
-        "let testSByteToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)";
-        "let testSByteToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)";
-        "let testSByteToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)";
-        "let testSByteToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)";
-        "let testSByteToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)";
-        "let testSByteToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)";
-        "let testSByteToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)";
-        "let testSByteToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)";
-        "let testSByteToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,45--45,51)";
-        "let testSByteToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)";
-        "let testSByteToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)";
-        "let testSByteToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)";
-        "let testSByteToUInt64Operator(e1) = Operators.ToInt64 (e1) @ (49,45--49,54)";
-        "let testSByteToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)";
-        "let testSByteToUIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (51,45--51,58)";
-        "let testSByteToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)";
-        "let testSByteToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)";
-        "let testSByteToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,45--54,55)";
-        "let testSByteToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)";
-#if DEBUG
-        @"let testSByteToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,45--56,54)";
-#else
-        "let testSByteToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,45--56,54)";
-#endif
+        [], "type OperatorTestsSByte";
+        [], "let testSByteEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)";
+        [], "let testSByteNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,66--5,76)";
+        [], "let testSByteLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)";
+        [], "let testSByteLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,66--7,76)";
+        [], "let testSByteGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)";
+        [], "let testSByteGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,66--9,76)";
+        [], "let testSByteAdditionOperator(e1) (e2) = Operators.ToSByte (Operators.op_Addition (e1,e2)) @ (11,58--11,67)";
+        [], "let testSByteSubtractionOperator(e1) (e2) = Operators.ToSByte (Operators.op_Subtraction (e1,e2)) @ (12,58--12,67)";
+        [], "let testSByteMultiplyOperator(e1) (e2) = Operators.ToSByte (Operators.op_Multiply (e1,e2)) @ (13,58--13,67)";
+        [], "let testSByteDivisionOperator(e1) (e2) = Operators.ToSByte (Operators.op_Division (e1,e2)) @ (14,58--14,67)";
+        [], "let testSByteModulusOperator(e1) (e2) = Operators.ToSByte (Operators.op_Modulus (e1,e2)) @ (15,58--15,67)";
+        [], "let testSByteBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,58--16,69)";
+        [], "let testSByteBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,58--17,69)";
+        [], "let testSByteBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,58--18,69)";
+        [], "let testSByteShiftLeftOperator(e1) (e2) = Operators.ToSByte (Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,7))) @ (19,56--19,67)";
+        [], "let testSByteShiftRightOperator(e1) (e2) = Operators.ToSByte (Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,7))) @ (20,56--20,67)";
+        [], "let testSByteUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,45--22,52)";
+        [], "let testSByteAdditionChecked(e1) (e2) = Checked.ToSByte (Checked.op_Addition (e1,e2)) @ (24,56--24,73)";
+        [], "let testSByteSubtractionChecked(e1) (e2) = Checked.ToSByte (Checked.op_Subtraction (e1,e2)) @ (25,56--25,73)";
+        [], "let testSByteMultiplyChecked(e1) (e2) = Checked.ToSByte (Checked.op_Multiply (e1,e2)) @ (26,56--26,73)";
+        [], "let testSByteUnaryNegChecked(e1) = Checked.op_Subtraction (0,e1) @ (27,45--27,60)";
+        [], "let testSByteToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)";
+        [], "let testSByteToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)";
+        [], "let testSByteToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)";
+        [], "let testSByteToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)";
+        [], "let testSByteToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,45--33,59)";
+        [], "let testSByteToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)";
+        [], "let testSByteToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)";
+        [], "let testSByteToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)";
+        [], "let testSByteToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)";
+        [], "let testSByteToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)";
+        [], "let testSByteToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)";
+        [], "let testSByteToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)";
+        [], "let testSByteToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)";
+        [], "let testSByteToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)";
+        [], "let testSByteToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)";
+        [], "let testSByteToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,45--45,51)";
+        [], "let testSByteToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)";
+        [], "let testSByteToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)";
+        [], "let testSByteToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)";
+        [], "let testSByteToUInt64Operator(e1) = Operators.ToInt64 (e1) @ (49,45--49,54)";
+        [], "let testSByteToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)";
+        [], "let testSByteToUIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (51,45--51,58)";
+        [], "let testSByteToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)";
+        [], "let testSByteToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)";
+        [], "let testSByteToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,45--54,55)";
+        [], "let testSByteToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)";
+        [FC47], "let testSByteToStringOperator(e1) = IntrinsicFunctions.UnboxGeneric (Operators.Box (e1)).ToString(dflt,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (56,45--56,54)"
     ]
 
     testOperators "SByte" "sbyte" excludedTests expectedUnoptimized expectedOptimized
@@ -1263,111 +1319,107 @@ let ``Test Operator Declarations for Int16`` () =
     let excludedTests = [ ]
     
     let expectedUnoptimized = [
-        "type OperatorTestsInt16";
-        "let testInt16EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)";
-        "let testInt16NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,66--5,76)";
-        "let testInt16LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)";
-        "let testInt16LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,66--7,76)";
-        "let testInt16GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)";
-        "let testInt16GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,66--9,76)";
-        "let testInt16AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,58--11,67)";
-        "let testInt16SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,58--12,67)";
-        "let testInt16MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,58--13,67)";
-        "let testInt16DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,58--14,67)";
-        "let testInt16ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,58--15,67)";
-        "let testInt16BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,58--16,69)";
-        "let testInt16BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,58--17,69)";
-        "let testInt16BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,58--18,69)";
-        "let testInt16ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,56--19,67)";
-        "let testInt16ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,56--20,67)";
-        "let testInt16UnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,45--22,52)";
-        "let testInt16AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,56--24,73)";
-        "let testInt16SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,56--25,73)";
-        "let testInt16MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,56--26,73)";
-        "let testInt16UnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,45--27,60)";
-        "let testInt16ToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)";
-        "let testInt16ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)";
-        "let testInt16ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)";
-        "let testInt16ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)";
-        "let testInt16ToIntChecked(e1) = Checked.ToInt (e1) @ (33,45--33,59)";
-        "let testInt16ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)";
-        "let testInt16ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)";
-        "let testInt16ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)";
-        "let testInt16ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)";
-        "let testInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)";
-        "let testInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)";
-        "let testInt16ToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)";
-        "let testInt16ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)";
-        "let testInt16ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)";
-        "let testInt16ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)";
-        "let testInt16ToIntOperator(e1) = Operators.ToInt (e1) @ (45,45--45,51)";
-        "let testInt16ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)";
-        "let testInt16ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)";
-        "let testInt16ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)";
-        "let testInt16ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,45--49,54)";
-        "let testInt16ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)";
-        "let testInt16ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,45--51,58)";
-        "let testInt16ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)";
-        "let testInt16ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)";
-        "let testInt16ToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,45--54,55)";
-        "let testInt16ToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)";
-        "let testInt16ToStringOperator(e1) = Operators.ToString (e1) @ (56,45--56,54)";
+        [], "type OperatorTestsInt16";
+        [], "let testInt16EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)";
+        [], "let testInt16NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,66--5,76)";
+        [], "let testInt16LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)";
+        [], "let testInt16LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,66--7,76)";
+        [], "let testInt16GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)";
+        [], "let testInt16GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,66--9,76)";
+        [], "let testInt16AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,58--11,67)";
+        [], "let testInt16SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,58--12,67)";
+        [], "let testInt16MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,58--13,67)";
+        [], "let testInt16DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,58--14,67)";
+        [], "let testInt16ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,58--15,67)";
+        [], "let testInt16BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,58--16,69)";
+        [], "let testInt16BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,58--17,69)";
+        [], "let testInt16BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,58--18,69)";
+        [], "let testInt16ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,56--19,67)";
+        [], "let testInt16ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,56--20,67)";
+        [], "let testInt16UnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,45--22,52)";
+        [], "let testInt16AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,56--24,73)";
+        [], "let testInt16SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,56--25,73)";
+        [], "let testInt16MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,56--26,73)";
+        [], "let testInt16UnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,45--27,60)";
+        [], "let testInt16ToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)";
+        [], "let testInt16ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)";
+        [], "let testInt16ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)";
+        [], "let testInt16ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)";
+        [], "let testInt16ToIntChecked(e1) = Checked.ToInt (e1) @ (33,45--33,59)";
+        [], "let testInt16ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)";
+        [], "let testInt16ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)";
+        [], "let testInt16ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)";
+        [], "let testInt16ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)";
+        [], "let testInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)";
+        [], "let testInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)";
+        [], "let testInt16ToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)";
+        [], "let testInt16ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)";
+        [], "let testInt16ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)";
+        [], "let testInt16ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)";
+        [], "let testInt16ToIntOperator(e1) = Operators.ToInt (e1) @ (45,45--45,51)";
+        [], "let testInt16ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)";
+        [], "let testInt16ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)";
+        [], "let testInt16ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)";
+        [], "let testInt16ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,45--49,54)";
+        [], "let testInt16ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)";
+        [], "let testInt16ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,45--51,58)";
+        [], "let testInt16ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)";
+        [], "let testInt16ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)";
+        [], "let testInt16ToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,45--54,55)";
+        [], "let testInt16ToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)";
+        [], "let testInt16ToStringOperator(e1) = Operators.ToString (e1) @ (56,45--56,54)";
       ]
 
     let expectedOptimized = [
-        "type OperatorTestsInt16";
-        "let testInt16EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)";
-        "let testInt16NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,66--5,76)";
-        "let testInt16LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)";
-        "let testInt16LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,66--7,76)";
-        "let testInt16GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)";
-        "let testInt16GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,66--9,76)";
-        "let testInt16AdditionOperator(e1) (e2) = Operators.ToInt16 (Operators.op_Addition (e1,e2)) @ (11,58--11,67)";
-        "let testInt16SubtractionOperator(e1) (e2) = Operators.ToInt16 (Operators.op_Subtraction (e1,e2)) @ (12,58--12,67)";
-        "let testInt16MultiplyOperator(e1) (e2) = Operators.ToInt16 (Operators.op_Multiply (e1,e2)) @ (13,58--13,67)";
-        "let testInt16DivisionOperator(e1) (e2) = Operators.ToInt16 (Operators.op_Division (e1,e2)) @ (14,58--14,67)";
-        "let testInt16ModulusOperator(e1) (e2) = Operators.ToInt16 (Operators.op_Modulus (e1,e2)) @ (15,58--15,67)";
-        "let testInt16BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,58--16,69)";
-        "let testInt16BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,58--17,69)";
-        "let testInt16BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,58--18,69)";
-        "let testInt16ShiftLeftOperator(e1) (e2) = Operators.ToInt16 (Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,15))) @ (19,56--19,67)";
-        "let testInt16ShiftRightOperator(e1) (e2) = Operators.ToInt16 (Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,15))) @ (20,56--20,67)";
-        "let testInt16UnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,45--22,52)";
-        "let testInt16AdditionChecked(e1) (e2) = Checked.ToInt16 (Checked.op_Addition (e1,e2)) @ (24,56--24,73)";
-        "let testInt16SubtractionChecked(e1) (e2) = Checked.ToInt16 (Checked.op_Subtraction (e1,e2)) @ (25,56--25,73)";
-        "let testInt16MultiplyChecked(e1) (e2) = Checked.ToInt16 (Checked.op_Multiply (e1,e2)) @ (26,56--26,73)";
-        "let testInt16UnaryNegChecked(e1) = Checked.op_Subtraction (0,e1) @ (27,45--27,60)";
-        "let testInt16ToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)";
-        "let testInt16ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)";
-        "let testInt16ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)";
-        "let testInt16ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)";
-        "let testInt16ToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,45--33,59)";
-        "let testInt16ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)";
-        "let testInt16ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)";
-        "let testInt16ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)";
-        "let testInt16ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)";
-        "let testInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)";
-        "let testInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)";
-        "let testInt16ToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)";
-        "let testInt16ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)";
-        "let testInt16ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)";
-        "let testInt16ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)";
-        "let testInt16ToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,45--45,51)";
-        "let testInt16ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)";
-        "let testInt16ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)";
-        "let testInt16ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)";
-        "let testInt16ToUInt64Operator(e1) = Operators.ToInt64 (e1) @ (49,45--49,54)";
-        "let testInt16ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)";
-        "let testInt16ToUIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (51,45--51,58)";
-        "let testInt16ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)";
-        "let testInt16ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)";
-        "let testInt16ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,45--54,55)";
-        "let testInt16ToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)";
-#if DEBUG
-        @"let testInt16ToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,45--56,54)";
-#else
-        "let testInt16ToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,45--56,54)";
-#endif
+        [], "type OperatorTestsInt16";
+        [], "let testInt16EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)";
+        [], "let testInt16NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,66--5,76)";
+        [], "let testInt16LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)";
+        [], "let testInt16LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,66--7,76)";
+        [], "let testInt16GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)";
+        [], "let testInt16GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,66--9,76)";
+        [], "let testInt16AdditionOperator(e1) (e2) = Operators.ToInt16 (Operators.op_Addition (e1,e2)) @ (11,58--11,67)";
+        [], "let testInt16SubtractionOperator(e1) (e2) = Operators.ToInt16 (Operators.op_Subtraction (e1,e2)) @ (12,58--12,67)";
+        [], "let testInt16MultiplyOperator(e1) (e2) = Operators.ToInt16 (Operators.op_Multiply (e1,e2)) @ (13,58--13,67)";
+        [], "let testInt16DivisionOperator(e1) (e2) = Operators.ToInt16 (Operators.op_Division (e1,e2)) @ (14,58--14,67)";
+        [], "let testInt16ModulusOperator(e1) (e2) = Operators.ToInt16 (Operators.op_Modulus (e1,e2)) @ (15,58--15,67)";
+        [], "let testInt16BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,58--16,69)";
+        [], "let testInt16BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,58--17,69)";
+        [], "let testInt16BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,58--18,69)";
+        [], "let testInt16ShiftLeftOperator(e1) (e2) = Operators.ToInt16 (Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,15))) @ (19,56--19,67)";
+        [], "let testInt16ShiftRightOperator(e1) (e2) = Operators.ToInt16 (Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,15))) @ (20,56--20,67)";
+        [], "let testInt16UnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,45--22,52)";
+        [], "let testInt16AdditionChecked(e1) (e2) = Checked.ToInt16 (Checked.op_Addition (e1,e2)) @ (24,56--24,73)";
+        [], "let testInt16SubtractionChecked(e1) (e2) = Checked.ToInt16 (Checked.op_Subtraction (e1,e2)) @ (25,56--25,73)";
+        [], "let testInt16MultiplyChecked(e1) (e2) = Checked.ToInt16 (Checked.op_Multiply (e1,e2)) @ (26,56--26,73)";
+        [], "let testInt16UnaryNegChecked(e1) = Checked.op_Subtraction (0,e1) @ (27,45--27,60)";
+        [], "let testInt16ToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)";
+        [], "let testInt16ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)";
+        [], "let testInt16ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)";
+        [], "let testInt16ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)";
+        [], "let testInt16ToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,45--33,59)";
+        [], "let testInt16ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)";
+        [], "let testInt16ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)";
+        [], "let testInt16ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)";
+        [], "let testInt16ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)";
+        [], "let testInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)";
+        [], "let testInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)";
+        [], "let testInt16ToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)";
+        [], "let testInt16ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)";
+        [], "let testInt16ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)";
+        [], "let testInt16ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)";
+        [], "let testInt16ToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,45--45,51)";
+        [], "let testInt16ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)";
+        [], "let testInt16ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)";
+        [], "let testInt16ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)";
+        [], "let testInt16ToUInt64Operator(e1) = Operators.ToInt64 (e1) @ (49,45--49,54)";
+        [], "let testInt16ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)";
+        [], "let testInt16ToUIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (51,45--51,58)";
+        [], "let testInt16ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)";
+        [], "let testInt16ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)";
+        [], "let testInt16ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,45--54,55)";
+        [], "let testInt16ToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)";
+        [FC47], "let testInt16ToStringOperator(e1) = IntrinsicFunctions.UnboxGeneric (Operators.Box (e1)).ToString(dflt,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (56,45--56,54)"
       ]
 
     testOperators "Int16" "int16" excludedTests expectedUnoptimized expectedOptimized
@@ -1380,107 +1432,103 @@ let ``Test Operator Declarations for UInt16`` () =
       ]
     
     let expectedUnoptimized = [
-        "type OperatorTestsUInt16";
-        "let testUInt16EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)";
-        "let testUInt16NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,69--5,79)";
-        "let testUInt16LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)";
-        "let testUInt16LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,69--7,79)";
-        "let testUInt16GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)";
-        "let testUInt16GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,69--9,79)";
-        "let testUInt16AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,61--11,70)";
-        "let testUInt16SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,61--12,70)";
-        "let testUInt16MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,61--13,70)";
-        "let testUInt16DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,61--14,70)";
-        "let testUInt16ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,61--15,70)";
-        "let testUInt16BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,61--16,72)";
-        "let testUInt16BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,61--17,72)";
-        "let testUInt16BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,61--18,72)";
-        "let testUInt16ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,58--19,69)";
-        "let testUInt16ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,58--20,69)";
-        "let testUInt16AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,59--24,76)";
-        "let testUInt16SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,59--25,76)";
-        "let testUInt16MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,59--26,76)";
-        "let testUInt16ToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)";
-        "let testUInt16ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)";
-        "let testUInt16ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)";
-        "let testUInt16ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)";
-        "let testUInt16ToIntChecked(e1) = Checked.ToInt (e1) @ (33,47--33,61)";
-        "let testUInt16ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)";
-        "let testUInt16ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)";
-        "let testUInt16ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)";
-        "let testUInt16ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)";
-        "let testUInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,47--38,67)";
-        "let testUInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,47--39,68)";
-        "let testUInt16ToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)";
-        "let testUInt16ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)";
-        "let testUInt16ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)";
-        "let testUInt16ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)";
-        "let testUInt16ToIntOperator(e1) = Operators.ToInt (e1) @ (45,47--45,53)";
-        "let testUInt16ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)";
-        "let testUInt16ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)";
-        "let testUInt16ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,47--48,55)";
-        "let testUInt16ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,47--49,56)";
-        "let testUInt16ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,47--50,59)";
-        "let testUInt16ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,47--51,60)";
-        "let testUInt16ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,47--52,57)";
-        "let testUInt16ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,47--53,55)";
-        "let testUInt16ToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,47--54,57)";
-        "let testUInt16ToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)";
-        "let testUInt16ToStringOperator(e1) = Operators.ToString (e1) @ (56,47--56,56)";
+        [], "type OperatorTestsUInt16";
+        [], "let testUInt16EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)";
+        [], "let testUInt16NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,69--5,79)";
+        [], "let testUInt16LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)";
+        [], "let testUInt16LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,69--7,79)";
+        [], "let testUInt16GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)";
+        [], "let testUInt16GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,69--9,79)";
+        [], "let testUInt16AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,61--11,70)";
+        [], "let testUInt16SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,61--12,70)";
+        [], "let testUInt16MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,61--13,70)";
+        [], "let testUInt16DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,61--14,70)";
+        [], "let testUInt16ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,61--15,70)";
+        [], "let testUInt16BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,61--16,72)";
+        [], "let testUInt16BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,61--17,72)";
+        [], "let testUInt16BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,61--18,72)";
+        [], "let testUInt16ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,58--19,69)";
+        [], "let testUInt16ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,58--20,69)";
+        [], "let testUInt16AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,59--24,76)";
+        [], "let testUInt16SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,59--25,76)";
+        [], "let testUInt16MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,59--26,76)";
+        [], "let testUInt16ToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)";
+        [], "let testUInt16ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)";
+        [], "let testUInt16ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)";
+        [], "let testUInt16ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)";
+        [], "let testUInt16ToIntChecked(e1) = Checked.ToInt (e1) @ (33,47--33,61)";
+        [], "let testUInt16ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)";
+        [], "let testUInt16ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)";
+        [], "let testUInt16ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)";
+        [], "let testUInt16ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)";
+        [], "let testUInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,47--38,67)";
+        [], "let testUInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,47--39,68)";
+        [], "let testUInt16ToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)";
+        [], "let testUInt16ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)";
+        [], "let testUInt16ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)";
+        [], "let testUInt16ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)";
+        [], "let testUInt16ToIntOperator(e1) = Operators.ToInt (e1) @ (45,47--45,53)";
+        [], "let testUInt16ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)";
+        [], "let testUInt16ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)";
+        [], "let testUInt16ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,47--48,55)";
+        [], "let testUInt16ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,47--49,56)";
+        [], "let testUInt16ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,47--50,59)";
+        [], "let testUInt16ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,47--51,60)";
+        [], "let testUInt16ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,47--52,57)";
+        [], "let testUInt16ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,47--53,55)";
+        [], "let testUInt16ToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,47--54,57)";
+        [], "let testUInt16ToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)";
+        [], "let testUInt16ToStringOperator(e1) = Operators.ToString (e1) @ (56,47--56,56)";
       ]
 
     let expectedOptimized = [
-        "type OperatorTestsUInt16";
-        "let testUInt16EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)";
-        "let testUInt16NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,69--5,79)";
-        "let testUInt16LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)";
-        "let testUInt16LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,69--7,79)";
-        "let testUInt16GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)";
-        "let testUInt16GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,69--9,79)";
-        "let testUInt16AdditionOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_Addition (e1,e2)) @ (11,61--11,70)";
-        "let testUInt16SubtractionOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_Subtraction (e1,e2)) @ (12,61--12,70)";
-        "let testUInt16MultiplyOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_Multiply (e1,e2)) @ (13,61--13,70)";
-        "let testUInt16DivisionOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_Division (e1,e2)) @ (14,61--14,70)";
-        "let testUInt16ModulusOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_Modulus (e1,e2)) @ (15,61--15,70)";
-        "let testUInt16BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,61--16,72)";
-        "let testUInt16BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,61--17,72)";
-        "let testUInt16BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,61--18,72)";
-        "let testUInt16ShiftLeftOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,15))) @ (19,58--19,69)";
-        "let testUInt16ShiftRightOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,15))) @ (20,58--20,69)";
-        "let testUInt16AdditionChecked(e1) (e2) = Checked.ToUInt16 (Checked.op_Addition (e1,e2)) @ (24,59--24,76)";
-        "let testUInt16SubtractionChecked(e1) (e2) = Checked.ToUInt16 (Checked.op_Subtraction (e1,e2)) @ (25,59--25,76)";
-        "let testUInt16MultiplyChecked(e1) (e2) = Checked.ToUInt16 (Checked.op_Multiply (e1,e2)) @ (26,59--26,76)";
-        "let testUInt16ToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)";
-        "let testUInt16ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)";
-        "let testUInt16ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)";
-        "let testUInt16ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)";
-        "let testUInt16ToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,47--33,61)";
-        "let testUInt16ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)";
-        "let testUInt16ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)";
-        "let testUInt16ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)";
-        "let testUInt16ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)";
-        "let testUInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,47--38,67)";
-        "let testUInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,47--39,68)";
-        "let testUInt16ToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)";
-        "let testUInt16ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)";
-        "let testUInt16ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)";
-        "let testUInt16ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)";
-        "let testUInt16ToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,47--45,53)";
-        "let testUInt16ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)";
-        "let testUInt16ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)";
-        "let testUInt16ToInt64Operator(e1) = Operators.ToUInt64 (e1) @ (48,47--48,55)";
-        "let testUInt16ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,47--49,56)";
-        "let testUInt16ToIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (50,47--50,59)";
-        "let testUInt16ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,47--51,60)";
-        "let testUInt16ToSingleOperator(e1) = Operators.ToSingle (Operators.ToDouble (e1)) @ (52,47--52,57)";
-        "let testUInt16ToDoubleOperator(e1) = Operators.ToDouble (Operators.ToDouble (e1)) @ (53,47--53,55)";
-        "let testUInt16ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,47--54,57)";
-        "let testUInt16ToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)";
-#if DEBUG
-        @"let testUInt16ToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,47--56,56)"
-#else
-        "let testUInt16ToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,47--56,56)";
-#endif
+        [], "type OperatorTestsUInt16";
+        [], "let testUInt16EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)";
+        [], "let testUInt16NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,69--5,79)";
+        [], "let testUInt16LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)";
+        [], "let testUInt16LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,69--7,79)";
+        [], "let testUInt16GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)";
+        [], "let testUInt16GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,69--9,79)";
+        [], "let testUInt16AdditionOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_Addition (e1,e2)) @ (11,61--11,70)";
+        [], "let testUInt16SubtractionOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_Subtraction (e1,e2)) @ (12,61--12,70)";
+        [], "let testUInt16MultiplyOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_Multiply (e1,e2)) @ (13,61--13,70)";
+        [], "let testUInt16DivisionOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_Division (e1,e2)) @ (14,61--14,70)";
+        [], "let testUInt16ModulusOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_Modulus (e1,e2)) @ (15,61--15,70)";
+        [], "let testUInt16BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,61--16,72)";
+        [], "let testUInt16BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,61--17,72)";
+        [], "let testUInt16BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,61--18,72)";
+        [], "let testUInt16ShiftLeftOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,15))) @ (19,58--19,69)";
+        [], "let testUInt16ShiftRightOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,15))) @ (20,58--20,69)";
+        [], "let testUInt16AdditionChecked(e1) (e2) = Checked.ToUInt16 (Checked.op_Addition (e1,e2)) @ (24,59--24,76)";
+        [], "let testUInt16SubtractionChecked(e1) (e2) = Checked.ToUInt16 (Checked.op_Subtraction (e1,e2)) @ (25,59--25,76)";
+        [], "let testUInt16MultiplyChecked(e1) (e2) = Checked.ToUInt16 (Checked.op_Multiply (e1,e2)) @ (26,59--26,76)";
+        [], "let testUInt16ToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)";
+        [], "let testUInt16ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)";
+        [], "let testUInt16ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)";
+        [], "let testUInt16ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)";
+        [], "let testUInt16ToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,47--33,61)";
+        [], "let testUInt16ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)";
+        [], "let testUInt16ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)";
+        [], "let testUInt16ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)";
+        [], "let testUInt16ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)";
+        [], "let testUInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,47--38,67)";
+        [], "let testUInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,47--39,68)";
+        [], "let testUInt16ToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)";
+        [], "let testUInt16ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)";
+        [], "let testUInt16ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)";
+        [], "let testUInt16ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)";
+        [], "let testUInt16ToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,47--45,53)";
+        [], "let testUInt16ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)";
+        [], "let testUInt16ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)";
+        [], "let testUInt16ToInt64Operator(e1) = Operators.ToUInt64 (e1) @ (48,47--48,55)";
+        [], "let testUInt16ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,47--49,56)";
+        [], "let testUInt16ToIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (50,47--50,59)";
+        [], "let testUInt16ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,47--51,60)";
+        [], "let testUInt16ToSingleOperator(e1) = Operators.ToSingle (Operators.ToDouble (e1)) @ (52,47--52,57)";
+        [], "let testUInt16ToDoubleOperator(e1) = Operators.ToDouble (Operators.ToDouble (e1)) @ (53,47--53,55)";
+        [], "let testUInt16ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,47--54,57)";
+        [], "let testUInt16ToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)";
+        [FC47], "let testUInt16ToStringOperator(e1) = let mutable copyOfStruct: Microsoft.FSharp.Core.uint16 = e1 in copyOfStruct.ToString() @ (56,47--56,56)"
       ]
 
     testOperators "UInt16" "uint16" excludedTests expectedUnoptimized expectedOptimized
@@ -1490,111 +1538,107 @@ let ``Test Operator Declarations for Int`` () =
     let excludedTests = [ ]
     
     let expectedUnoptimized = [
-        "type OperatorTestsInt";
-        "let testIntEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,60--4,69)";
-        "let testIntNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,60--5,70)";
-        "let testIntLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,60--6,69)";
-        "let testIntLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,60--7,70)";
-        "let testIntGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,60--8,69)";
-        "let testIntGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,60--9,70)";
-        "let testIntAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,52--11,61)";
-        "let testIntSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,52--12,61)";
-        "let testIntMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,52--13,61)";
-        "let testIntDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,52--14,61)";
-        "let testIntModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,52--15,61)";
-        "let testIntBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,52--16,63)";
-        "let testIntBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,52--17,63)";
-        "let testIntBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,52--18,63)";
-        "let testIntShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,52--19,63)";
-        "let testIntShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,52--20,63)";
-        "let testIntUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,41--22,48)";
-        "let testIntAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,50--24,67)";
-        "let testIntSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,50--25,67)";
-        "let testIntMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,50--26,67)";
-        "let testIntUnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,41--27,56)";
-        "let testIntToByteChecked(e1) = Checked.ToByte (e1) @ (29,41--29,56)";
-        "let testIntToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,41--30,57)";
-        "let testIntToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,41--31,57)";
-        "let testIntToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,41--32,58)";
-        "let testIntToIntChecked(e1) = Checked.ToInt (e1) @ (33,41--33,55)";
-        "let testIntToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,41--34,57)";
-        "let testIntToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,41--35,58)";
-        "let testIntToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,41--36,57)";
-        "let testIntToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,41--37,58)";
-        "let testIntToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,41--38,61)";
-        "let testIntToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,41--39,62)";
-        "let testIntToByteOperator(e1) = Operators.ToByte (e1) @ (41,41--41,48)";
-        "let testIntToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,41--42,49)";
-        "let testIntToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,41--43,49)";
-        "let testIntToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,41--44,50)";
-        "let testIntToIntOperator(e1) = Operators.ToInt (e1) @ (45,41--45,47)";
-        "let testIntToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,41--46,49)";
-        "let testIntToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,41--47,50)";
-        "let testIntToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,41--48,49)";
-        "let testIntToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,41--49,50)";
-        "let testIntToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,41--50,53)";
-        "let testIntToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,41--51,54)";
-        "let testIntToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,41--52,51)";
-        "let testIntToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,41--53,49)";
-        "let testIntToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,41--54,51)";
-        "let testIntToCharOperator(e1) = Operators.ToChar (e1) @ (55,41--55,48)";
-        "let testIntToStringOperator(e1) = Operators.ToString (e1) @ (56,41--56,50)";
+        [], "type OperatorTestsInt";
+        [], "let testIntEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,60--4,69)";
+        [], "let testIntNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,60--5,70)";
+        [], "let testIntLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,60--6,69)";
+        [], "let testIntLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,60--7,70)";
+        [], "let testIntGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,60--8,69)";
+        [], "let testIntGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,60--9,70)";
+        [], "let testIntAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,52--11,61)";
+        [], "let testIntSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,52--12,61)";
+        [], "let testIntMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,52--13,61)";
+        [], "let testIntDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,52--14,61)";
+        [], "let testIntModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,52--15,61)";
+        [], "let testIntBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,52--16,63)";
+        [], "let testIntBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,52--17,63)";
+        [], "let testIntBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,52--18,63)";
+        [], "let testIntShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,52--19,63)";
+        [], "let testIntShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,52--20,63)";
+        [], "let testIntUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,41--22,48)";
+        [], "let testIntAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,50--24,67)";
+        [], "let testIntSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,50--25,67)";
+        [], "let testIntMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,50--26,67)";
+        [], "let testIntUnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,41--27,56)";
+        [], "let testIntToByteChecked(e1) = Checked.ToByte (e1) @ (29,41--29,56)";
+        [], "let testIntToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,41--30,57)";
+        [], "let testIntToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,41--31,57)";
+        [], "let testIntToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,41--32,58)";
+        [], "let testIntToIntChecked(e1) = Checked.ToInt (e1) @ (33,41--33,55)";
+        [], "let testIntToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,41--34,57)";
+        [], "let testIntToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,41--35,58)";
+        [], "let testIntToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,41--36,57)";
+        [], "let testIntToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,41--37,58)";
+        [], "let testIntToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,41--38,61)";
+        [], "let testIntToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,41--39,62)";
+        [], "let testIntToByteOperator(e1) = Operators.ToByte (e1) @ (41,41--41,48)";
+        [], "let testIntToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,41--42,49)";
+        [], "let testIntToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,41--43,49)";
+        [], "let testIntToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,41--44,50)";
+        [], "let testIntToIntOperator(e1) = Operators.ToInt (e1) @ (45,41--45,47)";
+        [], "let testIntToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,41--46,49)";
+        [], "let testIntToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,41--47,50)";
+        [], "let testIntToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,41--48,49)";
+        [], "let testIntToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,41--49,50)";
+        [], "let testIntToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,41--50,53)";
+        [], "let testIntToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,41--51,54)";
+        [], "let testIntToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,41--52,51)";
+        [], "let testIntToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,41--53,49)";
+        [], "let testIntToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,41--54,51)";
+        [], "let testIntToCharOperator(e1) = Operators.ToChar (e1) @ (55,41--55,48)";
+        [], "let testIntToStringOperator(e1) = Operators.ToString (e1) @ (56,41--56,50)";
       ]
 
     let expectedOptimized = [
-        "type OperatorTestsInt";
-        "let testIntEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,60--4,69)";
-        "let testIntNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,60--5,70)";
-        "let testIntLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,60--6,69)";
-        "let testIntLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,60--7,70)";
-        "let testIntGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,60--8,69)";
-        "let testIntGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,60--9,70)";
-        "let testIntAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,52--11,61)";
-        "let testIntSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,52--12,61)";
-        "let testIntMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,52--13,61)";
-        "let testIntDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,52--14,61)";
-        "let testIntModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,52--15,61)";
-        "let testIntBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,52--16,63)";
-        "let testIntBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,52--17,63)";
-        "let testIntBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,52--18,63)";
-        "let testIntShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,31)) @ (19,52--19,63)";
-        "let testIntShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,31)) @ (20,52--20,63)";
-        "let testIntUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,41--22,48)";
-        "let testIntAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,50--24,67)";
-        "let testIntSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,50--25,67)";
-        "let testIntMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,50--26,67)";
-        "let testIntUnaryNegChecked(e1) = Checked.op_Subtraction (0,e1) @ (27,41--27,56)";
-        "let testIntToByteChecked(e1) = Checked.ToByte (e1) @ (29,41--29,56)";
-        "let testIntToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,41--30,57)";
-        "let testIntToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,41--31,57)";
-        "let testIntToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,41--32,58)";
-        "let testIntToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,41--33,55)";
-        "let testIntToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,41--34,57)";
-        "let testIntToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,41--35,58)";
-        "let testIntToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,41--36,57)";
-        "let testIntToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,41--37,58)";
-        "let testIntToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,41--38,61)";
-        "let testIntToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,41--39,62)";
-        "let testIntToByteOperator(e1) = Operators.ToByte (e1) @ (41,41--41,48)";
-        "let testIntToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,41--42,49)";
-        "let testIntToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,41--43,49)";
-        "let testIntToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,41--44,50)";
-        "let testIntToIntOperator(e1) = e1 @ (45,45--45,47)";
-        "let testIntToInt32Operator(e1) = e1 @ (46,47--46,49)";
-        "let testIntToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,41--47,50)";
-        "let testIntToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,41--48,49)";
-        "let testIntToUInt64Operator(e1) = Operators.ToInt64 (e1) @ (49,41--49,50)";
-        "let testIntToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,41--50,53)";
-        "let testIntToUIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (51,41--51,54)";
-        "let testIntToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,41--52,51)";
-        "let testIntToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,41--53,49)";
-        "let testIntToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,41--54,51)";
-        "let testIntToCharOperator(e1) = Operators.ToChar (e1) @ (55,41--55,48)";
-#if DEBUG
-        @"let testIntToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,41--56,50)"
-#else
-        "let testIntToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,41--56,50)";
-#endif
+        [], "type OperatorTestsInt";
+        [], "let testIntEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,60--4,69)";
+        [], "let testIntNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,60--5,70)";
+        [], "let testIntLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,60--6,69)";
+        [], "let testIntLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,60--7,70)";
+        [], "let testIntGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,60--8,69)";
+        [], "let testIntGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,60--9,70)";
+        [], "let testIntAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,52--11,61)";
+        [], "let testIntSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,52--12,61)";
+        [], "let testIntMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,52--13,61)";
+        [], "let testIntDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,52--14,61)";
+        [], "let testIntModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,52--15,61)";
+        [], "let testIntBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,52--16,63)";
+        [], "let testIntBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,52--17,63)";
+        [], "let testIntBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,52--18,63)";
+        [], "let testIntShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,31)) @ (19,52--19,63)";
+        [], "let testIntShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,31)) @ (20,52--20,63)";
+        [], "let testIntUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,41--22,48)";
+        [], "let testIntAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,50--24,67)";
+        [], "let testIntSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,50--25,67)";
+        [], "let testIntMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,50--26,67)";
+        [], "let testIntUnaryNegChecked(e1) = Checked.op_Subtraction (0,e1) @ (27,41--27,56)";
+        [], "let testIntToByteChecked(e1) = Checked.ToByte (e1) @ (29,41--29,56)";
+        [], "let testIntToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,41--30,57)";
+        [], "let testIntToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,41--31,57)";
+        [], "let testIntToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,41--32,58)";
+        [], "let testIntToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,41--33,55)";
+        [], "let testIntToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,41--34,57)";
+        [], "let testIntToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,41--35,58)";
+        [], "let testIntToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,41--36,57)";
+        [], "let testIntToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,41--37,58)";
+        [], "let testIntToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,41--38,61)";
+        [], "let testIntToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,41--39,62)";
+        [], "let testIntToByteOperator(e1) = Operators.ToByte (e1) @ (41,41--41,48)";
+        [], "let testIntToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,41--42,49)";
+        [], "let testIntToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,41--43,49)";
+        [], "let testIntToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,41--44,50)";
+        [], "let testIntToIntOperator(e1) = e1 @ (45,45--45,47)";
+        [], "let testIntToInt32Operator(e1) = e1 @ (46,47--46,49)";
+        [], "let testIntToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,41--47,50)";
+        [], "let testIntToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,41--48,49)";
+        [], "let testIntToUInt64Operator(e1) = Operators.ToInt64 (e1) @ (49,41--49,50)";
+        [], "let testIntToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,41--50,53)";
+        [], "let testIntToUIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (51,41--51,54)";
+        [], "let testIntToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,41--52,51)";
+        [], "let testIntToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,41--53,49)";
+        [], "let testIntToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,41--54,51)";
+        [], "let testIntToCharOperator(e1) = Operators.ToChar (e1) @ (55,41--55,48)";
+        [FC47], "let testIntToStringOperator(e1) = IntrinsicFunctions.UnboxGeneric (Operators.Box (e1)).ToString(dflt,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (56,41--56,50)"
       ]
 
     testOperators "Int" "int" excludedTests expectedUnoptimized expectedOptimized
@@ -1604,111 +1648,107 @@ let ``Test Operator Declarations for Int32`` () =
     let excludedTests = [ ]
     
     let expectedUnoptimized = [
-        "type OperatorTestsInt32";
-        "let testInt32EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)";
-        "let testInt32NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,66--5,76)";
-        "let testInt32LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)";
-        "let testInt32LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,66--7,76)";
-        "let testInt32GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)";
-        "let testInt32GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,66--9,76)";
-        "let testInt32AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,58--11,67)";
-        "let testInt32SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,58--12,67)";
-        "let testInt32MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,58--13,67)";
-        "let testInt32DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,58--14,67)";
-        "let testInt32ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,58--15,67)";
-        "let testInt32BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,58--16,69)";
-        "let testInt32BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,58--17,69)";
-        "let testInt32BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,58--18,69)";
-        "let testInt32ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,56--19,67)";
-        "let testInt32ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,56--20,67)";
-        "let testInt32UnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,45--22,52)";
-        "let testInt32AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,56--24,73)";
-        "let testInt32SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,56--25,73)";
-        "let testInt32MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,56--26,73)";
-        "let testInt32UnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,45--27,60)";
-        "let testInt32ToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)";
-        "let testInt32ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)";
-        "let testInt32ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)";
-        "let testInt32ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)";
-        "let testInt32ToIntChecked(e1) = Checked.ToInt (e1) @ (33,45--33,59)";
-        "let testInt32ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)";
-        "let testInt32ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)";
-        "let testInt32ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)";
-        "let testInt32ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)";
-        "let testInt32ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)";
-        "let testInt32ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)";
-        "let testInt32ToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)";
-        "let testInt32ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)";
-        "let testInt32ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)";
-        "let testInt32ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)";
-        "let testInt32ToIntOperator(e1) = Operators.ToInt (e1) @ (45,45--45,51)";
-        "let testInt32ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)";
-        "let testInt32ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)";
-        "let testInt32ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)";
-        "let testInt32ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,45--49,54)";
-        "let testInt32ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)";
-        "let testInt32ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,45--51,58)";
-        "let testInt32ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)";
-        "let testInt32ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)";
-        "let testInt32ToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,45--54,55)";
-        "let testInt32ToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)";
-        "let testInt32ToStringOperator(e1) = Operators.ToString (e1) @ (56,45--56,54)";
+        [], "type OperatorTestsInt32";
+        [], "let testInt32EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)";
+        [], "let testInt32NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,66--5,76)";
+        [], "let testInt32LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)";
+        [], "let testInt32LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,66--7,76)";
+        [], "let testInt32GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)";
+        [], "let testInt32GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,66--9,76)";
+        [], "let testInt32AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,58--11,67)";
+        [], "let testInt32SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,58--12,67)";
+        [], "let testInt32MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,58--13,67)";
+        [], "let testInt32DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,58--14,67)";
+        [], "let testInt32ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,58--15,67)";
+        [], "let testInt32BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,58--16,69)";
+        [], "let testInt32BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,58--17,69)";
+        [], "let testInt32BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,58--18,69)";
+        [], "let testInt32ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,56--19,67)";
+        [], "let testInt32ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,56--20,67)";
+        [], "let testInt32UnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,45--22,52)";
+        [], "let testInt32AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,56--24,73)";
+        [], "let testInt32SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,56--25,73)";
+        [], "let testInt32MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,56--26,73)";
+        [], "let testInt32UnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,45--27,60)";
+        [], "let testInt32ToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)";
+        [], "let testInt32ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)";
+        [], "let testInt32ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)";
+        [], "let testInt32ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)";
+        [], "let testInt32ToIntChecked(e1) = Checked.ToInt (e1) @ (33,45--33,59)";
+        [], "let testInt32ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)";
+        [], "let testInt32ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)";
+        [], "let testInt32ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)";
+        [], "let testInt32ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)";
+        [], "let testInt32ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)";
+        [], "let testInt32ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)";
+        [], "let testInt32ToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)";
+        [], "let testInt32ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)";
+        [], "let testInt32ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)";
+        [], "let testInt32ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)";
+        [], "let testInt32ToIntOperator(e1) = Operators.ToInt (e1) @ (45,45--45,51)";
+        [], "let testInt32ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)";
+        [], "let testInt32ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)";
+        [], "let testInt32ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)";
+        [], "let testInt32ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,45--49,54)";
+        [], "let testInt32ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)";
+        [], "let testInt32ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,45--51,58)";
+        [], "let testInt32ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)";
+        [], "let testInt32ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)";
+        [], "let testInt32ToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,45--54,55)";
+        [], "let testInt32ToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)";
+        [], "let testInt32ToStringOperator(e1) = Operators.ToString (e1) @ (56,45--56,54)";
       ]
 
     let expectedOptimized = [
-        "type OperatorTestsInt32";
-        "let testInt32EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)";
-        "let testInt32NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,66--5,76)";
-        "let testInt32LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)";
-        "let testInt32LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,66--7,76)";
-        "let testInt32GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)";
-        "let testInt32GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,66--9,76)";
-        "let testInt32AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,58--11,67)";
-        "let testInt32SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,58--12,67)";
-        "let testInt32MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,58--13,67)";
-        "let testInt32DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,58--14,67)";
-        "let testInt32ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,58--15,67)";
-        "let testInt32BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,58--16,69)";
-        "let testInt32BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,58--17,69)";
-        "let testInt32BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,58--18,69)";
-        "let testInt32ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,31)) @ (19,56--19,67)";
-        "let testInt32ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,31)) @ (20,56--20,67)";
-        "let testInt32UnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,45--22,52)";
-        "let testInt32AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,56--24,73)";
-        "let testInt32SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,56--25,73)";
-        "let testInt32MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,56--26,73)";
-        "let testInt32UnaryNegChecked(e1) = Checked.op_Subtraction (0,e1) @ (27,45--27,60)";
-        "let testInt32ToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)";
-        "let testInt32ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)";
-        "let testInt32ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)";
-        "let testInt32ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)";
-        "let testInt32ToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,45--33,59)";
-        "let testInt32ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)";
-        "let testInt32ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)";
-        "let testInt32ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)";
-        "let testInt32ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)";
-        "let testInt32ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)";
-        "let testInt32ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)";
-        "let testInt32ToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)";
-        "let testInt32ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)";
-        "let testInt32ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)";
-        "let testInt32ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)";
-        "let testInt32ToIntOperator(e1) = e1 @ (45,49--45,51)";
-        "let testInt32ToInt32Operator(e1) = e1 @ (46,51--46,53)";
-        "let testInt32ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)";
-        "let testInt32ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)";
-        "let testInt32ToUInt64Operator(e1) = Operators.ToInt64 (e1) @ (49,45--49,54)";
-        "let testInt32ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)";
-        "let testInt32ToUIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (51,45--51,58)";
-        "let testInt32ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)";
-        "let testInt32ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)";
-        "let testInt32ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,45--54,55)";
-        "let testInt32ToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)";
-#if DEBUG
-        @"let testInt32ToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,45--56,54)"
-#else
-        "let testInt32ToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,45--56,54)";
-#endif
+        [], "type OperatorTestsInt32";
+        [], "let testInt32EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)";
+        [], "let testInt32NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,66--5,76)";
+        [], "let testInt32LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)";
+        [], "let testInt32LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,66--7,76)";
+        [], "let testInt32GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)";
+        [], "let testInt32GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,66--9,76)";
+        [], "let testInt32AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,58--11,67)";
+        [], "let testInt32SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,58--12,67)";
+        [], "let testInt32MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,58--13,67)";
+        [], "let testInt32DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,58--14,67)";
+        [], "let testInt32ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,58--15,67)";
+        [], "let testInt32BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,58--16,69)";
+        [], "let testInt32BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,58--17,69)";
+        [], "let testInt32BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,58--18,69)";
+        [], "let testInt32ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,31)) @ (19,56--19,67)";
+        [], "let testInt32ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,31)) @ (20,56--20,67)";
+        [], "let testInt32UnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,45--22,52)";
+        [], "let testInt32AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,56--24,73)";
+        [], "let testInt32SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,56--25,73)";
+        [], "let testInt32MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,56--26,73)";
+        [], "let testInt32UnaryNegChecked(e1) = Checked.op_Subtraction (0,e1) @ (27,45--27,60)";
+        [], "let testInt32ToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)";
+        [], "let testInt32ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)";
+        [], "let testInt32ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)";
+        [], "let testInt32ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)";
+        [], "let testInt32ToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,45--33,59)";
+        [], "let testInt32ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)";
+        [], "let testInt32ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)";
+        [], "let testInt32ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)";
+        [], "let testInt32ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)";
+        [], "let testInt32ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)";
+        [], "let testInt32ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)";
+        [], "let testInt32ToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)";
+        [], "let testInt32ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)";
+        [], "let testInt32ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)";
+        [], "let testInt32ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)";
+        [], "let testInt32ToIntOperator(e1) = e1 @ (45,49--45,51)";
+        [], "let testInt32ToInt32Operator(e1) = e1 @ (46,51--46,53)";
+        [], "let testInt32ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)";
+        [], "let testInt32ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)";
+        [], "let testInt32ToUInt64Operator(e1) = Operators.ToInt64 (e1) @ (49,45--49,54)";
+        [], "let testInt32ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)";
+        [], "let testInt32ToUIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (51,45--51,58)";
+        [], "let testInt32ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)";
+        [], "let testInt32ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)";
+        [], "let testInt32ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,45--54,55)";
+        [], "let testInt32ToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)";
+        [FC47], "let testInt32ToStringOperator(e1) = IntrinsicFunctions.UnboxGeneric (Operators.Box (e1)).ToString(dflt,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (56,45--56,54)"
       ]
 
     testOperators "Int32" "int32" excludedTests expectedUnoptimized expectedOptimized
@@ -1721,107 +1761,103 @@ let ``Test Operator Declarations for UInt32`` () =
       ]
     
     let expectedUnoptimized = [
-        "type OperatorTestsUInt32";
-        "let testUInt32EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)";
-        "let testUInt32NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,69--5,79)";
-        "let testUInt32LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)";
-        "let testUInt32LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,69--7,79)";
-        "let testUInt32GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)";
-        "let testUInt32GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,69--9,79)";
-        "let testUInt32AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,61--11,70)";
-        "let testUInt32SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,61--12,70)";
-        "let testUInt32MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,61--13,70)";
-        "let testUInt32DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,61--14,70)";
-        "let testUInt32ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,61--15,70)";
-        "let testUInt32BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,61--16,72)";
-        "let testUInt32BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,61--17,72)";
-        "let testUInt32BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,61--18,72)";
-        "let testUInt32ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,58--19,69)";
-        "let testUInt32ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,58--20,69)";
-        "let testUInt32AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,59--24,76)";
-        "let testUInt32SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,59--25,76)";
-        "let testUInt32MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,59--26,76)";
-        "let testUInt32ToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)";
-        "let testUInt32ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)";
-        "let testUInt32ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)";
-        "let testUInt32ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)";
-        "let testUInt32ToIntChecked(e1) = Checked.ToInt (e1) @ (33,47--33,61)";
-        "let testUInt32ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)";
-        "let testUInt32ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)";
-        "let testUInt32ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)";
-        "let testUInt32ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)";
-        "let testUInt32ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,47--38,67)";
-        "let testUInt32ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,47--39,68)";
-        "let testUInt32ToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)";
-        "let testUInt32ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)";
-        "let testUInt32ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)";
-        "let testUInt32ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)";
-        "let testUInt32ToIntOperator(e1) = Operators.ToInt (e1) @ (45,47--45,53)";
-        "let testUInt32ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)";
-        "let testUInt32ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)";
-        "let testUInt32ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,47--48,55)";
-        "let testUInt32ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,47--49,56)";
-        "let testUInt32ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,47--50,59)";
-        "let testUInt32ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,47--51,60)";
-        "let testUInt32ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,47--52,57)";
-        "let testUInt32ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,47--53,55)";
-        "let testUInt32ToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,47--54,57)";
-        "let testUInt32ToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)";
-        "let testUInt32ToStringOperator(e1) = Operators.ToString (e1) @ (56,47--56,56)";
+        [], "type OperatorTestsUInt32";
+        [], "let testUInt32EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)";
+        [], "let testUInt32NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,69--5,79)";
+        [], "let testUInt32LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)";
+        [], "let testUInt32LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,69--7,79)";
+        [], "let testUInt32GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)";
+        [], "let testUInt32GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,69--9,79)";
+        [], "let testUInt32AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,61--11,70)";
+        [], "let testUInt32SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,61--12,70)";
+        [], "let testUInt32MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,61--13,70)";
+        [], "let testUInt32DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,61--14,70)";
+        [], "let testUInt32ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,61--15,70)";
+        [], "let testUInt32BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,61--16,72)";
+        [], "let testUInt32BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,61--17,72)";
+        [], "let testUInt32BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,61--18,72)";
+        [], "let testUInt32ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,58--19,69)";
+        [], "let testUInt32ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,58--20,69)";
+        [], "let testUInt32AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,59--24,76)";
+        [], "let testUInt32SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,59--25,76)";
+        [], "let testUInt32MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,59--26,76)";
+        [], "let testUInt32ToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)";
+        [], "let testUInt32ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)";
+        [], "let testUInt32ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)";
+        [], "let testUInt32ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)";
+        [], "let testUInt32ToIntChecked(e1) = Checked.ToInt (e1) @ (33,47--33,61)";
+        [], "let testUInt32ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)";
+        [], "let testUInt32ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)";
+        [], "let testUInt32ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)";
+        [], "let testUInt32ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)";
+        [], "let testUInt32ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,47--38,67)";
+        [], "let testUInt32ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,47--39,68)";
+        [], "let testUInt32ToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)";
+        [], "let testUInt32ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)";
+        [], "let testUInt32ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)";
+        [], "let testUInt32ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)";
+        [], "let testUInt32ToIntOperator(e1) = Operators.ToInt (e1) @ (45,47--45,53)";
+        [], "let testUInt32ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)";
+        [], "let testUInt32ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)";
+        [], "let testUInt32ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,47--48,55)";
+        [], "let testUInt32ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,47--49,56)";
+        [], "let testUInt32ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,47--50,59)";
+        [], "let testUInt32ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,47--51,60)";
+        [], "let testUInt32ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,47--52,57)";
+        [], "let testUInt32ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,47--53,55)";
+        [], "let testUInt32ToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,47--54,57)";
+        [], "let testUInt32ToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)";
+        [], "let testUInt32ToStringOperator(e1) = Operators.ToString (e1) @ (56,47--56,56)";
       ]
 
     let expectedOptimized = [
-        "type OperatorTestsUInt32";
-        "let testUInt32EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)";
-        "let testUInt32NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,69--5,79)";
-        "let testUInt32LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)";
-        "let testUInt32LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,69--7,79)";
-        "let testUInt32GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)";
-        "let testUInt32GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,69--9,79)";
-        "let testUInt32AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,61--11,70)";
-        "let testUInt32SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,61--12,70)";
-        "let testUInt32MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,61--13,70)";
-        "let testUInt32DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,61--14,70)";
-        "let testUInt32ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,61--15,70)";
-        "let testUInt32BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,61--16,72)";
-        "let testUInt32BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,61--17,72)";
-        "let testUInt32BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,61--18,72)";
-        "let testUInt32ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,31)) @ (19,58--19,69)";
-        "let testUInt32ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,31)) @ (20,58--20,69)";
-        "let testUInt32AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,59--24,76)";
-        "let testUInt32SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,59--25,76)";
-        "let testUInt32MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,59--26,76)";
-        "let testUInt32ToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)";
-        "let testUInt32ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)";
-        "let testUInt32ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)";
-        "let testUInt32ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)";
-        "let testUInt32ToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,47--33,61)";
-        "let testUInt32ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)";
-        "let testUInt32ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)";
-        "let testUInt32ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)";
-        "let testUInt32ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)";
-        "let testUInt32ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,47--38,67)";
-        "let testUInt32ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,47--39,68)";
-        "let testUInt32ToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)";
-        "let testUInt32ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)";
-        "let testUInt32ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)";
-        "let testUInt32ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)";
-        "let testUInt32ToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,47--45,53)";
-        "let testUInt32ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)";
-        "let testUInt32ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)";
-        "let testUInt32ToInt64Operator(e1) = Operators.ToUInt64 (e1) @ (48,47--48,55)";
-        "let testUInt32ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,47--49,56)";
-        "let testUInt32ToIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (50,47--50,59)";
-        "let testUInt32ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,47--51,60)";
-        "let testUInt32ToSingleOperator(e1) = Operators.ToSingle (Operators.ToDouble (e1)) @ (52,47--52,57)";
-        "let testUInt32ToDoubleOperator(e1) = Operators.ToDouble (Operators.ToDouble (e1)) @ (53,47--53,55)";
-        "let testUInt32ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,47--54,57)";
-        "let testUInt32ToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)";
-#if DEBUG
-        @"let testUInt32ToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,47--56,56)"
-#else
-        "let testUInt32ToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,47--56,56)";
-#endif
+        [], "type OperatorTestsUInt32";
+        [], "let testUInt32EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)";
+        [], "let testUInt32NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,69--5,79)";
+        [], "let testUInt32LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)";
+        [], "let testUInt32LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,69--7,79)";
+        [], "let testUInt32GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)";
+        [], "let testUInt32GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,69--9,79)";
+        [], "let testUInt32AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,61--11,70)";
+        [], "let testUInt32SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,61--12,70)";
+        [], "let testUInt32MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,61--13,70)";
+        [], "let testUInt32DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,61--14,70)";
+        [], "let testUInt32ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,61--15,70)";
+        [], "let testUInt32BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,61--16,72)";
+        [], "let testUInt32BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,61--17,72)";
+        [], "let testUInt32BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,61--18,72)";
+        [], "let testUInt32ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,31)) @ (19,58--19,69)";
+        [], "let testUInt32ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,31)) @ (20,58--20,69)";
+        [], "let testUInt32AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,59--24,76)";
+        [], "let testUInt32SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,59--25,76)";
+        [], "let testUInt32MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,59--26,76)";
+        [], "let testUInt32ToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)";
+        [], "let testUInt32ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)";
+        [], "let testUInt32ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)";
+        [], "let testUInt32ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)";
+        [], "let testUInt32ToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,47--33,61)";
+        [], "let testUInt32ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)";
+        [], "let testUInt32ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)";
+        [], "let testUInt32ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)";
+        [], "let testUInt32ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)";
+        [], "let testUInt32ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,47--38,67)";
+        [], "let testUInt32ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,47--39,68)";
+        [], "let testUInt32ToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)";
+        [], "let testUInt32ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)";
+        [], "let testUInt32ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)";
+        [], "let testUInt32ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)";
+        [], "let testUInt32ToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,47--45,53)";
+        [], "let testUInt32ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)";
+        [], "let testUInt32ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)";
+        [], "let testUInt32ToInt64Operator(e1) = Operators.ToUInt64 (e1) @ (48,47--48,55)";
+        [], "let testUInt32ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,47--49,56)";
+        [], "let testUInt32ToIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (50,47--50,59)";
+        [], "let testUInt32ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,47--51,60)";
+        [], "let testUInt32ToSingleOperator(e1) = Operators.ToSingle (Operators.ToDouble (e1)) @ (52,47--52,57)";
+        [], "let testUInt32ToDoubleOperator(e1) = Operators.ToDouble (Operators.ToDouble (e1)) @ (53,47--53,55)";
+        [], "let testUInt32ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,47--54,57)";
+        [], "let testUInt32ToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)";
+        [FC47], "let testUInt32ToStringOperator(e1) = let mutable copyOfStruct: Microsoft.FSharp.Core.uint32 = e1 in copyOfStruct.ToString() @ (56,47--56,56)"
       ]
 
     testOperators "UInt32" "uint32" excludedTests expectedUnoptimized expectedOptimized
@@ -1831,111 +1867,107 @@ let ``Test Operator Declarations for Int64`` () =
     let excludedTests = [ ]
     
     let expectedUnoptimized = [
-        "type OperatorTestsInt64";
-        "let testInt64EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)";
-        "let testInt64NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,66--5,76)";
-        "let testInt64LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)";
-        "let testInt64LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,66--7,76)";
-        "let testInt64GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)";
-        "let testInt64GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,66--9,76)";
-        "let testInt64AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,58--11,67)";
-        "let testInt64SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,58--12,67)";
-        "let testInt64MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,58--13,67)";
-        "let testInt64DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,58--14,67)";
-        "let testInt64ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,58--15,67)";
-        "let testInt64BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,58--16,69)";
-        "let testInt64BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,58--17,69)";
-        "let testInt64BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,58--18,69)";
-        "let testInt64ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,56--19,67)";
-        "let testInt64ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,56--20,67)";
-        "let testInt64UnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,45--22,52)";
-        "let testInt64AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,56--24,73)";
-        "let testInt64SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,56--25,73)";
-        "let testInt64MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,56--26,73)";
-        "let testInt64UnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,45--27,60)";
-        "let testInt64ToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)";
-        "let testInt64ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)";
-        "let testInt64ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)";
-        "let testInt64ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)";
-        "let testInt64ToIntChecked(e1) = Checked.ToInt (e1) @ (33,45--33,59)";
-        "let testInt64ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)";
-        "let testInt64ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)";
-        "let testInt64ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)";
-        "let testInt64ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)";
-        "let testInt64ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)";
-        "let testInt64ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)";
-        "let testInt64ToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)";
-        "let testInt64ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)";
-        "let testInt64ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)";
-        "let testInt64ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)";
-        "let testInt64ToIntOperator(e1) = Operators.ToInt (e1) @ (45,45--45,51)";
-        "let testInt64ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)";
-        "let testInt64ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)";
-        "let testInt64ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)";
-        "let testInt64ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,45--49,54)";
-        "let testInt64ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)";
-        "let testInt64ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,45--51,58)";
-        "let testInt64ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)";
-        "let testInt64ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)";
-        "let testInt64ToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,45--54,55)";
-        "let testInt64ToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)";
-        "let testInt64ToStringOperator(e1) = Operators.ToString (e1) @ (56,45--56,54)";
+        [], "type OperatorTestsInt64";
+        [], "let testInt64EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)";
+        [], "let testInt64NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,66--5,76)";
+        [], "let testInt64LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)";
+        [], "let testInt64LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,66--7,76)";
+        [], "let testInt64GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)";
+        [], "let testInt64GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,66--9,76)";
+        [], "let testInt64AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,58--11,67)";
+        [], "let testInt64SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,58--12,67)";
+        [], "let testInt64MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,58--13,67)";
+        [], "let testInt64DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,58--14,67)";
+        [], "let testInt64ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,58--15,67)";
+        [], "let testInt64BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,58--16,69)";
+        [], "let testInt64BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,58--17,69)";
+        [], "let testInt64BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,58--18,69)";
+        [], "let testInt64ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,56--19,67)";
+        [], "let testInt64ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,56--20,67)";
+        [], "let testInt64UnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,45--22,52)";
+        [], "let testInt64AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,56--24,73)";
+        [], "let testInt64SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,56--25,73)";
+        [], "let testInt64MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,56--26,73)";
+        [], "let testInt64UnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,45--27,60)";
+        [], "let testInt64ToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)";
+        [], "let testInt64ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)";
+        [], "let testInt64ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)";
+        [], "let testInt64ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)";
+        [], "let testInt64ToIntChecked(e1) = Checked.ToInt (e1) @ (33,45--33,59)";
+        [], "let testInt64ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)";
+        [], "let testInt64ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)";
+        [], "let testInt64ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)";
+        [], "let testInt64ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)";
+        [], "let testInt64ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)";
+        [], "let testInt64ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)";
+        [], "let testInt64ToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)";
+        [], "let testInt64ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)";
+        [], "let testInt64ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)";
+        [], "let testInt64ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)";
+        [], "let testInt64ToIntOperator(e1) = Operators.ToInt (e1) @ (45,45--45,51)";
+        [], "let testInt64ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)";
+        [], "let testInt64ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)";
+        [], "let testInt64ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)";
+        [], "let testInt64ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,45--49,54)";
+        [], "let testInt64ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)";
+        [], "let testInt64ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,45--51,58)";
+        [], "let testInt64ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)";
+        [], "let testInt64ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)";
+        [], "let testInt64ToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,45--54,55)";
+        [], "let testInt64ToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)";
+        [], "let testInt64ToStringOperator(e1) = Operators.ToString (e1) @ (56,45--56,54)";
       ]
 
     let expectedOptimized = [
-        "type OperatorTestsInt64";
-        "let testInt64EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)";
-        "let testInt64NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,66--5,76)";
-        "let testInt64LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)";
-        "let testInt64LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,66--7,76)";
-        "let testInt64GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)";
-        "let testInt64GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,66--9,76)";
-        "let testInt64AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,58--11,67)";
-        "let testInt64SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,58--12,67)";
-        "let testInt64MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,58--13,67)";
-        "let testInt64DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,58--14,67)";
-        "let testInt64ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,58--15,67)";
-        "let testInt64BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,58--16,69)";
-        "let testInt64BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,58--17,69)";
-        "let testInt64BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,58--18,69)";
-        "let testInt64ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,63)) @ (19,56--19,67)";
-        "let testInt64ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,63)) @ (20,56--20,67)";
-        "let testInt64UnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,45--22,52)";
-        "let testInt64AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,56--24,73)";
-        "let testInt64SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,56--25,73)";
-        "let testInt64MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,56--26,73)";
-        "let testInt64UnaryNegChecked(e1) = Checked.op_Subtraction (0,e1) @ (27,45--27,60)";
-        "let testInt64ToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)";
-        "let testInt64ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)";
-        "let testInt64ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)";
-        "let testInt64ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)";
-        "let testInt64ToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,45--33,59)";
-        "let testInt64ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)";
-        "let testInt64ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)";
-        "let testInt64ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)";
-        "let testInt64ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)";
-        "let testInt64ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)";
-        "let testInt64ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)";
-        "let testInt64ToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)";
-        "let testInt64ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)";
-        "let testInt64ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)";
-        "let testInt64ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)";
-        "let testInt64ToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,45--45,51)";
-        "let testInt64ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)";
-        "let testInt64ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)";
-        "let testInt64ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)";
-        "let testInt64ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,45--49,54)";
-        "let testInt64ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)";
-        "let testInt64ToUIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (51,45--51,58)";
-        "let testInt64ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)";
-        "let testInt64ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)";
-        "let testInt64ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,45--54,55)";
-        "let testInt64ToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)";
-#if DEBUG
-        @"let testInt64ToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,45--56,54)"
-#else
-        "let testInt64ToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,45--56,54)";
-#endif
+        [], "type OperatorTestsInt64";
+        [], "let testInt64EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)";
+        [], "let testInt64NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,66--5,76)";
+        [], "let testInt64LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)";
+        [], "let testInt64LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,66--7,76)";
+        [], "let testInt64GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)";
+        [], "let testInt64GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,66--9,76)";
+        [], "let testInt64AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,58--11,67)";
+        [], "let testInt64SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,58--12,67)";
+        [], "let testInt64MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,58--13,67)";
+        [], "let testInt64DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,58--14,67)";
+        [], "let testInt64ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,58--15,67)";
+        [], "let testInt64BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,58--16,69)";
+        [], "let testInt64BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,58--17,69)";
+        [], "let testInt64BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,58--18,69)";
+        [], "let testInt64ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,63)) @ (19,56--19,67)";
+        [], "let testInt64ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,63)) @ (20,56--20,67)";
+        [], "let testInt64UnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,45--22,52)";
+        [], "let testInt64AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,56--24,73)";
+        [], "let testInt64SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,56--25,73)";
+        [], "let testInt64MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,56--26,73)";
+        [], "let testInt64UnaryNegChecked(e1) = Checked.op_Subtraction (0,e1) @ (27,45--27,60)";
+        [], "let testInt64ToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)";
+        [], "let testInt64ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)";
+        [], "let testInt64ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)";
+        [], "let testInt64ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)";
+        [], "let testInt64ToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,45--33,59)";
+        [], "let testInt64ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)";
+        [], "let testInt64ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)";
+        [], "let testInt64ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)";
+        [], "let testInt64ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)";
+        [], "let testInt64ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)";
+        [], "let testInt64ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)";
+        [], "let testInt64ToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)";
+        [], "let testInt64ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)";
+        [], "let testInt64ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)";
+        [], "let testInt64ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)";
+        [], "let testInt64ToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,45--45,51)";
+        [], "let testInt64ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)";
+        [], "let testInt64ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)";
+        [], "let testInt64ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)";
+        [], "let testInt64ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,45--49,54)";
+        [], "let testInt64ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)";
+        [], "let testInt64ToUIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (51,45--51,58)";
+        [], "let testInt64ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)";
+        [], "let testInt64ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)";
+        [], "let testInt64ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,45--54,55)";
+        [], "let testInt64ToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)";
+        [FC47], "let testInt64ToStringOperator(e1) = IntrinsicFunctions.UnboxGeneric (Operators.Box (e1)).ToString(dflt,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (56,45--56,54)"
       ]
 
     testOperators "Int64" "int64" excludedTests expectedUnoptimized expectedOptimized
@@ -1948,107 +1980,103 @@ let ``Test Operator Declarations for UInt64`` () =
       ]
     
     let expectedUnoptimized = [
-        "type OperatorTestsUInt64";
-        "let testUInt64EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)";
-        "let testUInt64NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,69--5,79)";
-        "let testUInt64LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)";
-        "let testUInt64LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,69--7,79)";
-        "let testUInt64GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)";
-        "let testUInt64GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,69--9,79)";
-        "let testUInt64AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,61--11,70)";
-        "let testUInt64SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,61--12,70)";
-        "let testUInt64MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,61--13,70)";
-        "let testUInt64DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,61--14,70)";
-        "let testUInt64ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,61--15,70)";
-        "let testUInt64BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,61--16,72)";
-        "let testUInt64BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,61--17,72)";
-        "let testUInt64BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,61--18,72)";
-        "let testUInt64ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,58--19,69)";
-        "let testUInt64ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,58--20,69)";
-        "let testUInt64AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,59--24,76)";
-        "let testUInt64SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,59--25,76)";
-        "let testUInt64MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,59--26,76)";
-        "let testUInt64ToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)";
-        "let testUInt64ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)";
-        "let testUInt64ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)";
-        "let testUInt64ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)";
-        "let testUInt64ToIntChecked(e1) = Checked.ToInt (e1) @ (33,47--33,61)";
-        "let testUInt64ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)";
-        "let testUInt64ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)";
-        "let testUInt64ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)";
-        "let testUInt64ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)";
-        "let testUInt64ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,47--38,67)";
-        "let testUInt64ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,47--39,68)";
-        "let testUInt64ToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)";
-        "let testUInt64ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)";
-        "let testUInt64ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)";
-        "let testUInt64ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)";
-        "let testUInt64ToIntOperator(e1) = Operators.ToInt (e1) @ (45,47--45,53)";
-        "let testUInt64ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)";
-        "let testUInt64ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)";
-        "let testUInt64ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,47--48,55)";
-        "let testUInt64ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,47--49,56)";
-        "let testUInt64ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,47--50,59)";
-        "let testUInt64ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,47--51,60)";
-        "let testUInt64ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,47--52,57)";
-        "let testUInt64ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,47--53,55)";
-        "let testUInt64ToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,47--54,57)";
-        "let testUInt64ToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)";
-        "let testUInt64ToStringOperator(e1) = Operators.ToString (e1) @ (56,47--56,56)";
+        [], "type OperatorTestsUInt64";
+        [], "let testUInt64EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)";
+        [], "let testUInt64NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,69--5,79)";
+        [], "let testUInt64LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)";
+        [], "let testUInt64LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,69--7,79)";
+        [], "let testUInt64GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)";
+        [], "let testUInt64GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,69--9,79)";
+        [], "let testUInt64AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,61--11,70)";
+        [], "let testUInt64SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,61--12,70)";
+        [], "let testUInt64MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,61--13,70)";
+        [], "let testUInt64DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,61--14,70)";
+        [], "let testUInt64ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,61--15,70)";
+        [], "let testUInt64BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,61--16,72)";
+        [], "let testUInt64BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,61--17,72)";
+        [], "let testUInt64BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,61--18,72)";
+        [], "let testUInt64ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,58--19,69)";
+        [], "let testUInt64ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,58--20,69)";
+        [], "let testUInt64AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,59--24,76)";
+        [], "let testUInt64SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,59--25,76)";
+        [], "let testUInt64MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,59--26,76)";
+        [], "let testUInt64ToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)";
+        [], "let testUInt64ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)";
+        [], "let testUInt64ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)";
+        [], "let testUInt64ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)";
+        [], "let testUInt64ToIntChecked(e1) = Checked.ToInt (e1) @ (33,47--33,61)";
+        [], "let testUInt64ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)";
+        [], "let testUInt64ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)";
+        [], "let testUInt64ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)";
+        [], "let testUInt64ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)";
+        [], "let testUInt64ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,47--38,67)";
+        [], "let testUInt64ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,47--39,68)";
+        [], "let testUInt64ToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)";
+        [], "let testUInt64ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)";
+        [], "let testUInt64ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)";
+        [], "let testUInt64ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)";
+        [], "let testUInt64ToIntOperator(e1) = Operators.ToInt (e1) @ (45,47--45,53)";
+        [], "let testUInt64ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)";
+        [], "let testUInt64ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)";
+        [], "let testUInt64ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,47--48,55)";
+        [], "let testUInt64ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,47--49,56)";
+        [], "let testUInt64ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,47--50,59)";
+        [], "let testUInt64ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,47--51,60)";
+        [], "let testUInt64ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,47--52,57)";
+        [], "let testUInt64ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,47--53,55)";
+        [], "let testUInt64ToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,47--54,57)";
+        [], "let testUInt64ToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)";
+        [], "let testUInt64ToStringOperator(e1) = Operators.ToString (e1) @ (56,47--56,56)";
       ]
 
     let expectedOptimized = [
-        "type OperatorTestsUInt64";
-        "let testUInt64EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)";
-        "let testUInt64NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,69--5,79)";
-        "let testUInt64LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)";
-        "let testUInt64LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,69--7,79)";
-        "let testUInt64GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)";
-        "let testUInt64GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,69--9,79)";
-        "let testUInt64AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,61--11,70)";
-        "let testUInt64SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,61--12,70)";
-        "let testUInt64MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,61--13,70)";
-        "let testUInt64DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,61--14,70)";
-        "let testUInt64ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,61--15,70)";
-        "let testUInt64BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,61--16,72)";
-        "let testUInt64BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,61--17,72)";
-        "let testUInt64BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,61--18,72)";
-        "let testUInt64ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,63)) @ (19,58--19,69)";
-        "let testUInt64ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,63)) @ (20,58--20,69)";
-        "let testUInt64AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,59--24,76)";
-        "let testUInt64SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,59--25,76)";
-        "let testUInt64MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,59--26,76)";
-        "let testUInt64ToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)";
-        "let testUInt64ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)";
-        "let testUInt64ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)";
-        "let testUInt64ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)";
-        "let testUInt64ToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,47--33,61)";
-        "let testUInt64ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)";
-        "let testUInt64ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)";
-        "let testUInt64ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)";
-        "let testUInt64ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)";
-        "let testUInt64ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,47--38,67)";
-        "let testUInt64ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,47--39,68)";
-        "let testUInt64ToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)";
-        "let testUInt64ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)";
-        "let testUInt64ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)";
-        "let testUInt64ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)";
-        "let testUInt64ToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,47--45,53)";
-        "let testUInt64ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)";
-        "let testUInt64ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)";
-        "let testUInt64ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,47--48,55)";
-        "let testUInt64ToUInt64Operator(e1) = e1 @ (49,54--49,56)";
-        "let testUInt64ToIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (50,47--50,59)";
-        "let testUInt64ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,47--51,60)";
-        "let testUInt64ToSingleOperator(e1) = Operators.ToSingle (Operators.ToDouble (e1)) @ (52,47--52,57)";
-        "let testUInt64ToDoubleOperator(e1) = Operators.ToDouble (Operators.ToDouble (e1)) @ (53,47--53,55)";
-        "let testUInt64ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,47--54,57)";
-        "let testUInt64ToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)";
-#if DEBUG
-        @"let testUInt64ToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,47--56,56)"
-#else
-        "let testUInt64ToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,47--56,56)";
-#endif
+        [], "type OperatorTestsUInt64";
+        [], "let testUInt64EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)";
+        [], "let testUInt64NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,69--5,79)";
+        [], "let testUInt64LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)";
+        [], "let testUInt64LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,69--7,79)";
+        [], "let testUInt64GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)";
+        [], "let testUInt64GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,69--9,79)";
+        [], "let testUInt64AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,61--11,70)";
+        [], "let testUInt64SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,61--12,70)";
+        [], "let testUInt64MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,61--13,70)";
+        [], "let testUInt64DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,61--14,70)";
+        [], "let testUInt64ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,61--15,70)";
+        [], "let testUInt64BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,61--16,72)";
+        [], "let testUInt64BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,61--17,72)";
+        [], "let testUInt64BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,61--18,72)";
+        [], "let testUInt64ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,63)) @ (19,58--19,69)";
+        [], "let testUInt64ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,63)) @ (20,58--20,69)";
+        [], "let testUInt64AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,59--24,76)";
+        [], "let testUInt64SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,59--25,76)";
+        [], "let testUInt64MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,59--26,76)";
+        [], "let testUInt64ToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)";
+        [], "let testUInt64ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)";
+        [], "let testUInt64ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)";
+        [], "let testUInt64ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)";
+        [], "let testUInt64ToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,47--33,61)";
+        [], "let testUInt64ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)";
+        [], "let testUInt64ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)";
+        [], "let testUInt64ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)";
+        [], "let testUInt64ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)";
+        [], "let testUInt64ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,47--38,67)";
+        [], "let testUInt64ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,47--39,68)";
+        [], "let testUInt64ToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)";
+        [], "let testUInt64ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)";
+        [], "let testUInt64ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)";
+        [], "let testUInt64ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)";
+        [], "let testUInt64ToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,47--45,53)";
+        [], "let testUInt64ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)";
+        [], "let testUInt64ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)";
+        [], "let testUInt64ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,47--48,55)";
+        [], "let testUInt64ToUInt64Operator(e1) = e1 @ (49,54--49,56)";
+        [], "let testUInt64ToIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (50,47--50,59)";
+        [], "let testUInt64ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,47--51,60)";
+        [], "let testUInt64ToSingleOperator(e1) = Operators.ToSingle (Operators.ToDouble (e1)) @ (52,47--52,57)";
+        [], "let testUInt64ToDoubleOperator(e1) = Operators.ToDouble (Operators.ToDouble (e1)) @ (53,47--53,55)";
+        [], "let testUInt64ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,47--54,57)";
+        [], "let testUInt64ToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)";
+        [FC47], "let testUInt64ToStringOperator(e1) = let mutable copyOfStruct: Microsoft.FSharp.Core.uint64 = e1 in copyOfStruct.ToString() @ (56,47--56,56)"
       ]
 
     testOperators "UInt64" "uint64" excludedTests expectedUnoptimized expectedOptimized
@@ -2058,111 +2086,107 @@ let ``Test Operator Declarations for IntPtr`` () =
     let excludedTests = [ ]
     
     let expectedUnoptimized = [
-        "type OperatorTestsIntPtr";
-        "let testIntPtrEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,75--4,84)";
-        "let testIntPtrNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,75--5,85)";
-        "let testIntPtrLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,75--6,84)";
-        "let testIntPtrLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,75--7,85)";
-        "let testIntPtrGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,75--8,84)";
-        "let testIntPtrGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,75--9,85)";
-        "let testIntPtrAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,67--11,76)";
-        "let testIntPtrSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,67--12,76)";
-        "let testIntPtrMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,67--13,76)";
-        "let testIntPtrDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,67--14,76)";
-        "let testIntPtrModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,67--15,76)";
-        "let testIntPtrBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,67--16,78)";
-        "let testIntPtrBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,67--17,78)";
-        "let testIntPtrBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,67--18,78)";
-        "let testIntPtrShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,61--19,72)";
-        "let testIntPtrShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,61--20,72)";
-        "let testIntPtrUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,50--22,57)";
-        "let testIntPtrAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,65--24,82)";
-        "let testIntPtrSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,65--25,82)";
-        "let testIntPtrMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,65--26,82)";
-        "let testIntPtrUnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,50--27,65)";
-        "let testIntPtrToByteChecked(e1) = Checked.ToByte (e1) @ (29,50--29,65)";
-        "let testIntPtrToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,50--30,66)";
-        "let testIntPtrToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,50--31,66)";
-        "let testIntPtrToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,50--32,67)";
-        "let testIntPtrToIntChecked(e1) = Checked.ToInt (e1) @ (33,50--33,64)";
-        "let testIntPtrToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,50--34,66)";
-        "let testIntPtrToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,50--35,67)";
-        "let testIntPtrToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,50--36,66)";
-        "let testIntPtrToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,50--37,67)";
-        "let testIntPtrToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,50--38,70)";
-        "let testIntPtrToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,50--39,71)";
-        "let testIntPtrToByteOperator(e1) = Operators.ToByte (e1) @ (41,50--41,57)";
-        "let testIntPtrToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,50--42,58)";
-        "let testIntPtrToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,50--43,58)";
-        "let testIntPtrToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,50--44,59)";
-        "let testIntPtrToIntOperator(e1) = Operators.ToInt (e1) @ (45,50--45,56)";
-        "let testIntPtrToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,50--46,58)";
-        "let testIntPtrToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,50--47,59)";
-        "let testIntPtrToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,50--48,58)";
-        "let testIntPtrToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,50--49,59)";
-        "let testIntPtrToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,50--50,62)";
-        "let testIntPtrToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,50--51,63)";
-        "let testIntPtrToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,50--52,60)";
-        "let testIntPtrToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,50--53,58)";
-        "let testIntPtrToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,50--54,60)";
-        "let testIntPtrToCharOperator(e1) = Operators.ToChar (e1) @ (55,50--55,57)";
-        "let testIntPtrToStringOperator(e1) = Operators.ToString (e1) @ (56,50--56,59)";
+        [], "type OperatorTestsIntPtr";
+        [], "let testIntPtrEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,75--4,84)";
+        [], "let testIntPtrNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,75--5,85)";
+        [], "let testIntPtrLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,75--6,84)";
+        [], "let testIntPtrLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,75--7,85)";
+        [], "let testIntPtrGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,75--8,84)";
+        [], "let testIntPtrGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,75--9,85)";
+        [], "let testIntPtrAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,67--11,76)";
+        [], "let testIntPtrSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,67--12,76)";
+        [], "let testIntPtrMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,67--13,76)";
+        [], "let testIntPtrDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,67--14,76)";
+        [], "let testIntPtrModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,67--15,76)";
+        [], "let testIntPtrBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,67--16,78)";
+        [], "let testIntPtrBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,67--17,78)";
+        [], "let testIntPtrBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,67--18,78)";
+        [], "let testIntPtrShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,61--19,72)";
+        [], "let testIntPtrShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,61--20,72)";
+        [], "let testIntPtrUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,50--22,57)";
+        [], "let testIntPtrAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,65--24,82)";
+        [], "let testIntPtrSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,65--25,82)";
+        [], "let testIntPtrMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,65--26,82)";
+        [], "let testIntPtrUnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,50--27,65)";
+        [], "let testIntPtrToByteChecked(e1) = Checked.ToByte (e1) @ (29,50--29,65)";
+        [], "let testIntPtrToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,50--30,66)";
+        [], "let testIntPtrToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,50--31,66)";
+        [], "let testIntPtrToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,50--32,67)";
+        [], "let testIntPtrToIntChecked(e1) = Checked.ToInt (e1) @ (33,50--33,64)";
+        [], "let testIntPtrToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,50--34,66)";
+        [], "let testIntPtrToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,50--35,67)";
+        [], "let testIntPtrToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,50--36,66)";
+        [], "let testIntPtrToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,50--37,67)";
+        [], "let testIntPtrToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,50--38,70)";
+        [], "let testIntPtrToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,50--39,71)";
+        [], "let testIntPtrToByteOperator(e1) = Operators.ToByte (e1) @ (41,50--41,57)";
+        [], "let testIntPtrToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,50--42,58)";
+        [], "let testIntPtrToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,50--43,58)";
+        [], "let testIntPtrToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,50--44,59)";
+        [], "let testIntPtrToIntOperator(e1) = Operators.ToInt (e1) @ (45,50--45,56)";
+        [], "let testIntPtrToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,50--46,58)";
+        [], "let testIntPtrToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,50--47,59)";
+        [], "let testIntPtrToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,50--48,58)";
+        [], "let testIntPtrToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,50--49,59)";
+        [], "let testIntPtrToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,50--50,62)";
+        [], "let testIntPtrToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,50--51,63)";
+        [], "let testIntPtrToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,50--52,60)";
+        [], "let testIntPtrToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,50--53,58)";
+        [], "let testIntPtrToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,50--54,60)";
+        [], "let testIntPtrToCharOperator(e1) = Operators.ToChar (e1) @ (55,50--55,57)";
+        [], "let testIntPtrToStringOperator(e1) = Operators.ToString (e1) @ (56,50--56,59)";
       ]
 
     let expectedOptimized = [
-        "type OperatorTestsIntPtr";
-        "let testIntPtrEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,75--4,84)";
-        "let testIntPtrNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,75--5,85)";
-        "let testIntPtrLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,75--6,84)";
-        "let testIntPtrLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,75--7,85)";
-        "let testIntPtrGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,75--8,84)";
-        "let testIntPtrGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,75--9,85)";
-        "let testIntPtrAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,67--11,76)";
-        "let testIntPtrSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,67--12,76)";
-        "let testIntPtrMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,67--13,76)";
-        "let testIntPtrDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,67--14,76)";
-        "let testIntPtrModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,67--15,76)";
-        "let testIntPtrBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,67--16,78)";
-        "let testIntPtrBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,67--17,78)";
-        "let testIntPtrBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,67--18,78)";
-        "let testIntPtrShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,61--19,72)";
-        "let testIntPtrShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,61--20,72)";
-        "let testIntPtrUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,50--22,57)";
-        "let testIntPtrAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,65--24,82)";
-        "let testIntPtrSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,65--25,82)";
-        "let testIntPtrMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,65--26,82)";
-        "let testIntPtrUnaryNegChecked(e1) = Checked.op_Subtraction (0,e1) @ (27,50--27,65)";
-        "let testIntPtrToByteChecked(e1) = Checked.ToByte (e1) @ (29,50--29,65)";
-        "let testIntPtrToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,50--30,66)";
-        "let testIntPtrToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,50--31,66)";
-        "let testIntPtrToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,50--32,67)";
-        "let testIntPtrToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,50--33,64)";
-        "let testIntPtrToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,50--34,66)";
-        "let testIntPtrToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,50--35,67)";
-        "let testIntPtrToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,50--36,66)";
-        "let testIntPtrToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,50--37,67)";
-        "let testIntPtrToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,50--38,70)";
-        "let testIntPtrToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,50--39,71)";
-        "let testIntPtrToByteOperator(e1) = Operators.ToByte (e1) @ (41,50--41,57)";
-        "let testIntPtrToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,50--42,58)";
-        "let testIntPtrToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,50--43,58)";
-        "let testIntPtrToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,50--44,59)";
-        "let testIntPtrToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,50--45,56)";
-        "let testIntPtrToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,50--46,58)";
-        "let testIntPtrToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,50--47,59)";
-        "let testIntPtrToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,50--48,58)";
-        "let testIntPtrToUInt64Operator(e1) = Operators.ToInt64 (e1) @ (49,50--49,59)";
-        "let testIntPtrToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,50--50,62)";
-        "let testIntPtrToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,50--51,63)";
-        "let testIntPtrToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,50--52,60)";
-        "let testIntPtrToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,50--53,58)";
-        "let testIntPtrToDecimalOperator(e1) = Convert.ToDecimal (Operators.ToInt64 (e1)) @ (54,50--54,60)";
-        "let testIntPtrToCharOperator(e1) = Operators.ToChar (e1) @ (55,50--55,57)";
-#if DEBUG
-        @"let testIntPtrToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,50--56,59)"
-#else
-        "let testIntPtrToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,50--56,59)";
-#endif
+        [], "type OperatorTestsIntPtr";
+        [], "let testIntPtrEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,75--4,84)";
+        [], "let testIntPtrNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,75--5,85)";
+        [], "let testIntPtrLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,75--6,84)";
+        [], "let testIntPtrLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,75--7,85)";
+        [], "let testIntPtrGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,75--8,84)";
+        [], "let testIntPtrGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,75--9,85)";
+        [], "let testIntPtrAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,67--11,76)";
+        [], "let testIntPtrSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,67--12,76)";
+        [], "let testIntPtrMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,67--13,76)";
+        [], "let testIntPtrDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,67--14,76)";
+        [], "let testIntPtrModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,67--15,76)";
+        [], "let testIntPtrBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,67--16,78)";
+        [], "let testIntPtrBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,67--17,78)";
+        [], "let testIntPtrBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,67--18,78)";
+        [], "let testIntPtrShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,61--19,72)";
+        [], "let testIntPtrShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,61--20,72)";
+        [], "let testIntPtrUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,50--22,57)";
+        [], "let testIntPtrAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,65--24,82)";
+        [], "let testIntPtrSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,65--25,82)";
+        [], "let testIntPtrMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,65--26,82)";
+        [], "let testIntPtrUnaryNegChecked(e1) = Checked.op_Subtraction (0,e1) @ (27,50--27,65)";
+        [], "let testIntPtrToByteChecked(e1) = Checked.ToByte (e1) @ (29,50--29,65)";
+        [], "let testIntPtrToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,50--30,66)";
+        [], "let testIntPtrToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,50--31,66)";
+        [], "let testIntPtrToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,50--32,67)";
+        [], "let testIntPtrToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,50--33,64)";
+        [], "let testIntPtrToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,50--34,66)";
+        [], "let testIntPtrToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,50--35,67)";
+        [], "let testIntPtrToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,50--36,66)";
+        [], "let testIntPtrToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,50--37,67)";
+        [], "let testIntPtrToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,50--38,70)";
+        [], "let testIntPtrToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,50--39,71)";
+        [], "let testIntPtrToByteOperator(e1) = Operators.ToByte (e1) @ (41,50--41,57)";
+        [], "let testIntPtrToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,50--42,58)";
+        [], "let testIntPtrToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,50--43,58)";
+        [], "let testIntPtrToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,50--44,59)";
+        [], "let testIntPtrToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,50--45,56)";
+        [], "let testIntPtrToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,50--46,58)";
+        [], "let testIntPtrToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,50--47,59)";
+        [], "let testIntPtrToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,50--48,58)";
+        [], "let testIntPtrToUInt64Operator(e1) = Operators.ToInt64 (e1) @ (49,50--49,59)";
+        [], "let testIntPtrToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,50--50,62)";
+        [], "let testIntPtrToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,50--51,63)";
+        [], "let testIntPtrToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,50--52,60)";
+        [], "let testIntPtrToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,50--53,58)";
+        [], "let testIntPtrToDecimalOperator(e1) = Convert.ToDecimal (Operators.ToInt64 (e1)) @ (54,50--54,60)";
+        [], "let testIntPtrToCharOperator(e1) = Operators.ToChar (e1) @ (55,50--55,57)";
+        [FC47], "let testIntPtrToStringOperator(e1) = e1.ToString() @ (56,50--56,59)"
       ]
 
     testOperators "IntPtr" "nativeint" excludedTests expectedUnoptimized expectedOptimized
@@ -2175,107 +2199,103 @@ let ``Test Operator Declarations for UIntPtr`` () =
       ]
     
     let expectedUnoptimized = [
-        "type OperatorTestsUIntPtr";
-        "let testUIntPtrEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,78--4,87)";
-        "let testUIntPtrNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,78--5,88)";
-        "let testUIntPtrLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,78--6,87)";
-        "let testUIntPtrLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,78--7,88)";
-        "let testUIntPtrGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,78--8,87)";
-        "let testUIntPtrGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,78--9,88)";
-        "let testUIntPtrAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,70--11,79)";
-        "let testUIntPtrSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,70--12,79)";
-        "let testUIntPtrMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,70--13,79)";
-        "let testUIntPtrDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,70--14,79)";
-        "let testUIntPtrModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,70--15,79)";
-        "let testUIntPtrBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,70--16,81)";
-        "let testUIntPtrBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,70--17,81)";
-        "let testUIntPtrBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,70--18,81)";
-        "let testUIntPtrShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,63--19,74)";
-        "let testUIntPtrShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,63--20,74)";
-        "let testUIntPtrAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,68--24,85)";
-        "let testUIntPtrSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,68--25,85)";
-        "let testUIntPtrMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,68--26,85)";
-        "let testUIntPtrToByteChecked(e1) = Checked.ToByte (e1) @ (29,52--29,67)";
-        "let testUIntPtrToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,52--30,68)";
-        "let testUIntPtrToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,52--31,68)";
-        "let testUIntPtrToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,52--32,69)";
-        "let testUIntPtrToIntChecked(e1) = Checked.ToInt (e1) @ (33,52--33,66)";
-        "let testUIntPtrToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,52--34,68)";
-        "let testUIntPtrToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,52--35,69)";
-        "let testUIntPtrToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,52--36,68)";
-        "let testUIntPtrToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,52--37,69)";
-        "let testUIntPtrToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,52--38,72)";
-        "let testUIntPtrToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,52--39,73)";
-        "let testUIntPtrToByteOperator(e1) = Operators.ToByte (e1) @ (41,52--41,59)";
-        "let testUIntPtrToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,52--42,60)";
-        "let testUIntPtrToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,52--43,60)";
-        "let testUIntPtrToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,52--44,61)";
-        "let testUIntPtrToIntOperator(e1) = Operators.ToInt (e1) @ (45,52--45,58)";
-        "let testUIntPtrToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,52--46,60)";
-        "let testUIntPtrToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,52--47,61)";
-        "let testUIntPtrToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,52--48,60)";
-        "let testUIntPtrToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,52--49,61)";
-        "let testUIntPtrToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,52--50,64)";
-        "let testUIntPtrToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,52--51,65)";
-        "let testUIntPtrToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,52--52,62)";
-        "let testUIntPtrToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,52--53,60)";
-        "let testUIntPtrToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,52--54,62)";
-        "let testUIntPtrToCharOperator(e1) = Operators.ToChar (e1) @ (55,52--55,59)";
-        "let testUIntPtrToStringOperator(e1) = Operators.ToString (e1) @ (56,52--56,61)";
+        [], "type OperatorTestsUIntPtr";
+        [], "let testUIntPtrEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,78--4,87)";
+        [], "let testUIntPtrNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,78--5,88)";
+        [], "let testUIntPtrLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,78--6,87)";
+        [], "let testUIntPtrLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,78--7,88)";
+        [], "let testUIntPtrGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,78--8,87)";
+        [], "let testUIntPtrGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,78--9,88)";
+        [], "let testUIntPtrAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,70--11,79)";
+        [], "let testUIntPtrSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,70--12,79)";
+        [], "let testUIntPtrMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,70--13,79)";
+        [], "let testUIntPtrDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,70--14,79)";
+        [], "let testUIntPtrModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,70--15,79)";
+        [], "let testUIntPtrBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,70--16,81)";
+        [], "let testUIntPtrBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,70--17,81)";
+        [], "let testUIntPtrBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,70--18,81)";
+        [], "let testUIntPtrShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,63--19,74)";
+        [], "let testUIntPtrShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,63--20,74)";
+        [], "let testUIntPtrAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,68--24,85)";
+        [], "let testUIntPtrSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,68--25,85)";
+        [], "let testUIntPtrMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,68--26,85)";
+        [], "let testUIntPtrToByteChecked(e1) = Checked.ToByte (e1) @ (29,52--29,67)";
+        [], "let testUIntPtrToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,52--30,68)";
+        [], "let testUIntPtrToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,52--31,68)";
+        [], "let testUIntPtrToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,52--32,69)";
+        [], "let testUIntPtrToIntChecked(e1) = Checked.ToInt (e1) @ (33,52--33,66)";
+        [], "let testUIntPtrToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,52--34,68)";
+        [], "let testUIntPtrToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,52--35,69)";
+        [], "let testUIntPtrToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,52--36,68)";
+        [], "let testUIntPtrToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,52--37,69)";
+        [], "let testUIntPtrToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,52--38,72)";
+        [], "let testUIntPtrToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,52--39,73)";
+        [], "let testUIntPtrToByteOperator(e1) = Operators.ToByte (e1) @ (41,52--41,59)";
+        [], "let testUIntPtrToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,52--42,60)";
+        [], "let testUIntPtrToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,52--43,60)";
+        [], "let testUIntPtrToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,52--44,61)";
+        [], "let testUIntPtrToIntOperator(e1) = Operators.ToInt (e1) @ (45,52--45,58)";
+        [], "let testUIntPtrToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,52--46,60)";
+        [], "let testUIntPtrToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,52--47,61)";
+        [], "let testUIntPtrToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,52--48,60)";
+        [], "let testUIntPtrToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,52--49,61)";
+        [], "let testUIntPtrToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,52--50,64)";
+        [], "let testUIntPtrToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,52--51,65)";
+        [], "let testUIntPtrToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,52--52,62)";
+        [], "let testUIntPtrToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,52--53,60)";
+        [], "let testUIntPtrToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,52--54,62)";
+        [], "let testUIntPtrToCharOperator(e1) = Operators.ToChar (e1) @ (55,52--55,59)";
+        [], "let testUIntPtrToStringOperator(e1) = Operators.ToString (e1) @ (56,52--56,61)";
       ]
 
     let expectedOptimized = [
-        "type OperatorTestsUIntPtr";
-        "let testUIntPtrEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,78--4,87)";
-        "let testUIntPtrNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,78--5,88)";
-        "let testUIntPtrLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,78--6,87)";
-        "let testUIntPtrLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,78--7,88)";
-        "let testUIntPtrGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,78--8,87)";
-        "let testUIntPtrGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,78--9,88)";
-        "let testUIntPtrAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,70--11,79)";
-        "let testUIntPtrSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,70--12,79)";
-        "let testUIntPtrMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,70--13,79)";
-        "let testUIntPtrDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,70--14,79)";
-        "let testUIntPtrModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,70--15,79)";
-        "let testUIntPtrBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,70--16,81)";
-        "let testUIntPtrBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,70--17,81)";
-        "let testUIntPtrBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,70--18,81)";
-        "let testUIntPtrShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,63--19,74)";
-        "let testUIntPtrShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,63--20,74)";
-        "let testUIntPtrAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,68--24,85)";
-        "let testUIntPtrSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,68--25,85)";
-        "let testUIntPtrMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,68--26,85)";
-        "let testUIntPtrToByteChecked(e1) = Checked.ToByte (e1) @ (29,52--29,67)";
-        "let testUIntPtrToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,52--30,68)";
-        "let testUIntPtrToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,52--31,68)";
-        "let testUIntPtrToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,52--32,69)";
-        "let testUIntPtrToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,52--33,66)";
-        "let testUIntPtrToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,52--34,68)";
-        "let testUIntPtrToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,52--35,69)";
-        "let testUIntPtrToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,52--36,68)";
-        "let testUIntPtrToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,52--37,69)";
-        "let testUIntPtrToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,52--38,72)";
-        "let testUIntPtrToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,52--39,73)";
-        "let testUIntPtrToByteOperator(e1) = Operators.ToByte (e1) @ (41,52--41,59)";
-        "let testUIntPtrToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,52--42,60)";
-        "let testUIntPtrToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,52--43,60)";
-        "let testUIntPtrToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,52--44,61)";
-        "let testUIntPtrToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,52--45,58)";
-        "let testUIntPtrToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,52--46,60)";
-        "let testUIntPtrToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,52--47,61)";
-        "let testUIntPtrToInt64Operator(e1) = Operators.ToUInt64 (e1) @ (48,52--48,60)";
-        "let testUIntPtrToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,52--49,61)";
-        "let testUIntPtrToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,52--50,64)";
-        "let testUIntPtrToUIntPtrOperator(e1) = e1 @ (51,63--51,65)";
-        "let testUIntPtrToSingleOperator(e1) = Operators.ToSingle (Operators.ToDouble (e1)) @ (52,52--52,62)";
-        "let testUIntPtrToDoubleOperator(e1) = Operators.ToDouble (Operators.ToDouble (e1)) @ (53,52--53,60)";
-        "let testUIntPtrToDecimalOperator(e1) = Convert.ToDecimal (Operators.ToUInt64 (e1)) @ (54,52--54,62)";
-        "let testUIntPtrToCharOperator(e1) = Operators.ToChar (e1) @ (55,52--55,59)";
-#if DEBUG
-        @"let testUIntPtrToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,52--56,61)"
-#else
-        "let testUIntPtrToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,52--56,61)";
-#endif
+        [], "type OperatorTestsUIntPtr";
+        [], "let testUIntPtrEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,78--4,87)";
+        [], "let testUIntPtrNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,78--5,88)";
+        [], "let testUIntPtrLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,78--6,87)";
+        [], "let testUIntPtrLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,78--7,88)";
+        [], "let testUIntPtrGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,78--8,87)";
+        [], "let testUIntPtrGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,78--9,88)";
+        [], "let testUIntPtrAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,70--11,79)";
+        [], "let testUIntPtrSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,70--12,79)";
+        [], "let testUIntPtrMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,70--13,79)";
+        [], "let testUIntPtrDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,70--14,79)";
+        [], "let testUIntPtrModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,70--15,79)";
+        [], "let testUIntPtrBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,70--16,81)";
+        [], "let testUIntPtrBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,70--17,81)";
+        [], "let testUIntPtrBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,70--18,81)";
+        [], "let testUIntPtrShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,63--19,74)";
+        [], "let testUIntPtrShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,63--20,74)";
+        [], "let testUIntPtrAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,68--24,85)";
+        [], "let testUIntPtrSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,68--25,85)";
+        [], "let testUIntPtrMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,68--26,85)";
+        [], "let testUIntPtrToByteChecked(e1) = Checked.ToByte (e1) @ (29,52--29,67)";
+        [], "let testUIntPtrToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,52--30,68)";
+        [], "let testUIntPtrToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,52--31,68)";
+        [], "let testUIntPtrToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,52--32,69)";
+        [], "let testUIntPtrToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,52--33,66)";
+        [], "let testUIntPtrToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,52--34,68)";
+        [], "let testUIntPtrToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,52--35,69)";
+        [], "let testUIntPtrToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,52--36,68)";
+        [], "let testUIntPtrToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,52--37,69)";
+        [], "let testUIntPtrToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,52--38,72)";
+        [], "let testUIntPtrToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,52--39,73)";
+        [], "let testUIntPtrToByteOperator(e1) = Operators.ToByte (e1) @ (41,52--41,59)";
+        [], "let testUIntPtrToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,52--42,60)";
+        [], "let testUIntPtrToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,52--43,60)";
+        [], "let testUIntPtrToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,52--44,61)";
+        [], "let testUIntPtrToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,52--45,58)";
+        [], "let testUIntPtrToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,52--46,60)";
+        [], "let testUIntPtrToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,52--47,61)";
+        [], "let testUIntPtrToInt64Operator(e1) = Operators.ToUInt64 (e1) @ (48,52--48,60)";
+        [], "let testUIntPtrToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,52--49,61)";
+        [], "let testUIntPtrToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,52--50,64)";
+        [], "let testUIntPtrToUIntPtrOperator(e1) = e1 @ (51,63--51,65)";
+        [], "let testUIntPtrToSingleOperator(e1) = Operators.ToSingle (Operators.ToDouble (e1)) @ (52,52--52,62)";
+        [], "let testUIntPtrToDoubleOperator(e1) = Operators.ToDouble (Operators.ToDouble (e1)) @ (53,52--53,60)";
+        [], "let testUIntPtrToDecimalOperator(e1) = Convert.ToDecimal (Operators.ToUInt64 (e1)) @ (54,52--54,62)";
+        [], "let testUIntPtrToCharOperator(e1) = Operators.ToChar (e1) @ (55,52--55,59)";
+        [FC47], "let testUIntPtrToStringOperator(e1) = e1.ToString() @ (56,52--56,61)"
       ]
 
     testOperators "UIntPtr" "unativeint" excludedTests expectedUnoptimized expectedOptimized
@@ -2291,101 +2311,97 @@ let ``Test Operator Declarations for Single`` () =
       ]
 
     let expectedUnoptimized = [
-        "type OperatorTestsSingle";
-        "let testSingleEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,71--4,80)";
-        "let testSingleNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,71--5,81)";
-        "let testSingleLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,71--6,80)";
-        "let testSingleLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,71--7,81)";
-        "let testSingleGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,71--8,80)";
-        "let testSingleGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,71--9,81)";
-        "let testSingleAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,63--11,72)";
-        "let testSingleSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,63--12,72)";
-        "let testSingleMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,63--13,72)";
-        "let testSingleDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,63--14,72)";
-        "let testSingleModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,63--15,72)";
-        "let testSingleUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,48--22,55)";
-        "let testSingleAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,61--24,78)";
-        "let testSingleSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,61--25,78)";
-        "let testSingleMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,61--26,78)";
-        "let testSingleUnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,48--27,63)";
-        "let testSingleToByteChecked(e1) = Checked.ToByte (e1) @ (29,48--29,63)";
-        "let testSingleToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,48--30,64)";
-        "let testSingleToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,48--31,64)";
-        "let testSingleToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,48--32,65)";
-        "let testSingleToIntChecked(e1) = Checked.ToInt (e1) @ (33,48--33,62)";
-        "let testSingleToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,48--34,64)";
-        "let testSingleToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,48--35,65)";
-        "let testSingleToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,48--36,64)";
-        "let testSingleToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,48--37,65)";
-        "let testSingleToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,48--38,68)";
-        "let testSingleToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,48--39,69)";
-        "let testSingleToByteOperator(e1) = Operators.ToByte (e1) @ (41,48--41,55)";
-        "let testSingleToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,48--42,56)";
-        "let testSingleToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,48--43,56)";
-        "let testSingleToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,48--44,57)";
-        "let testSingleToIntOperator(e1) = Operators.ToInt (e1) @ (45,48--45,54)";
-        "let testSingleToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,48--46,56)";
-        "let testSingleToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,48--47,57)";
-        "let testSingleToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,48--48,56)";
-        "let testSingleToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,48--49,57)";
-        "let testSingleToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,48--50,60)";
-        "let testSingleToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,48--51,61)";
-        "let testSingleToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,48--52,58)";
-        "let testSingleToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,48--53,56)";
-        "let testSingleToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,48--54,58)";
-        "let testSingleToCharOperator(e1) = Operators.ToChar (e1) @ (55,48--55,55)";
-        "let testSingleToStringOperator(e1) = Operators.ToString (e1) @ (56,48--56,57)";
+        [], "type OperatorTestsSingle";
+        [], "let testSingleEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,71--4,80)";
+        [], "let testSingleNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,71--5,81)";
+        [], "let testSingleLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,71--6,80)";
+        [], "let testSingleLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,71--7,81)";
+        [], "let testSingleGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,71--8,80)";
+        [], "let testSingleGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,71--9,81)";
+        [], "let testSingleAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,63--11,72)";
+        [], "let testSingleSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,63--12,72)";
+        [], "let testSingleMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,63--13,72)";
+        [], "let testSingleDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,63--14,72)";
+        [], "let testSingleModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,63--15,72)";
+        [], "let testSingleUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,48--22,55)";
+        [], "let testSingleAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,61--24,78)";
+        [], "let testSingleSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,61--25,78)";
+        [], "let testSingleMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,61--26,78)";
+        [], "let testSingleUnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,48--27,63)";
+        [], "let testSingleToByteChecked(e1) = Checked.ToByte (e1) @ (29,48--29,63)";
+        [], "let testSingleToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,48--30,64)";
+        [], "let testSingleToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,48--31,64)";
+        [], "let testSingleToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,48--32,65)";
+        [], "let testSingleToIntChecked(e1) = Checked.ToInt (e1) @ (33,48--33,62)";
+        [], "let testSingleToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,48--34,64)";
+        [], "let testSingleToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,48--35,65)";
+        [], "let testSingleToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,48--36,64)";
+        [], "let testSingleToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,48--37,65)";
+        [], "let testSingleToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,48--38,68)";
+        [], "let testSingleToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,48--39,69)";
+        [], "let testSingleToByteOperator(e1) = Operators.ToByte (e1) @ (41,48--41,55)";
+        [], "let testSingleToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,48--42,56)";
+        [], "let testSingleToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,48--43,56)";
+        [], "let testSingleToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,48--44,57)";
+        [], "let testSingleToIntOperator(e1) = Operators.ToInt (e1) @ (45,48--45,54)";
+        [], "let testSingleToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,48--46,56)";
+        [], "let testSingleToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,48--47,57)";
+        [], "let testSingleToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,48--48,56)";
+        [], "let testSingleToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,48--49,57)";
+        [], "let testSingleToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,48--50,60)";
+        [], "let testSingleToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,48--51,61)";
+        [], "let testSingleToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,48--52,58)";
+        [], "let testSingleToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,48--53,56)";
+        [], "let testSingleToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,48--54,58)";
+        [], "let testSingleToCharOperator(e1) = Operators.ToChar (e1) @ (55,48--55,55)";
+        [], "let testSingleToStringOperator(e1) = Operators.ToString (e1) @ (56,48--56,57)";
       ]
 
     let expectedOptimized = [
-        "type OperatorTestsSingle";
-        "let testSingleEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,71--4,80)";
-        "let testSingleNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,71--5,81)";
-        "let testSingleLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,71--6,80)";
-        "let testSingleLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,71--7,81)";
-        "let testSingleGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,71--8,80)";
-        "let testSingleGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,71--9,81)";
-        "let testSingleAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,63--11,72)";
-        "let testSingleSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,63--12,72)";
-        "let testSingleMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,63--13,72)";
-        "let testSingleDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,63--14,72)";
-        "let testSingleModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,63--15,72)";
-        "let testSingleUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,48--22,55)";
-        "let testSingleAdditionChecked(e1) (e2) = Operators.op_Addition (e1,e2) @ (24,61--24,78)";
-        "let testSingleSubtractionChecked(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (25,61--25,78)";
-        "let testSingleMultiplyChecked(e1) (e2) = Operators.op_Multiply (e1,e2) @ (26,61--26,78)";
-        "let testSingleUnaryNegChecked(e1) = Operators.op_UnaryNegation (e1) @ (27,48--27,63)";
-        "let testSingleToByteChecked(e1) = Checked.ToByte (e1) @ (29,48--29,63)";
-        "let testSingleToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,48--30,64)";
-        "let testSingleToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,48--31,64)";
-        "let testSingleToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,48--32,65)";
-        "let testSingleToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,48--33,62)";
-        "let testSingleToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,48--34,64)";
-        "let testSingleToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,48--35,65)";
-        "let testSingleToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,48--36,64)";
-        "let testSingleToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,48--37,65)";
-        "let testSingleToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,48--38,68)";
-        "let testSingleToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,48--39,69)";
-        "let testSingleToByteOperator(e1) = Operators.ToByte (e1) @ (41,48--41,55)";
-        "let testSingleToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,48--42,56)";
-        "let testSingleToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,48--43,56)";
-        "let testSingleToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,48--44,57)";
-        "let testSingleToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,48--45,54)";
-        "let testSingleToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,48--46,56)";
-        "let testSingleToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,48--47,57)";
-        "let testSingleToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,48--48,56)";
-        "let testSingleToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,48--49,57)";
-        "let testSingleToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,48--50,60)";
-        "let testSingleToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,48--51,61)";
-        "let testSingleToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,48--52,58)";
-        "let testSingleToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,48--53,56)";
-        "let testSingleToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,48--54,58)";
-        "let testSingleToCharOperator(e1) = Operators.ToChar (e1) @ (55,48--55,55)";
-#if DEBUG
-        @"let testSingleToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,48--56,57)"
-#else
-        "let testSingleToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,48--56,57)";
-#endif
+        [], "type OperatorTestsSingle";
+        [], "let testSingleEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,71--4,80)";
+        [], "let testSingleNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,71--5,81)";
+        [], "let testSingleLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,71--6,80)";
+        [], "let testSingleLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,71--7,81)";
+        [], "let testSingleGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,71--8,80)";
+        [], "let testSingleGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,71--9,81)";
+        [], "let testSingleAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,63--11,72)";
+        [], "let testSingleSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,63--12,72)";
+        [], "let testSingleMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,63--13,72)";
+        [], "let testSingleDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,63--14,72)";
+        [], "let testSingleModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,63--15,72)";
+        [], "let testSingleUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,48--22,55)";
+        [], "let testSingleAdditionChecked(e1) (e2) = Operators.op_Addition (e1,e2) @ (24,61--24,78)";
+        [], "let testSingleSubtractionChecked(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (25,61--25,78)";
+        [], "let testSingleMultiplyChecked(e1) (e2) = Operators.op_Multiply (e1,e2) @ (26,61--26,78)";
+        [], "let testSingleUnaryNegChecked(e1) = Operators.op_UnaryNegation (e1) @ (27,48--27,63)";
+        [], "let testSingleToByteChecked(e1) = Checked.ToByte (e1) @ (29,48--29,63)";
+        [], "let testSingleToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,48--30,64)";
+        [], "let testSingleToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,48--31,64)";
+        [], "let testSingleToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,48--32,65)";
+        [], "let testSingleToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,48--33,62)";
+        [], "let testSingleToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,48--34,64)";
+        [], "let testSingleToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,48--35,65)";
+        [], "let testSingleToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,48--36,64)";
+        [], "let testSingleToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,48--37,65)";
+        [], "let testSingleToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,48--38,68)";
+        [], "let testSingleToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,48--39,69)";
+        [], "let testSingleToByteOperator(e1) = Operators.ToByte (e1) @ (41,48--41,55)";
+        [], "let testSingleToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,48--42,56)";
+        [], "let testSingleToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,48--43,56)";
+        [], "let testSingleToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,48--44,57)";
+        [], "let testSingleToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,48--45,54)";
+        [], "let testSingleToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,48--46,56)";
+        [], "let testSingleToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,48--47,57)";
+        [], "let testSingleToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,48--48,56)";
+        [], "let testSingleToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,48--49,57)";
+        [], "let testSingleToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,48--50,60)";
+        [], "let testSingleToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,48--51,61)";
+        [], "let testSingleToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,48--52,58)";
+        [], "let testSingleToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,48--53,56)";
+        [], "let testSingleToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,48--54,58)";
+        [], "let testSingleToCharOperator(e1) = Operators.ToChar (e1) @ (55,48--55,55)";
+        [FC47], "let testSingleToStringOperator(e1) = e1.ToString(dflt,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (56,48--56,57)"
       ]
 
     testOperators "Single" "float32" excludedTests expectedUnoptimized expectedOptimized
@@ -2401,101 +2417,97 @@ let ``Test Operator Declarations for Double`` () =
       ]
     
     let expectedUnoptimized = [
-        "type OperatorTestsDouble";
-        "let testDoubleEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,67--4,76)";
-        "let testDoubleNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,67--5,77)";
-        "let testDoubleLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,67--6,76)";
-        "let testDoubleLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,67--7,77)";
-        "let testDoubleGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,67--8,76)";
-        "let testDoubleGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,67--9,77)";
-        "let testDoubleAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,59--11,68)";
-        "let testDoubleSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,59--12,68)";
-        "let testDoubleMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,59--13,68)";
-        "let testDoubleDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,59--14,68)";
-        "let testDoubleModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,59--15,68)";
-        "let testDoubleUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,46--22,53)";
-        "let testDoubleAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,57--24,74)";
-        "let testDoubleSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,57--25,74)";
-        "let testDoubleMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,57--26,74)";
-        "let testDoubleUnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,46--27,61)";
-        "let testDoubleToByteChecked(e1) = Checked.ToByte (e1) @ (29,46--29,61)";
-        "let testDoubleToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,46--30,62)";
-        "let testDoubleToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,46--31,62)";
-        "let testDoubleToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,46--32,63)";
-        "let testDoubleToIntChecked(e1) = Checked.ToInt (e1) @ (33,46--33,60)";
-        "let testDoubleToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,46--34,62)";
-        "let testDoubleToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,46--35,63)";
-        "let testDoubleToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,46--36,62)";
-        "let testDoubleToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,46--37,63)";
-        "let testDoubleToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,46--38,66)";
-        "let testDoubleToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,46--39,67)";
-        "let testDoubleToByteOperator(e1) = Operators.ToByte (e1) @ (41,46--41,53)";
-        "let testDoubleToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,46--42,54)";
-        "let testDoubleToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,46--43,54)";
-        "let testDoubleToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,46--44,55)";
-        "let testDoubleToIntOperator(e1) = Operators.ToInt (e1) @ (45,46--45,52)";
-        "let testDoubleToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,46--46,54)";
-        "let testDoubleToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,46--47,55)";
-        "let testDoubleToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,46--48,54)";
-        "let testDoubleToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,46--49,55)";
-        "let testDoubleToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,46--50,58)";
-        "let testDoubleToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,46--51,59)";
-        "let testDoubleToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,46--52,56)";
-        "let testDoubleToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,46--53,54)";
-        "let testDoubleToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,46--54,56)";
-        "let testDoubleToCharOperator(e1) = Operators.ToChar (e1) @ (55,46--55,53)";
-        "let testDoubleToStringOperator(e1) = Operators.ToString (e1) @ (56,46--56,55)";
+        [], "type OperatorTestsDouble";
+        [], "let testDoubleEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,67--4,76)";
+        [], "let testDoubleNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,67--5,77)";
+        [], "let testDoubleLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,67--6,76)";
+        [], "let testDoubleLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,67--7,77)";
+        [], "let testDoubleGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,67--8,76)";
+        [], "let testDoubleGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,67--9,77)";
+        [], "let testDoubleAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,59--11,68)";
+        [], "let testDoubleSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,59--12,68)";
+        [], "let testDoubleMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,59--13,68)";
+        [], "let testDoubleDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,59--14,68)";
+        [], "let testDoubleModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,59--15,68)";
+        [], "let testDoubleUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,46--22,53)";
+        [], "let testDoubleAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,57--24,74)";
+        [], "let testDoubleSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,57--25,74)";
+        [], "let testDoubleMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,57--26,74)";
+        [], "let testDoubleUnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,46--27,61)";
+        [], "let testDoubleToByteChecked(e1) = Checked.ToByte (e1) @ (29,46--29,61)";
+        [], "let testDoubleToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,46--30,62)";
+        [], "let testDoubleToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,46--31,62)";
+        [], "let testDoubleToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,46--32,63)";
+        [], "let testDoubleToIntChecked(e1) = Checked.ToInt (e1) @ (33,46--33,60)";
+        [], "let testDoubleToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,46--34,62)";
+        [], "let testDoubleToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,46--35,63)";
+        [], "let testDoubleToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,46--36,62)";
+        [], "let testDoubleToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,46--37,63)";
+        [], "let testDoubleToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,46--38,66)";
+        [], "let testDoubleToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,46--39,67)";
+        [], "let testDoubleToByteOperator(e1) = Operators.ToByte (e1) @ (41,46--41,53)";
+        [], "let testDoubleToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,46--42,54)";
+        [], "let testDoubleToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,46--43,54)";
+        [], "let testDoubleToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,46--44,55)";
+        [], "let testDoubleToIntOperator(e1) = Operators.ToInt (e1) @ (45,46--45,52)";
+        [], "let testDoubleToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,46--46,54)";
+        [], "let testDoubleToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,46--47,55)";
+        [], "let testDoubleToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,46--48,54)";
+        [], "let testDoubleToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,46--49,55)";
+        [], "let testDoubleToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,46--50,58)";
+        [], "let testDoubleToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,46--51,59)";
+        [], "let testDoubleToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,46--52,56)";
+        [], "let testDoubleToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,46--53,54)";
+        [], "let testDoubleToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,46--54,56)";
+        [], "let testDoubleToCharOperator(e1) = Operators.ToChar (e1) @ (55,46--55,53)";
+        [], "let testDoubleToStringOperator(e1) = Operators.ToString (e1) @ (56,46--56,55)";
       ]
 
     let expectedOptimized = [
-        "type OperatorTestsDouble";
-        "let testDoubleEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,67--4,76)";
-        "let testDoubleNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,67--5,77)";
-        "let testDoubleLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,67--6,76)";
-        "let testDoubleLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,67--7,77)";
-        "let testDoubleGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,67--8,76)";
-        "let testDoubleGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,67--9,77)";
-        "let testDoubleAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,59--11,68)";
-        "let testDoubleSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,59--12,68)";
-        "let testDoubleMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,59--13,68)";
-        "let testDoubleDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,59--14,68)";
-        "let testDoubleModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,59--15,68)";
-        "let testDoubleUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,46--22,53)";
-        "let testDoubleAdditionChecked(e1) (e2) = Operators.op_Addition (e1,e2) @ (24,57--24,74)";
-        "let testDoubleSubtractionChecked(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (25,57--25,74)";
-        "let testDoubleMultiplyChecked(e1) (e2) = Operators.op_Multiply (e1,e2) @ (26,57--26,74)";
-        "let testDoubleUnaryNegChecked(e1) = Operators.op_UnaryNegation (e1) @ (27,46--27,61)";
-        "let testDoubleToByteChecked(e1) = Checked.ToByte (e1) @ (29,46--29,61)";
-        "let testDoubleToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,46--30,62)";
-        "let testDoubleToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,46--31,62)";
-        "let testDoubleToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,46--32,63)";
-        "let testDoubleToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,46--33,60)";
-        "let testDoubleToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,46--34,62)";
-        "let testDoubleToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,46--35,63)";
-        "let testDoubleToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,46--36,62)";
-        "let testDoubleToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,46--37,63)";
-        "let testDoubleToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,46--38,66)";
-        "let testDoubleToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,46--39,67)";
-        "let testDoubleToByteOperator(e1) = Operators.ToByte (e1) @ (41,46--41,53)";
-        "let testDoubleToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,46--42,54)";
-        "let testDoubleToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,46--43,54)";
-        "let testDoubleToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,46--44,55)";
-        "let testDoubleToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,46--45,52)";
-        "let testDoubleToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,46--46,54)";
-        "let testDoubleToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,46--47,55)";
-        "let testDoubleToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,46--48,54)";
-        "let testDoubleToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,46--49,55)";
-        "let testDoubleToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,46--50,58)";
-        "let testDoubleToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,46--51,59)";
-        "let testDoubleToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,46--52,56)";
-        "let testDoubleToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,46--53,54)";
-        "let testDoubleToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,46--54,56)";
-        "let testDoubleToCharOperator(e1) = Operators.ToChar (e1) @ (55,46--55,53)";
-#if DEBUG
-        @"let testDoubleToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,46--56,55)"
-#else
-        "let testDoubleToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,46--56,55)";
-#endif
+        [], "type OperatorTestsDouble";
+        [], "let testDoubleEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,67--4,76)";
+        [], "let testDoubleNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,67--5,77)";
+        [], "let testDoubleLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,67--6,76)";
+        [], "let testDoubleLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,67--7,77)";
+        [], "let testDoubleGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,67--8,76)";
+        [], "let testDoubleGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,67--9,77)";
+        [], "let testDoubleAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,59--11,68)";
+        [], "let testDoubleSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,59--12,68)";
+        [], "let testDoubleMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,59--13,68)";
+        [], "let testDoubleDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,59--14,68)";
+        [], "let testDoubleModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,59--15,68)";
+        [], "let testDoubleUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,46--22,53)";
+        [], "let testDoubleAdditionChecked(e1) (e2) = Operators.op_Addition (e1,e2) @ (24,57--24,74)";
+        [], "let testDoubleSubtractionChecked(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (25,57--25,74)";
+        [], "let testDoubleMultiplyChecked(e1) (e2) = Operators.op_Multiply (e1,e2) @ (26,57--26,74)";
+        [], "let testDoubleUnaryNegChecked(e1) = Operators.op_UnaryNegation (e1) @ (27,46--27,61)";
+        [], "let testDoubleToByteChecked(e1) = Checked.ToByte (e1) @ (29,46--29,61)";
+        [], "let testDoubleToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,46--30,62)";
+        [], "let testDoubleToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,46--31,62)";
+        [], "let testDoubleToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,46--32,63)";
+        [], "let testDoubleToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,46--33,60)";
+        [], "let testDoubleToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,46--34,62)";
+        [], "let testDoubleToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,46--35,63)";
+        [], "let testDoubleToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,46--36,62)";
+        [], "let testDoubleToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,46--37,63)";
+        [], "let testDoubleToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,46--38,66)";
+        [], "let testDoubleToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,46--39,67)";
+        [], "let testDoubleToByteOperator(e1) = Operators.ToByte (e1) @ (41,46--41,53)";
+        [], "let testDoubleToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,46--42,54)";
+        [], "let testDoubleToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,46--43,54)";
+        [], "let testDoubleToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,46--44,55)";
+        [], "let testDoubleToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,46--45,52)";
+        [], "let testDoubleToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,46--46,54)";
+        [], "let testDoubleToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,46--47,55)";
+        [], "let testDoubleToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,46--48,54)";
+        [], "let testDoubleToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,46--49,55)";
+        [], "let testDoubleToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,46--50,58)";
+        [], "let testDoubleToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,46--51,59)";
+        [], "let testDoubleToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,46--52,56)";
+        [], "let testDoubleToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,46--53,54)";
+        [], "let testDoubleToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,46--54,56)";
+        [], "let testDoubleToCharOperator(e1) = Operators.ToChar (e1) @ (55,46--55,53)";
+        [FC47], "let testDoubleToStringOperator(e1) = e1.ToString(dflt,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (56,46--56,55)"
       ]
 
     testOperators "Double" "float" excludedTests expectedUnoptimized expectedOptimized
@@ -2519,85 +2531,81 @@ let ``Test Operator Declarations for Decimal`` () =
       ]
 
     let expectedUnoptimized = [
-        "type OperatorTestsDecimal";
-        "let testDecimalEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,72--4,81)";
-        "let testDecimalNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,72--5,82)";
-        "let testDecimalLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,72--6,81)";
-        "let testDecimalLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,72--7,82)";
-        "let testDecimalGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,72--8,81)";
-        "let testDecimalGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,72--9,82)";
-        "let testDecimalAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,64--11,73)";
-        "let testDecimalSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,64--12,73)";
-        "let testDecimalMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,64--13,73)";
-        "let testDecimalDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,64--14,73)";
-        "let testDecimalModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,64--15,73)";
-        "let testDecimalAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,62--24,79)";
-        "let testDecimalToByteChecked(e1) = Checked.ToByte (e1) @ (29,49--29,64)";
-        "let testDecimalToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,49--30,65)";
-        "let testDecimalToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,49--31,65)";
-        "let testDecimalToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,49--32,66)";
-        "let testDecimalToIntChecked(e1) = Checked.ToInt (e1) @ (33,49--33,63)";
-        "let testDecimalToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,49--34,65)";
-        "let testDecimalToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,49--35,66)";
-        "let testDecimalToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,49--36,65)";
-        "let testDecimalToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,49--37,66)";
-        "let testDecimalToByteOperator(e1) = Operators.ToByte (e1) @ (41,49--41,56)";
-        "let testDecimalToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,49--42,57)";
-        "let testDecimalToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,49--43,57)";
-        "let testDecimalToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,49--44,58)";
-        "let testDecimalToIntOperator(e1) = Operators.ToInt (e1) @ (45,49--45,55)";
-        "let testDecimalToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,49--46,57)";
-        "let testDecimalToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,49--47,58)";
-        "let testDecimalToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,49--48,57)";
-        "let testDecimalToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,49--49,58)";
-        "let testDecimalToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,49--52,59)";
-        "let testDecimalToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,49--53,57)";
-        "let testDecimalToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,49--54,59)";
-        "let testDecimalToCharOperator(e1) = Operators.ToChar (e1) @ (55,49--55,56)";
-        "let testDecimalToStringOperator(e1) = Operators.ToString (e1) @ (56,49--56,58)";
+        [], "type OperatorTestsDecimal";
+        [], "let testDecimalEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,72--4,81)";
+        [], "let testDecimalNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,72--5,82)";
+        [], "let testDecimalLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,72--6,81)";
+        [], "let testDecimalLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,72--7,82)";
+        [], "let testDecimalGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,72--8,81)";
+        [], "let testDecimalGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,72--9,82)";
+        [], "let testDecimalAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,64--11,73)";
+        [], "let testDecimalSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,64--12,73)";
+        [], "let testDecimalMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,64--13,73)";
+        [], "let testDecimalDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,64--14,73)";
+        [], "let testDecimalModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,64--15,73)";
+        [], "let testDecimalAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,62--24,79)";
+        [], "let testDecimalToByteChecked(e1) = Checked.ToByte (e1) @ (29,49--29,64)";
+        [], "let testDecimalToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,49--30,65)";
+        [], "let testDecimalToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,49--31,65)";
+        [], "let testDecimalToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,49--32,66)";
+        [], "let testDecimalToIntChecked(e1) = Checked.ToInt (e1) @ (33,49--33,63)";
+        [], "let testDecimalToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,49--34,65)";
+        [], "let testDecimalToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,49--35,66)";
+        [], "let testDecimalToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,49--36,65)";
+        [], "let testDecimalToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,49--37,66)";
+        [], "let testDecimalToByteOperator(e1) = Operators.ToByte (e1) @ (41,49--41,56)";
+        [], "let testDecimalToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,49--42,57)";
+        [], "let testDecimalToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,49--43,57)";
+        [], "let testDecimalToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,49--44,58)";
+        [], "let testDecimalToIntOperator(e1) = Operators.ToInt (e1) @ (45,49--45,55)";
+        [], "let testDecimalToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,49--46,57)";
+        [], "let testDecimalToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,49--47,58)";
+        [], "let testDecimalToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,49--48,57)";
+        [], "let testDecimalToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,49--49,58)";
+        [], "let testDecimalToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,49--52,59)";
+        [], "let testDecimalToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,49--53,57)";
+        [], "let testDecimalToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,49--54,59)";
+        [], "let testDecimalToCharOperator(e1) = Operators.ToChar (e1) @ (55,49--55,56)";
+        [], "let testDecimalToStringOperator(e1) = Operators.ToString (e1) @ (56,49--56,58)";
       ]
 
     let expectedOptimized = [
-        "type OperatorTestsDecimal";
-        "let testDecimalEqualsOperator(e1) (e2) = Decimal.op_Equality (e1,e2) @ (4,72--4,81)";
-        "let testDecimalNotEqualsOperator(e1) (e2) = Operators.op_Equality (Decimal.op_Equality (e1,e2),False) @ (5,72--5,82)";
-        "let testDecimalLessThanOperator(e1) (e2) = Decimal.op_LessThan (e1,e2) @ (6,72--6,81)";
-        "let testDecimalLessThanOrEqualsOperator(e1) (e2) = Decimal.op_LessThanOrEqual (e1,e2) @ (7,72--7,82)";
-        "let testDecimalGreaterThanOperator(e1) (e2) = Decimal.op_GreaterThan (e1,e2) @ (8,72--8,81)";
-        "let testDecimalGreaterThanOrEqualsOperator(e1) (e2) = Decimal.op_GreaterThanOrEqual (e1,e2) @ (9,72--9,82)";
-        "let testDecimalAdditionOperator(e1) (e2) = Decimal.op_Addition (e1,e2) @ (11,64--11,73)";
-        "let testDecimalSubtractionOperator(e1) (e2) = Decimal.op_Subtraction (e1,e2) @ (12,64--12,73)";
-        "let testDecimalMultiplyOperator(e1) (e2) = Decimal.op_Multiply (e1,e2) @ (13,64--13,73)";
-        "let testDecimalDivisionOperator(e1) (e2) = Decimal.op_Division (e1,e2) @ (14,64--14,73)";
-        "let testDecimalModulusOperator(e1) (e2) = Decimal.op_Modulus (e1,e2) @ (15,64--15,73)";
-        "let testDecimalAdditionChecked(e1) (e2) = Decimal.op_Addition (e1,e2) @ (24,62--24,79)";
-        "let testDecimalToByteChecked(e1) = Decimal.op_Explicit (e1) @ (29,49--29,64)";
-        "let testDecimalToSByteChecked(e1) = Decimal.op_Explicit (e1) @ (30,49--30,65)";
-        "let testDecimalToInt16Checked(e1) = Decimal.op_Explicit (e1) @ (31,49--31,65)";
-        "let testDecimalToUInt16Checked(e1) = Decimal.op_Explicit (e1) @ (32,49--32,66)";
-        "let testDecimalToIntChecked(e1) = Decimal.op_Explicit (e1) @ (33,49--33,63)";
-        "let testDecimalToInt32Checked(e1) = Decimal.op_Explicit (e1) @ (34,49--34,65)";
-        "let testDecimalToUInt32Checked(e1) = Decimal.op_Explicit (e1) @ (35,49--35,66)";
-        "let testDecimalToInt64Checked(e1) = Decimal.op_Explicit (e1) @ (36,49--36,65)";
-        "let testDecimalToUInt64Checked(e1) = Decimal.op_Explicit (e1) @ (37,49--37,66)";
-        "let testDecimalToByteOperator(e1) = Decimal.op_Explicit (e1) @ (41,49--41,56)";
-        "let testDecimalToSByteOperator(e1) = Decimal.op_Explicit (e1) @ (42,49--42,57)";
-        "let testDecimalToInt16Operator(e1) = Decimal.op_Explicit (e1) @ (43,49--43,57)";
-        "let testDecimalToUInt16Operator(e1) = Decimal.op_Explicit (e1) @ (44,49--44,58)";
-        "let testDecimalToIntOperator(e1) = Decimal.op_Explicit (e1) @ (45,49--45,55)";
-        "let testDecimalToInt32Operator(e1) = Decimal.op_Explicit (e1) @ (46,49--46,57)";
-        "let testDecimalToUInt32Operator(e1) = Decimal.op_Explicit (e1) @ (47,49--47,58)";
-        "let testDecimalToInt64Operator(e1) = Decimal.op_Explicit (e1) @ (48,49--48,57)";
-        "let testDecimalToUInt64Operator(e1) = Decimal.op_Explicit (e1) @ (49,49--49,58)";
-        "let testDecimalToSingleOperator(e1) = Decimal.op_Explicit (e1) @ (52,49--52,59)";
-        "let testDecimalToDoubleOperator(e1) = Convert.ToDouble (e1) @ (53,49--53,57)";
-        "let testDecimalToDecimalOperator(e1) = e1 @ (54,57--54,59)";
-        "let testDecimalToCharOperator(e1) = Decimal.op_Explicit (e1) @ (55,49--55,56)";
-#if DEBUG
-        @"let testDecimalToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,49--56,58)"
-#else
-        "let testDecimalToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,49--56,58)";
-#endif
+        [], "type OperatorTestsDecimal";
+        [], "let testDecimalEqualsOperator(e1) (e2) = Decimal.op_Equality (e1,e2) @ (4,72--4,81)";
+        [], "let testDecimalNotEqualsOperator(e1) (e2) = Operators.op_Equality (Decimal.op_Equality (e1,e2),False) @ (5,72--5,82)";
+        [], "let testDecimalLessThanOperator(e1) (e2) = Decimal.op_LessThan (e1,e2) @ (6,72--6,81)";
+        [], "let testDecimalLessThanOrEqualsOperator(e1) (e2) = Decimal.op_LessThanOrEqual (e1,e2) @ (7,72--7,82)";
+        [], "let testDecimalGreaterThanOperator(e1) (e2) = Decimal.op_GreaterThan (e1,e2) @ (8,72--8,81)";
+        [], "let testDecimalGreaterThanOrEqualsOperator(e1) (e2) = Decimal.op_GreaterThanOrEqual (e1,e2) @ (9,72--9,82)";
+        [], "let testDecimalAdditionOperator(e1) (e2) = Decimal.op_Addition (e1,e2) @ (11,64--11,73)";
+        [], "let testDecimalSubtractionOperator(e1) (e2) = Decimal.op_Subtraction (e1,e2) @ (12,64--12,73)";
+        [], "let testDecimalMultiplyOperator(e1) (e2) = Decimal.op_Multiply (e1,e2) @ (13,64--13,73)";
+        [], "let testDecimalDivisionOperator(e1) (e2) = Decimal.op_Division (e1,e2) @ (14,64--14,73)";
+        [], "let testDecimalModulusOperator(e1) (e2) = Decimal.op_Modulus (e1,e2) @ (15,64--15,73)";
+        [], "let testDecimalAdditionChecked(e1) (e2) = Decimal.op_Addition (e1,e2) @ (24,62--24,79)";
+        [], "let testDecimalToByteChecked(e1) = Decimal.op_Explicit (e1) @ (29,49--29,64)";
+        [], "let testDecimalToSByteChecked(e1) = Decimal.op_Explicit (e1) @ (30,49--30,65)";
+        [], "let testDecimalToInt16Checked(e1) = Decimal.op_Explicit (e1) @ (31,49--31,65)";
+        [], "let testDecimalToUInt16Checked(e1) = Decimal.op_Explicit (e1) @ (32,49--32,66)";
+        [], "let testDecimalToIntChecked(e1) = Decimal.op_Explicit (e1) @ (33,49--33,63)";
+        [], "let testDecimalToInt32Checked(e1) = Decimal.op_Explicit (e1) @ (34,49--34,65)";
+        [], "let testDecimalToUInt32Checked(e1) = Decimal.op_Explicit (e1) @ (35,49--35,66)";
+        [], "let testDecimalToInt64Checked(e1) = Decimal.op_Explicit (e1) @ (36,49--36,65)";
+        [], "let testDecimalToUInt64Checked(e1) = Decimal.op_Explicit (e1) @ (37,49--37,66)";
+        [], "let testDecimalToByteOperator(e1) = Decimal.op_Explicit (e1) @ (41,49--41,56)";
+        [], "let testDecimalToSByteOperator(e1) = Decimal.op_Explicit (e1) @ (42,49--42,57)";
+        [], "let testDecimalToInt16Operator(e1) = Decimal.op_Explicit (e1) @ (43,49--43,57)";
+        [], "let testDecimalToUInt16Operator(e1) = Decimal.op_Explicit (e1) @ (44,49--44,58)";
+        [], "let testDecimalToIntOperator(e1) = Decimal.op_Explicit (e1) @ (45,49--45,55)";
+        [], "let testDecimalToInt32Operator(e1) = Decimal.op_Explicit (e1) @ (46,49--46,57)";
+        [], "let testDecimalToUInt32Operator(e1) = Decimal.op_Explicit (e1) @ (47,49--47,58)";
+        [], "let testDecimalToInt64Operator(e1) = Decimal.op_Explicit (e1) @ (48,49--48,57)";
+        [], "let testDecimalToUInt64Operator(e1) = Decimal.op_Explicit (e1) @ (49,49--49,58)";
+        [], "let testDecimalToSingleOperator(e1) = Decimal.op_Explicit (e1) @ (52,49--52,59)";
+        [], "let testDecimalToDoubleOperator(e1) = Convert.ToDouble (e1) @ (53,49--53,57)";
+        [], "let testDecimalToDecimalOperator(e1) = e1 @ (54,57--54,59)";
+        [], "let testDecimalToCharOperator(e1) = Decimal.op_Explicit (e1) @ (55,49--55,56)";
+        [FC47], "let testDecimalToStringOperator(e1) = e1.ToString(dflt,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (56,49--56,58)"
       ]
 
     testOperators "Decimal" "decimal" excludedTests expectedUnoptimized expectedOptimized
@@ -2622,83 +2630,79 @@ let ``Test Operator Declarations for Char`` () =
       ]
 
     let expectedUnoptimized = [
-        "type OperatorTestsChar";
-        "let testCharEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,63--4,72)";
-        "let testCharNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,63--5,73)";
-        "let testCharLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,63--6,72)";
-        "let testCharLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,63--7,73)";
-        "let testCharGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,63--8,72)";
-        "let testCharGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,63--9,73)";
-        "let testCharAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,55--11,64)";
-        "let testCharAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,53--24,70)";
-        "let testCharToByteChecked(e1) = Checked.ToByte (e1) @ (29,43--29,58)";
-        "let testCharToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,43--30,59)";
-        "let testCharToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,43--31,59)";
-        "let testCharToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,43--32,60)";
-        "let testCharToIntChecked(e1) = Checked.ToInt (e1) @ (33,43--33,57)";
-        "let testCharToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,43--34,59)";
-        "let testCharToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,43--35,60)";
-        "let testCharToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,43--36,59)";
-        "let testCharToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,43--37,60)";
-        "let testCharToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,43--38,63)";
-        "let testCharToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,43--39,64)";
-        "let testCharToByteOperator(e1) = Operators.ToByte (e1) @ (41,43--41,50)";
-        "let testCharToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,43--42,51)";
-        "let testCharToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,43--43,51)";
-        "let testCharToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,43--44,52)";
-        "let testCharToIntOperator(e1) = Operators.ToInt (e1) @ (45,43--45,49)";
-        "let testCharToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,43--46,51)";
-        "let testCharToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,43--47,52)";
-        "let testCharToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,43--48,51)";
-        "let testCharToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,43--49,52)";
-        "let testCharToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,43--50,55)";
-        "let testCharToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,43--51,56)";
-        "let testCharToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,43--52,53)";
-        "let testCharToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,43--53,51)";
-        "let testCharToCharOperator(e1) = Operators.ToChar (e1) @ (55,43--55,50)";
-        "let testCharToStringOperator(e1) = Operators.ToString (e1) @ (56,43--56,52)";
+        [], "type OperatorTestsChar";
+        [], "let testCharEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,63--4,72)";
+        [], "let testCharNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,63--5,73)";
+        [], "let testCharLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,63--6,72)";
+        [], "let testCharLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,63--7,73)";
+        [], "let testCharGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,63--8,72)";
+        [], "let testCharGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,63--9,73)";
+        [], "let testCharAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,55--11,64)";
+        [], "let testCharAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,53--24,70)";
+        [], "let testCharToByteChecked(e1) = Checked.ToByte (e1) @ (29,43--29,58)";
+        [], "let testCharToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,43--30,59)";
+        [], "let testCharToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,43--31,59)";
+        [], "let testCharToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,43--32,60)";
+        [], "let testCharToIntChecked(e1) = Checked.ToInt (e1) @ (33,43--33,57)";
+        [], "let testCharToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,43--34,59)";
+        [], "let testCharToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,43--35,60)";
+        [], "let testCharToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,43--36,59)";
+        [], "let testCharToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,43--37,60)";
+        [], "let testCharToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,43--38,63)";
+        [], "let testCharToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,43--39,64)";
+        [], "let testCharToByteOperator(e1) = Operators.ToByte (e1) @ (41,43--41,50)";
+        [], "let testCharToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,43--42,51)";
+        [], "let testCharToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,43--43,51)";
+        [], "let testCharToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,43--44,52)";
+        [], "let testCharToIntOperator(e1) = Operators.ToInt (e1) @ (45,43--45,49)";
+        [], "let testCharToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,43--46,51)";
+        [], "let testCharToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,43--47,52)";
+        [], "let testCharToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,43--48,51)";
+        [], "let testCharToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,43--49,52)";
+        [], "let testCharToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,43--50,55)";
+        [], "let testCharToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,43--51,56)";
+        [], "let testCharToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,43--52,53)";
+        [], "let testCharToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,43--53,51)";
+        [], "let testCharToCharOperator(e1) = Operators.ToChar (e1) @ (55,43--55,50)";
+        [], "let testCharToStringOperator(e1) = Operators.ToString (e1) @ (56,43--56,52)";
       ]
 
     let expectedOptimized = [
-        "type OperatorTestsChar";
-        "let testCharEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,63--4,72)";
-        "let testCharNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,63--5,73)";
-        "let testCharLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,63--6,72)";
-        "let testCharLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,63--7,73)";
-        "let testCharGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,63--8,72)";
-        "let testCharGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,63--9,73)";
-        "let testCharAdditionOperator(e1) (e2) = Operators.ToChar (Operators.op_Addition (e1,e2)) @ (11,55--11,64)";
-        "let testCharAdditionChecked(e1) (e2) = Operators.ToChar (Checked.op_Addition (e1,e2)) @ (24,53--24,70)";
-        "let testCharToByteChecked(e1) = Checked.ToByte (e1) @ (29,43--29,58)";
-        "let testCharToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,43--30,59)";
-        "let testCharToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,43--31,59)";
-        "let testCharToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,43--32,60)";
-        "let testCharToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,43--33,57)";
-        "let testCharToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,43--34,59)";
-        "let testCharToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,43--35,60)";
-        "let testCharToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,43--36,59)";
-        "let testCharToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,43--37,60)";
-        "let testCharToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,43--38,63)";
-        "let testCharToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,43--39,64)";
-        "let testCharToByteOperator(e1) = Operators.ToByte (e1) @ (41,43--41,50)";
-        "let testCharToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,43--42,51)";
-        "let testCharToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,43--43,51)";
-        "let testCharToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,43--44,52)";
-        "let testCharToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,43--45,49)";
-        "let testCharToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,43--46,51)";
-        "let testCharToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,43--47,52)";
-        "let testCharToInt64Operator(e1) = Operators.ToUInt64 (e1) @ (48,43--48,51)";
-        "let testCharToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,43--49,52)";
-        "let testCharToIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (50,43--50,55)";
-        "let testCharToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,43--51,56)";
-        "let testCharToSingleOperator(e1) = Operators.ToSingle (Operators.ToDouble (e1)) @ (52,43--52,53)";
-        "let testCharToDoubleOperator(e1) = Operators.ToDouble (Operators.ToDouble (e1)) @ (53,43--53,51)";
-        "let testCharToCharOperator(e1) = Operators.ToChar (e1) @ (55,43--55,50)";
-#if DEBUG
-        @"let testCharToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,43--56,52)"
-#else
-        "let testCharToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,43--56,52)";
-#endif
+        [], "type OperatorTestsChar";
+        [], "let testCharEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,63--4,72)";
+        [], "let testCharNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,63--5,73)";
+        [], "let testCharLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,63--6,72)";
+        [], "let testCharLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,63--7,73)";
+        [], "let testCharGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,63--8,72)";
+        [], "let testCharGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,63--9,73)";
+        [], "let testCharAdditionOperator(e1) (e2) = Operators.ToChar (Operators.op_Addition (e1,e2)) @ (11,55--11,64)";
+        [], "let testCharAdditionChecked(e1) (e2) = Operators.ToChar (Checked.op_Addition (e1,e2)) @ (24,53--24,70)";
+        [], "let testCharToByteChecked(e1) = Checked.ToByte (e1) @ (29,43--29,58)";
+        [], "let testCharToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,43--30,59)";
+        [], "let testCharToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,43--31,59)";
+        [], "let testCharToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,43--32,60)";
+        [], "let testCharToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,43--33,57)";
+        [], "let testCharToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,43--34,59)";
+        [], "let testCharToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,43--35,60)";
+        [], "let testCharToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,43--36,59)";
+        [], "let testCharToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,43--37,60)";
+        [], "let testCharToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,43--38,63)";
+        [], "let testCharToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,43--39,64)";
+        [], "let testCharToByteOperator(e1) = Operators.ToByte (e1) @ (41,43--41,50)";
+        [], "let testCharToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,43--42,51)";
+        [], "let testCharToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,43--43,51)";
+        [], "let testCharToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,43--44,52)";
+        [], "let testCharToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,43--45,49)";
+        [], "let testCharToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,43--46,51)";
+        [], "let testCharToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,43--47,52)";
+        [], "let testCharToInt64Operator(e1) = Operators.ToUInt64 (e1) @ (48,43--48,51)";
+        [], "let testCharToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,43--49,52)";
+        [], "let testCharToIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (50,43--50,55)";
+        [], "let testCharToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,43--51,56)";
+        [], "let testCharToSingleOperator(e1) = Operators.ToSingle (Operators.ToDouble (e1)) @ (52,43--52,53)";
+        [], "let testCharToDoubleOperator(e1) = Operators.ToDouble (Operators.ToDouble (e1)) @ (53,43--53,51)";
+        [], "let testCharToCharOperator(e1) = Operators.ToChar (e1) @ (55,43--55,50)";
+        [FC47], "let testCharToStringOperator(e1) = let mutable copyOfStruct: Microsoft.FSharp.Core.char = e1 in copyOfStruct.ToString() @ (56,43--56,52)"
       ]
 
     testOperators "Char" "char" excludedTests expectedUnoptimized expectedOptimized
@@ -2726,77 +2730,73 @@ let ``Test Operator Declarations for String`` () =
       ]
 
     let expectedUnoptimized = [
-        "type OperatorTestsString";
-        "let testStringEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)";
-        "let testStringNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,69--5,79)";
-        "let testStringLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)";
-        "let testStringLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,69--7,79)";
-        "let testStringGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)";
-        "let testStringGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,69--9,79)";
-        "let testStringAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,61--11,70)";
-        "let testStringAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,59--24,76)";
-        "let testStringToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)";
-        "let testStringToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)";
-        "let testStringToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)";
-        "let testStringToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)";
-        "let testStringToIntChecked(e1) = Checked.ToInt (e1) @ (33,47--33,61)";
-        "let testStringToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)";
-        "let testStringToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)";
-        "let testStringToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)";
-        "let testStringToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)";
-        "let testStringToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)";
-        "let testStringToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)";
-        "let testStringToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)";
-        "let testStringToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)";
-        "let testStringToIntOperator(e1) = Operators.ToInt (e1) @ (45,47--45,53)";
-        "let testStringToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)";
-        "let testStringToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)";
-        "let testStringToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,47--48,55)";
-        "let testStringToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,47--49,56)";
-        "let testStringToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,47--52,57)";
-        "let testStringToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,47--53,55)";
-        "let testStringToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,47--54,57)";
-        "let testStringToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)";
-        "let testStringToStringOperator(e1) = Operators.ToString (e1) @ (56,47--56,56)";
+        [], "type OperatorTestsString";
+        [], "let testStringEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)";
+        [], "let testStringNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,69--5,79)";
+        [], "let testStringLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)";
+        [], "let testStringLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,69--7,79)";
+        [], "let testStringGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)";
+        [], "let testStringGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,69--9,79)";
+        [], "let testStringAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,61--11,70)";
+        [], "let testStringAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,59--24,76)";
+        [], "let testStringToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)";
+        [], "let testStringToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)";
+        [], "let testStringToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)";
+        [], "let testStringToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)";
+        [], "let testStringToIntChecked(e1) = Checked.ToInt (e1) @ (33,47--33,61)";
+        [], "let testStringToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)";
+        [], "let testStringToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)";
+        [], "let testStringToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)";
+        [], "let testStringToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)";
+        [], "let testStringToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)";
+        [], "let testStringToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)";
+        [], "let testStringToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)";
+        [], "let testStringToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)";
+        [], "let testStringToIntOperator(e1) = Operators.ToInt (e1) @ (45,47--45,53)";
+        [], "let testStringToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)";
+        [], "let testStringToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)";
+        [], "let testStringToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,47--48,55)";
+        [], "let testStringToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,47--49,56)";
+        [], "let testStringToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,47--52,57)";
+        [], "let testStringToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,47--53,55)";
+        [], "let testStringToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,47--54,57)";
+        [], "let testStringToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)";
+        [], "let testStringToStringOperator(e1) = Operators.ToString (e1) @ (56,47--56,56)";
       ]
 
     let expectedOptimized = [
-        "type OperatorTestsString";
-        "let testStringEqualsOperator(e1) (e2) = String.Equals (e1,e2) @ (4,69--4,78)";
-        "let testStringNotEqualsOperator(e1) (e2) = Operators.op_Equality (String.Equals (e1,e2),False) @ (5,69--5,79)";
-        "let testStringLessThanOperator(e1) (e2) = HashCompare.GenericLessThanIntrinsic (e1,e2) @ (6,69--6,78)";
-        "let testStringLessThanOrEqualsOperator(e1) (e2) = HashCompare.GenericLessOrEqualIntrinsic (e1,e2) @ (7,69--7,79)";
-        "let testStringGreaterThanOperator(e1) (e2) = HashCompare.GenericGreaterThanIntrinsic (e1,e2) @ (8,69--8,78)";
-        "let testStringGreaterThanOrEqualsOperator(e1) (e2) = HashCompare.GenericGreaterOrEqualIntrinsic (e1,e2) @ (9,69--9,79)";
-        "let testStringAdditionOperator(e1) (e2) = String.Concat (e1,e2) @ (11,61--11,70)";
-        "let testStringAdditionChecked(e1) (e2) = String.Concat (e1,e2) @ (24,59--24,76)";
-        "let testStringToByteChecked(e1) = Checked.ToByte (LanguagePrimitives.ParseUInt32 (e1)) @ (29,47--29,62)";
-        "let testStringToSByteChecked(e1) = Checked.ToSByte (LanguagePrimitives.ParseInt32 (e1)) @ (30,47--30,63)";
-        "let testStringToInt16Checked(e1) = Checked.ToInt16 (LanguagePrimitives.ParseInt32 (e1)) @ (31,47--31,63)";
-        "let testStringToUInt16Checked(e1) = Checked.ToUInt16 (LanguagePrimitives.ParseUInt32 (e1)) @ (32,47--32,64)";
-        "let testStringToIntChecked(e1) = LanguagePrimitives.ParseInt32 (e1) @ (33,47--33,61)";
-        "let testStringToInt32Checked(e1) = LanguagePrimitives.ParseInt32 (e1) @ (34,47--34,63)";
-        "let testStringToUInt32Checked(e1) = LanguagePrimitives.ParseUInt32 (e1) @ (35,47--35,64)";
-        "let testStringToInt64Checked(e1) = LanguagePrimitives.ParseInt64 (e1) @ (36,47--36,63)";
-        "let testStringToUInt64Checked(e1) = LanguagePrimitives.ParseUInt64 (e1) @ (37,47--37,64)";
-        "let testStringToByteOperator(e1) = Checked.ToByte (LanguagePrimitives.ParseUInt32 (e1)) @ (41,47--41,54)";
-        "let testStringToSByteOperator(e1) = Checked.ToSByte (LanguagePrimitives.ParseInt32 (e1)) @ (42,47--42,55)";
-        "let testStringToInt16Operator(e1) = Checked.ToInt16 (LanguagePrimitives.ParseInt32 (e1)) @ (43,47--43,55)";
-        "let testStringToUInt16Operator(e1) = Checked.ToUInt16 (LanguagePrimitives.ParseUInt32 (e1)) @ (44,47--44,56)";
-        "let testStringToIntOperator(e1) = LanguagePrimitives.ParseInt32 (e1) @ (45,47--45,53)";
-        "let testStringToInt32Operator(e1) = LanguagePrimitives.ParseInt32 (e1) @ (46,47--46,55)";
-        "let testStringToUInt32Operator(e1) = LanguagePrimitives.ParseUInt32 (e1) @ (47,47--47,56)";
-        "let testStringToInt64Operator(e1) = LanguagePrimitives.ParseInt64 (e1) @ (48,47--48,55)";
-        "let testStringToUInt64Operator(e1) = LanguagePrimitives.ParseUInt64 (e1) @ (49,47--49,56)";
-        "let testStringToSingleOperator(e1) = Single.Parse ((if Operators.op_Equality (e1,dflt) then dflt else e1.Replace(\"_\",\"\")),167,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (52,47--52,57)";
-        "let testStringToDoubleOperator(e1) = Double.Parse ((if Operators.op_Equality (e1,dflt) then dflt else e1.Replace(\"_\",\"\")),167,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (53,47--53,55)";
-        "let testStringToDecimalOperator(e1) = Decimal.Parse (e1,167,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (54,47--54,57)";
-        "let testStringToCharOperator(e1) = Char.Parse (e1) @ (55,47--55,54)";
-#if DEBUG
-        @"let testStringToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,47--56,56)"
-#else
-        "let testStringToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,47--56,56)";
-#endif
+        [], "type OperatorTestsString";
+        [], "let testStringEqualsOperator(e1) (e2) = String.Equals (e1,e2) @ (4,69--4,78)";
+        [], "let testStringNotEqualsOperator(e1) (e2) = Operators.op_Equality (String.Equals (e1,e2),False) @ (5,69--5,79)";
+        [], "let testStringLessThanOperator(e1) (e2) = HashCompare.GenericLessThanIntrinsic (e1,e2) @ (6,69--6,78)";
+        [], "let testStringLessThanOrEqualsOperator(e1) (e2) = HashCompare.GenericLessOrEqualIntrinsic (e1,e2) @ (7,69--7,79)";
+        [], "let testStringGreaterThanOperator(e1) (e2) = HashCompare.GenericGreaterThanIntrinsic (e1,e2) @ (8,69--8,78)";
+        [], "let testStringGreaterThanOrEqualsOperator(e1) (e2) = HashCompare.GenericGreaterOrEqualIntrinsic (e1,e2) @ (9,69--9,79)";
+        [], "let testStringAdditionOperator(e1) (e2) = String.Concat (e1,e2) @ (11,61--11,70)";
+        [], "let testStringAdditionChecked(e1) (e2) = String.Concat (e1,e2) @ (24,59--24,76)";
+        [], "let testStringToByteChecked(e1) = Checked.ToByte (LanguagePrimitives.ParseUInt32 (e1)) @ (29,47--29,62)";
+        [], "let testStringToSByteChecked(e1) = Checked.ToSByte (LanguagePrimitives.ParseInt32 (e1)) @ (30,47--30,63)";
+        [], "let testStringToInt16Checked(e1) = Checked.ToInt16 (LanguagePrimitives.ParseInt32 (e1)) @ (31,47--31,63)";
+        [], "let testStringToUInt16Checked(e1) = Checked.ToUInt16 (LanguagePrimitives.ParseUInt32 (e1)) @ (32,47--32,64)";
+        [], "let testStringToIntChecked(e1) = LanguagePrimitives.ParseInt32 (e1) @ (33,47--33,61)";
+        [], "let testStringToInt32Checked(e1) = LanguagePrimitives.ParseInt32 (e1) @ (34,47--34,63)";
+        [], "let testStringToUInt32Checked(e1) = LanguagePrimitives.ParseUInt32 (e1) @ (35,47--35,64)";
+        [], "let testStringToInt64Checked(e1) = LanguagePrimitives.ParseInt64 (e1) @ (36,47--36,63)";
+        [], "let testStringToUInt64Checked(e1) = LanguagePrimitives.ParseUInt64 (e1) @ (37,47--37,64)";
+        [], "let testStringToByteOperator(e1) = Checked.ToByte (LanguagePrimitives.ParseUInt32 (e1)) @ (41,47--41,54)";
+        [], "let testStringToSByteOperator(e1) = Checked.ToSByte (LanguagePrimitives.ParseInt32 (e1)) @ (42,47--42,55)";
+        [], "let testStringToInt16Operator(e1) = Checked.ToInt16 (LanguagePrimitives.ParseInt32 (e1)) @ (43,47--43,55)";
+        [], "let testStringToUInt16Operator(e1) = Checked.ToUInt16 (LanguagePrimitives.ParseUInt32 (e1)) @ (44,47--44,56)";
+        [], "let testStringToIntOperator(e1) = LanguagePrimitives.ParseInt32 (e1) @ (45,47--45,53)";
+        [], "let testStringToInt32Operator(e1) = LanguagePrimitives.ParseInt32 (e1) @ (46,47--46,55)";
+        [], "let testStringToUInt32Operator(e1) = LanguagePrimitives.ParseUInt32 (e1) @ (47,47--47,56)";
+        [], "let testStringToInt64Operator(e1) = LanguagePrimitives.ParseInt64 (e1) @ (48,47--48,55)";
+        [], "let testStringToUInt64Operator(e1) = LanguagePrimitives.ParseUInt64 (e1) @ (49,47--49,56)";
+        [], "let testStringToSingleOperator(e1) = Single.Parse ((if Operators.op_Equality (e1,dflt) then dflt else e1.Replace(\"_\",\"\")),167,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (52,47--52,57)";
+        [], "let testStringToDoubleOperator(e1) = Double.Parse ((if Operators.op_Equality (e1,dflt) then dflt else e1.Replace(\"_\",\"\")),167,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (53,47--53,55)";
+        [], "let testStringToDecimalOperator(e1) = Decimal.Parse (e1,167,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (54,47--54,57)";
+        [], "let testStringToCharOperator(e1) = Char.Parse (e1) @ (55,47--55,54)";
+        [FC47], "let testStringToStringOperator(e1) = e1 @ (56,54--56,56)"
       ]
 
     testOperators "String" "string" excludedTests expectedUnoptimized expectedOptimized
diff --git a/vsintegration/tests/GetTypesVS.UnitTests/GetTypesVS.UnitTests.fsproj b/vsintegration/tests/GetTypesVS.UnitTests/GetTypesVS.UnitTests.fsproj
index d2613d8c217..62f7adee2ba 100644
--- a/vsintegration/tests/GetTypesVS.UnitTests/GetTypesVS.UnitTests.fsproj
+++ b/vsintegration/tests/GetTypesVS.UnitTests/GetTypesVS.UnitTests.fsproj
@@ -12,6 +12,7 @@
     false
     true
     true
+    nunit
     true
   
 
diff --git a/vsintegration/tests/UnitTests/VisualFSharp.UnitTests.fsproj b/vsintegration/tests/UnitTests/VisualFSharp.UnitTests.fsproj
index 8956299d6ec..3a299196a9f 100644
--- a/vsintegration/tests/UnitTests/VisualFSharp.UnitTests.fsproj
+++ b/vsintegration/tests/UnitTests/VisualFSharp.UnitTests.fsproj
@@ -13,6 +13,7 @@
     true
     true
     false
+    nunit
     true