From 473aa793c56bf3cd01da9e4b548a796ff26b1c6f Mon Sep 17 00:00:00 2001 From: Vlad Zarytovskii Date: Mon, 18 Mar 2024 11:22:15 +0100 Subject: [PATCH 01/19] Separate PR and Signed pipelines, migrate to 1ES pipelines templates (#16821) Migrate signed pipeline to 1ES templates. --- azure-pipelines-PR.yml | 2 +- azure-pipelines.yml | 1050 ++++++-------------------------- eng/release/insert-into-vs.yml | 22 +- 3 files changed, 213 insertions(+), 861 deletions(-) diff --git a/azure-pipelines-PR.yml b/azure-pipelines-PR.yml index a3f9bb53187..713a654c341 100644 --- a/azure-pipelines-PR.yml +++ b/azure-pipelines-PR.yml @@ -890,4 +890,4 @@ stages: insertTargetBranch: rel/d17.9 insertTeamEmail: fsharpteam@microsoft.com insertTeamName: 'F#' - completeInsertion: 'auto' + completeInsertion: 'auto' \ No newline at end of file diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a3f9bb53187..e6535fbc1a3 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -3,7 +3,6 @@ trigger: branches: include: - main - - dev16.1 - feature/* - release/* paths: @@ -25,34 +24,26 @@ trigger: - release-notes.md - TESTGUIDE.md -pr: - branches: - include: - - main - - dev16.1 - - feature/* - - release/* - paths: - include: - - '*' - exclude: - - .github/* - - docs/ - - attributions.md - - CODE_OF_CONDUCT.md - - DEVGUIDE.md - - INTERNAL.md - - Language-Version-History.md - - License.txt - - README.md - - release-notes.md - - TESTGUIDE.md - variables: + # Release branch for F# + # Should be 'current' release branch name, i.e. 'release/dev17.10' in dotnet/fsharp/refs/heads/main, 'release/dev17.10' in dotnet/fsharp/refs/heads/release/dev17.10 and 'release/dev17.9' in dotnet/fsharp/refs/heads/release/dev17.9 + # Should **never** be 'main' in dotnet/fsharp/refs/heads/main, since it will start inserting to VS twice. + - name: FSharpReleaseBranchName + value: release/dev17.10 + # VS Insertion branch name (NOT the same as F# branch) + # Should be previous release branch in 'main' and 'main' in release branch + # (since for all *new* release branches we insert into VS main and for all *previous* releases we insert into corresponding VS release), + # i.e. 'rel/d17.9' in dotnet/fsharp/refs/heads/main and 'main' in F# dotnet/fsharp/refs/heads/release/dev17.10 + - name: VSInsertionTargetBranchName + value: main - name: _TeamName value: FSharp + - name: TeamName + value: FSharp - name: _BuildConfig value: Release + - name: _SignType + value: Real - name: _PublishUsingPipelines value: true - name: _DotNetArtifactsCategory @@ -61,833 +52,190 @@ variables: value: Products/$(System.TeamProject)/$(Build.Repository.Name)/$(Build.SourceBranchName)/$(Build.BuildNumber) - name: Codeql.Enabled value: true - - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - name: _DotNetValidationArtifactsCategory - value: .NETCoreValidation - - group: DotNet-FSharp-SDLValidation-Params - - ${{ if and(eq(variables['System.TeamProject'], 'public'), eq(variables['Build.Reason'], 'PullRequest')) }}: - - name: RunningAsPullRequest - value: true - # Pick up pool provider name behavior from shared yaml template - - template: /eng/common/templates/variables/pool-providers.yml - -# Variables defined in yml cannot be overridden at queue time; instead overridable variables must be defined in the web UI. -# Commenting out until something like this is supported: https://github.com/Microsoft/azure-pipelines-yaml/pull/129 -#variables: -#- name: SkipTests -# defaultValue: false - -stages: -- stage: build - displayName: Build - jobs: - - #-------------------------------------------------------------------------------------------------------------------# - # Signed build # - #-------------------------------------------------------------------------------------------------------------------# - - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/release/dev17.9') }}: - - template: /eng/common/templates/job/onelocbuild.yml + - name: _DotNetValidationArtifactsCategory + value: .NETCoreValidation + - group: DotNet-FSharp-SDLValidation-Params + - template: /eng/common/templates-official/variables/pool-providers.yml@self + +resources: + repositories: + - repository: MicroBuildTemplate + type: git + name: 1ESPipelineTemplates/MicroBuildTemplate + ref: refs/tags/release + +extends: + template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate + parameters: + featureFlags: + autoBaseline: true + sdl: + binskim: + enabled: true + policheck: + enabled: true + sbom: + enabled: false # VS SBOM is generated with other steps + justificationForDisabling: 'SBOM for F# is generated via build process. Will be migrated at later date.' + sourceAnalysisPool: + name: NetCore1ESPool-Svc-Internal + image: 1es-windows-2022-pt + os: windows + stages: + - stage: build + displayName: Build + jobs: + #-------------------------------------------------------------------------------------------------------------------# + # Signed build # + #-------------------------------------------------------------------------------------------------------------------# + # Localization: we only run it for specific release branches + - ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/release/dev17.10') }}: + - template: /eng/common/templates-official/job/onelocbuild.yml@self + parameters: + MirrorRepo: fsharp + MirrorBranch: $(FSharpReleaseBranchName) + LclSource: lclFilesfromPackage + LclPackageId: 'LCL-JUNO-PROD-FSHARP' + - template: /eng/common/templates-official/jobs/jobs.yml@self parameters: - MirrorRepo: fsharp - MirrorBranch: release/dev17.9 - LclSource: lclFilesfromPackage - LclPackageId: 'LCL-JUNO-PROD-FSHARP' - - template: /eng/common/templates/jobs/jobs.yml + enableMicrobuild: true + enablePublishBuildArtifacts: true + enablePublishTestResults: false + enablePublishBuildAssets: true + enablePublishUsingPipelines: $(_PublishUsingPipelines) + enableSourceBuild: true + enableTelemetry: true + helixRepo: dotnet/fsharp + jobs: + - job: Full_Signed + pool: + name: NetCore1ESPool-Svc-Internal + image: windows.vs2022preview.amd64 + timeoutInMinutes: 300 + templateContext: + mb: + signing: + enabled: true + feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json + signType: $(_SignType) + zipSources: false + + variables: + - group: DotNet-Symbol-Server-Pats + - group: DotNet-DevDiv-Insertion-Workflow-Variables + - name: _SignType + value: Real + steps: + - checkout: self + clean: true + - template: /eng/restore-internal-tools.yml + - script: eng\CIBuild.cmd + -configuration $(_BuildConfig) + -prepareMachine + -testAllButIntegration + -officialSkipTests $(SkipTests) + /p:SignType=$(_SignType) + /p:DotNetSignType=$(_SignType) + /p:MicroBuild_SigningEnabled=true + /p:OverridePackageSource=https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json + /p:TeamName=$(_TeamName) + /p:DotNetPublishUsingPipelines=$(_PublishUsingPipelines) + /p:DotNetArtifactsCategory=$(_DotNetArtifactsCategory) + /p:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat) + /p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat) + /p:OfficialBuildId=$(BUILD.BUILDNUMBER) + /p:PublishToSymbolServer=true + /p:VisualStudioDropName=$(VisualStudioDropName) + /p:GenerateSbom=true + env: + NativeToolsOnMachine: true + - task: PublishTestResults@2 + displayName: Publish Test Results + inputs: + testResultsFormat: 'NUnit' + testResultsFiles: '*.xml' + searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + continueOnError: true + condition: ne(variables['SkipTests'], 'true') + - task: 1ES.PublishPipelineArtifact@1 + displayName: Publish Test Logs + inputs: + targetPath: '$(Build.SourcesDirectory)\artifacts\TestResults\$(_BuildConfig)' + artifactName: 'Test Logs' + publishLocation: Container + continueOnError: true + condition: ne(variables['SkipTests'], 'true') + - task: 1ES.PublishPipelineArtifact@1 + displayName: Publish Artifact Packages + inputs: + targetPath: '$(Build.SourcesDirectory)\artifacts\packages\$(_BuildConfig)' + artifactName: 'Packages' + condition: succeeded() + - task: 1ES.PublishPipelineArtifact@1 + displayName: Publish Artifact VSSetup + inputs: + targetPath: '$(Build.SourcesDirectory)\artifacts\VSSetup\$(_BuildConfig)\Insertion' + artifactName: 'VSSetup' + condition: succeeded() + - task: 1ES.PublishPipelineArtifact@1 + displayName: Publish Artifact Nightly + inputs: + targetPath: '$(Build.SourcesDirectory)\artifacts\VSSetup\$(_BuildConfig)\VisualFSharpDebug.vsix' + artifactName: 'Nightly' + condition: succeeded() + - task: 1ES.PublishPipelineArtifact@1 + displayName: Publish Artifact Symbols + inputs: + targetPath: '$(Build.SourcesDirectory)\artifacts\SymStore\$(_BuildConfig)' + artifactName: 'NativeSymbols' + condition: succeeded() + - task: 1ES.MicroBuildVstsDrop@1 + displayName: Upload VSTS Drop + inputs: + dropName: $(VisualStudioDropName) + dropFolder: '$(Build.SourcesDirectory)\artifacts\VSSetup\$(_BuildConfig)\Insertion' + dropRetentionDays: 90 + accessToken: $(dn-bot-devdiv-drop-rw-code-rw) + dropServiceUri: 'https://devdiv.artifacts.visualstudio.com' + vsDropServiceUri: 'https://vsdrop.corp.microsoft.com/file/v1' + + condition: succeeded() + + #---------------------------------------------------------------------------------------------------------------------# + # Post Build # + #---------------------------------------------------------------------------------------------------------------------# + - template: eng/common/templates-official/post-build/post-build.yml@self parameters: - enableMicrobuild: true - enablePublishBuildArtifacts: true - enablePublishTestResults: false - enablePublishBuildAssets: true - enablePublishUsingPipelines: $(_PublishUsingPipelines) - enableSourceBuild: true - enableTelemetry: true - helixRepo: dotnet/fsharp - jobs: - - job: Full_Signed - pool: - name: $(DncEngInternalBuildPool) - demands: ImageOverride -equals windows.vs2022preview.amd64 - timeoutInMinutes: 300 - variables: - - group: DotNet-Symbol-Server-Pats - - group: DotNet-DevDiv-Insertion-Workflow-Variables - - name: _SignType - value: Real - steps: - - checkout: self - clean: true - - template: /eng/restore-internal-tools.yml - - script: eng\CIBuild.cmd - -configuration $(_BuildConfig) - -prepareMachine - -testAllButIntegration - -officialSkipTests $(SkipTests) - /p:SignType=$(_SignType) - /p:DotNetSignType=$(_SignType) - /p:MicroBuild_SigningEnabled=true - /p:OverridePackageSource=https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json - /p:TeamName=$(_TeamName) - /p:DotNetPublishUsingPipelines=$(_PublishUsingPipelines) - /p:DotNetArtifactsCategory=$(_DotNetArtifactsCategory) - /p:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat) - /p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat) - /p:OfficialBuildId=$(BUILD.BUILDNUMBER) - /p:PublishToSymbolServer=true - /p:VisualStudioDropName=$(VisualStudioDropName) - /p:GenerateSbom=true - env: - NativeToolsOnMachine: true - - script: .\tests\EndToEndBuildTests\EndToEndBuildTests.cmd -c $(_BuildConfig) - displayName: End to end build tests - continueOnError: true - condition: always() - - task: PublishTestResults@2 - displayName: Publish Test Results - inputs: - testResultsFormat: 'NUnit' - testResultsFiles: '*.xml' - searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' - continueOnError: true - condition: ne(variables['SkipTests'], 'true') - - task: PublishBuildArtifacts@1 - displayName: Publish Test Logs - inputs: - PathtoPublish: '$(Build.SourcesDirectory)\artifacts\TestResults\$(_BuildConfig)' - ArtifactName: 'Test Logs' - publishLocation: Container - continueOnError: true - condition: ne(variables['SkipTests'], 'true') - - task: PublishBuildArtifacts@1 - displayName: Publish Artifact Packages - inputs: - PathtoPublish: '$(Build.SourcesDirectory)\artifacts\packages\$(_BuildConfig)' - ArtifactName: 'Packages' - condition: succeeded() - - task: PublishBuildArtifacts@1 - displayName: Publish Artifact VSSetup - inputs: - PathtoPublish: '$(Build.SourcesDirectory)\artifacts\VSSetup\$(_BuildConfig)\Insertion' - ArtifactName: 'VSSetup' - condition: succeeded() - - task: PublishBuildArtifacts@1 - displayName: Publish Artifact Nightly - inputs: - PathtoPublish: '$(Build.SourcesDirectory)\artifacts\VSSetup\$(_BuildConfig)\VisualFSharpDebug.vsix' - ArtifactName: 'Nightly' - condition: succeeded() - - task: PublishBuildArtifacts@1 - displayName: Publish Artifact Symbols - inputs: - PathtoPublish: '$(Build.SourcesDirectory)\artifacts\SymStore\$(_BuildConfig)' - ArtifactName: 'NativeSymbols' - condition: succeeded() - - task: ms-vseng.MicroBuildTasks.4305a8de-ba66-4d8b-b2d1-0dc4ecbbf5e8.MicroBuildUploadVstsDropFolder@1 - displayName: Upload VSTS Drop - inputs: - DropName: $(VisualStudioDropName) - DropFolder: '$(Build.SourcesDirectory)\artifacts\VSSetup\$(_BuildConfig)\Insertion' - AccessToken: $(dn-bot-devdiv-drop-rw-code-rw) - condition: succeeded() - - #-------------------------------------------------------------------------------------------------------------------# - # PR builds without logs publishing # - #-------------------------------------------------------------------------------------------------------------------# - - ${{ if eq(variables['System.TeamProject'], 'public') }}: - - template: /eng/common/templates/jobs/jobs.yml + publishingInfraVersion: 3 + # Symbol validation is not entirely reliable as of yet, so should be turned off until https://github.com/dotnet/arcade/issues/2871 is resolved. + enableSymbolValidation: false + # SourceLink improperly looks for generated files. See https://github.com/dotnet/arcade/issues/3069 + enableSourceLinkValidation: false + # Enable SDL validation, passing through values from the 'DotNet-FSharp-SDLValidation-Params' group. + SDLValidationParameters: + enable: true + params: >- + -SourceToolsList @("policheck","credscan") + -ArtifactToolsList @("binskim") + -BinskimAdditionalRunConfigParams @("IgnorePdbLoadError < True","Recurse < True") + -TsaInstanceURL $(_TsaInstanceURL) + -TsaProjectName $(_TsaProjectName) + -TsaNotificationEmail $(_TsaNotificationEmail) + -TsaCodebaseAdmin $(_TsaCodebaseAdmin) + -TsaBugAreaPath $(_TsaBugAreaPath) + -TsaIterationPath $(_TsaIterationPath) + -TsaRepositoryName "FSharp" + -TsaCodebaseName "FSharp-GitHub" + -TsaPublish $True + -PoliCheckAdditionalRunConfigParams @("UserExclusionPath < $(Build.SourcesDirectory)/eng/policheck_exclusions.xml") + + #---------------------------------------------------------------------------------------------------------------------# + # VS Insertion # + #---------------------------------------------------------------------------------------------------------------------# + - template: eng/release/insert-into-vs.yml@self parameters: - enableMicrobuild: false - enablePublishBuildArtifacts: false - enablePublishTestResults: false - enablePublishBuildAssets: false - enablePublishUsingPipelines: $(_PublishUsingPipelines) - enableSourceBuild: false - enableTelemetry: true - helixRepo: dotnet/fsharp - jobs: - # Determinism, we want to run it only in PR builds - - job: Determinism_Debug - condition: eq(variables['Build.Reason'], 'PullRequest') - variables: - - name: _SignType - value: Test - pool: - name: $(DncEngPublicBuildPool) - demands: ImageOverride -equals $(WindowsMachineQueueName) - timeoutInMinutes: 90 - strategy: - maxParallel: 2 - matrix: - regular: - _experimental_flag: '' - experimental_features: - _experimental_flag: '' - steps: - - checkout: self - clean: true - - task: UseDotNet@2 - displayName: install SDK - inputs: - packageType: sdk - useGlobalJson: true - includePreviewVersions: false - workingDirectory: $(Build.SourcesDirectory) - installationPath: $(Build.SourcesDirectory)/.dotnet - - script: .\eng\test-determinism.cmd -configuration Debug - env: - FSHARP_EXPERIMENTAL_FEATURES: $(_experimental_flag) - displayName: Determinism tests with Debug configuration - - task: PublishPipelineArtifact@1 - displayName: Publish Determinism Logs - inputs: - targetPath: '$(Build.SourcesDirectory)/artifacts/log/Debug' - artifactName: 'Determinism_Debug Attempt $(System.JobAttempt) Logs' - continueOnError: true - condition: not(succeeded()) - - # Check FSComp.txt error code sorting and code formatting - - job: CheckCodeFormatting - pool: - vmImage: $(UbuntuMachineQueueName) - steps: - - checkout: self - clean: true - - script: dotnet --list-sdks - displayName: Report dotnet SDK versions - - task: UseDotNet@2 - displayName: install SDK - inputs: - packageType: sdk - useGlobalJson: true - includePreviewVersions: true - workingDirectory: $(Build.SourcesDirectory) - installationPath: $(Agent.ToolsDirectory)/dotnet - - script: dotnet tool restore - env: - DOTNET_ROLL_FORWARD_TO_PRERELEASE: 1 - displayName: Install tools - - script: dotnet fsi src/Compiler/FSCompCheck.fsx - env: - DOTNET_ROLL_FORWARD_TO_PRERELEASE: 1 - displayName: Check error code sorting in src/Compiler/FSComp.txt - - script: dotnet fantomas . --check - env: - DOTNET_ROLL_FORWARD_TO_PRERELEASE: 1 - displayName: Check code formatting (run 'dotnet fantomas .' to fix) - - # Check whether package with current version has been published to nuget.org - # We will try to restore both FSharp.Core and FCS and if restore is _successful_, package version needs to be bumped. - # NOTE: The check now runs on all branches (not just release), - # because we want to catch cases when version is desynched and we didn't update it. - # It is also helping the release notes automation to be up to date with packages versions. - - job: Check_Published_Package_Versions - # condition: or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), or(startsWith(variables['System.PullRequest.SourceBranch'], 'release/dev'), startsWith(variables['System.PullRequest.TargetBranch'], 'release/dev'))) - pool: - vmImage: $(UbuntuMachineQueueName) - strategy: - maxParallel: 2 - matrix: - FCS: - _project: "FSharp.Compiler.Service_notshipped.fsproj" - FSCore: - _project: "FSharp.Core_notshipped.fsproj" - steps: - - checkout: self - clean: true - - task: UseDotNet@2 - displayName: install SDK - inputs: - packageType: sdk - useGlobalJson: true - includePreviewVersions: true - workingDirectory: $(Build.SourcesDirectory) - installationPath: $(Agent.ToolsDirectory)/dotnet - - pwsh: ./check.ps1 -project $(_project) - workingDirectory: $(Build.SourcesDirectory)/buildtools/checkpackages - env: - DOTNET_ROLL_FORWARD_TO_PRERELEASE: 1 - displayName: Check published package version - - - #-------------------------------------------------------------------------------------------------------------------# - # PR builds # - #-------------------------------------------------------------------------------------------------------------------# - - ${{ if eq(variables['System.TeamProject'], 'public') }}: - - template: /eng/common/templates/jobs/jobs.yml - parameters: - enableMicrobuild: true - enablePublishBuildArtifacts: true - enablePublishTestResults: false - enablePublishBuildAssets: true - enablePublishUsingPipelines: $(_PublishUsingPipelines) - enableSourceBuild: true - enableTelemetry: true - helixRepo: dotnet/fsharp - jobs: - - - job: WindowsLangVersionPreview - pool: - # The PR build definition sets this variable: - # WindowsMachineQueueName=Windows.vs2022.amd64.open - # and there is an alternate build definition that sets this to a queue that is always scouting the - # next preview of Visual Studio. - name: $(DncEngPublicBuildPool) - demands: ImageOverride -equals $(WindowsMachineQueueName) - timeoutInMinutes: 120 - steps: - - checkout: self - clean: true - - - script: eng\CIBuild.cmd -compressallmetadata -configuration Release /p:FSharpLangVersion=preview - env: - NativeToolsOnMachine: true - displayName: Build - - - task: PublishBuildArtifacts@1 - displayName: Publish Build BinLog - condition: always() - continueOnError: true - inputs: - PathToPublish: '$(Build.SourcesDirectory)\artifacts\log/Release\Build.VisualFSharp.sln.binlog' - ArtifactName: 'Windows Release build binlogs' - ArtifactType: Container - parallel: true - - - job: WindowsNoRealsig_testCoreclr - pool: - # The PR build definition sets this variable: - # WindowsMachineQueueName=Windows.vs2022.amd64.open - # and there is an alternate build definition that sets this to a queue that is always scouting the - # next preview of Visual Studio. - name: $(DncEngPublicBuildPool) - demands: ImageOverride -equals $(WindowsMachineQueueName) - timeoutInMinutes: 120 - steps: - - checkout: self - clean: true - - - script: eng\CIBuild.cmd -compressallmetadata -norealsig -testCoreclr -configuration Release - env: - NativeToolsOnMachine: true - displayName: Build - - - task: PublishBuildArtifacts@1 - displayName: Publish Build BinLog - condition: always() - continueOnError: true - inputs: - PathToPublish: '$(Build.SourcesDirectory)\artifacts\log/Release\Build.VisualFSharp.sln.binlog' - ArtifactName: 'Windows Release build binlogs' - ArtifactType: Container - parallel: true - - - job: WindowsNoRealsig_testDesktop - pool: - # The PR build definition sets this variable: - # WindowsMachineQueueName=Windows.vs2022.amd64.open - # and there is an alternate build definition that sets this to a queue that is always scouting the - # next preview of Visual Studio. - name: $(DncEngPublicBuildPool) - demands: ImageOverride -equals $(WindowsMachineQueueName) - timeoutInMinutes: 120 - steps: - - checkout: self - clean: true - - - script: eng\CIBuild.cmd -compressallmetadata -norealsig -testDesktop -configuration Release - env: - NativeToolsOnMachine: true - displayName: Build - - - task: PublishBuildArtifacts@1 - displayName: Publish Build BinLog - condition: always() - continueOnError: true - inputs: - PathToPublish: '$(Build.SourcesDirectory)\artifacts\log/Release\Build.VisualFSharp.sln.binlog' - ArtifactName: 'Windows Release build binlogs' - ArtifactType: Container - parallel: true - - - job: WindowsStrictIndentation - pool: - # The PR build definition sets this variable: - # WindowsMachineQueueName=Windows.vs2022.amd64.open - # and there is an alternate build definition that sets this to a queue that is always scouting the - # next preview of Visual Studio. - name: $(DncEngPublicBuildPool) - demands: ImageOverride -equals $(WindowsMachineQueueName) - timeoutInMinutes: 120 - steps: - - checkout: self - clean: true - - - script: eng\CIBuild.cmd -compressallmetadata -configuration Release /p:AdditionalFscCmdFlags=--strict-indentation+ - env: - NativeToolsOnMachine: true - displayName: Build - - - task: PublishBuildArtifacts@1 - displayName: Publish Build BinLog - condition: always() - continueOnError: true - inputs: - PathToPublish: '$(Build.SourcesDirectory)\artifacts\log/Release\Build.VisualFSharp.sln.binlog' - ArtifactName: 'Windows Release build binlogs' - ArtifactType: Container - parallel: true - - - job: WindowsNoStrictIndentation - pool: - name: $(DncEngPublicBuildPool) - demands: ImageOverride -equals $(WindowsMachineQueueName) - timeoutInMinutes: 120 - steps: - - checkout: self - clean: true - - - script: eng\CIBuild.cmd -compressallmetadata -configuration Release /p:AdditionalFscCmdFlags=--strict-indentation- - env: - NativeToolsOnMachine: true - displayName: Build - - - task: PublishBuildArtifacts@1 - displayName: Publish Build BinLog - condition: always() - continueOnError: true - inputs: - PathToPublish: '$(Build.SourcesDirectory)\artifacts\log/Release\Build.VisualFSharp.sln.binlog' - ArtifactName: 'Windows Release build binlogs' - ArtifactType: Container - parallel: true - - # Windows With Compressed Metadata - - job: WindowsCompressedMetadata - variables: - - name: XUNIT_LOGS - value: $(Build.SourcesDirectory)\artifacts\TestResults\$(_configuration) - - name: __VSNeverShowWhatsNew - value: 1 - pool: - # The PR build definition sets this variable: - # WindowsMachineQueueName=Windows.vs2022.amd64.open - # and there is an alternate build definition that sets this to a queue that is always scouting the - # next preview of Visual Studio. - name: $(DncEngPublicBuildPool) - demands: ImageOverride -equals $(WindowsMachineQueueName) - timeoutInMinutes: 120 - strategy: - maxParallel: 5 - matrix: - desktop_release: - _configuration: Release - _testKind: testDesktop - coreclr_release: - _configuration: Release - _testKind: testCoreclr - fsharpqa_release: - _configuration: Release - _testKind: testFSharpQA - vs_release: - _configuration: Release - _testKind: testVs - transparent_compiler_release: - _configuration: Release - _testKind: testCoreclr - - ${{ if eq(variables['Build.Reason'], 'Flaky, disabled, was PullRequest') }}: - inttests_release: - _configuration: Release - _testKind: testIntegration - steps: - - checkout: self - clean: true - - - powershell: eng\SetupVSHive.ps1 - displayName: Setup VS Hive - condition: or(eq(variables['_testKind'], 'testVs'), eq(variables['_testKind'], 'testIntegration')) - - # yes, this is miserable, but - https://github.com/dotnet/arcade/issues/13239 - - script: eng\CIBuild.cmd -compressallmetadata -configuration $(_configuration) -$(_testKind) - env: - NativeToolsOnMachine: true - displayName: Build / Test - condition: and( ne(variables['_testKind'], 'testIntegration'), ne(variables['System.JobName'], 'transparent_compiler_release') ) - - - script: eng\CIBuild.cmd -compressallmetadata -configuration $(_configuration) -$(_testKind) - env: - TEST_TRANSPARENT_COMPILER: 1 - NativeToolsOnMachine: true - displayName: Build / Test Transparent Compiler - condition: and( eq(variables['System.JobName'], 'transparent_compiler_release'), ne(variables['_testKind'], 'testIntegration') ) - - - script: eng\CIBuild.cmd -compressallmetadata -configuration $(_configuration) -$(_testKind) - env: - NativeToolsOnMachine: true - displayName: Build / Integration Test - continueOnError: true - condition: eq(variables['_testKind'], 'testIntegration') - - - task: PublishTestResults@2 - displayName: Publish Test Results - inputs: - testResultsFormat: 'NUnit' - testResultsFiles: '*.xml' - searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_configuration)' - continueOnError: true - condition: ne(variables['_testKind'], 'testFSharpQA') - - task: PublishBuildArtifacts@1 - displayName: Publish Tests BinLog - condition: always() - continueOnError: true - inputs: - PathToPublish: '$(Build.SourcesDirectory)\artifacts\log/$(_configuration)\Build.VisualFSharp.sln.binlog' - ArtifactName: 'Windows $(_configuration) $(_testKind) test binlogs' - ArtifactType: Container - parallel: true - - task: PublishBuildArtifacts@1 - displayName: Publish Test Logs - inputs: - PathtoPublish: '$(Build.SourcesDirectory)\artifacts\TestResults\$(_configuration)' - ArtifactName: 'Windows $(_configuration) $(_testKind) test logs' - publishLocation: Container - continueOnError: true - condition: always() - - script: dotnet build $(Build.SourcesDirectory)/eng/DumpPackageRoot/DumpPackageRoot.csproj - displayName: Dump NuGet cache contents - condition: failed() - - task: PublishBuildArtifacts@1 - displayName: Publish NuGet cache contents - inputs: - PathtoPublish: '$(Build.SourcesDirectory)\artifacts\NugetPackageRootContents' - ArtifactName: 'NuGetPackageContents Windows $(_testKind)' - publishLocation: Container - continueOnError: true - condition: failed() - - # Mock official build - - job: MockOfficial - pool: - name: $(DncEngPublicBuildPool) - demands: ImageOverride -equals $(WindowsMachineQueueName) - steps: - - checkout: self - clean: true - - pwsh: .\eng\MockBuild.ps1 - displayName: Build with OfficialBuildId - - # Linux - - job: Linux - pool: - vmImage: $(UbuntuMachineQueueName) - variables: - - name: _SignType - value: Test - steps: - - checkout: self - clean: true - - script: ./eng/cibuild.sh --configuration $(_BuildConfig) --testcoreclr - displayName: Build / Test - - task: PublishTestResults@2 - displayName: Publish Test Results - inputs: - testResultsFormat: 'NUnit' - testResultsFiles: '*.xml' - searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' - continueOnError: true - condition: always() - - task: PublishBuildArtifacts@1 - displayName: Publish Test Logs - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' - ArtifactName: 'Linux $(_BuildConfig) test logs' - publishLocation: Container - continueOnError: true - condition: failed() - - script: dotnet build $(Build.SourcesDirectory)/eng/DumpPackageRoot/DumpPackageRoot.csproj - displayName: Dump NuGet cache contents - condition: failed() - - task: PublishBuildArtifacts@1 - displayName: Publish NuGet cache contents - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/artifacts/NugetPackageRootContents' - ArtifactName: 'NuGetPackageContents Linux' - publishLocation: Container - continueOnError: true - condition: failed() - - # MacOS - - job: MacOS - pool: - vmImage: macos-11 - variables: - - name: _SignType - value: Test - steps: - - checkout: self - clean: true - - script: ./eng/cibuild.sh --configuration $(_BuildConfig) --testcoreclr - env: - COMPlus_DefaultStackSize: 1000000 - displayName: Build / Test - - task: PublishTestResults@2 - displayName: Publish Test Results - inputs: - testResultsFormat: 'NUnit' - testResultsFiles: '*.xml' - searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' - continueOnError: true - condition: always() - - task: PublishBuildArtifacts@1 - displayName: Publish Test Logs - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' - ArtifactName: 'MacOS $(_BuildConfig) test logs' - publishLocation: Container - continueOnError: true - condition: failed() - - script: dotnet build $(Build.SourcesDirectory)/eng/DumpPackageRoot/DumpPackageRoot.csproj - displayName: Dump NuGet cache contents - condition: failed() - - task: PublishBuildArtifacts@1 - displayName: Publish NuGet cache contents - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/artifacts/NugetPackageRootContents' - ArtifactName: 'NuGetPackageContents Mac' - publishLocation: Container - continueOnError: true - condition: failed() - - # End to end build - - job: EndToEndBuildTests - pool: - name: $(DncEngPublicBuildPool) - demands: ImageOverride -equals $(WindowsMachineQueueName) - strategy: - maxParallel: 2 - matrix: - regular: - _experimental_flag: '' - experimental_features: - _experimental_flag: '' - steps: - - checkout: self - clean: true - - script: .\Build.cmd -c Release -pack - env: - NativeToolsOnMachine: true - FSHARP_EXPERIMENTAL_FEATURES: $(_experimental_flag) - - script: .\tests\EndToEndBuildTests\EndToEndBuildTests.cmd -c Release - env: - FSHARP_EXPERIMENTAL_FEATURES: $(_experimental_flag) - displayName: End to end build tests - - # Up-to-date - disabled due to it being flaky - #- job: UpToDate_Windows - # pool: - # vmImage: windows-latest - # steps: - # - checkout: self - # clean: true - # - task: PowerShell@2 - # displayName: Run up-to-date build check - # inputs: - # filePath: eng\tests\UpToDate.ps1 - # arguments: -configuration $(_BuildConfig) -ci -binaryLog - - # Run Build with Fsharp Experimental Features - # Possible change: --times:$(Build.SourcesDirectory)/artifacts/log/Release/compiler_timing.csv - - # Plain FCS build Windows - - job: Plain_Build_Windows - pool: - name: $(DncEngPublicBuildPool) - demands: ImageOverride -equals $(WindowsMachineQueueName) - variables: - - name: _BuildConfig - value: Debug - steps: - - checkout: self - clean: true - - script: dotnet --list-sdks - displayName: Report dotnet SDK versions - - task: UseDotNet@2 - displayName: install SDK - inputs: - packageType: sdk - useGlobalJson: true - includePreviewVersions: true - workingDirectory: $(Build.SourcesDirectory) - installationPath: $(Agent.ToolsDirectory)/dotnet - - script: dotnet build .\FSharp.Compiler.Service.sln /bl:\"artifacts/log/$(_BuildConfig)/ServiceRegularBuild.binlog\" - workingDirectory: $(Build.SourcesDirectory) - displayName: Regular rebuild of FSharp.Compiler.Service.sln - continueOnError: true - condition: always() - - # Plain FCS build Linux - - job: Plain_Build_Linux - pool: - vmImage: $(UbuntuMachineQueueName) - variables: - - name: _BuildConfig - value: Debug - steps: - - checkout: self - clean: true - - script: dotnet --list-sdks - displayName: Report dotnet SDK versions - - task: UseDotNet@2 - displayName: install SDK - inputs: - packageType: sdk - useGlobalJson: true - includePreviewVersions: true - workingDirectory: $(Build.SourcesDirectory) - installationPath: $(Agent.ToolsDirectory)/dotnet - - script: dotnet build ./FSharp.Compiler.Service.sln /bl:\"artifacts/log/$(_BuildConfig)/ServiceRegularBuild.binlog\" - workingDirectory: $(Build.SourcesDirectory) - displayName: Regular rebuild of FSharp.Compiler.Service.sln - continueOnError: true - condition: always() - - # Plain FCS build Mac - - job: Plain_Build_MacOS - pool: - vmImage: macos-11 - variables: - - name: _BuildConfig - value: Debug - steps: - - checkout: self - clean: true - - script: dotnet --list-sdks - displayName: Report dotnet SDK versions - - task: UseDotNet@2 - displayName: install SDK - inputs: - packageType: sdk - useGlobalJson: true - includePreviewVersions: true - workingDirectory: $(Build.SourcesDirectory) - installationPath: $(Agent.ToolsDirectory)/dotnet - - script: dotnet build ./FSharp.Compiler.Service.sln /bl:\"artifacts/log/$(_BuildConfig)/ServiceRegularBuild.binlog\" - workingDirectory: $(Build.SourcesDirectory) - displayName: Regular rebuild of FSharp.Compiler.Service.sln - continueOnError: true - condition: always() - - # Build and run fast benchmarks - - job: Benchmarks - pool: - name: $(DncEngPublicBuildPool) - demands: ImageOverride -equals $(WindowsMachineQueueName) - variables: - - name: _BuildConfig - value: Release - steps: - - checkout: self - clean: true - - script: eng\CIBuild.cmd -configuration $(_BuildConfig) -testBenchmarks - displayName: Smoke test fast benchmarks - continueOnError: true - condition: always() - - # Test trimming on Windows - - job: Build_And_Test_AOT_Windows - pool: - name: $(DncEngPublicBuildPool) - demands: ImageOverride -equals $(WindowsMachineQueueName) - strategy: - maxParallel: 2 - matrix: - compressed_metadata: - _kind: "-compressAllMetadata" - classic_metadata: - _kind: "" - variables: - - name: _BuildConfig - value: Release - steps: - - checkout: self - clean: true - - task: UseDotNet@2 - displayName: install SDK - inputs: - packageType: sdk - useGlobalJson: true - includePreviewVersions: true - workingDirectory: $(Build.SourcesDirectory) - installationPath: $(Agent.ToolsDirectory)/dotnet - - script: dotnet --list-sdks - displayName: Report dotnet SDK versions - - script: .\Build.cmd $(_kind) -pack -c $(_BuildConfig) - env: - NativeToolsOnMachine: true - displayName: Initial build and prepare packages. - - script: $(Build.SourcesDirectory)/tests/AheadOfTime/check.cmd - displayName: Build, trim, publish and check the state of the trimmed app. - workingDirectory: $(Build.SourcesDirectory)/tests/AheadOfTime - - task: PublishPipelineArtifact@1 - displayName: Publish Trim Tests Logs - inputs: - targetPath: './artifacts/log/Release/AheadOfTime/Trimming/' - artifactName: 'Trim Test Logs Attempt $(System.JobAttempt) Logs $(_kind)' - continueOnError: true - condition: always() - - # Arcade-powered source build - # turned off until https://github.com/dotnet/source-build/issues/1795 is fixed - # - template: /eng/common/templates/jobs/jobs.yml - # parameters: - # enablePublishUsingPipelines: true - # enablePublishBuildArtifacts: true - # enablePublishBuildAssets: true - # artifacts: - # publish: - # artifacts: true - # manifests: true - # runSourceBuild: true - # sourceBuildParameters: - # includeDefaultManagedPlatform: true - -#---------------------------------------------------------------------------------------------------------------------# -# Post Build # -#---------------------------------------------------------------------------------------------------------------------# -- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - template: eng/common/templates/post-build/post-build.yml - parameters: - publishingInfraVersion: 3 - # Symbol validation is not entirely reliable as of yet, so should be turned off until https://github.com/dotnet/arcade/issues/2871 is resolved. - enableSymbolValidation: false - # SourceLink improperly looks for generated files. See https://github.com/dotnet/arcade/issues/3069 - enableSourceLinkValidation: false - # Enable SDL validation, passing through values from the 'DotNet-FSharp-SDLValidation-Params' group. - SDLValidationParameters: - enable: true - params: >- - -SourceToolsList @("policheck","credscan") - -ArtifactToolsList @("binskim") - -BinskimAdditionalRunConfigParams @("IgnorePdbLoadError < True","Recurse < True") - -TsaInstanceURL $(_TsaInstanceURL) - -TsaProjectName $(_TsaProjectName) - -TsaNotificationEmail $(_TsaNotificationEmail) - -TsaCodebaseAdmin $(_TsaCodebaseAdmin) - -TsaBugAreaPath $(_TsaBugAreaPath) - -TsaIterationPath $(_TsaIterationPath) - -TsaRepositoryName "FSharp" - -TsaCodebaseName "FSharp-GitHub" - -TsaPublish $True - -PoliCheckAdditionalRunConfigParams @("UserExclusionPath < $(Build.SourcesDirectory)/eng/policheck_exclusions.xml") - -#---------------------------------------------------------------------------------------------------------------------# -# VS Insertion # -#---------------------------------------------------------------------------------------------------------------------# -- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - template: eng/release/insert-into-vs.yml - parameters: - componentBranchName: refs/heads/release/dev17.9 - insertTargetBranch: rel/d17.9 - insertTeamEmail: fsharpteam@microsoft.com - insertTeamName: 'F#' - completeInsertion: 'auto' + componentBranchName: refs/heads/${{ variables.FSharpReleaseBranchName }} + insertTargetBranch: ${{ variables.VSInsertionTargetBranchName }} + insertTeamEmail: fsharpteam@microsoft.com + insertTeamName: 'F#' + completeInsertion: 'auto' diff --git a/eng/release/insert-into-vs.yml b/eng/release/insert-into-vs.yml index 63973516ba8..e15b691f59a 100644 --- a/eng/release/insert-into-vs.yml +++ b/eng/release/insert-into-vs.yml @@ -15,7 +15,7 @@ stages: - job: Insert_VS pool: name: NetCore1ESPool-Svc-Internal - demands: ImageOverride -equals windows.vs2019.amd64 + image: windows.vs2022preview.amd64 variables: - group: DotNet-VSTS-Infra-Access - name: InsertAccessToken @@ -31,26 +31,30 @@ stages: - name: InsertPayloadName value: '${{ parameters.insertTeamName }} $(Build.SourceBranchName) $(Build.BuildNumber)' steps: - - task: DownloadBuildArtifacts@0 - displayName: Download Insertion Artifacts + - download: current + artifact: VSSetup + - task: PowerShell@2 + displayName: List Workspace inputs: - buildType: current - artifactName: VSSetup + targetType: 'inline' + pwsh: true + script: | + Tree $(Pipeline.Workspace) /F - task: PowerShell@2 displayName: Get Publish URLs inputs: filePath: $(Build.SourcesDirectory)/eng/release/scripts/GetPublishUrls.ps1 - arguments: -accessToken $(System.AccessToken) -buildId $(Build.BuildId) -insertionDir $(Build.ArtifactStagingDirectory)\VSSetup + arguments: -accessToken $(System.AccessToken) -buildId $(Build.BuildId) -insertionDir $(Pipeline.Workspace)\VSSetup - task: PowerShell@2 displayName: Get versions for default.config inputs: filePath: $(Build.SourcesDirectory)/eng/release/scripts/GetDefaultConfigVersions.ps1 - arguments: -packagesDir $(Build.ArtifactStagingDirectory)\VSSetup\DevDivPackages + arguments: -packagesDir $(Pipeline.Workspace)\VSSetup\DevDivPackages - task: PowerShell@2 displayName: Get versions for AssemblyVersions.tt inputs: filePath: $(Build.SourcesDirectory)/eng/release/scripts/GetAssemblyVersions.ps1 - arguments: -assemblyVersionsPath $(Build.ArtifactStagingDirectory)\VSSetup\DevDivPackages\DependentAssemblyVersions.csv + arguments: -assemblyVersionsPath $(Pipeline.Workspace)\VSSetup\DevDivPackages\DependentAssemblyVersions.csv - task: PowerShell@2 displayName: Calculate autocompletion state inputs: @@ -69,5 +73,5 @@ stages: - task: ms-vseng.MicroBuildShipTasks.55100717-a81d-45ea-a363-b8fe3ec375ad.MicroBuildInsertVsPayload@3 displayName: 'Insert VS Payload' inputs: - LinkWorkItemsToPR: false + LinkWorkItemsToPR: true condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], '${{ parameters.componentBranchName }}'), eq(variables['Build.SourceBranch'], 'refs/heads/${{ parameters.componentBranchName }}'))) From 307627b756b52c9b47aa85d5b4b66154e93558f1 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 18 Mar 2024 10:37:41 +0000 Subject: [PATCH 02/19] Implicit constructors should only target AttributeTargets.Constructor (#16845) * Implicit constructors should only target AttributeTargets.Constructor * release notes * Update FSComp * Use LanguageFeature.EnforceAttributeTargets --- .../.FSharp.Compiler.Service/8.0.300.md | 1 + docs/release-notes/.Language/preview.md | 1 + src/Compiler/Checking/CheckDeclarations.fs | 6 ++--- src/Compiler/Checking/CheckExpressions.fs | 2 +- .../Checking/CheckIncrementalClasses.fs | 9 +++++++- src/Compiler/FSComp.txt | 4 +--- src/Compiler/Facilities/LanguageFeatures.fs | 12 +++------- src/Compiler/Facilities/LanguageFeatures.fsi | 4 +--- src/Compiler/xlf/FSComp.txt.cs.xlf | 16 +++----------- src/Compiler/xlf/FSComp.txt.de.xlf | 16 +++----------- src/Compiler/xlf/FSComp.txt.es.xlf | 16 +++----------- src/Compiler/xlf/FSComp.txt.fr.xlf | 16 +++----------- src/Compiler/xlf/FSComp.txt.it.xlf | 16 +++----------- src/Compiler/xlf/FSComp.txt.ja.xlf | 16 +++----------- src/Compiler/xlf/FSComp.txt.ko.xlf | 16 +++----------- src/Compiler/xlf/FSComp.txt.pl.xlf | 16 +++----------- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 16 +++----------- src/Compiler/xlf/FSComp.txt.ru.xlf | 16 +++----------- src/Compiler/xlf/FSComp.txt.tr.xlf | 16 +++----------- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 16 +++----------- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 16 +++----------- .../AttributeUsage/AttributeUsage.fs | 22 ++++++++++++++++++- .../E_AttributeTargetIsCtor01.fs | 17 ++++++++++++++ 23 files changed, 96 insertions(+), 190 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsCtor01.fs diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index 83b2c864908..6a2c4414491 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -16,6 +16,7 @@ * Enforce AttributeTargets on let values and functions. ([PR #16692](https://github.com/dotnet/fsharp/pull/16692)) * Enforce AttributeTargets on union case declarations. ([PR #16764](https://github.com/dotnet/fsharp/pull/16764)) * Disallow using base to invoke an abstract base method. ([Issue #13926](https://github.com/dotnet/fsharp/issues/13926), [PR #16773](https://github.com/dotnet/fsharp/pull/16773)) +* Enforce AttributeTargets on implicit constructors. ([PR #16845](https://github.com/dotnet/fsharp/pull/16845/)) * Enforce AttributeTargets on structs and classes ([PR #16790](https://github.com/dotnet/fsharp/pull/16790)) * Parser: fix pattern range for idents with trivia ([PR #16824](https://github.com/dotnet/fsharp/pull/16824)) * Fix broken code completion after a record type declaration ([PR #16813](https://github.com/dotnet/fsharp/pull/16813)) diff --git a/docs/release-notes/.Language/preview.md b/docs/release-notes/.Language/preview.md index 4a6122e29dd..1e51f83984c 100644 --- a/docs/release-notes/.Language/preview.md +++ b/docs/release-notes/.Language/preview.md @@ -11,6 +11,7 @@ * Allow extension methods without type attribute work for types from imported assemblies. ([PR #16368](https://github.com/dotnet/fsharp/pull/16368)) * Enforce AttributeTargets on let values and functions. ([PR #16692](https://github.com/dotnet/fsharp/pull/16692)) * Enforce AttributeTargets on union case declarations. ([PR #16764](https://github.com/dotnet/fsharp/pull/16764)) +* Enforce AttributeTargets on implicit constructors. ([PR #16845](https://github.com/dotnet/fsharp/pull/16845/)) * Enforce AttributeTargets on structs and classes ([PR #16790](https://github.com/dotnet/fsharp/pull/16790)) ### Changed diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 88c8c7b5a72..442a21e3601 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -574,7 +574,7 @@ module TcRecdUnionAndEnumDeclarations = type SomeUnion = | Case1 // Compiles down to a static property *) - if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargetsUnionCaseDeclarations) then + if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) then let target = if rfields.IsEmpty then AttributeTargets.Property else AttributeTargets.Method TcAttributes cenv env target synAttrs else @@ -2927,13 +2927,13 @@ module EstablishTypeDefinitionCores = let kind = match kind with | SynTypeDefnKind.Class -> - if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargetsOnStructAndClasses) then + if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) then TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Class synAttrs |> ignore TFSharpClass | SynTypeDefnKind.Interface -> TFSharpInterface | SynTypeDefnKind.Delegate _ -> TFSharpDelegate (MakeSlotSig("Invoke", g.unit_ty, [], [], [], None)) | SynTypeDefnKind.Struct -> - if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargetsOnStructAndClasses) then + if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) then TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Struct synAttrs |> ignore TFSharpStruct | _ -> error(InternalError("should have inferred tycon kind", m)) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index f7e048223bf..220e4da4c82 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10874,7 +10874,7 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt if not (isNil declaredTypars) then errorR(Error(FSComp.SR.tcLiteralCannotHaveGenericParameters(), mBinding)) - if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargetsOnFunctions) && memberFlagsOpt.IsNone && not attrs.IsEmpty then + if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) && memberFlagsOpt.IsNone && not attrs.IsEmpty then TcAttributeTargetsOnLetBindings cenv env attrs overallPatTy overallExprTy (not declaredTypars.IsEmpty) CheckedBindingInfo(inlineFlag, valAttribs, xmlDoc, tcPatPhase2, explicitTyparInfo, nameToPrelimValSchemeMap, rhsExprChecked, argAndRetAttribs, overallPatTy, mBinding, debugPoint, isCompGen, literalValue, isFixed), tpenv diff --git a/src/Compiler/Checking/CheckIncrementalClasses.fs b/src/Compiler/Checking/CheckIncrementalClasses.fs index 1424a8ef7f3..014e3144717 100644 --- a/src/Compiler/Checking/CheckIncrementalClasses.fs +++ b/src/Compiler/Checking/CheckIncrementalClasses.fs @@ -5,6 +5,7 @@ module internal FSharp.Compiler.CheckIncrementalClasses open System open FSharp.Compiler.Diagnostics +open FSharp.Compiler.Features open Internal.Utilities.Collections open Internal.Utilities.Library open Internal.Utilities.Library.Extras @@ -173,7 +174,13 @@ let TcImplicitCtorInfo_Phase2A(cenv: cenv, env, tpenv, tcref: TyconRef, vis, att let ctorTy = mkFunTy g argTy objTy // NOTE: no attributes can currently be specified for the implicit constructor - let attribs = TcAttributes cenv env (AttributeTargets.Constructor ||| AttributeTargets.Method) attrs + let attribs = + // Implicit constructors can only target AttributeTargets.Constructor + if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) then + TcAttributes cenv env AttributeTargets.Constructor attrs + else + TcAttributes cenv env (AttributeTargets.Constructor ||| AttributeTargets.Method) attrs + let memberFlags = CtorMemberFlags let synArgInfos = List.map (SynInfo.InferSynArgInfoFromSimplePat []) spats diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index eda76095bb2..a716fe7204c 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1593,10 +1593,8 @@ featureWarningIndexedPropertiesGetSetSameType,"Indexed properties getter and set featureChkTailCallAttrOnNonRec,"Raises warnings if the 'TailCall' attribute is used on non-recursive functions." featureUnionIsPropertiesVisible,"Union case test properties" featureBooleanReturningAndReturnTypeDirectedPartialActivePattern,"Boolean-returning and return-type-directed partial active patterns" -featureEnforceAttributeTargetsOnFunctions,"Enforce AttributeTargets on functions" -featureEnforceAttributeTargetsUnionCaseDeclarations,"Enforce AttributeTargets on union case declarations" +featureEnforceAttributeTargets,"Enforce AttributeTargets" featureLowerInterpolatedStringToConcat,"Optimizes interpolated strings in certain cases, by lowering to concatenation" -featureEnforceAttributeTargetsOnStructAndClasses,"Enforce AttributeTargets on structs and classes" featureLowerIntegralRangesToFastLoops,"Optimizes certain uses of the integral range (..) and range-step (.. ..) operators to fast while-loops." 3354,tcNotAFunctionButIndexerNamedIndexingNotYetEnabled,"This value supports indexing, e.g. '%s.[index]'. The syntax '%s[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." 3354,tcNotAFunctionButIndexerIndexingNotYetEnabled,"This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index ac48fc40b91..2ce326d9c75 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -85,10 +85,8 @@ type LanguageFeature = | WarningIndexedPropertiesGetSetSameType | WarningWhenTailCallAttrOnNonRec | BooleanReturningAndReturnTypeDirectedPartialActivePattern - | EnforceAttributeTargetsOnFunctions - | EnforceAttributeTargetsUnionCaseDeclarations + | EnforceAttributeTargets | LowerInterpolatedStringToConcat - | EnforceAttributeTargetsOnStructAndClasses | LowerIntegralRangesToFastLoops /// LanguageVersion management @@ -202,10 +200,8 @@ type LanguageVersion(versionText) = LanguageFeature.WarningWhenTailCallAttrOnNonRec, previewVersion LanguageFeature.UnionIsPropertiesVisible, previewVersion LanguageFeature.BooleanReturningAndReturnTypeDirectedPartialActivePattern, previewVersion - LanguageFeature.EnforceAttributeTargetsOnFunctions, previewVersion - LanguageFeature.EnforceAttributeTargetsUnionCaseDeclarations, previewVersion + LanguageFeature.EnforceAttributeTargets, previewVersion LanguageFeature.LowerInterpolatedStringToConcat, previewVersion - LanguageFeature.EnforceAttributeTargetsOnStructAndClasses, previewVersion LanguageFeature.LowerIntegralRangesToFastLoops, previewVersion ] @@ -350,10 +346,8 @@ type LanguageVersion(versionText) = | LanguageFeature.WarningWhenTailCallAttrOnNonRec -> FSComp.SR.featureChkTailCallAttrOnNonRec () | LanguageFeature.BooleanReturningAndReturnTypeDirectedPartialActivePattern -> FSComp.SR.featureBooleanReturningAndReturnTypeDirectedPartialActivePattern () - | LanguageFeature.EnforceAttributeTargetsOnFunctions -> FSComp.SR.featureEnforceAttributeTargetsOnFunctions () - | LanguageFeature.EnforceAttributeTargetsUnionCaseDeclarations -> FSComp.SR.featureEnforceAttributeTargetsUnionCaseDeclarations () + | LanguageFeature.EnforceAttributeTargets -> FSComp.SR.featureEnforceAttributeTargets () | LanguageFeature.LowerInterpolatedStringToConcat -> FSComp.SR.featureLowerInterpolatedStringToConcat () - | LanguageFeature.EnforceAttributeTargetsOnStructAndClasses -> FSComp.SR.featureEnforceAttributeTargetsOnStructAndClasses () | LanguageFeature.LowerIntegralRangesToFastLoops -> FSComp.SR.featureLowerIntegralRangesToFastLoops () /// Get a version string associated with the given feature. diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi index 80a41c8ce54..f166975ec42 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fsi +++ b/src/Compiler/Facilities/LanguageFeatures.fsi @@ -76,10 +76,8 @@ type LanguageFeature = | WarningIndexedPropertiesGetSetSameType | WarningWhenTailCallAttrOnNonRec | BooleanReturningAndReturnTypeDirectedPartialActivePattern - | EnforceAttributeTargetsOnFunctions - | EnforceAttributeTargetsUnionCaseDeclarations + | EnforceAttributeTargets | LowerInterpolatedStringToConcat - | EnforceAttributeTargetsOnStructAndClasses | LowerIntegralRangesToFastLoops /// LanguageVersion management diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 29a83a20d98..bb150927db9 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -292,19 +292,9 @@ literál float32 bez tečky - - Enforce AttributeTargets on functions - Enforce AttributeTargets on functions - - - - Enforce AttributeTargets on structs and classes - Enforce AttributeTargets on structs and classes - - - - Enforce AttributeTargets on union case declarations - Enforce AttributeTargets on union case declarations + + Enforce AttributeTargets + Enforce AttributeTargets diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index e28b1177ea9..8bde903616f 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -292,19 +292,9 @@ punktloses float32-Literal - - Enforce AttributeTargets on functions - Enforce AttributeTargets on functions - - - - Enforce AttributeTargets on structs and classes - Enforce AttributeTargets on structs and classes - - - - Enforce AttributeTargets on union case declarations - Enforce AttributeTargets on union case declarations + + Enforce AttributeTargets + Enforce AttributeTargets diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index d86bb178a0d..ff17bae30d1 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -292,19 +292,9 @@ literal float32 sin punto - - Enforce AttributeTargets on functions - Enforce AttributeTargets on functions - - - - Enforce AttributeTargets on structs and classes - Enforce AttributeTargets on structs and classes - - - - Enforce AttributeTargets on union case declarations - Enforce AttributeTargets on union case declarations + + Enforce AttributeTargets + Enforce AttributeTargets diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index e9cefd5803b..2006cd4a0e1 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -292,19 +292,9 @@ littéral float32 sans point - - Enforce AttributeTargets on functions - Enforce AttributeTargets on functions - - - - Enforce AttributeTargets on structs and classes - Enforce AttributeTargets on structs and classes - - - - Enforce AttributeTargets on union case declarations - Enforce AttributeTargets on union case declarations + + Enforce AttributeTargets + Enforce AttributeTargets diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 539502d9670..70c046f57d7 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -292,19 +292,9 @@ valore letterale float32 senza punti - - Enforce AttributeTargets on functions - Enforce AttributeTargets on functions - - - - Enforce AttributeTargets on structs and classes - Enforce AttributeTargets on structs and classes - - - - Enforce AttributeTargets on union case declarations - Enforce AttributeTargets on union case declarations + + Enforce AttributeTargets + Enforce AttributeTargets diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index a364c7953d6..97d052f9bc4 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -292,19 +292,9 @@ ドットなしの float32 リテラル - - Enforce AttributeTargets on functions - Enforce AttributeTargets on functions - - - - Enforce AttributeTargets on structs and classes - Enforce AttributeTargets on structs and classes - - - - Enforce AttributeTargets on union case declarations - Enforce AttributeTargets on union case declarations + + Enforce AttributeTargets + Enforce AttributeTargets diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 96768306e24..edbbbc1f0ab 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -292,19 +292,9 @@ 점이 없는 float32 리터럴 - - Enforce AttributeTargets on functions - Enforce AttributeTargets on functions - - - - Enforce AttributeTargets on structs and classes - Enforce AttributeTargets on structs and classes - - - - Enforce AttributeTargets on union case declarations - Enforce AttributeTargets on union case declarations + + Enforce AttributeTargets + Enforce AttributeTargets diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 22210fdee9c..4960765fa1a 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -292,19 +292,9 @@ bezkropkowy literał float32 - - Enforce AttributeTargets on functions - Enforce AttributeTargets on functions - - - - Enforce AttributeTargets on structs and classes - Enforce AttributeTargets on structs and classes - - - - Enforce AttributeTargets on union case declarations - Enforce AttributeTargets on union case declarations + + Enforce AttributeTargets + Enforce AttributeTargets diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 8449413e457..8ea97b7b5b1 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -292,19 +292,9 @@ literal float32 sem ponto - - Enforce AttributeTargets on functions - Enforce AttributeTargets on functions - - - - Enforce AttributeTargets on structs and classes - Enforce AttributeTargets on structs and classes - - - - Enforce AttributeTargets on union case declarations - Enforce AttributeTargets on union case declarations + + Enforce AttributeTargets + Enforce AttributeTargets diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 41129014c1b..8793d14fbfd 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -292,19 +292,9 @@ литерал float32 без точки - - Enforce AttributeTargets on functions - Enforce AttributeTargets on functions - - - - Enforce AttributeTargets on structs and classes - Enforce AttributeTargets on structs and classes - - - - Enforce AttributeTargets on union case declarations - Enforce AttributeTargets on union case declarations + + Enforce AttributeTargets + Enforce AttributeTargets diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 659004ddc36..4261665d83e 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -292,19 +292,9 @@ noktasız float32 sabit değeri - - Enforce AttributeTargets on functions - Enforce AttributeTargets on functions - - - - Enforce AttributeTargets on structs and classes - Enforce AttributeTargets on structs and classes - - - - Enforce AttributeTargets on union case declarations - Enforce AttributeTargets on union case declarations + + Enforce AttributeTargets + Enforce AttributeTargets diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 1b8716f794d..eac9a233793 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -292,19 +292,9 @@ 无点 float32 文本 - - Enforce AttributeTargets on functions - Enforce AttributeTargets on functions - - - - Enforce AttributeTargets on structs and classes - Enforce AttributeTargets on structs and classes - - - - Enforce AttributeTargets on union case declarations - Enforce AttributeTargets on union case declarations + + Enforce AttributeTargets + Enforce AttributeTargets diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 43da50f6960..e0f3f70149c 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -292,19 +292,9 @@ 無點號的 float32 常值 - - Enforce AttributeTargets on functions - Enforce AttributeTargets on functions - - - - Enforce AttributeTargets on structs and classes - Enforce AttributeTargets on structs and classes - - - - Enforce AttributeTargets on union case declarations - Enforce AttributeTargets on union case declarations + + Enforce AttributeTargets + Enforce AttributeTargets diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs index 652755fd5cd..d34f6d797c1 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs @@ -481,7 +481,6 @@ module CustomAttributes_AttributeUsage = (Error 842, Line 15, Col 5, Line 15, Col 25, "This attribute is not valid for use on this language element") ] - // SOURCE=E_AttributeTargetIsProperty01.fs # E_AttributeTargetIsField03.fs [] let ``E_AttributeTargetIsProperty01_fs`` compilation = @@ -499,4 +498,25 @@ module CustomAttributes_AttributeUsage = |> withDiagnostics [ (Error 842, Line 14, Col 5, Line 14, Col 18, "This attribute is not valid for use on this language element") (Error 842, Line 15, Col 5, Line 15, Col 25, "This attribute is not valid for use on this language element") + ] + + // SOURCE=E_AttributeTargetIsCtor01.fs # E_AttributeTargetIsCtor01.fs + [] + let ``E_AttributeTargetIsCtor01_fs`` compilation = + compilation + |> verifyCompile + |> shouldSucceed + + // SOURCE=E_AttributeTargetIsCtor01.fs # E_AttributeTargetIsCtor01.fs + [] + let ``E_AttributeTargetIsCtor01_fs preview`` compilation = + compilation + |> withLangVersionPreview + |> verifyCompile + |> shouldFail + |> withDiagnostics [ + (Error 842, Line 9, Col 15, Line 9, Col 27, "This attribute is not valid for use on this language element") + (Error 842, Line 11, Col 16, Line 11, Col 28, "This attribute is not valid for use on this language element") + (Error 842, Line 14, Col 15, Line 14, Col 27, "This attribute is not valid for use on this language element") + (Error 842, Line 17, Col 16, Line 17, Col 28, "This attribute is not valid for use on this language element") ] \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsCtor01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsCtor01.fs new file mode 100644 index 00000000000..6112b952fbf --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsCtor01.fs @@ -0,0 +1,17 @@ +open System + +open System + +[] +type CustomMethodAttribute() = + inherit Attribute() + +type Class1 [] () = class end + +type Struct1 [](c: int) = struct end + +[] +type Class2 []() = class end + +[] +type Struct2 [](c: int) = struct end From 001a7dd070639af65efb065c6b6cebe7a3184f1c Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 18 Mar 2024 14:14:40 +0000 Subject: [PATCH 03/19] AttributeTargets.Class and AttributeTargets.Struct can be targeted in an enum incorrectly (#16887) --- .../.FSharp.Compiler.Service/8.0.300.md | 1 + docs/release-notes/.FSharp.Core/8.0.300.md | 3 +- src/Compiler/Checking/CheckDeclarations.fs | 4 ++- src/FSharp.Core/prim-types.fs | 2 +- src/FSharp.Core/prim-types.fsi | 2 +- .../AttributeTargetsIsEnum01.fs | 11 ++++++ .../AttributeUsage/AttributeUsage.fs | 36 +++++++++++++++++++ .../E_AttributeTargetIsEnum01.fs | 26 ++++++++++++++ 8 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsEnum01.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsEnum01.fs diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index 6a2c4414491..e68afa41dc8 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -20,6 +20,7 @@ * Enforce AttributeTargets on structs and classes ([PR #16790](https://github.com/dotnet/fsharp/pull/16790)) * Parser: fix pattern range for idents with trivia ([PR #16824](https://github.com/dotnet/fsharp/pull/16824)) * Fix broken code completion after a record type declaration ([PR #16813](https://github.com/dotnet/fsharp/pull/16813)) +* Enforce AttributeTargets on enums ([PR #16887](https://github.com/dotnet/fsharp/pull/16887)) ### Added diff --git a/docs/release-notes/.FSharp.Core/8.0.300.md b/docs/release-notes/.FSharp.Core/8.0.300.md index 60b25705745..d4d7036b296 100644 --- a/docs/release-notes/.FSharp.Core/8.0.300.md +++ b/docs/release-notes/.FSharp.Core/8.0.300.md @@ -6,4 +6,5 @@ ### Fixed * Preserve original stack traces in resumable state machines generated code if available. ([PR #16568](https://github.com/dotnet/fsharp/pull/16568)) -* Enforce AttributeTargets on structs and classes. Also update `RequireQualifiedAccessAttribute` and `AutoOpenAttribute` to use `AttributeTargets.Struct` ([PR #16790](https://github.com/dotnet/fsharp/pull/16790)) \ No newline at end of file +* Enforce AttributeTargets on structs and classes. Also update `RequireQualifiedAccessAttribute` and `AutoOpenAttribute` to use `AttributeTargets.Struct` ([PR #16790](https://github.com/dotnet/fsharp/pull/16790)) +* Enforce AttributeTargets on enums. Also update `RequireQualifiedAccessAttribute` to use `AttributeTargets.Enum` ([PR #16887](https://github.com/dotnet/fsharp/pull/16887)) \ No newline at end of file diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 442a21e3601..501d7927ec2 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -2940,7 +2940,9 @@ module EstablishTypeDefinitionCores = TFSharpTyconRepr (Construct.NewEmptyFSharpTyconData kind) - | SynTypeDefnSimpleRepr.Enum _ -> + | SynTypeDefnSimpleRepr.Enum _ -> + if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) then + TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Enum synAttrs |> ignore TFSharpTyconRepr (Construct.NewEmptyFSharpTyconData TFSharpEnum) // OK, now fill in the (partially computed) type representation diff --git a/src/FSharp.Core/prim-types.fs b/src/FSharp.Core/prim-types.fs index 777a31b8e15..2eca8c20333 100644 --- a/src/FSharp.Core/prim-types.fs +++ b/src/FSharp.Core/prim-types.fs @@ -350,7 +350,7 @@ namespace Microsoft.FSharp.Core type RequiresExplicitTypeArgumentsAttribute() = inherit Attribute() - [] + [] [] type RequireQualifiedAccessAttribute() = inherit Attribute() diff --git a/src/FSharp.Core/prim-types.fsi b/src/FSharp.Core/prim-types.fsi index fc2b4d756a9..3e88abdea32 100644 --- a/src/FSharp.Core/prim-types.fsi +++ b/src/FSharp.Core/prim-types.fsi @@ -898,7 +898,7 @@ namespace Microsoft.FSharp.Core /// type require explicit qualified access. /// /// Attributes - [] + [] [] type RequireQualifiedAccessAttribute = inherit Attribute diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsEnum01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsEnum01.fs new file mode 100644 index 00000000000..292f19d070a --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsEnum01.fs @@ -0,0 +1,11 @@ +open System + +[] +type CustomEnumAttribute() = + inherit Attribute() + +[] +type Color = + | Red = 0 + | Green = 1 + | Blue = 2 diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs index d34f6d797c1..15851371cb5 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs @@ -519,4 +519,40 @@ module CustomAttributes_AttributeUsage = (Error 842, Line 11, Col 16, Line 11, Col 28, "This attribute is not valid for use on this language element") (Error 842, Line 14, Col 15, Line 14, Col 27, "This attribute is not valid for use on this language element") (Error 842, Line 17, Col 16, Line 17, Col 28, "This attribute is not valid for use on this language element") + ] + + // SOURCE=AttributeTargetsIsEnum01.fs # AttributeTargetsIsEnum01.fs + [] + let ``AttributeTargetsIsEnum01_fs`` compilation = + compilation + |> verifyCompile + |> shouldSucceed + + // SOURCE=AttributeTargetsIsEnum01.fs # AttributeTargetsIsEnum01.fs + [] + let ``AttributeTargetsIsEnum01_fs preview`` compilation = + compilation + |> withLangVersionPreview + |> verifyCompile + |> shouldSucceed + + // SOURCE=E_AttributeTargetIsEnum01.fs # E_AttributeTargetIsEnum01.fs + [] + let ``E_AttributeTargetIsEnum01_fs`` compilation = + compilation + |> verifyCompile + |> shouldSucceed + + // SOURCE=E_AttributeTargetIsEnum01.fs # E_AttributeTargetIsEnum01.fs + [] + let ``E_AttributeTargetIsEnum01_fs preview`` compilation = + compilation + |> withLangVersionPreview + |> verifyCompile + |> shouldFail + |> withDiagnostics [ + (Error 842, Line 19, Col 3, Line 19, Col 15, "This attribute is not valid for use on this language element") + (Error 842, Line 20, Col 3, Line 20, Col 14, "This attribute is not valid for use on this language element") + (Error 842, Line 21, Col 3, Line 21, Col 18, "This attribute is not valid for use on this language element") + (Error 842, Line 22, Col 3, Line 22, Col 17, "This attribute is not valid for use on this language element") ] \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsEnum01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsEnum01.fs new file mode 100644 index 00000000000..5d8f0a81b3e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsEnum01.fs @@ -0,0 +1,26 @@ +open System + +[] +type CustomStructAttribute() = + inherit Attribute() + +[] +type CustomClassAttribute() = + inherit Attribute() + +[] +type CustomInterfaceAttribute() = + inherit Attribute() + +[] +type CustomDelegateAttribute() = + inherit Attribute() + +[] +[] +[] +[] +type Color = + | Red = 0 + | Green = 1 + | Blue = 2 \ No newline at end of file From a71a64128138f8ea6e39786cabb2890c28f85483 Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Mon, 18 Mar 2024 16:14:58 +0200 Subject: [PATCH 04/19] fix typos in two lex.fsl SR error names (lexOuside) (#16885) --- src/Compiler/FSComp.txt | 4 ++-- src/Compiler/lex.fsl | 4 ++-- src/Compiler/xlf/FSComp.txt.cs.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.de.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.es.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.fr.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.it.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ja.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ko.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.pl.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ru.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.tr.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 4 ++-- 15 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index a716fe7204c..89ec86bba00 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1033,8 +1033,8 @@ lexUnexpectedChar,"Unexpected character '%s'" 1151,lexOutsideNativeSigned,"This number is outside the allowable range for signed native integers" 1152,lexOutsideNativeUnsigned,"This number is outside the allowable range for unsigned native integers" 1153,lexInvalidFloat,"Invalid floating point number" -1154,lexOusideDecimal,"This number is outside the allowable range for decimal literals" -1155,lexOusideThirtyTwoBitFloat,"This number is outside the allowable range for 32-bit floats" +1154,lexOutsideDecimal,"This number is outside the allowable range for decimal literals" +1155,lexOutsideThirtyTwoBitFloat,"This number is outside the allowable range for 32-bit floats" 1156,lexInvalidNumericLiteral,"This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int/int32), 1u (uint/uint32), 1L (int64), 1UL (uint64), 1s (int16), 1us (uint16), 1y (int8/sbyte), 1uy (uint8/byte), 1.0 (float/double), 1.0f (float32/single), 1.0m (decimal), 1I (bigint)." 1157,lexInvalidByteLiteral,"This is not a valid byte literal" 1158,lexInvalidCharLiteral,"This is not a valid character literal" diff --git a/src/Compiler/lex.fsl b/src/Compiler/lex.fsl index 1e48cc8d0a2..cd73aa454c2 100644 --- a/src/Compiler/lex.fsl +++ b/src/Compiler/lex.fsl @@ -488,14 +488,14 @@ rule token (args: LexArgs) (skip: bool) = parse let d = System.Decimal.Parse(s,System.Globalization.NumberStyles.AllowExponent ||| System.Globalization.NumberStyles.Number,System.Globalization.CultureInfo.InvariantCulture) DECIMAL d with - e -> fail args lexbuf (FSComp.SR.lexOusideDecimal()) (DECIMAL (decimal 0)) + e -> fail args lexbuf (FSComp.SR.lexOutsideDecimal()) (DECIMAL (decimal 0)) } | xieee32 { let s = removeUnderscores (lexemeTrimRight lexbuf 2) // Even though the intermediate step is an int64, display the "invalid float" message, since it will be less confusing to the user let n64 = (try (int64 s) with _ -> fail args lexbuf (FSComp.SR.lexInvalidFloat()) 0L) - if n64 > 0xFFFFFFFFL || n64 < 0L then fail args lexbuf (FSComp.SR.lexOusideThirtyTwoBitFloat()) (IEEE32 0.0f) else + if n64 > 0xFFFFFFFFL || n64 < 0L then fail args lexbuf (FSComp.SR.lexOutsideThirtyTwoBitFloat()) (IEEE32 0.0f) else IEEE32 (System.BitConverter.ToSingle(System.BitConverter.GetBytes(int32 (uint32 (uint64 n64))),0)) } | xieee64 diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index bb150927db9..a0e72e38f55 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -6407,12 +6407,12 @@ Neplatné číslo s plovoucí desetinnou čárkou - + This number is outside the allowable range for decimal literals Toto číslo je mimo povolený rozsah pro desítkové literály. - + This number is outside the allowable range for 32-bit floats Toto číslo je mimo povolený rozsah pro 32bitové číslo s plovoucí desetinnou čárkou. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 8bde903616f..db630788fe5 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -6407,12 +6407,12 @@ Ungültige Gleitkommazahl. - + This number is outside the allowable range for decimal literals Diese Zahl liegt außerhalb des zulässigen Bereichs für Dezimalliterale. - + This number is outside the allowable range for 32-bit floats Diese Zahl liegt außerhalb des zulässigen Bereichs für 32-Bit-Gleitkommastellen. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index ff17bae30d1..64065720f63 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -6407,12 +6407,12 @@ Número de punto flotante no válido. - + This number is outside the allowable range for decimal literals Este número está fuera del intervalo permitido para literales decimales. - + This number is outside the allowable range for 32-bit floats Este número está fuera del intervalo permitido para flotantes de 32 bits. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 2006cd4a0e1..09c5ea47036 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -6407,12 +6407,12 @@ Nombre à virgule flottante non valide - + This number is outside the allowable range for decimal literals Ce nombre se trouve en dehors de la plage autorisée pour les littéraux décimaux - + This number is outside the allowable range for 32-bit floats Ce nombre se trouve en dehors de la plage autorisée pour les valeurs float 32 bits diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 70c046f57d7..eafd86fb6b6 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -6407,12 +6407,12 @@ Numero a virgola mobile non valido - + This number is outside the allowable range for decimal literals Questo numero non è compreso nell'intervallo consentito per valori letterali decimali - + This number is outside the allowable range for 32-bit floats Questo numero non è compreso nell'intervallo consentito per valori float a 32 bit diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 97d052f9bc4..acd7378d081 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -6407,12 +6407,12 @@ 浮動小数点数が無効です - + This number is outside the allowable range for decimal literals この数値は、10 進リテラルに使用できる範囲から外れています - + This number is outside the allowable range for 32-bit floats この数値は、32 ビット浮動小数点に使用できる範囲から外れています diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index edbbbc1f0ab..801acd6ae54 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -6407,12 +6407,12 @@ 부동 소수점 수가 잘못되었습니다. - + This number is outside the allowable range for decimal literals 이 숫자는 10진 리터럴에 대해 허용 가능한 범위를 벗어납니다. - + This number is outside the allowable range for 32-bit floats 이 숫자는 32비트 부동 수에 대해 허용 가능한 범위를 벗어납니다. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 4960765fa1a..a0e2d6bab57 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -6407,12 +6407,12 @@ Nieprawidłowa liczba zmiennoprzecinkowa - + This number is outside the allowable range for decimal literals Ta liczba jest poza dozwolonym zakresem literałów dziesiętnych - + This number is outside the allowable range for 32-bit floats Ta liczba jest poza dozwolonym zakresem 32-bitowych liczb zmiennoprzecinkowych diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 8ea97b7b5b1..53d88045b1f 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -6407,12 +6407,12 @@ Número do ponto flutuante inválido - + This number is outside the allowable range for decimal literals Este número está fora do intervalo permitido para literais decimais - + This number is outside the allowable range for 32-bit floats Este número está fora do intervalo permitido para floats de 32-bit diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 8793d14fbfd..8835e79c771 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -6407,12 +6407,12 @@ Недопустимое число с плавающей точкой - + This number is outside the allowable range for decimal literals Это число находится вне допустимого диапазона для десятичных литералов - + This number is outside the allowable range for 32-bit floats Это число находится вне допустимого диапазона для 32-битных чисел с плавающей точкой diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 4261665d83e..efbc5278f76 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -6407,12 +6407,12 @@ Geçersiz kayan noktalı sayı - + This number is outside the allowable range for decimal literals Bu sayı, ondalık sabit değerleri için izin verilen aralığın dışında - + This number is outside the allowable range for 32-bit floats Bu sayı, 32 bit kayan noktalı sayılar için izin verilen aralığın dışında diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index eac9a233793..eae9f70d47f 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -6407,12 +6407,12 @@ 浮点数无效 - + This number is outside the allowable range for decimal literals 此数字在允许的十进制文本范围之外 - + This number is outside the allowable range for 32-bit floats 此数字在允许的 32 位浮点数范围之外 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index e0f3f70149c..1fef6695fe5 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -6407,12 +6407,12 @@ 無效的浮點數 - + This number is outside the allowable range for decimal literals 這個數字已經超出十進位常值允許的範圍 - + This number is outside the allowable range for 32-bit floats 這個數字已經超出 32 位元浮點數允許的範圍 From 9c2bb4bb91fec98776484d339d74f27ca7ea793e Mon Sep 17 00:00:00 2001 From: Jakub Majocha <1760221+majocha@users.noreply.github.com> Date: Mon, 18 Mar 2024 16:14:11 +0100 Subject: [PATCH 05/19] Fix some possibly buggy usage of `UseDiagnosticsLogger` (#16753) --- src/Compiler/Driver/ParseAndCheckInputs.fs | 30 +++++++++++++--------- src/Compiler/Driver/fsc.fs | 6 ++--- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs index 5a23c95ca7b..bdb0d1defd6 100644 --- a/src/Compiler/Driver/ParseAndCheckInputs.fs +++ b/src/Compiler/Driver/ParseAndCheckInputs.fs @@ -1389,15 +1389,17 @@ let DiagnosticsLoggerForInput (tcConfig: TcConfig, input: ParsedInput, oldLogger /// Typecheck a single file (or interactive entry into F# Interactive) let CheckOneInputEntry (ctok, checkForErrors, tcConfig: TcConfig, tcImports, tcGlobals, prefixPathOpt) tcState input = - // Equip loggers to locally filter w.r.t. scope pragmas in each input - use _ = - UseTransformedDiagnosticsLogger(fun oldLogger -> DiagnosticsLoggerForInput(tcConfig, input, oldLogger)) + cancellable { + // Equip loggers to locally filter w.r.t. scope pragmas in each input + use _ = + UseTransformedDiagnosticsLogger(fun oldLogger -> DiagnosticsLoggerForInput(tcConfig, input, oldLogger)) - use _ = UseBuildPhase BuildPhase.TypeCheck + use _ = UseBuildPhase BuildPhase.TypeCheck - RequireCompilationThread ctok + RequireCompilationThread ctok - CheckOneInput(checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt, TcResultsSink.NoSink, tcState, input) + return! CheckOneInput(checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt, TcResultsSink.NoSink, tcState, input) + } |> Cancellable.runWithoutCancellation /// Finish checking multiple files (or one interactive entry into F# Interactive) @@ -1859,14 +1861,18 @@ let CheckMultipleInputsUsingGraphMode ((input, logger): ParsedInput * DiagnosticsLogger) ((currentTcState, _currentPriorErrors): State) : Finisher = - use _ = UseDiagnosticsLogger logger - let checkForErrors2 () = priorErrors || (logger.ErrorCount > 0) - let tcSink = TcResultsSink.NoSink let (Finisher(finisher = finisher)) = - CheckOneInputWithCallback - node - (checkForErrors2, tcConfig, tcImports, tcGlobals, prefixPathOpt, tcSink, currentTcState, input, false) + cancellable { + use _ = UseDiagnosticsLogger logger + let checkForErrors2 () = priorErrors || (logger.ErrorCount > 0) + let tcSink = TcResultsSink.NoSink + + return! + CheckOneInputWithCallback + node + (checkForErrors2, tcConfig, tcImports, tcGlobals, prefixPathOpt, tcSink, currentTcState, input, false) + } |> Cancellable.runWithoutCancellation Finisher( diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs index 014ed840222..3cebc51d10f 100644 --- a/src/Compiler/Driver/fsc.fs +++ b/src/Compiler/Driver/fsc.fs @@ -525,7 +525,7 @@ let main1 // Now install a delayed logger to hold all errors from flags until after all flags have been parsed (for example, --vserrors) let delayForFlagsLogger = CapturingDiagnosticsLogger("DelayFlagsLogger") - let _holder = UseDiagnosticsLogger delayForFlagsLogger + SetThreadDiagnosticsLoggerNoUnwind delayForFlagsLogger // Share intern'd strings across all lexing/parsing let lexResourceManager = Lexhelp.LexResourceManager() @@ -596,7 +596,7 @@ let main1 let diagnosticsLogger = diagnosticsLoggerProvider.CreateLogger(tcConfigB, exiter) // Install the global error logger and never remove it. This logger does have all command-line flags considered. - let _holder = UseDiagnosticsLogger diagnosticsLogger + SetThreadDiagnosticsLoggerNoUnwind diagnosticsLogger // Forward all errors from flags delayForFlagsLogger.CommitDelayedDiagnostics diagnosticsLogger @@ -749,7 +749,7 @@ let main2 GetDiagnosticsLoggerFilteringByScopedPragmas(true, scopedPragmas, tcConfig.diagnosticsOptions, oldLogger) - let _holder = UseDiagnosticsLogger diagnosticsLogger + SetThreadDiagnosticsLoggerNoUnwind diagnosticsLogger // Try to find an AssemblyVersion attribute let assemVerFromAttrib = From dc78363e4b642a91d0dbf8248084eeafd48b7f75 Mon Sep 17 00:00:00 2001 From: Florian Verdonck Date: Mon, 18 Mar 2024 16:40:11 +0100 Subject: [PATCH 06/19] Use TransparentCompiler cache for GetProjectOptionsFromScript (#16889) --- src/Compiler/Facilities/AsyncMemoize.fs | 2 ++ src/Compiler/Facilities/AsyncMemoize.fsi | 2 ++ src/Compiler/Service/TransparentCompiler.fs | 34 ++++++++++++------- src/Compiler/Utilities/LruCache.fs | 2 ++ src/Compiler/Utilities/LruCache.fsi | 3 ++ .../FSharpChecker/TransparentCompiler.fs | 10 ++++++ 6 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/Compiler/Facilities/AsyncMemoize.fs b/src/Compiler/Facilities/AsyncMemoize.fs index d6ae83ada6e..7e6bed533e9 100644 --- a/src/Compiler/Facilities/AsyncMemoize.fs +++ b/src/Compiler/Facilities/AsyncMemoize.fs @@ -551,6 +551,8 @@ type internal AsyncMemoize<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'T member this.OnEvent = this.Event.Add + member this.Count = cache.Count + member _.Locked = lock.Semaphore.CurrentCount < 1 member _.Running = diff --git a/src/Compiler/Facilities/AsyncMemoize.fsi b/src/Compiler/Facilities/AsyncMemoize.fsi index 1cce68cf999..9c317749464 100644 --- a/src/Compiler/Facilities/AsyncMemoize.fsi +++ b/src/Compiler/Facilities/AsyncMemoize.fsi @@ -75,6 +75,8 @@ type internal AsyncMemoize<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'T member OnEvent: ((JobEvent * (string * 'TKey * 'TVersion) -> unit) -> unit) + member Count: int + /// A drop-in replacement for AsyncMemoize that disables caching and just runs the computation every time. type internal AsyncMemoizeDisabled<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'TVersion: equality> = diff --git a/src/Compiler/Service/TransparentCompiler.fs b/src/Compiler/Service/TransparentCompiler.fs index f13b7be6d69..953c7c5dd6e 100644 --- a/src/Compiler/Service/TransparentCompiler.fs +++ b/src/Compiler/Service/TransparentCompiler.fs @@ -2151,19 +2151,27 @@ type internal TransparentCompiler optionsStamp: int64 option, userOpName: string ) : Async = - backgroundCompiler.GetProjectOptionsFromScript( - fileName, - sourceText, - previewEnabled, - loadedTimeStamp, - otherFlags, - useFsiAuxLib, - useSdkRefs, - sdkDirOverride, - assumeDotNetFramework, - optionsStamp, - userOpName - ) + async { + let bc = this :> IBackgroundCompiler + + let! snapshot, diagnostics = + bc.GetProjectSnapshotFromScript( + fileName, + SourceTextNew.ofISourceText sourceText, + previewEnabled, + loadedTimeStamp, + otherFlags, + useFsiAuxLib, + useSdkRefs, + sdkDirOverride, + assumeDotNetFramework, + optionsStamp, + userOpName + ) + + let projectOptions = snapshot.ToOptions() + return projectOptions, diagnostics + } member this.GetProjectSnapshotFromScript ( diff --git a/src/Compiler/Utilities/LruCache.fs b/src/Compiler/Utilities/LruCache.fs index 7b06292c2e2..62abc1d829c 100644 --- a/src/Compiler/Utilities/LruCache.fs +++ b/src/Compiler/Utilities/LruCache.fs @@ -277,3 +277,5 @@ type internal LruCache<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'TVers match w.TryGetTarget() with | true, value -> Some(label, version, value) | _ -> None) + + member this.Count = Seq.length (this.GetValues()) diff --git a/src/Compiler/Utilities/LruCache.fsi b/src/Compiler/Utilities/LruCache.fsi index eb2880047d7..d4d4d5ea83f 100644 --- a/src/Compiler/Utilities/LruCache.fsi +++ b/src/Compiler/Utilities/LruCache.fsi @@ -38,6 +38,9 @@ type internal LruCache<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'TVers member GetValues: unit -> (string * 'TVersion * 'TValue) seq + /// Gets the number of items in the cache + member Count: int + member Remove: key: 'TKey -> unit member Remove: key: 'TKey * version: 'TVersion -> unit diff --git a/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs b/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs index 7e78cda1704..476adb99c5d 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs +++ b/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs @@ -1011,3 +1011,13 @@ printfn "Hello from F#" ProjectWorkflowBuilder(project, useTransparentCompiler = useTransparentCompiler) { checkFile "As 01" expectTwoWarnings } + +[] +let ``Transparent Compiler ScriptClosure cache is populated after GetProjectOptionsFromScript`` () = + async { + let transparentChecker = FSharpChecker.Create(useTransparentCompiler = true) + let scriptName = Path.Combine(__SOURCE_DIRECTORY__, "script.fsx") + let content = SourceTextNew.ofString "" + let! _ = transparentChecker.GetProjectOptionsFromScript(scriptName, content) + Assert.Equal(1, transparentChecker.Caches.ScriptClosure.Count) + } From 74e336297f1140f15013ba239a504d30e95277d5 Mon Sep 17 00:00:00 2001 From: Florian Verdonck Date: Mon, 18 Mar 2024 19:18:53 +0100 Subject: [PATCH 07/19] Ensure script load closure is always executed for GetProjectSnapshotFromScript (#16880) * Ensure script load closure is always executed for GetProjectSnapshotFromScript. * assumeDotNetFramework is false for non Windows. * Update Surface Area * Check for FF in test. * Address bad merge. --- src/Compiler/Service/BackgroundCompiler.fs | 4 +- src/Compiler/Service/BackgroundCompiler.fsi | 1 + src/Compiler/Service/TransparentCompiler.fs | 193 ++++++++++++------ src/Compiler/Service/service.fs | 3 + src/Compiler/Service/service.fsi | 2 + .../FSharpChecker/TransparentCompiler.fs | 105 ++++++++++ ...ervice.SurfaceArea.netstandard20.debug.bsl | 2 +- ...vice.SurfaceArea.netstandard20.release.bsl | 2 +- 8 files changed, 249 insertions(+), 63 deletions(-) diff --git a/src/Compiler/Service/BackgroundCompiler.fs b/src/Compiler/Service/BackgroundCompiler.fs index d0af1284f14..3a9b805b676 100644 --- a/src/Compiler/Service/BackgroundCompiler.fs +++ b/src/Compiler/Service/BackgroundCompiler.fs @@ -126,6 +126,7 @@ type internal IBackgroundCompiler = abstract GetProjectSnapshotFromScript: fileName: string * sourceText: ISourceTextNew * + documentSource: DocumentSource * previewEnabled: bool option * loadedTimeStamp: System.DateTime option * otherFlags: string array option * @@ -1627,6 +1628,7 @@ type internal BackgroundCompiler ( fileName: string, sourceText: ISourceTextNew, + documentSource: DocumentSource, previewEnabled: bool option, loadedTimeStamp: DateTime option, otherFlags: string array option, @@ -1653,7 +1655,7 @@ type internal BackgroundCompiler userOpName ) - let! snapshot = FSharpProjectSnapshot.FromOptions(options, DocumentSource.FileSystem) + let! snapshot = FSharpProjectSnapshot.FromOptions(options, documentSource) return snapshot, diagnostics } diff --git a/src/Compiler/Service/BackgroundCompiler.fsi b/src/Compiler/Service/BackgroundCompiler.fsi index fff6324be35..498e2a5102e 100644 --- a/src/Compiler/Service/BackgroundCompiler.fsi +++ b/src/Compiler/Service/BackgroundCompiler.fsi @@ -105,6 +105,7 @@ type internal IBackgroundCompiler = abstract GetProjectSnapshotFromScript: fileName: string * sourceText: ISourceTextNew * + documentSource: DocumentSource * previewEnabled: bool option * loadedTimeStamp: System.DateTime option * otherFlags: string array option * diff --git a/src/Compiler/Service/TransparentCompiler.fs b/src/Compiler/Service/TransparentCompiler.fs index 953c7c5dd6e..e206971eaad 100644 --- a/src/Compiler/Service/TransparentCompiler.fs +++ b/src/Compiler/Service/TransparentCompiler.fs @@ -376,6 +376,76 @@ type internal TransparentCompiler ) :> IBackgroundCompiler + let ComputeScriptClosureInner + (fileName: string) + (source: ISourceTextNew) + (defaultFSharpBinariesDir: string) + (useSimpleResolution: bool) + (useFsiAuxLib: bool) + (useSdkRefs: bool) + (sdkDirOverride: string option) + (assumeDotNetFramework: bool) + (otherOptions: string list) + = + let reduceMemoryUsage = ReduceMemoryFlag.Yes + + let applyCompilerOptions tcConfig = + let fsiCompilerOptions = GetCoreFsiCompilerOptions tcConfig + ParseCompilerOptions(ignore, fsiCompilerOptions, otherOptions) + + let closure = + LoadClosure.ComputeClosureOfScriptText( + legacyReferenceResolver, + defaultFSharpBinariesDir, + fileName, + source, + CodeContext.Editing, + useSimpleResolution, + useFsiAuxLib, + useSdkRefs, + sdkDirOverride, + Lexhelp.LexResourceManager(), + applyCompilerOptions, + assumeDotNetFramework, + tryGetMetadataSnapshot, + reduceMemoryUsage, + dependencyProviderForScripts + ) + + closure + + let mkScriptClosureCacheKey + (fileName: string) + (source: ISourceTextNew) + (useSimpleResolution: bool) + (useFsiAuxLib: bool) + (useSdkRefs: bool) + (assumeDotNetFramework: bool) + (projectIdentifier: ProjectIdentifier) + (otherOptions: string list) + (stamp: int64 option) + = + { new ICacheKey with + member _.GetKey() = fileName, projectIdentifier + member _.GetLabel() = $"ScriptClosure for %s{fileName}" + + member _.GetVersion() = + Md5Hasher.empty + |> Md5Hasher.addStrings + [| + yield! otherOptions + match stamp with + | None -> () + | Some stamp -> string stamp + |] + |> Md5Hasher.addBytes (source.GetChecksum().ToArray()) + |> Md5Hasher.addBool useSimpleResolution + |> Md5Hasher.addBool useFsiAuxLib + |> Md5Hasher.addBool useSdkRefs + |> Md5Hasher.addBool assumeDotNetFramework + |> Md5Hasher.toString + } + let ComputeScriptClosure (fileName: string) (source: ISourceTextNew) @@ -393,57 +463,32 @@ type internal TransparentCompiler let useSdkRefs = defaultArg useSdkRefs true let assumeDotNetFramework = defaultArg assumeDotNetFramework false - let key = - { new ICacheKey with - member _.GetKey() = fileName, projectIdentifier - member _.GetLabel() = $"ScriptClosure for %s{fileName}" - - member _.GetVersion() = - Md5Hasher.empty - |> Md5Hasher.addStrings - [| - yield! otherOptions - match stamp with - | None -> () - | Some stamp -> string stamp - |] - |> Md5Hasher.addBytes (source.GetChecksum().ToArray()) - |> Md5Hasher.addBool useFsiAuxLib - |> Md5Hasher.addBool useFsiAuxLib - |> Md5Hasher.addBool useSdkRefs - |> Md5Hasher.addBool assumeDotNetFramework - |> Md5Hasher.toString - } + let key: ICacheKey = + mkScriptClosureCacheKey + fileName + source + useSimpleResolution + useFsiAuxLib + useSdkRefs + assumeDotNetFramework + projectIdentifier + otherOptions + stamp caches.ScriptClosure.Get( key, node { - let reduceMemoryUsage = ReduceMemoryFlag.Yes - - let applyCompilerOptions tcConfig = - let fsiCompilerOptions = GetCoreFsiCompilerOptions tcConfig - ParseCompilerOptions(ignore, fsiCompilerOptions, otherOptions) - - let closure = - LoadClosure.ComputeClosureOfScriptText( - legacyReferenceResolver, - defaultFSharpBinariesDir, - fileName, - source, - CodeContext.Editing, - useSimpleResolution, - useFsiAuxLib, - useSdkRefs, - sdkDirOverride, - Lexhelp.LexResourceManager(), - applyCompilerOptions, - assumeDotNetFramework, - tryGetMetadataSnapshot, - reduceMemoryUsage, - dependencyProviderForScripts - ) - - return closure + return + ComputeScriptClosureInner + fileName + source + defaultFSharpBinariesDir + useSimpleResolution + useFsiAuxLib + useSdkRefs + sdkDirOverride + assumeDotNetFramework + otherOptions } ) @@ -676,8 +721,13 @@ type internal TransparentCompiler (getSwitchValue useSimpleResolutionSwitch) |> Option.isSome let! (loadClosureOpt: LoadClosure option) = - match projectSnapshot.SourceFiles, projectSnapshot.UseScriptResolutionRules with - | [ fsxFile ], true -> // assuming UseScriptResolutionRules and a single source file means we are doing this for a script + let lastScriptFile = + match List.tryLast projectSnapshot.SourceFiles with + | None -> None + | Some file -> if IsScript file.FileName then Some file else None + + match lastScriptFile, projectSnapshot.UseScriptResolutionRules with + | Some fsxFile, true -> // assuming UseScriptResolutionRules and a single source file means we are doing this for a script node { let! source = fsxFile.GetSource() |> NodeCode.AwaitTask @@ -2158,6 +2208,7 @@ type internal TransparentCompiler bc.GetProjectSnapshotFromScript( fileName, SourceTextNew.ofISourceText sourceText, + DocumentSource.FileSystem, previewEnabled, loadedTimeStamp, otherFlags, @@ -2177,6 +2228,7 @@ type internal TransparentCompiler ( fileName: string, sourceText: ISourceTextNew, + documentSource: DocumentSource, previewEnabled: bool option, loadedTimeStamp: DateTime option, otherFlags: string array option, @@ -2199,7 +2251,8 @@ type internal TransparentCompiler let previewEnabled = defaultArg previewEnabled false // Do we assume .NET Framework references for scripts? - let assumeDotNetFramework = defaultArg assumeDotNetFramework true + // No, because the bootstrap info call also doesn't + let assumeDotNetFramework = defaultArg assumeDotNetFramework false let extraFlags = if previewEnabled then @@ -2219,20 +2272,22 @@ type internal TransparentCompiler let currentSourceFile = FSharpFileSnapshot.Create(fileName, sourceText.GetHashCode().ToString(), (fun () -> Task.FromResult sourceText)) - let! loadClosure = - ComputeScriptClosure + let otherFlags = List.ofArray otherFlags + + // Always perform the load closure as we cannot be sure that the incoming file does not load any new additional files. + // Consider the scenario where a.fsx loads b.fsx. Based purely on a.fsx, we cannot know if b.fsx loads another file. + // Therefore we cannot rely on any caching for the script closure in this API. + let loadClosure = + ComputeScriptClosureInner fileName sourceText FSharpCheckerResultsSettings.defaultFSharpBinariesDir useSimpleResolution - (Some useFsiAuxLib) - (Some useSdkRefs) + useFsiAuxLib + useSdkRefs sdkDirOverride - (Some assumeDotNetFramework) - (projectFileName, fileName) - (List.ofArray otherFlags) - optionsStamp - |> Async.AwaitNodeCode + assumeDotNetFramework + otherFlags let otherFlags = [ @@ -2243,13 +2298,31 @@ type internal TransparentCompiler yield "--nowarn:" + code ] + // Once we do have the script closure, we can populate the cache to re-use can later. + let loadClosureKey = + mkScriptClosureCacheKey + fileName + sourceText + useSimpleResolution + useFsiAuxLib + useSdkRefs + assumeDotNetFramework + (projectFileName, "") + otherFlags + optionsStamp + + // Populate the cache. + let! _ = + caches.ScriptClosure.Get(loadClosureKey, node { return loadClosure }) + |> Async.AwaitNodeCode + let sourceFiles = loadClosure.SourceFiles |> List.map (fun (sf, _) -> if sf = fileName then currentSourceFile else - FSharpFileSnapshot.CreateFromFileSystem sf) + FSharpFileSnapshot.CreateFromDocumentSource(sf, documentSource)) let references = loadClosure.References diff --git a/src/Compiler/Service/service.fs b/src/Compiler/Service/service.fs index 103c84e63cf..093a692f1ec 100644 --- a/src/Compiler/Service/service.fs +++ b/src/Compiler/Service/service.fs @@ -566,6 +566,7 @@ type FSharpChecker ( fileName, source, + ?documentSource, ?previewEnabled, ?loadedTimeStamp, ?otherFlags, @@ -577,10 +578,12 @@ type FSharpChecker ?userOpName: string ) = let userOpName = defaultArg userOpName "Unknown" + let documentSource = defaultArg documentSource DocumentSource.FileSystem backgroundCompiler.GetProjectSnapshotFromScript( fileName, source, + documentSource, previewEnabled, loadedTimeStamp, otherFlags, diff --git a/src/Compiler/Service/service.fsi b/src/Compiler/Service/service.fsi index 71e0f51df3d..a15c208c26c 100644 --- a/src/Compiler/Service/service.fsi +++ b/src/Compiler/Service/service.fsi @@ -253,6 +253,7 @@ type public FSharpChecker = /// Used to differentiate between scripts, to consider each script a separate project. Also used in formatted error messages. /// The source for the file. + /// DocumentSource to load any additional files. /// Is the preview compiler enabled. /// Indicates when the script was loaded into the editing environment, /// so that an 'unload' and 'reload' action will cause the script to be considered as a new project, @@ -268,6 +269,7 @@ type public FSharpChecker = member GetProjectSnapshotFromScript: fileName: string * source: ISourceTextNew * + ?documentSource: DocumentSource * ?previewEnabled: bool * ?loadedTimeStamp: DateTime * ?otherFlags: string[] * diff --git a/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs b/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs index 476adb99c5d..c7e7777fd98 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs +++ b/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs @@ -3,6 +3,7 @@ open System.Collections.Concurrent open System.Diagnostics open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.IO open FSharp.Compiler.Text open Internal.Utilities.Collections open FSharp.Compiler.CodeAnalysis.TransparentCompiler @@ -1020,4 +1021,108 @@ let ``Transparent Compiler ScriptClosure cache is populated after GetProjectOpti let content = SourceTextNew.ofString "" let! _ = transparentChecker.GetProjectOptionsFromScript(scriptName, content) Assert.Equal(1, transparentChecker.Caches.ScriptClosure.Count) + } + +type private LoadClosureTestShim(currentFileSystem: IFileSystem) = + inherit DefaultFileSystem() + let mutable bDidUpdate = false + let asStream (v:string) = new MemoryStream(System.Text.Encoding.UTF8.GetBytes v) + let knownFiles = set [ "a.fsx"; "b.fsx"; "c.fsx" ] + + member val aFsx = "#load \"b.fsx\"" + member val bFsxInitial = "" + member val bFsxUpdate = "#load \"c.fsx\"" + member val cFsx = "" + + member x.DocumentSource (fileName: string) = + async { + if not (knownFiles.Contains fileName) then + return None + else + match fileName with + | "a.fsx" -> return Some (SourceText.ofString x.aFsx) + | "b.fsx" -> return Some (SourceText.ofString (if bDidUpdate then x.bFsxUpdate else x.bFsxInitial)) + | "c.fsx" -> return Some (SourceText.ofString x.cFsx) + | _ -> return None + } + + member x.UpdateB () = bDidUpdate <- true + + override _.FileExistsShim(path) = + if knownFiles.Contains path then true else currentFileSystem.FileExistsShim(path) + override _.GetFullPathShim(fileName) = + if knownFiles.Contains fileName then fileName else currentFileSystem.GetFullPathShim(fileName) + override x.OpenFileForReadShim(fileName, ?useMemoryMappedFile: bool, ?shouldShadowCopy: bool) = + match fileName with + | "a.fsx" -> asStream x.aFsx + | "b.fsx" -> asStream (if bDidUpdate then x.bFsxUpdate else x.bFsxInitial) + | "c.fsx" -> asStream x.cFsx + | _ -> + currentFileSystem.OpenFileForReadShim( + fileName, + ?useMemoryMappedFile = useMemoryMappedFile, + ?shouldShadowCopy = shouldShadowCopy + ) + +[] +[] +[] +let ``The script load closure should always be evaluated`` useTransparentCompiler = + async { + // The LoadScriptClosure uses the file system shim so we need to reset that. + let currentFileSystem = FileSystemAutoOpens.FileSystem + let assumeDotNetFramework = + // The old BackgroundCompiler uses assumeDotNetFramework = true + // This is not always correctly loading when this test runs on non-Windows. + if System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription.StartsWith(".NET Framework") then + None + else + Some false + + try + let checker = FSharpChecker.Create(useTransparentCompiler = useTransparentCompiler) + let fileSystemShim = LoadClosureTestShim(currentFileSystem) + // Override the file system shim for loading b.fsx + FileSystem <- fileSystemShim + + let! initialSnapshot, _ = + checker.GetProjectSnapshotFromScript( + "a.fsx", + SourceTextNew.ofString fileSystemShim.aFsx, + documentSource = DocumentSource.Custom fileSystemShim.DocumentSource, + ?assumeDotNetFramework = assumeDotNetFramework + ) + + // File b.fsx should also be included in the snapshot. + Assert.Equal(2, initialSnapshot.SourceFiles.Length) + + let! checkResults = checker.ParseAndCheckFileInProject("a.fsx", initialSnapshot) + + match snd checkResults with + | FSharpCheckFileAnswer.Aborted -> failwith "Did not expected FSharpCheckFileAnswer.Aborted" + | FSharpCheckFileAnswer.Succeeded checkFileResults -> Assert.Equal(0, checkFileResults.Diagnostics.Length) + + // Update b.fsx, it should now load c.fsx + fileSystemShim.UpdateB() + + // The constructed key for the load closure will the exactly the same as the first GetProjectSnapshotFromScript call. + // However, a none cached version will be computed first in GetProjectSnapshotFromScript and update the cache afterwards. + let! secondSnapshot, _ = + checker.GetProjectSnapshotFromScript( + "a.fsx", + SourceTextNew.ofString fileSystemShim.aFsx, + documentSource = DocumentSource.Custom fileSystemShim.DocumentSource, + ?assumeDotNetFramework = assumeDotNetFramework + ) + + Assert.Equal(3, secondSnapshot.SourceFiles.Length) + + let! checkResults = checker.ParseAndCheckFileInProject("a.fsx", secondSnapshot) + + match snd checkResults with + | FSharpCheckFileAnswer.Aborted -> failwith "Did not expected FSharpCheckFileAnswer.Aborted" + | FSharpCheckFileAnswer.Succeeded checkFileResults -> Assert.Equal(0, checkFileResults.Diagnostics.Length) + finally + FileSystemAutoOpens.FileSystem <- currentFileSystem + } \ No newline at end of file diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl index 9dda7f12180..ccebabe8695 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl @@ -2067,7 +2067,7 @@ FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults,FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer]] ParseAndCheckFileInProject(System.String, Int32, FSharp.Compiler.Text.ISourceText, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults,FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults]] GetBackgroundCheckResultsForFileInProject(System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectOptionsFromScript(System.String, FSharp.Compiler.Text.ISourceText, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String]) -FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.ProjectSnapshot+FSharpProjectSnapshot,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectSnapshotFromScript(System.String, FSharp.Compiler.Text.ISourceTextNew, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.ProjectSnapshot+FSharpProjectSnapshot,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectSnapshotFromScript(System.String, FSharp.Compiler.Text.ISourceTextNew, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.DocumentSource], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],System.Int32]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, FSharp.Compiler.Text.ISourceText, FSharp.Compiler.CodeAnalysis.FSharpParsingOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl index 9dda7f12180..ccebabe8695 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl @@ -2067,7 +2067,7 @@ FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults,FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer]] ParseAndCheckFileInProject(System.String, Int32, FSharp.Compiler.Text.ISourceText, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults,FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults]] GetBackgroundCheckResultsForFileInProject(System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectOptionsFromScript(System.String, FSharp.Compiler.Text.ISourceText, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String]) -FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.ProjectSnapshot+FSharpProjectSnapshot,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectSnapshotFromScript(System.String, FSharp.Compiler.Text.ISourceTextNew, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.ProjectSnapshot+FSharpProjectSnapshot,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectSnapshotFromScript(System.String, FSharp.Compiler.Text.ISourceTextNew, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.DocumentSource], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],System.Int32]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, FSharp.Compiler.Text.ISourceText, FSharp.Compiler.CodeAnalysis.FSharpParsingOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) From 6b7aa6e05c64bc9d2285a7291be5d70d59c5f832 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Mon, 18 Mar 2024 20:13:09 +0100 Subject: [PATCH 08/19] Parser: more 'as' pattern recovery (#16837) * Parser: more 'as' pattern recovery * Release notes --------- Co-authored-by: Petr --- .../.FSharp.Compiler.Service/8.0.300.md | 1 + src/Compiler/pars.fsy | 6 +++++ .../data/SyntaxTree/Pattern/As 02.fs.bsl | 2 +- .../data/SyntaxTree/Pattern/As 05.fs.bsl | 4 +-- .../data/SyntaxTree/Pattern/As 08.fs.bsl | 2 +- .../data/SyntaxTree/Pattern/As 10.fs.bsl | 2 +- .../service/data/SyntaxTree/Pattern/As 12.fs | 6 +++++ .../data/SyntaxTree/Pattern/As 12.fs.bsl | 26 +++++++++++++++++++ 8 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 tests/service/data/SyntaxTree/Pattern/As 12.fs create mode 100644 tests/service/data/SyntaxTree/Pattern/As 12.fs.bsl diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index e68afa41dc8..d5dc02e051e 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -31,6 +31,7 @@ * Add switch to generate types and members with IL visibility that accurately represents their F# visibility. ([PR #15484](https://github.com/dotnet/fsharp/pull/15484) * Allow returning bool instead of unit option for partial active patterns. ([Language suggestion #1041](https://github.com/fsharp/fslang-suggestions/issues/1041), [PR #16473](https://github.com/dotnet/fsharp/pull/16473)) * Symbols: Add GenericArguments to FSharpEntity ([PR #16470](https://github.com/dotnet/fsharp/pull/16470)) +* Parser: more 'as' pattern recovery ([PR #16837](https://github.com/dotnet/fsharp/pull/16837)) * Add extended data for `DefinitionsInSigAndImplNotCompatibleAbbreviationsDiffer` (FS0318). ([PR #16811](https://github.com/dotnet/fsharp/pull/16811))) ### Changed diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index b33d55722a5..73fcdaf17e6 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -3719,6 +3719,12 @@ parenPattern: let pat2 = SynPat.Wild(mAs.EndRange) SynPat.As($1, pat2, rhs2 parseState 1 2) } + | parenPattern AS + { let mAs = rhs parseState 2 + let pat2 = SynPat.Wild(mAs.EndRange) + reportParseErrorAt mAs (FSComp.SR.parsExpectingPattern ()) + SynPat.As($1, pat2, rhs2 parseState 1 2) } + | parenPattern BAR parenPattern { let mBar = rhs parseState 2 SynPat.Or($1, $3, rhs2 parseState 1 3, { BarRange = mBar }) } diff --git a/tests/service/data/SyntaxTree/Pattern/As 02.fs.bsl b/tests/service/data/SyntaxTree/Pattern/As 02.fs.bsl index a39bda6bb7c..dc9ff5caae9 100644 --- a/tests/service/data/SyntaxTree/Pattern/As 02.fs.bsl +++ b/tests/service/data/SyntaxTree/Pattern/As 02.fs.bsl @@ -21,4 +21,4 @@ ImplFile { ConditionalDirectives = [] CodeComments = [] }, set [])) -(4,7)-(4,9) parse error Unexpected symbol '->' in pattern +(4,4)-(4,6) parse error Expecting pattern diff --git a/tests/service/data/SyntaxTree/Pattern/As 05.fs.bsl b/tests/service/data/SyntaxTree/Pattern/As 05.fs.bsl index 1e26e340c11..07a1aac463e 100644 --- a/tests/service/data/SyntaxTree/Pattern/As 05.fs.bsl +++ b/tests/service/data/SyntaxTree/Pattern/As 05.fs.bsl @@ -21,5 +21,5 @@ ImplFile { ConditionalDirectives = [] CodeComments = [] }, set [])) -(5,0)-(5,0) parse error Incomplete structured construct at or before this point in pattern -(3,13)-(3,17) parse error Unexpected end of input in 'match' or 'try' expression +(4,4)-(4,6) parse error Expecting pattern +(5,0)-(5,0) parse error Incomplete structured construct at or before this point in pattern matching. Expected '->' or other token. diff --git a/tests/service/data/SyntaxTree/Pattern/As 08.fs.bsl b/tests/service/data/SyntaxTree/Pattern/As 08.fs.bsl index 48501827087..bfe069db512 100644 --- a/tests/service/data/SyntaxTree/Pattern/As 08.fs.bsl +++ b/tests/service/data/SyntaxTree/Pattern/As 08.fs.bsl @@ -20,4 +20,4 @@ ImplFile { ConditionalDirectives = [] CodeComments = [] }, set [])) -(5,0)-(5,1) parse error Unexpected symbol '|' in pattern +(4,4)-(4,6) parse error Expecting pattern diff --git a/tests/service/data/SyntaxTree/Pattern/As 10.fs.bsl b/tests/service/data/SyntaxTree/Pattern/As 10.fs.bsl index 2b44d412f46..384bd2c6d06 100644 --- a/tests/service/data/SyntaxTree/Pattern/As 10.fs.bsl +++ b/tests/service/data/SyntaxTree/Pattern/As 10.fs.bsl @@ -22,4 +22,4 @@ ImplFile { ConditionalDirectives = [] CodeComments = [] }, set [])) -(3,10)-(3,11) parse error Unexpected symbol ')' in pattern +(3,7)-(3,9) parse error Expecting pattern diff --git a/tests/service/data/SyntaxTree/Pattern/As 12.fs b/tests/service/data/SyntaxTree/Pattern/As 12.fs new file mode 100644 index 00000000000..be8217acbd0 --- /dev/null +++ b/tests/service/data/SyntaxTree/Pattern/As 12.fs @@ -0,0 +1,6 @@ +module Module + +match a with +| :? T as + +() diff --git a/tests/service/data/SyntaxTree/Pattern/As 12.fs.bsl b/tests/service/data/SyntaxTree/Pattern/As 12.fs.bsl new file mode 100644 index 00000000000..f77b92aba46 --- /dev/null +++ b/tests/service/data/SyntaxTree/Pattern/As 12.fs.bsl @@ -0,0 +1,26 @@ +ImplFile + (ParsedImplFileInput + ("/root/Pattern/As 12.fs", false, QualifiedNameOfFile Module, [], [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Expr + (Match + (Yes (3,0--3,12), Ident a, + [SynMatchClause + (As + (IsInst + (LongIdent (SynLongIdent ([T], [], [None])), + (4,2--4,6)), Wild (4,9--4,9), (4,2--4,9)), None, + ArbitraryAfterError ("patternClauses2", (4,9--4,9)), + (4,2--4,9), Yes, { ArrowRange = None + BarRange = Some (4,0--4,1) })], + (3,0--4,9), { MatchKeyword = (3,0--3,5) + WithKeyword = (3,8--3,12) }), (3,0--4,9)); + Expr (Const (Unit, (6,0--6,2)), (6,0--6,2))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--6,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(4,7)-(4,9) parse error Expecting pattern +(6,0)-(6,1) parse error Incomplete structured construct at or before this point in pattern matching. Expected '->' or other token. From 5a19ccfe5dd6693960ab855a84927bec9831d6ff Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Tue, 19 Mar 2024 12:40:35 +0000 Subject: [PATCH 09/19] Delegates allowed to target AttributeTargets.Class AttributeTargets.Struct AttributeTargets.Interface incorrectly (#16891) --- .../.FSharp.Compiler.Service/8.0.300.md | 1 + docs/release-notes/.FSharp.Core/8.0.300.md | 3 +- src/Compiler/Checking/CheckDeclarations.fs | 5 ++- src/FSharp.Core/prim-types.fs | 3 +- src/FSharp.Core/prim-types.fsi | 2 +- .../AttributeTargetsIsDelegate01.fs | 8 +++++ .../AttributeUsage/AttributeUsage.fs | 36 +++++++++++++++++++ .../E_AttributeTargetIsDelegate01.fs | 23 ++++++++++++ 8 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsDelegate01.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsDelegate01.fs diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index d5dc02e051e..dde1ee4031f 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -21,6 +21,7 @@ * Parser: fix pattern range for idents with trivia ([PR #16824](https://github.com/dotnet/fsharp/pull/16824)) * Fix broken code completion after a record type declaration ([PR #16813](https://github.com/dotnet/fsharp/pull/16813)) * Enforce AttributeTargets on enums ([PR #16887](https://github.com/dotnet/fsharp/pull/16887)) +* Enforce AttributeTargets on delegates ([PR #16891](https://github.com/dotnet/fsharp/pull/16891)) ### Added diff --git a/docs/release-notes/.FSharp.Core/8.0.300.md b/docs/release-notes/.FSharp.Core/8.0.300.md index d4d7036b296..f1f8588d65b 100644 --- a/docs/release-notes/.FSharp.Core/8.0.300.md +++ b/docs/release-notes/.FSharp.Core/8.0.300.md @@ -7,4 +7,5 @@ * Preserve original stack traces in resumable state machines generated code if available. ([PR #16568](https://github.com/dotnet/fsharp/pull/16568)) * Enforce AttributeTargets on structs and classes. Also update `RequireQualifiedAccessAttribute` and `AutoOpenAttribute` to use `AttributeTargets.Struct` ([PR #16790](https://github.com/dotnet/fsharp/pull/16790)) -* Enforce AttributeTargets on enums. Also update `RequireQualifiedAccessAttribute` to use `AttributeTargets.Enum` ([PR #16887](https://github.com/dotnet/fsharp/pull/16887)) \ No newline at end of file +* Enforce AttributeTargets on enums. Also update `RequireQualifiedAccessAttribute` to use `AttributeTargets.Enum` ([PR #16887](https://github.com/dotnet/fsharp/pull/16887)) +* Enforce AttributeTargets on delegates. Also update `ReflectedDefinitionAttribute` to use `AttributeTargets.Delegate` ([PR #16891](https://github.com/dotnet/fsharp/pull/16891)) \ No newline at end of file diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 501d7927ec2..d64c1b648f5 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -2931,7 +2931,10 @@ module EstablishTypeDefinitionCores = TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Class synAttrs |> ignore TFSharpClass | SynTypeDefnKind.Interface -> TFSharpInterface - | SynTypeDefnKind.Delegate _ -> TFSharpDelegate (MakeSlotSig("Invoke", g.unit_ty, [], [], [], None)) + | SynTypeDefnKind.Delegate _ -> + if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) then + TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Delegate synAttrs |> ignore + TFSharpDelegate (MakeSlotSig("Invoke", g.unit_ty, [], [], [], None)) | SynTypeDefnKind.Struct -> if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) then TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Struct synAttrs |> ignore diff --git a/src/FSharp.Core/prim-types.fs b/src/FSharp.Core/prim-types.fs index 2eca8c20333..245a83380f5 100644 --- a/src/FSharp.Core/prim-types.fs +++ b/src/FSharp.Core/prim-types.fs @@ -163,7 +163,8 @@ namespace Microsoft.FSharp.Core [] + AttributeTargets.Property ||| AttributeTargets.Constructor ||| + AttributeTargets.Delegate, AllowMultiple=false)>] [] type ReflectedDefinitionAttribute(includeValue: bool) = inherit Attribute() diff --git a/src/FSharp.Core/prim-types.fsi b/src/FSharp.Core/prim-types.fsi index 3e88abdea32..e7ceb9b6166 100644 --- a/src/FSharp.Core/prim-types.fsi +++ b/src/FSharp.Core/prim-types.fsi @@ -129,7 +129,7 @@ namespace Microsoft.FSharp.Core /// for use at runtime. /// /// Attributes - [] + [] [] type ReflectedDefinitionAttribute = inherit Attribute diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsDelegate01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsDelegate01.fs new file mode 100644 index 00000000000..1fa686c1666 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsDelegate01.fs @@ -0,0 +1,8 @@ +open System + +[] +type CustomDelegateAttribute() = + inherit Attribute() + +[] +type Delegate1 = delegate of int -> int diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs index 15851371cb5..71cc1266dd4 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs @@ -555,4 +555,40 @@ module CustomAttributes_AttributeUsage = (Error 842, Line 20, Col 3, Line 20, Col 14, "This attribute is not valid for use on this language element") (Error 842, Line 21, Col 3, Line 21, Col 18, "This attribute is not valid for use on this language element") (Error 842, Line 22, Col 3, Line 22, Col 17, "This attribute is not valid for use on this language element") + ] + + // SOURCE=AttributeTargetsIsDelegate01.fs # AttributeTargetsIsDelegate01.fs + [] + let ``AttributeTargetsIsDelegate01_fs`` compilation = + compilation + |> verifyCompile + |> shouldSucceed + + // SOURCE=AttributeTargetsIsDelegate01.fs # AttributeTargetsIsDelegate01.fs + [] + let ``AttributeTargetsIsDelegate01_fs preview`` compilation = + compilation + |> withLangVersionPreview + |> verifyCompile + |> shouldSucceed + + // SOURCE=E_AttributeTargetIsDelegate01.fs # E_AttributeTargetIsDelegate01.fs + [] + let ``E_AttributeTargetIsDelegate01_fs`` compilation = + compilation + |> verifyCompile + |> shouldSucceed + + // SOURCE=E_AttributeTargetIsDelegate01.fs # E_AttributeTargetIsDelegate01.fs + [] + let ``E_AttributeTargetsIsDelegate01_fs preview`` compilation = + compilation + |> withLangVersionPreview + |> verifyCompile + |> shouldFail + |> withDiagnostics [ + (Error 842, Line 19, Col 3, Line 19, Col 14, "This attribute is not valid for use on this language element") + (Error 842, Line 20, Col 3, Line 20, Col 15, "This attribute is not valid for use on this language element") + (Error 842, Line 21, Col 3, Line 21, Col 18, "This attribute is not valid for use on this language element") + (Error 842, Line 22, Col 3, Line 22, Col 13, "This attribute is not valid for use on this language element") ] \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsDelegate01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsDelegate01.fs new file mode 100644 index 00000000000..0ea6a74827a --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsDelegate01.fs @@ -0,0 +1,23 @@ +open System + +[] +type CustomClassAttribute() = + inherit Attribute() + +[] +type CustomStructAttribute() = + inherit Attribute() + +[] +type CustomInterfaceAttribute() = + inherit Attribute() + +[] +type CustomEnumAttribute() = + inherit Attribute() + +[] +[] +[] +[] +type Delegate1 = delegate of int -> int \ No newline at end of file From b3536885087cf3c131b9db18f949acdb1fb33e1c Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Tue, 19 Mar 2024 16:02:02 +0100 Subject: [PATCH 10/19] Completion: fix for unfinished record field decl (#16893) * Completion: fix for unfinished record field decl * Fantomas * Release notes --- docs/release-notes/.FSharp.Compiler.Service/8.0.300.md | 2 ++ src/Compiler/Service/ServiceParsedInputOps.fs | 7 ++++--- tests/service/CompletionTests.fs | 9 ++++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index dde1ee4031f..b5a86a6540f 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -21,8 +21,10 @@ * Parser: fix pattern range for idents with trivia ([PR #16824](https://github.com/dotnet/fsharp/pull/16824)) * Fix broken code completion after a record type declaration ([PR #16813](https://github.com/dotnet/fsharp/pull/16813)) * Enforce AttributeTargets on enums ([PR #16887](https://github.com/dotnet/fsharp/pull/16887)) +* Completion: fix for unfinished record field decl ([PR #16893](https://github.com/dotnet/fsharp/pull/16893)) * Enforce AttributeTargets on delegates ([PR #16891](https://github.com/dotnet/fsharp/pull/16891)) + ### Added * The stackguard depth for ILPdbWriter.unshadowScopes can be modified via the environment variable `FSHARP_ILPdb_UnshadowScopes_StackGuardDepth`([PR #16583](https://github.com/dotnet/fsharp/pull/16583)) diff --git a/src/Compiler/Service/ServiceParsedInputOps.fs b/src/Compiler/Service/ServiceParsedInputOps.fs index 90062e81c68..d739526a025 100644 --- a/src/Compiler/Service/ServiceParsedInputOps.fs +++ b/src/Compiler/Service/ServiceParsedInputOps.fs @@ -1646,11 +1646,12 @@ module ParsedInput = member _.VisitRecordDefn(_, fields, range) = fields - |> List.tryPick (fun (SynField(idOpt = idOpt; range = fieldRange)) -> - match idOpt with - | Some id when rangeContainsPos id.idRange pos -> + |> List.tryPick (fun (SynField(idOpt = idOpt; range = fieldRange; fieldType = fieldType)) -> + match idOpt, fieldType with + | Some id, _ when rangeContainsPos id.idRange pos -> Some(CompletionContext.RecordField(RecordContext.Declaration true)) | _ when rangeContainsPos fieldRange pos -> Some(CompletionContext.RecordField(RecordContext.Declaration false)) + | _, SynType.FromParseError _ -> Some(CompletionContext.RecordField(RecordContext.Declaration false)) | _ -> None) // No completions in a record outside of all fields, except in attributes, which is established earlier in VisitAttributeApplication |> Option.orElseWith (fun _ -> diff --git a/tests/service/CompletionTests.fs b/tests/service/CompletionTests.fs index f973c434377..c3859e0b82f 100644 --- a/tests/service/CompletionTests.fs +++ b/tests/service/CompletionTests.fs @@ -80,4 +80,11 @@ let ``Underscore dot lambda - method completion`` () = let myFancyFunc (x:string) = x |> _.ToL""" - assertHasItemWithNames ["ToLower"] info \ No newline at end of file + assertHasItemWithNames ["ToLower"] info + +[] +let ``Type decl - Record - Field type 01`` () = + let info = getCompletionInfo "type Record = { Field: }" (2, 23) """ +type Record = { Field: } +""" + assertHasItemWithNames ["string"] info From 696c1a52c8a1d8bd8c98817703165fc91b1a96aa Mon Sep 17 00:00:00 2001 From: Vlad Zarytovskii Date: Tue, 19 Mar 2024 16:48:05 +0100 Subject: [PATCH 11/19] Don't link work items to insertion (#16898) It's not useful for us since it doesn't cross azdo<->gh boundaries. --- eng/release/insert-into-vs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/release/insert-into-vs.yml b/eng/release/insert-into-vs.yml index e15b691f59a..64b8ab7242b 100644 --- a/eng/release/insert-into-vs.yml +++ b/eng/release/insert-into-vs.yml @@ -73,5 +73,5 @@ stages: - task: ms-vseng.MicroBuildShipTasks.55100717-a81d-45ea-a363-b8fe3ec375ad.MicroBuildInsertVsPayload@3 displayName: 'Insert VS Payload' inputs: - LinkWorkItemsToPR: true + LinkWorkItemsToPR: false condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], '${{ parameters.componentBranchName }}'), eq(variables['Build.SourceBranch'], 'refs/heads/${{ parameters.componentBranchName }}'))) From 43b71400f955957dd12c237a24ec94bab07b3fe6 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Tue, 19 Mar 2024 17:12:48 +0100 Subject: [PATCH 12/19] Parser: more unfinished member recovery (#16835) * Parser: more unfinished member recovery * Release notes * Update test baselines * Undo commit * Update test baselines * Revert --------- Co-authored-by: Tomas Grosup --- .../.FSharp.Compiler.Service/8.0.300.md | 1 + src/Compiler/pars.fsy | 3 +- .../OnTypeMembers/OnTypeMembers.fs | 1 + .../ImportDeclarations/ImportDeclarations.fs | 1 + .../General/E_IncompleteConstruct01.fs | 2 +- .../General/E_IncompleteConstruct01b.fs | 2 +- .../Expression/Object - Class 07.fs.bsl | 2 +- .../Expression/Object - Class 08.fs.bsl | 2 +- .../Expression/Object - Class 09.fs.bsl | 2 +- .../data/SyntaxTree/Member/Member 08.fs.bsl | 2 +- .../data/SyntaxTree/Member/Member 10.fs.bsl | 2 +- .../data/SyntaxTree/Member/Member 12.fs.bsl | 2 +- .../data/SyntaxTree/Member/Member 13.fs | 9 +++ .../data/SyntaxTree/Member/Member 13.fs.bsl | 77 +++++++++++++++++++ 14 files changed, 99 insertions(+), 9 deletions(-) create mode 100644 tests/service/data/SyntaxTree/Member/Member 13.fs create mode 100644 tests/service/data/SyntaxTree/Member/Member 13.fs.bsl diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index b5a86a6540f..01d3fa6237a 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -16,6 +16,7 @@ * Enforce AttributeTargets on let values and functions. ([PR #16692](https://github.com/dotnet/fsharp/pull/16692)) * Enforce AttributeTargets on union case declarations. ([PR #16764](https://github.com/dotnet/fsharp/pull/16764)) * Disallow using base to invoke an abstract base method. ([Issue #13926](https://github.com/dotnet/fsharp/issues/13926), [PR #16773](https://github.com/dotnet/fsharp/pull/16773)) +* Parser: more unfinished member recovery ([PR #16835](https://github.com/dotnet/fsharp/pull/16835)) * Enforce AttributeTargets on implicit constructors. ([PR #16845](https://github.com/dotnet/fsharp/pull/16845/)) * Enforce AttributeTargets on structs and classes ([PR #16790](https://github.com/dotnet/fsharp/pull/16790)) * Parser: fix pattern range for idents with trivia ([PR #16824](https://github.com/dotnet/fsharp/pull/16824)) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 73fcdaf17e6..b1b4f43a473 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -1910,7 +1910,7 @@ memberCore: let memberRange = unionRanges rangeStart mEnd |> unionRangeWithXmlDoc xmlDoc [ SynMemberDefn.Member (binding, memberRange) ] } - | opt_inline bindingPattern opt_topReturnTypeWithTypeConstraints recover + | opt_inline bindingPattern opt_topReturnTypeWithTypeConstraints ends_coming_soon_or_recover { let optReturnType = $3 let bindingPat, mBindLhs = $2 let mEnd = @@ -1918,6 +1918,7 @@ memberCore: | Some(_, ty) -> ty.Range.EndRange | _ -> bindingPat.Range.EndRange let expr = arbExpr ("memberCore2", mEnd) + errorR (Error(FSComp.SR.parsMissingMemberBody(), rhs parseState 4)) fun vis flagsBuilderAndLeadingKeyword attrs rangeStart -> let xmlDoc = grabXmlDocAtRangeStart(parseState, attrs, rangeStart) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/AccessibilityAnnotations/OnTypeMembers/OnTypeMembers.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/AccessibilityAnnotations/OnTypeMembers/OnTypeMembers.fs index 0fbbe44a903..49c79c2600d 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/AccessibilityAnnotations/OnTypeMembers/OnTypeMembers.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/AccessibilityAnnotations/OnTypeMembers/OnTypeMembers.fs @@ -90,6 +90,7 @@ module AccessibilityAnnotations_OnTypeMembers = (Error 10, Line 20, Col 49, Line 20, Col 50, "Unexpected identifier in pattern") (Error 1244, Line 20, Col 48, Line 20, Col 57, "Attempted to parse this as an operator name, but failed") (Error 10, Line 23, Col 36, Line 23, Col 42, "Unexpected keyword 'public' in member definition") + (Error 3567, Line 23, Col 36, Line 23, Col 42, "Expecting member body") ] // SOURCE=OnProperty01.fs # OnProperty01.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/ImportDeclarations/ImportDeclarations.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/ImportDeclarations/ImportDeclarations.fs index 851746df35c..449fb5bd9d3 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/ImportDeclarations/ImportDeclarations.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/ImportDeclarations/ImportDeclarations.fs @@ -73,6 +73,7 @@ module ImportDeclarations = (Error 10, Line 9, Col 5, Line 9, Col 9, "Unexpected keyword 'open' in binding. Expected incomplete structured construct at or before this point or other token.") (Error 10, Line 17, Col 9, Line 17, Col 13, "Unexpected keyword 'open' in binding") (Error 10, Line 23, Col 9, Line 23, Col 13, "Unexpected keyword 'open' in expression") + (Error 3567, Line 23, Col 9, Line 23, Col 13, "Expecting member body") ] // SOURCE=OpenNestedModule01.fs # OpenNestedModule01.fs diff --git a/tests/fsharpqa/Source/Diagnostics/General/E_IncompleteConstruct01.fs b/tests/fsharpqa/Source/Diagnostics/General/E_IncompleteConstruct01.fs index e6d2ee6c084..63bbad5d811 100644 --- a/tests/fsharpqa/Source/Diagnostics/General/E_IncompleteConstruct01.fs +++ b/tests/fsharpqa/Source/Diagnostics/General/E_IncompleteConstruct01.fs @@ -1,6 +1,6 @@ // #Regression #Diagnostics // Regression test for FSHARP1.0:1181 -//Incomplete structured construct at or before this point in member definition\. Expected 'with', '=' or other token\. +//Expecting member body type INumericNorm<'T,'Measure> = interface INumeric<'T> diff --git a/tests/fsharpqa/Source/Diagnostics/General/E_IncompleteConstruct01b.fs b/tests/fsharpqa/Source/Diagnostics/General/E_IncompleteConstruct01b.fs index e3fb451018e..b029157e52b 100644 --- a/tests/fsharpqa/Source/Diagnostics/General/E_IncompleteConstruct01b.fs +++ b/tests/fsharpqa/Source/Diagnostics/General/E_IncompleteConstruct01b.fs @@ -1,7 +1,7 @@ // #Regression #Diagnostics // Regression test for FSHARP1.0:1181 //syntax error -// +// diff --git a/tests/service/data/SyntaxTree/Expression/Object - Class 07.fs.bsl b/tests/service/data/SyntaxTree/Expression/Object - Class 07.fs.bsl index 02f2b2c4bb5..eeaef3fd16a 100644 --- a/tests/service/data/SyntaxTree/Expression/Object - Class 07.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/Object - Class 07.fs.bsl @@ -35,4 +35,4 @@ ImplFile { ConditionalDirectives = [] CodeComments = [] }, set [])) -(4,17)-(4,18) parse error Incomplete structured construct at or before this point in object expression. Expected 'with', '=' or other token. +(4,17)-(4,18) parse error Expecting member body diff --git a/tests/service/data/SyntaxTree/Expression/Object - Class 08.fs.bsl b/tests/service/data/SyntaxTree/Expression/Object - Class 08.fs.bsl index da2aa3f44bc..f7c76b0b8fb 100644 --- a/tests/service/data/SyntaxTree/Expression/Object - Class 08.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/Object - Class 08.fs.bsl @@ -36,4 +36,4 @@ ImplFile CodeComments = [] }, set [])) (4,18)-(4,19) parse error Identifier expected -(4,18)-(4,19) parse error Incomplete structured construct at or before this point in object expression. Expected 'with', '=' or other token. +(4,18)-(4,19) parse error Expecting member body diff --git a/tests/service/data/SyntaxTree/Expression/Object - Class 09.fs.bsl b/tests/service/data/SyntaxTree/Expression/Object - Class 09.fs.bsl index 5fc68741000..831deffbeac 100644 --- a/tests/service/data/SyntaxTree/Expression/Object - Class 09.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/Object - Class 09.fs.bsl @@ -38,4 +38,4 @@ ImplFile { ConditionalDirectives = [] CodeComments = [] }, set [])) -(4,19)-(4,20) parse error Incomplete structured construct at or before this point in object expression. Expected 'with', '=' or other token. +(4,19)-(4,20) parse error Expecting member body diff --git a/tests/service/data/SyntaxTree/Member/Member 08.fs.bsl b/tests/service/data/SyntaxTree/Member/Member 08.fs.bsl index d7a7eda73ea..b2e10558c6a 100644 --- a/tests/service/data/SyntaxTree/Member/Member 08.fs.bsl +++ b/tests/service/data/SyntaxTree/Member/Member 08.fs.bsl @@ -76,4 +76,4 @@ ImplFile { ConditionalDirectives = [] CodeComments = [] }, set [])) -(5,0)-(5,0) parse error Incomplete structured construct at or before this point in member definition. Expected 'with', '=' or other token. +(5,0)-(5,0) parse error Expecting member body diff --git a/tests/service/data/SyntaxTree/Member/Member 10.fs.bsl b/tests/service/data/SyntaxTree/Member/Member 10.fs.bsl index 5749df6a18b..e0e6936d612 100644 --- a/tests/service/data/SyntaxTree/Member/Member 10.fs.bsl +++ b/tests/service/data/SyntaxTree/Member/Member 10.fs.bsl @@ -45,4 +45,4 @@ ImplFile { ConditionalDirectives = [] CodeComments = [] }, set [])) -(7,0)-(7,0) parse error Incomplete structured construct at or before this point in member definition. Expected 'with', '=' or other token. +(7,0)-(7,0) parse error Expecting member body diff --git a/tests/service/data/SyntaxTree/Member/Member 12.fs.bsl b/tests/service/data/SyntaxTree/Member/Member 12.fs.bsl index 94ece410c41..44e361be813 100644 --- a/tests/service/data/SyntaxTree/Member/Member 12.fs.bsl +++ b/tests/service/data/SyntaxTree/Member/Member 12.fs.bsl @@ -43,4 +43,4 @@ ImplFile CodeComments = [] }, set [])) (6,0)-(6,1) parse error Identifier expected -(6,0)-(6,1) parse error Incomplete structured construct at or before this point in member definition. Expected 'with', '=' or other token. +(6,0)-(6,1) parse error Expecting member body diff --git a/tests/service/data/SyntaxTree/Member/Member 13.fs b/tests/service/data/SyntaxTree/Member/Member 13.fs new file mode 100644 index 00000000000..98b5bc08640 --- /dev/null +++ b/tests/service/data/SyntaxTree/Member/Member 13.fs @@ -0,0 +1,9 @@ +module Module + +type A = + static member P: + +type B = + | A of int + +() diff --git a/tests/service/data/SyntaxTree/Member/Member 13.fs.bsl b/tests/service/data/SyntaxTree/Member/Member 13.fs.bsl new file mode 100644 index 00000000000..129c9f529ce --- /dev/null +++ b/tests/service/data/SyntaxTree/Member/Member 13.fs.bsl @@ -0,0 +1,77 @@ +ImplFile + (ParsedImplFileInput + ("/root/Member/Member 13.fs", false, QualifiedNameOfFile Module, [], [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [A], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (3,5--3,6)), + ObjectModel + (Unspecified, + [Member + (SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (Some { IsInstance = false + IsDispatchSlot = false + IsOverrideOrExplicitImpl = false + IsFinal = false + GetterOrSetterIsCompilerGenerated = false + MemberKind = Member }, + SynValInfo ([[]], SynArgInfo ([], false, None)), + None), + LongIdent + (SynLongIdent ([P], [], [None]), None, None, + Pats [], None, (4,18--4,19)), + Some + (SynBindingReturnInfo + (FromParseError (4,20--4,20), (4,20--4,20), [], + { ColonRange = Some (4,19--4,20) })), + Typed + (ArbitraryAfterError ("memberCore2", (4,20--4,20)), + FromParseError (4,20--4,20), (4,20--4,20)), + (4,18--4,19), NoneAtInvisible, + { LeadingKeyword = + StaticMember ((4,4--4,10), (4,11--4,17)) + InlineKeyword = None + EqualsRange = None }), (4,4--4,20))], (4,4--4,20)), + [], None, (3,5--4,20), { LeadingKeyword = Type (3,0--3,4) + EqualsRange = Some (3,7--3,8) + WithKeyword = None })], (3,0--4,20)); + Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [B], + PreXmlDoc ((6,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (6,5--6,6)), + Simple + (Union + (None, + [SynUnionCase + ([], SynIdent (A, None), + Fields + [SynField + ([], false, None, + LongIdent (SynLongIdent ([int], [], [None])), + false, + PreXmlDoc ((7,11), FSharp.Compiler.Xml.XmlDocCollector), + None, (7,11--7,14), { LeadingKeyword = None + MutableKeyword = None })], + PreXmlDoc ((7,4), FSharp.Compiler.Xml.XmlDocCollector), + None, (7,6--7,14), { BarRange = Some (7,4--7,5) })], + (7,4--7,14)), (7,4--7,14)), [], None, (6,5--7,14), + { LeadingKeyword = Type (6,0--6,4) + EqualsRange = Some (6,7--6,8) + WithKeyword = None })], (6,0--7,14)); + Expr (Const (Unit, (9,0--9,2)), (9,0--9,2))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--9,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(6,0)-(6,4) parse error Incomplete structured construct at or before this point in member definition +(6,0)-(6,4) parse error Expecting member body From 3d3fc393eec18b463ab06259fdadc1fb8081b086 Mon Sep 17 00:00:00 2001 From: Brian Rourke Boll Date: Tue, 19 Mar 2024 15:58:17 -0400 Subject: [PATCH 13/19] Optimize simple range mappings: `[for n in start..finish -> f n]`, &c. (#16832) --- .../.FSharp.Compiler.Service/8.0.300.md | 2 +- docs/release-notes/.Language/preview.md | 2 +- src/Compiler/CodeGen/IlxGen.fs | 3 +- .../Optimize/LowerComputedCollections.fs | 144 +- .../Optimize/LowerComputedCollections.fsi | 8 +- .../ComputedCollections.fs | 10 + .../ComputedCollections/ForNInRangeArrays.fs | 32 + .../ForNInRangeArrays.fs.il.bsl | 2493 +++++++++++++++++ .../ComputedCollections/ForNInRangeLists.fs | 32 + .../ForNInRangeLists.fs.il.bsl | 2166 ++++++++++++++ .../GeneratedIterators/GenIter01.fs.il.bsl | 91 +- .../GeneratedIterators/GenIter02.fs.il.bsl | 99 +- .../GeneratedIterators/GenIter03.fs.il.bsl | 91 +- ...nIter04_RealInternalSignatureOff.fs.il.bsl | 94 +- ...enIter04_RealInternalSignatureOn.fs.il.bsl | 90 +- .../GeneratedIterators/GeneratedIterators.fs | 1 + ...InternalSignatureOff.il.net472.release.bsl | 92 +- ...nternalSignatureOff.il.netcore.release.bsl | 92 +- ...lInternalSignatureOn.il.net472.release.bsl | 92 +- ...InternalSignatureOn.il.netcore.release.bsl | 92 +- 20 files changed, 5197 insertions(+), 529 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeArrays.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeArrays.fs.il.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeLists.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeLists.fs.il.bsl diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index 01d3fa6237a..afade2e0dc0 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -47,4 +47,4 @@ * Reverted [#16348](https://github.com/dotnet/fsharp/pull/16348) `ThreadStatic` `CancellationToken` changes to improve test stability and prevent potential unwanted cancellations. ([PR #16536](https://github.com/dotnet/fsharp/pull/16536)) * Refactored parenthesization API. ([PR #16461])(https://github.com/dotnet/fsharp/pull/16461)) * Optimize some interpolated strings by lowering to string concatenation. ([PR #16556](https://github.com/dotnet/fsharp/pull/16556)) -* Integral range optimizations. ([PR #16650](https://github.com/dotnet/fsharp/pull/16650)) +* Integral range optimizations. ([PR #16650](https://github.com/dotnet/fsharp/pull/16650), [PR #16832](https://github.com/dotnet/fsharp/pull/16832)) diff --git a/docs/release-notes/.Language/preview.md b/docs/release-notes/.Language/preview.md index 1e51f83984c..e886bd53225 100644 --- a/docs/release-notes/.Language/preview.md +++ b/docs/release-notes/.Language/preview.md @@ -1,6 +1,6 @@ ### Added -* Lower integral ranges to fast loops in more cases and optimize list and array construction from ranges. ([PR #16650](https://github.com/dotnet/fsharp/pull/16650)) +* Lower integral ranges to fast loops in more cases and optimize list and array construction from ranges. ([PR #16650](https://github.com/dotnet/fsharp/pull/16650), [PR #16832](https://github.com/dotnet/fsharp/pull/16832)) * Better generic unmanaged structs handling. ([Language suggestion #692](https://github.com/fsharp/fslang-suggestions/issues/692), [PR #12154](https://github.com/dotnet/fsharp/pull/12154)) * Bidirectional F#/C# interop for 'unmanaged' constraint. ([PR #12154](https://github.com/dotnet/fsharp/pull/12154)) * Make `.Is*` discriminated union properties visible. ([Language suggestion #222](https://github.com/fsharp/fslang-suggestions/issues/222), [PR #16341](https://github.com/dotnet/fsharp/pull/16341)) diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs index 976bba1c82f..5c174ecf9de 100644 --- a/src/Compiler/CodeGen/IlxGen.fs +++ b/src/Compiler/CodeGen/IlxGen.fs @@ -2920,7 +2920,8 @@ and GenExprPreSteps (cenv: cenv) (cgbuf: CodeGenBuffer) eenv expr sequel = let lowering = if compileSequenceExpressions then - LowerComputedCollectionExpressions.LowerComputedListOrArrayExpr cenv.tcVal g cenv.amap expr + let ilTyForTy ty = GenType cenv expr.Range eenv.tyenv ty + LowerComputedCollectionExpressions.LowerComputedListOrArrayExpr cenv.tcVal g cenv.amap ilTyForTy expr else None diff --git a/src/Compiler/Optimize/LowerComputedCollections.fs b/src/Compiler/Optimize/LowerComputedCollections.fs index 7ceff0a676c..18eafb2c6de 100644 --- a/src/Compiler/Optimize/LowerComputedCollections.fs +++ b/src/Compiler/Optimize/LowerComputedCollections.fs @@ -258,7 +258,7 @@ let (|SeqToArray|_|) g expr = module List = /// Makes an expression that will build a list from an integral range. - let mkFromIntegralRange tcVal (g: TcGlobals) amap m overallElemTy overallSeqExpr start step finish = + let mkFromIntegralRange tcVal (g: TcGlobals) amap m rangeTy overallElemTy rangeExpr start step finish body = let collectorTy = g.mk_ListCollector_ty overallElemTy /// let collector = ListCollector () in @@ -267,7 +267,16 @@ module List = let mkListInit mkLoop = mkCompGenLetMutableIn m "collector" collectorTy (mkDefault (m, collectorTy)) (fun (_, collector) -> let reader = InfoReader (g, amap) - let loop = mkLoop (fun _idxVar loopVar -> mkCallCollectorAdd tcVal g reader m collector loopVar) + + let loop = + mkLoop (fun _idxVar loopVar -> + let body = + body + |> Option.map (fun (loopVal, body) -> mkInvisibleLet m loopVal loopVar body) + |> Option.defaultValue loopVar + + mkCallCollectorAdd tcVal g reader m collector body) + let close = mkCallCollectorClose tcVal g reader m collector mkSequential m loop close ) @@ -275,7 +284,7 @@ module List = mkOptimizedRangeLoop g (m, m, m, DebugPointAtWhile.No) - (overallElemTy, overallSeqExpr) + (rangeTy, rangeExpr) (start, step, finish) (fun count mkLoop -> match count with @@ -301,7 +310,7 @@ module Array = | NoCheckOvf /// Makes an expression that will build an array from an integral range. - let mkFromIntegralRange g m overallElemTy overallSeqExpr start step finish = + let mkFromIntegralRange g m rangeTy ilTy overallElemTy rangeExpr start step finish body = let arrayTy = mkArrayType g overallElemTy let convToNativeInt ovf expr = @@ -324,21 +333,21 @@ module Array = else expr - let ilTy, ilBasicTy = - let ty = stripMeasuresFromTy g overallElemTy - - if typeEquiv g ty g.int32_ty then g.ilg.typ_Int32, DT_I4 - elif typeEquiv g ty g.int64_ty then g.ilg.typ_Int64, DT_I8 - elif typeEquiv g ty g.uint64_ty then g.ilg.typ_UInt64, DT_U8 - elif typeEquiv g ty g.uint32_ty then g.ilg.typ_UInt32, DT_U4 - elif typeEquiv g ty g.nativeint_ty then g.ilg.typ_IntPtr, DT_I - elif typeEquiv g ty g.unativeint_ty then g.ilg.typ_UIntPtr, DT_U - elif typeEquiv g ty g.int16_ty then g.ilg.typ_Int16, DT_I2 - elif typeEquiv g ty g.uint16_ty then g.ilg.typ_UInt16, DT_U2 - elif typeEquiv g ty g.sbyte_ty then g.ilg.typ_SByte, DT_I1 - elif typeEquiv g ty g.byte_ty then g.ilg.typ_Byte, DT_U1 - elif typeEquiv g ty g.char_ty then g.ilg.typ_Char, DT_U2 - else error (InternalError ($"Unable to find IL type for integral type '{overallElemTy}'.", m)) + let stelem = + if ilTy = g.ilg.typ_Int32 then I_stelem DT_I4 + elif ilTy = g.ilg.typ_Int64 then I_stelem DT_I8 + elif ilTy = g.ilg.typ_UInt64 then I_stelem DT_U8 + elif ilTy = g.ilg.typ_UInt32 then I_stelem DT_U4 + elif ilTy = g.ilg.typ_IntPtr then I_stelem DT_I + elif ilTy = g.ilg.typ_UIntPtr then I_stelem DT_U + elif ilTy = g.ilg.typ_Int16 then I_stelem DT_I2 + elif ilTy = g.ilg.typ_UInt16 then I_stelem DT_U2 + elif ilTy = g.ilg.typ_SByte then I_stelem DT_I1 + elif ilTy = g.ilg.typ_Byte then I_stelem DT_U1 + elif ilTy = g.ilg.typ_Char then I_stelem DT_U2 + elif ilTy = g.ilg.typ_Double then I_stelem DT_R8 + elif ilTy = g.ilg.typ_Single then I_stelem DT_R4 + else I_stelem_any (ILArrayShape.SingleDimensional, ilTy) /// (# "newarr !0" type ('T) count : 'T array #) let mkNewArray count = @@ -356,13 +365,21 @@ module Array = /// array let mkArrayInit count mkLoop = mkCompGenLetIn m "array" arrayTy (mkNewArray count) (fun (_, array) -> - let loop = mkLoop (fun idxVar loopVar -> mkAsmExpr ([I_stelem ilBasicTy], [], [array; convToNativeInt NoCheckOvf idxVar; loopVar], [], m)) + let loop = + mkLoop (fun idxVar loopVar -> + let body = + body + |> Option.map (fun (loopVal, body) -> mkInvisibleLet m loopVal loopVar body) + |> Option.defaultValue loopVar + + mkAsmExpr ([stelem], [], [array; convToNativeInt NoCheckOvf idxVar; body], [], m)) + mkSequential m loop array) mkOptimizedRangeLoop g (m, m, m, DebugPointAtWhile.No) - (overallElemTy, overallSeqExpr) + (rangeTy, rangeExpr) (start, step, finish) (fun count mkLoop -> match count with @@ -399,7 +416,64 @@ module Array = ) ) -let LowerComputedListOrArrayExpr tcVal (g: TcGlobals) amap overallExpr = +/// f (); …; Seq.singleton x +/// +/// E.g., in [for x in … do f (); …; yield x] +[] +let (|SimpleSequential|_|) g expr = + let rec loop expr cont = + match expr with + | Expr.Sequential (expr1, DebugPoints (ValApp g g.seq_singleton_vref (_, [body], _), debug), kind, m) -> + ValueSome (cont (expr1, debug body, kind, m)) + + | Expr.Sequential (expr1, body, kind, m) -> + loop body (cont >> fun body -> Expr.Sequential (expr1, body, kind, m)) + + | _ -> ValueNone + + loop expr Expr.Sequential + +/// The representation used for +/// +/// for … in … -> … +/// +/// and +/// +/// for … in … do yield … +[] +let (|SeqMap|_|) g expr = + match expr with + | ValApp g g.seq_map_vref ([ty1; ty2], [Expr.Lambda (valParams = [loopVal]; bodyExpr = body) as mapping; input], _) -> + ValueSome (ty1, ty2, input, mapping, loopVal, body) + | _ -> ValueNone + +/// The representation used for +/// +/// for … in … do f (); …; yield … +[] +let (|SeqCollectSingle|_|) g expr = + match expr with + | ValApp g g.seq_collect_vref ([ty1; _; ty2], [Expr.Lambda (valParams = [loopVal]; bodyExpr = SimpleSequential g body) as mapping; input], _) -> + ValueSome (ty1, ty2, input, mapping, loopVal, body) + | _ -> ValueNone + +/// for … in … -> … +/// for … in … do yield … +/// for … in … do f (); …; yield … +[] +let (|SimpleMapping|_|) g expr = + match expr with + // for … in … -> … + // for … in … do yield … + | ValApp g g.seq_delay_vref (_, [Expr.Lambda (bodyExpr = SeqMap g (ty1, ty2, input, mapping, loopVal, body))], _) + + // for … in … do f (); …; yield … + | ValApp g g.seq_delay_vref (_, [Expr.Lambda (bodyExpr = SeqCollectSingle g (ty1, ty2, input, mapping, loopVal, body))], _) -> + ValueSome (ty1, ty2, input, mapping, loopVal, body) + + | _ -> ValueNone + +let LowerComputedListOrArrayExpr tcVal (g: TcGlobals) amap ilTyForTy overallExpr = // If ListCollector is in FSharp.Core then this optimization kicks in if g.ListCollector_tcr.CanDeref then match overallExpr with @@ -408,8 +482,17 @@ let LowerComputedListOrArrayExpr tcVal (g: TcGlobals) amap overallExpr = match overallSeqExpr with // [start..finish] // [start..step..finish] - | IntegralRange g (_, (start, step, finish)) when g.langVersion.SupportsFeature LanguageFeature.LowerIntegralRangesToFastLoops -> - Some (List.mkFromIntegralRange tcVal g amap m overallElemTy overallSeqExpr start step finish) + | IntegralRange g (rangeTy, (start, step, finish)) when + g.langVersion.SupportsFeature LanguageFeature.LowerIntegralRangesToFastLoops + -> + Some (List.mkFromIntegralRange tcVal g amap m rangeTy overallElemTy overallSeqExpr start step finish None) + + // [for … in start..finish -> …] + // [for … in start..step..finish -> …] + | SimpleMapping g (_, _, rangeExpr & IntegralRange g (rangeTy, (start, step, finish)), _, loopVal, body) when + g.langVersion.SupportsFeature LanguageFeature.LowerIntegralRangesToFastLoops + -> + Some (List.mkFromIntegralRange tcVal g amap m rangeTy overallElemTy rangeExpr start step finish (Some (loopVal, body))) // [(* Anything more complex. *)] | _ -> @@ -421,8 +504,17 @@ let LowerComputedListOrArrayExpr tcVal (g: TcGlobals) amap overallExpr = match overallSeqExpr with // [|start..finish|] // [|start..step..finish|] - | IntegralRange g (_, (start, step, finish)) when g.langVersion.SupportsFeature LanguageFeature.LowerIntegralRangesToFastLoops -> - Some (Array.mkFromIntegralRange g m overallElemTy overallSeqExpr start step finish) + | IntegralRange g (rangeTy, (start, step, finish)) when + g.langVersion.SupportsFeature LanguageFeature.LowerIntegralRangesToFastLoops + -> + Some (Array.mkFromIntegralRange g m rangeTy (ilTyForTy overallElemTy) overallElemTy overallSeqExpr start step finish None) + + // [|for … in start..finish -> …|] + // [|for … in start..step..finish -> …|] + | SimpleMapping g (_, _, rangeExpr & IntegralRange g (rangeTy, (start, step, finish)), _, loopVal, body) when + g.langVersion.SupportsFeature LanguageFeature.LowerIntegralRangesToFastLoops + -> + Some (Array.mkFromIntegralRange g m rangeTy (ilTyForTy overallElemTy) overallElemTy rangeExpr start step finish (Some (loopVal, body))) // [|(* Anything more complex. *)|] | _ -> diff --git a/src/Compiler/Optimize/LowerComputedCollections.fsi b/src/Compiler/Optimize/LowerComputedCollections.fsi index a1656361776..e504af7e3ec 100644 --- a/src/Compiler/Optimize/LowerComputedCollections.fsi +++ b/src/Compiler/Optimize/LowerComputedCollections.fsi @@ -2,9 +2,15 @@ module internal FSharp.Compiler.LowerComputedCollectionExpressions +open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.Import open FSharp.Compiler.TcGlobals open FSharp.Compiler.TypedTree val LowerComputedListOrArrayExpr: - tcVal: ConstraintSolver.TcValF -> g: TcGlobals -> amap: ImportMap -> Expr -> Expr option + tcVal: ConstraintSolver.TcValF -> + g: TcGlobals -> + amap: ImportMap -> + ilTyForTy: (TType -> ILType) -> + overallExpr: Expr -> + Expr option diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ComputedCollections.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ComputedCollections.fs index b97d6e164fb..f8fbb00a4e2 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ComputedCollections.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ComputedCollections.fs @@ -34,3 +34,13 @@ module ComputedCollections = let ``UInt64RangeLists_fs`` compilation = compilation |> verifyCompilation + + [] + let ``ForNInRangeArrays_fs`` compilation = + compilation + |> verifyCompilation + + [] + let ``ForNInRangeLists_fs`` compilation = + compilation + |> verifyCompilation diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeArrays.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeArrays.fs new file mode 100644 index 00000000000..5e2867fae3a --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeArrays.fs @@ -0,0 +1,32 @@ +let f0 f = [|for n in 1..10 do f (); yield n|] +let f00 f g = [|for n in 1..10 do f (); g (); yield n|] +let f000 f = [|for n in 1..10 do f (); yield n; yield n + 1|] +let f0000 () = [|for n in 1..10 do yield n|] +let f1 () = [|for n in 1..10 -> n|] +let f2 () = [|for n in 10..1 -> n|] +let f3 () = [|for n in 1..1..10 -> n|] +let f4 () = [|for n in 1..2..10 -> n|] +let f5 () = [|for n in 10..1..1 -> n|] +let f6 () = [|for n in 1..-1..10 -> n|] +let f7 () = [|for n in 10..-1..1 -> n|] +let f8 () = [|for n in 10..-2..1 -> n|] +let f9 start = [|for n in start..10 -> n|] +let f10 finish = [|for n in 1..finish -> n|] +let f11 start finish = [|for n in start..finish -> n|] +let f12 start = [|for n in start..1..10 -> n|] +let f13 step = [|for n in 1..step..10 -> n|] +let f14 finish = [|for n in 1..1..finish -> n|] +let f15 start step = [|for n in start..step..10 -> n|] +let f16 start finish = [|for n in start..1..finish -> n|] +let f17 step finish = [|for n in 1..step..finish -> n|] +let f18 start step finish = [|for n in start..step..finish -> n|] +let f19 f = [|for n in f ()..10 -> n|] +let f20 f = [|for n in 1..f () -> n|] +let f21 f g = [|for n in f ()..g() -> n|] +let f22 f = [|for n in f ()..1..10 -> n|] +let f23 f = [|for n in 1..f ()..10 -> n|] +let f24 f = [|for n in 1..1..f () -> n|] +let f25 f g h = [|for n in f ()..g ()..h () -> n|] +let f26 start step finish = [|for n in start..step..finish -> n, float n|] +let f27 start step finish = [|for n in start..step..finish -> struct (n, float n)|] +let f28 start step finish = [|for n in start..step..finish -> let x = n + 1 in n * n|] diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeArrays.fs.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeArrays.fs.il.bsl new file mode 100644 index 00000000000..fe63ecb7138 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeArrays.fs.il.bsl @@ -0,0 +1,2493 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.mresource public FSharpSignatureData.assembly +{ + + +} +.mresource public FSharpOptimizationData.assembly +{ + + +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .method public static int32[] f0(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + + .maxstack 6 + .locals init (int32[] V_0, + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.s 10 + IL_0002: conv.i8 + IL_0003: conv.ovf.i.un + IL_0004: newarr [runtime]System.Int32 + IL_0009: stloc.0 + IL_000a: ldc.i4.0 + IL_000b: conv.i8 + IL_000c: stloc.1 + IL_000d: ldc.i4.1 + IL_000e: stloc.2 + IL_000f: br.s IL_0029 + + IL_0011: ldloc.0 + IL_0012: ldloc.1 + IL_0013: conv.i + IL_0014: ldloc.2 + IL_0015: stloc.3 + IL_0016: ldarg.0 + IL_0017: ldnull + IL_0018: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001d: pop + IL_001e: ldloc.3 + IL_001f: stelem.i4 + IL_0020: ldloc.2 + IL_0021: ldc.i4.1 + IL_0022: add + IL_0023: stloc.2 + IL_0024: ldloc.1 + IL_0025: ldc.i4.1 + IL_0026: conv.i8 + IL_0027: add + IL_0028: stloc.1 + IL_0029: ldloc.1 + IL_002a: ldc.i4.s 10 + IL_002c: conv.i8 + IL_002d: blt.un.s IL_0011 + + IL_002f: ldloc.0 + IL_0030: ret + } + + .method public static int32[] f00(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 6 + .locals init (int32[] V_0, + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.s 10 + IL_0002: conv.i8 + IL_0003: conv.ovf.i.un + IL_0004: newarr [runtime]System.Int32 + IL_0009: stloc.0 + IL_000a: ldc.i4.0 + IL_000b: conv.i8 + IL_000c: stloc.1 + IL_000d: ldc.i4.1 + IL_000e: stloc.2 + IL_000f: br.s IL_0031 + + IL_0011: ldloc.0 + IL_0012: ldloc.1 + IL_0013: conv.i + IL_0014: ldloc.2 + IL_0015: stloc.3 + IL_0016: ldarg.0 + IL_0017: ldnull + IL_0018: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001d: pop + IL_001e: ldarg.1 + IL_001f: ldnull + IL_0020: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0025: pop + IL_0026: ldloc.3 + IL_0027: stelem.i4 + IL_0028: ldloc.2 + IL_0029: ldc.i4.1 + IL_002a: add + IL_002b: stloc.2 + IL_002c: ldloc.1 + IL_002d: ldc.i4.1 + IL_002e: conv.i8 + IL_002f: add + IL_0030: stloc.1 + IL_0031: ldloc.1 + IL_0032: ldc.i4.s 10 + IL_0034: conv.i8 + IL_0035: blt.un.s IL_0011 + + IL_0037: ldloc.0 + IL_0038: ret + } + + .method public static int32[] f000(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1 V_0, + class [runtime]System.Collections.Generic.IEnumerator`1 V_1, + class [runtime]System.Collections.Generic.IEnumerable`1 V_2, + int32 V_3, + class [runtime]System.IDisposable V_4) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: ldc.i4.1 + IL_0003: ldc.i4.s 10 + IL_0005: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_000a: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_000f: stloc.1 + .try + { + IL_0010: br.s IL_0035 + + IL_0012: ldloc.1 + IL_0013: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0018: stloc.3 + IL_0019: ldarg.0 + IL_001a: ldnull + IL_001b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0020: pop + IL_0021: ldloca.s V_0 + IL_0023: ldloc.3 + IL_0024: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1::Add(!0) + IL_0029: nop + IL_002a: ldloca.s V_0 + IL_002c: ldloc.3 + IL_002d: ldc.i4.1 + IL_002e: add + IL_002f: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1::Add(!0) + IL_0034: nop + IL_0035: ldloc.1 + IL_0036: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_003b: brtrue.s IL_0012 + + IL_003d: ldnull + IL_003e: stloc.2 + IL_003f: leave.s IL_0056 + + } + finally + { + IL_0041: ldloc.1 + IL_0042: isinst [runtime]System.IDisposable + IL_0047: stloc.s V_4 + IL_0049: ldloc.s V_4 + IL_004b: brfalse.s IL_0055 + + IL_004d: ldloc.s V_4 + IL_004f: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_0054: endfinally + IL_0055: endfinally + } + IL_0056: ldloc.2 + IL_0057: pop + IL_0058: ldloca.s V_0 + IL_005a: call instance !0[] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1::Close() + IL_005f: ret + } + + .method public static int32[] f0000() cil managed + { + + .maxstack 5 + .locals init (int32[] V_0, + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.s 10 + IL_0002: conv.i8 + IL_0003: conv.ovf.i.un + IL_0004: newarr [runtime]System.Int32 + IL_0009: stloc.0 + IL_000a: ldc.i4.0 + IL_000b: conv.i8 + IL_000c: stloc.1 + IL_000d: ldc.i4.1 + IL_000e: stloc.2 + IL_000f: br.s IL_0021 + + IL_0011: ldloc.0 + IL_0012: ldloc.1 + IL_0013: conv.i + IL_0014: ldloc.2 + IL_0015: stloc.3 + IL_0016: ldloc.3 + IL_0017: stelem.i4 + IL_0018: ldloc.2 + IL_0019: ldc.i4.1 + IL_001a: add + IL_001b: stloc.2 + IL_001c: ldloc.1 + IL_001d: ldc.i4.1 + IL_001e: conv.i8 + IL_001f: add + IL_0020: stloc.1 + IL_0021: ldloc.1 + IL_0022: ldc.i4.s 10 + IL_0024: conv.i8 + IL_0025: blt.un.s IL_0011 + + IL_0027: ldloc.0 + IL_0028: ret + } + + .method public static int32[] f1() cil managed + { + + .maxstack 5 + .locals init (int32[] V_0, + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.s 10 + IL_0002: conv.i8 + IL_0003: conv.ovf.i.un + IL_0004: newarr [runtime]System.Int32 + IL_0009: stloc.0 + IL_000a: ldc.i4.0 + IL_000b: conv.i8 + IL_000c: stloc.1 + IL_000d: ldc.i4.1 + IL_000e: stloc.2 + IL_000f: br.s IL_0021 + + IL_0011: ldloc.0 + IL_0012: ldloc.1 + IL_0013: conv.i + IL_0014: ldloc.2 + IL_0015: stloc.3 + IL_0016: ldloc.3 + IL_0017: stelem.i4 + IL_0018: ldloc.2 + IL_0019: ldc.i4.1 + IL_001a: add + IL_001b: stloc.2 + IL_001c: ldloc.1 + IL_001d: ldc.i4.1 + IL_001e: conv.i8 + IL_001f: add + IL_0020: stloc.1 + IL_0021: ldloc.1 + IL_0022: ldc.i4.s 10 + IL_0024: conv.i8 + IL_0025: blt.un.s IL_0011 + + IL_0027: ldloc.0 + IL_0028: ret + } + + .method public static int32[] f2() cil managed + { + + .maxstack 8 + IL_0000: call !!0[] [runtime]System.Array::Empty() + IL_0005: ret + } + + .method public static int32[] f3() cil managed + { + + .maxstack 5 + .locals init (int32[] V_0, + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.s 10 + IL_0002: conv.i8 + IL_0003: conv.ovf.i.un + IL_0004: newarr [runtime]System.Int32 + IL_0009: stloc.0 + IL_000a: ldc.i4.0 + IL_000b: conv.i8 + IL_000c: stloc.1 + IL_000d: ldc.i4.1 + IL_000e: stloc.2 + IL_000f: br.s IL_0021 + + IL_0011: ldloc.0 + IL_0012: ldloc.1 + IL_0013: conv.i + IL_0014: ldloc.2 + IL_0015: stloc.3 + IL_0016: ldloc.3 + IL_0017: stelem.i4 + IL_0018: ldloc.2 + IL_0019: ldc.i4.1 + IL_001a: add + IL_001b: stloc.2 + IL_001c: ldloc.1 + IL_001d: ldc.i4.1 + IL_001e: conv.i8 + IL_001f: add + IL_0020: stloc.1 + IL_0021: ldloc.1 + IL_0022: ldc.i4.s 10 + IL_0024: conv.i8 + IL_0025: blt.un.s IL_0011 + + IL_0027: ldloc.0 + IL_0028: ret + } + + .method public static int32[] f4() cil managed + { + + .maxstack 5 + .locals init (int32[] V_0, + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.5 + IL_0001: conv.i8 + IL_0002: conv.ovf.i.un + IL_0003: newarr [runtime]System.Int32 + IL_0008: stloc.0 + IL_0009: ldc.i4.0 + IL_000a: conv.i8 + IL_000b: stloc.1 + IL_000c: ldc.i4.1 + IL_000d: stloc.2 + IL_000e: br.s IL_0020 + + IL_0010: ldloc.0 + IL_0011: ldloc.1 + IL_0012: conv.i + IL_0013: ldloc.2 + IL_0014: stloc.3 + IL_0015: ldloc.3 + IL_0016: stelem.i4 + IL_0017: ldloc.2 + IL_0018: ldc.i4.2 + IL_0019: add + IL_001a: stloc.2 + IL_001b: ldloc.1 + IL_001c: ldc.i4.1 + IL_001d: conv.i8 + IL_001e: add + IL_001f: stloc.1 + IL_0020: ldloc.1 + IL_0021: ldc.i4.5 + IL_0022: conv.i8 + IL_0023: blt.un.s IL_0010 + + IL_0025: ldloc.0 + IL_0026: ret + } + + .method public static int32[] f5() cil managed + { + + .maxstack 8 + IL_0000: call !!0[] [runtime]System.Array::Empty() + IL_0005: ret + } + + .method public static int32[] f6() cil managed + { + + .maxstack 8 + IL_0000: call !!0[] [runtime]System.Array::Empty() + IL_0005: ret + } + + .method public static int32[] f7() cil managed + { + + .maxstack 5 + .locals init (int32[] V_0, + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.s 10 + IL_0002: conv.i8 + IL_0003: conv.ovf.i.un + IL_0004: newarr [runtime]System.Int32 + IL_0009: stloc.0 + IL_000a: ldc.i4.0 + IL_000b: conv.i8 + IL_000c: stloc.1 + IL_000d: ldc.i4.s 10 + IL_000f: stloc.2 + IL_0010: br.s IL_0022 + + IL_0012: ldloc.0 + IL_0013: ldloc.1 + IL_0014: conv.i + IL_0015: ldloc.2 + IL_0016: stloc.3 + IL_0017: ldloc.3 + IL_0018: stelem.i4 + IL_0019: ldloc.2 + IL_001a: ldc.i4.m1 + IL_001b: add + IL_001c: stloc.2 + IL_001d: ldloc.1 + IL_001e: ldc.i4.1 + IL_001f: conv.i8 + IL_0020: add + IL_0021: stloc.1 + IL_0022: ldloc.1 + IL_0023: ldc.i4.s 10 + IL_0025: conv.i8 + IL_0026: blt.un.s IL_0012 + + IL_0028: ldloc.0 + IL_0029: ret + } + + .method public static int32[] f8() cil managed + { + + .maxstack 5 + .locals init (int32[] V_0, + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.5 + IL_0001: conv.i8 + IL_0002: conv.ovf.i.un + IL_0003: newarr [runtime]System.Int32 + IL_0008: stloc.0 + IL_0009: ldc.i4.0 + IL_000a: conv.i8 + IL_000b: stloc.1 + IL_000c: ldc.i4.s 10 + IL_000e: stloc.2 + IL_000f: br.s IL_0022 + + IL_0011: ldloc.0 + IL_0012: ldloc.1 + IL_0013: conv.i + IL_0014: ldloc.2 + IL_0015: stloc.3 + IL_0016: ldloc.3 + IL_0017: stelem.i4 + IL_0018: ldloc.2 + IL_0019: ldc.i4.s -2 + IL_001b: add + IL_001c: stloc.2 + IL_001d: ldloc.1 + IL_001e: ldc.i4.1 + IL_001f: conv.i8 + IL_0020: add + IL_0021: stloc.1 + IL_0022: ldloc.1 + IL_0023: ldc.i4.5 + IL_0024: conv.i8 + IL_0025: blt.un.s IL_0011 + + IL_0027: ldloc.0 + IL_0028: ret + } + + .method public static int32[] f9(int32 start) cil managed + { + + .maxstack 5 + .locals init (uint64 V_0, + uint64 V_1, + int32[] V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: nop + IL_0001: ldc.i4.s 10 + IL_0003: ldarg.0 + IL_0004: bge.s IL_000b + + IL_0006: ldc.i4.0 + IL_0007: conv.i8 + IL_0008: nop + IL_0009: br.s IL_0014 + + IL_000b: ldc.i4.s 10 + IL_000d: ldarg.0 + IL_000e: sub + IL_000f: conv.i8 + IL_0010: ldc.i4.1 + IL_0011: conv.i8 + IL_0012: add + IL_0013: nop + IL_0014: stloc.0 + IL_0015: ldloc.0 + IL_0016: stloc.1 + IL_0017: ldloc.1 + IL_0018: ldc.i4.1 + IL_0019: conv.i8 + IL_001a: bge.un.s IL_0022 + + IL_001c: call !!0[] [runtime]System.Array::Empty() + IL_0021: ret + + IL_0022: ldloc.1 + IL_0023: conv.ovf.i.un + IL_0024: newarr [runtime]System.Int32 + IL_0029: stloc.2 + IL_002a: ldc.i4.0 + IL_002b: conv.i8 + IL_002c: stloc.3 + IL_002d: ldarg.0 + IL_002e: stloc.s V_4 + IL_0030: br.s IL_0047 + + IL_0032: ldloc.2 + IL_0033: ldloc.3 + IL_0034: conv.i + IL_0035: ldloc.s V_4 + IL_0037: stloc.s V_5 + IL_0039: ldloc.s V_5 + IL_003b: stelem.i4 + IL_003c: ldloc.s V_4 + IL_003e: ldc.i4.1 + IL_003f: add + IL_0040: stloc.s V_4 + IL_0042: ldloc.3 + IL_0043: ldc.i4.1 + IL_0044: conv.i8 + IL_0045: add + IL_0046: stloc.3 + IL_0047: ldloc.3 + IL_0048: ldloc.0 + IL_0049: blt.un.s IL_0032 + + IL_004b: ldloc.2 + IL_004c: ret + } + + .method public static int32[] f10(int32 finish) cil managed + { + + .maxstack 5 + .locals init (uint64 V_0, + uint64 V_1, + int32[] V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.1 + IL_0003: bge.s IL_000a + + IL_0005: ldc.i4.0 + IL_0006: conv.i8 + IL_0007: nop + IL_0008: br.s IL_0012 + + IL_000a: ldarg.0 + IL_000b: ldc.i4.1 + IL_000c: sub + IL_000d: conv.i8 + IL_000e: ldc.i4.1 + IL_000f: conv.i8 + IL_0010: add + IL_0011: nop + IL_0012: stloc.0 + IL_0013: ldloc.0 + IL_0014: stloc.1 + IL_0015: ldloc.1 + IL_0016: ldc.i4.1 + IL_0017: conv.i8 + IL_0018: bge.un.s IL_0020 + + IL_001a: call !!0[] [runtime]System.Array::Empty() + IL_001f: ret + + IL_0020: ldloc.1 + IL_0021: conv.ovf.i.un + IL_0022: newarr [runtime]System.Int32 + IL_0027: stloc.2 + IL_0028: ldc.i4.0 + IL_0029: conv.i8 + IL_002a: stloc.3 + IL_002b: ldc.i4.1 + IL_002c: stloc.s V_4 + IL_002e: br.s IL_0045 + + IL_0030: ldloc.2 + IL_0031: ldloc.3 + IL_0032: conv.i + IL_0033: ldloc.s V_4 + IL_0035: stloc.s V_5 + IL_0037: ldloc.s V_5 + IL_0039: stelem.i4 + IL_003a: ldloc.s V_4 + IL_003c: ldc.i4.1 + IL_003d: add + IL_003e: stloc.s V_4 + IL_0040: ldloc.3 + IL_0041: ldc.i4.1 + IL_0042: conv.i8 + IL_0043: add + IL_0044: stloc.3 + IL_0045: ldloc.3 + IL_0046: ldloc.0 + IL_0047: blt.un.s IL_0030 + + IL_0049: ldloc.2 + IL_004a: ret + } + + .method public static int32[] f11(int32 start, + int32 finish) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 5 + .locals init (uint64 V_0, + uint64 V_1, + int32[] V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.0 + IL_0003: bge.s IL_000a + + IL_0005: ldc.i4.0 + IL_0006: conv.i8 + IL_0007: nop + IL_0008: br.s IL_0012 + + IL_000a: ldarg.1 + IL_000b: ldarg.0 + IL_000c: sub + IL_000d: conv.i8 + IL_000e: ldc.i4.1 + IL_000f: conv.i8 + IL_0010: add + IL_0011: nop + IL_0012: stloc.0 + IL_0013: ldloc.0 + IL_0014: stloc.1 + IL_0015: ldloc.1 + IL_0016: ldc.i4.1 + IL_0017: conv.i8 + IL_0018: bge.un.s IL_0020 + + IL_001a: call !!0[] [runtime]System.Array::Empty() + IL_001f: ret + + IL_0020: ldloc.1 + IL_0021: conv.ovf.i.un + IL_0022: newarr [runtime]System.Int32 + IL_0027: stloc.2 + IL_0028: ldc.i4.0 + IL_0029: conv.i8 + IL_002a: stloc.3 + IL_002b: ldarg.0 + IL_002c: stloc.s V_4 + IL_002e: br.s IL_0045 + + IL_0030: ldloc.2 + IL_0031: ldloc.3 + IL_0032: conv.i + IL_0033: ldloc.s V_4 + IL_0035: stloc.s V_5 + IL_0037: ldloc.s V_5 + IL_0039: stelem.i4 + IL_003a: ldloc.s V_4 + IL_003c: ldc.i4.1 + IL_003d: add + IL_003e: stloc.s V_4 + IL_0040: ldloc.3 + IL_0041: ldc.i4.1 + IL_0042: conv.i8 + IL_0043: add + IL_0044: stloc.3 + IL_0045: ldloc.3 + IL_0046: ldloc.0 + IL_0047: blt.un.s IL_0030 + + IL_0049: ldloc.2 + IL_004a: ret + } + + .method public static int32[] f12(int32 start) cil managed + { + + .maxstack 5 + .locals init (uint64 V_0, + uint64 V_1, + int32[] V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: nop + IL_0001: ldc.i4.s 10 + IL_0003: ldarg.0 + IL_0004: bge.s IL_000b + + IL_0006: ldc.i4.0 + IL_0007: conv.i8 + IL_0008: nop + IL_0009: br.s IL_0014 + + IL_000b: ldc.i4.s 10 + IL_000d: ldarg.0 + IL_000e: sub + IL_000f: conv.i8 + IL_0010: ldc.i4.1 + IL_0011: conv.i8 + IL_0012: add + IL_0013: nop + IL_0014: stloc.0 + IL_0015: ldloc.0 + IL_0016: stloc.1 + IL_0017: ldloc.1 + IL_0018: ldc.i4.1 + IL_0019: conv.i8 + IL_001a: bge.un.s IL_0022 + + IL_001c: call !!0[] [runtime]System.Array::Empty() + IL_0021: ret + + IL_0022: ldloc.1 + IL_0023: conv.ovf.i.un + IL_0024: newarr [runtime]System.Int32 + IL_0029: stloc.2 + IL_002a: ldc.i4.0 + IL_002b: conv.i8 + IL_002c: stloc.3 + IL_002d: ldarg.0 + IL_002e: stloc.s V_4 + IL_0030: br.s IL_0047 + + IL_0032: ldloc.2 + IL_0033: ldloc.3 + IL_0034: conv.i + IL_0035: ldloc.s V_4 + IL_0037: stloc.s V_5 + IL_0039: ldloc.s V_5 + IL_003b: stelem.i4 + IL_003c: ldloc.s V_4 + IL_003e: ldc.i4.1 + IL_003f: add + IL_0040: stloc.s V_4 + IL_0042: ldloc.3 + IL_0043: ldc.i4.1 + IL_0044: conv.i8 + IL_0045: add + IL_0046: stloc.3 + IL_0047: ldloc.3 + IL_0048: ldloc.0 + IL_0049: blt.un.s IL_0032 + + IL_004b: ldloc.2 + IL_004c: ret + } + + .method public static int32[] f13(int32 step) cil managed + { + + .maxstack 5 + .locals init (uint64 V_0, + uint64 V_1, + int32[] V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: brtrue.s IL_0011 + + IL_0004: ldc.i4.1 + IL_0005: ldarg.0 + IL_0006: ldc.i4.s 10 + IL_0008: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_000d: pop + IL_000e: nop + IL_000f: br.s IL_0012 + + IL_0011: nop + IL_0012: ldc.i4.0 + IL_0013: ldarg.0 + IL_0014: bge.s IL_002d + + IL_0016: ldc.i4.s 10 + IL_0018: ldc.i4.1 + IL_0019: bge.s IL_0020 + + IL_001b: ldc.i4.0 + IL_001c: conv.i8 + IL_001d: nop + IL_001e: br.s IL_0045 + + IL_0020: ldc.i4.s 10 + IL_0022: ldc.i4.1 + IL_0023: sub + IL_0024: ldarg.0 + IL_0025: div.un + IL_0026: conv.i8 + IL_0027: ldc.i4.1 + IL_0028: conv.i8 + IL_0029: add + IL_002a: nop + IL_002b: br.s IL_0045 + + IL_002d: ldc.i4.1 + IL_002e: ldc.i4.s 10 + IL_0030: bge.s IL_0037 + + IL_0032: ldc.i4.0 + IL_0033: conv.i8 + IL_0034: nop + IL_0035: br.s IL_0045 + + IL_0037: ldc.i4.1 + IL_0038: ldc.i4.s 10 + IL_003a: sub + IL_003b: ldarg.0 + IL_003c: not + IL_003d: ldc.i4.1 + IL_003e: add + IL_003f: div.un + IL_0040: conv.i8 + IL_0041: ldc.i4.1 + IL_0042: conv.i8 + IL_0043: add + IL_0044: nop + IL_0045: stloc.0 + IL_0046: ldloc.0 + IL_0047: stloc.1 + IL_0048: ldloc.1 + IL_0049: ldc.i4.1 + IL_004a: conv.i8 + IL_004b: bge.un.s IL_0053 + + IL_004d: call !!0[] [runtime]System.Array::Empty() + IL_0052: ret + + IL_0053: ldloc.1 + IL_0054: conv.ovf.i.un + IL_0055: newarr [runtime]System.Int32 + IL_005a: stloc.2 + IL_005b: ldc.i4.0 + IL_005c: conv.i8 + IL_005d: stloc.3 + IL_005e: ldc.i4.1 + IL_005f: stloc.s V_4 + IL_0061: br.s IL_0078 + + IL_0063: ldloc.2 + IL_0064: ldloc.3 + IL_0065: conv.i + IL_0066: ldloc.s V_4 + IL_0068: stloc.s V_5 + IL_006a: ldloc.s V_5 + IL_006c: stelem.i4 + IL_006d: ldloc.s V_4 + IL_006f: ldarg.0 + IL_0070: add + IL_0071: stloc.s V_4 + IL_0073: ldloc.3 + IL_0074: ldc.i4.1 + IL_0075: conv.i8 + IL_0076: add + IL_0077: stloc.3 + IL_0078: ldloc.3 + IL_0079: ldloc.0 + IL_007a: blt.un.s IL_0063 + + IL_007c: ldloc.2 + IL_007d: ret + } + + .method public static int32[] f14(int32 finish) cil managed + { + + .maxstack 5 + .locals init (uint64 V_0, + uint64 V_1, + int32[] V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.1 + IL_0003: bge.s IL_000a + + IL_0005: ldc.i4.0 + IL_0006: conv.i8 + IL_0007: nop + IL_0008: br.s IL_0012 + + IL_000a: ldarg.0 + IL_000b: ldc.i4.1 + IL_000c: sub + IL_000d: conv.i8 + IL_000e: ldc.i4.1 + IL_000f: conv.i8 + IL_0010: add + IL_0011: nop + IL_0012: stloc.0 + IL_0013: ldloc.0 + IL_0014: stloc.1 + IL_0015: ldloc.1 + IL_0016: ldc.i4.1 + IL_0017: conv.i8 + IL_0018: bge.un.s IL_0020 + + IL_001a: call !!0[] [runtime]System.Array::Empty() + IL_001f: ret + + IL_0020: ldloc.1 + IL_0021: conv.ovf.i.un + IL_0022: newarr [runtime]System.Int32 + IL_0027: stloc.2 + IL_0028: ldc.i4.0 + IL_0029: conv.i8 + IL_002a: stloc.3 + IL_002b: ldc.i4.1 + IL_002c: stloc.s V_4 + IL_002e: br.s IL_0045 + + IL_0030: ldloc.2 + IL_0031: ldloc.3 + IL_0032: conv.i + IL_0033: ldloc.s V_4 + IL_0035: stloc.s V_5 + IL_0037: ldloc.s V_5 + IL_0039: stelem.i4 + IL_003a: ldloc.s V_4 + IL_003c: ldc.i4.1 + IL_003d: add + IL_003e: stloc.s V_4 + IL_0040: ldloc.3 + IL_0041: ldc.i4.1 + IL_0042: conv.i8 + IL_0043: add + IL_0044: stloc.3 + IL_0045: ldloc.3 + IL_0046: ldloc.0 + IL_0047: blt.un.s IL_0030 + + IL_0049: ldloc.2 + IL_004a: ret + } + + .method public static int32[] f15(int32 start, + int32 step) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 5 + .locals init (uint64 V_0, + uint64 V_1, + int32[] V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: brtrue.s IL_0011 + + IL_0004: ldarg.0 + IL_0005: ldarg.1 + IL_0006: ldc.i4.s 10 + IL_0008: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_000d: pop + IL_000e: nop + IL_000f: br.s IL_0012 + + IL_0011: nop + IL_0012: ldc.i4.0 + IL_0013: ldarg.1 + IL_0014: bge.s IL_002d + + IL_0016: ldc.i4.s 10 + IL_0018: ldarg.0 + IL_0019: bge.s IL_0020 + + IL_001b: ldc.i4.0 + IL_001c: conv.i8 + IL_001d: nop + IL_001e: br.s IL_0045 + + IL_0020: ldc.i4.s 10 + IL_0022: ldarg.0 + IL_0023: sub + IL_0024: ldarg.1 + IL_0025: div.un + IL_0026: conv.i8 + IL_0027: ldc.i4.1 + IL_0028: conv.i8 + IL_0029: add + IL_002a: nop + IL_002b: br.s IL_0045 + + IL_002d: ldarg.0 + IL_002e: ldc.i4.s 10 + IL_0030: bge.s IL_0037 + + IL_0032: ldc.i4.0 + IL_0033: conv.i8 + IL_0034: nop + IL_0035: br.s IL_0045 + + IL_0037: ldarg.0 + IL_0038: ldc.i4.s 10 + IL_003a: sub + IL_003b: ldarg.1 + IL_003c: not + IL_003d: ldc.i4.1 + IL_003e: add + IL_003f: div.un + IL_0040: conv.i8 + IL_0041: ldc.i4.1 + IL_0042: conv.i8 + IL_0043: add + IL_0044: nop + IL_0045: stloc.0 + IL_0046: ldloc.0 + IL_0047: stloc.1 + IL_0048: ldloc.1 + IL_0049: ldc.i4.1 + IL_004a: conv.i8 + IL_004b: bge.un.s IL_0053 + + IL_004d: call !!0[] [runtime]System.Array::Empty() + IL_0052: ret + + IL_0053: ldloc.1 + IL_0054: conv.ovf.i.un + IL_0055: newarr [runtime]System.Int32 + IL_005a: stloc.2 + IL_005b: ldc.i4.0 + IL_005c: conv.i8 + IL_005d: stloc.3 + IL_005e: ldarg.0 + IL_005f: stloc.s V_4 + IL_0061: br.s IL_0078 + + IL_0063: ldloc.2 + IL_0064: ldloc.3 + IL_0065: conv.i + IL_0066: ldloc.s V_4 + IL_0068: stloc.s V_5 + IL_006a: ldloc.s V_5 + IL_006c: stelem.i4 + IL_006d: ldloc.s V_4 + IL_006f: ldarg.1 + IL_0070: add + IL_0071: stloc.s V_4 + IL_0073: ldloc.3 + IL_0074: ldc.i4.1 + IL_0075: conv.i8 + IL_0076: add + IL_0077: stloc.3 + IL_0078: ldloc.3 + IL_0079: ldloc.0 + IL_007a: blt.un.s IL_0063 + + IL_007c: ldloc.2 + IL_007d: ret + } + + .method public static int32[] f16(int32 start, + int32 finish) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 5 + .locals init (uint64 V_0, + uint64 V_1, + int32[] V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.0 + IL_0003: bge.s IL_000a + + IL_0005: ldc.i4.0 + IL_0006: conv.i8 + IL_0007: nop + IL_0008: br.s IL_0012 + + IL_000a: ldarg.1 + IL_000b: ldarg.0 + IL_000c: sub + IL_000d: conv.i8 + IL_000e: ldc.i4.1 + IL_000f: conv.i8 + IL_0010: add + IL_0011: nop + IL_0012: stloc.0 + IL_0013: ldloc.0 + IL_0014: stloc.1 + IL_0015: ldloc.1 + IL_0016: ldc.i4.1 + IL_0017: conv.i8 + IL_0018: bge.un.s IL_0020 + + IL_001a: call !!0[] [runtime]System.Array::Empty() + IL_001f: ret + + IL_0020: ldloc.1 + IL_0021: conv.ovf.i.un + IL_0022: newarr [runtime]System.Int32 + IL_0027: stloc.2 + IL_0028: ldc.i4.0 + IL_0029: conv.i8 + IL_002a: stloc.3 + IL_002b: ldarg.0 + IL_002c: stloc.s V_4 + IL_002e: br.s IL_0045 + + IL_0030: ldloc.2 + IL_0031: ldloc.3 + IL_0032: conv.i + IL_0033: ldloc.s V_4 + IL_0035: stloc.s V_5 + IL_0037: ldloc.s V_5 + IL_0039: stelem.i4 + IL_003a: ldloc.s V_4 + IL_003c: ldc.i4.1 + IL_003d: add + IL_003e: stloc.s V_4 + IL_0040: ldloc.3 + IL_0041: ldc.i4.1 + IL_0042: conv.i8 + IL_0043: add + IL_0044: stloc.3 + IL_0045: ldloc.3 + IL_0046: ldloc.0 + IL_0047: blt.un.s IL_0030 + + IL_0049: ldloc.2 + IL_004a: ret + } + + .method public static int32[] f17(int32 step, + int32 finish) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 5 + .locals init (uint64 V_0, + uint64 V_1, + int32[] V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: brtrue.s IL_0010 + + IL_0004: ldc.i4.1 + IL_0005: ldarg.0 + IL_0006: ldarg.1 + IL_0007: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_000c: pop + IL_000d: nop + IL_000e: br.s IL_0011 + + IL_0010: nop + IL_0011: ldc.i4.0 + IL_0012: ldarg.0 + IL_0013: bge.s IL_002a + + IL_0015: ldarg.1 + IL_0016: ldc.i4.1 + IL_0017: bge.s IL_001e + + IL_0019: ldc.i4.0 + IL_001a: conv.i8 + IL_001b: nop + IL_001c: br.s IL_0040 + + IL_001e: ldarg.1 + IL_001f: ldc.i4.1 + IL_0020: sub + IL_0021: ldarg.0 + IL_0022: div.un + IL_0023: conv.i8 + IL_0024: ldc.i4.1 + IL_0025: conv.i8 + IL_0026: add + IL_0027: nop + IL_0028: br.s IL_0040 + + IL_002a: ldc.i4.1 + IL_002b: ldarg.1 + IL_002c: bge.s IL_0033 + + IL_002e: ldc.i4.0 + IL_002f: conv.i8 + IL_0030: nop + IL_0031: br.s IL_0040 + + IL_0033: ldc.i4.1 + IL_0034: ldarg.1 + IL_0035: sub + IL_0036: ldarg.0 + IL_0037: not + IL_0038: ldc.i4.1 + IL_0039: add + IL_003a: div.un + IL_003b: conv.i8 + IL_003c: ldc.i4.1 + IL_003d: conv.i8 + IL_003e: add + IL_003f: nop + IL_0040: stloc.0 + IL_0041: ldloc.0 + IL_0042: stloc.1 + IL_0043: ldloc.1 + IL_0044: ldc.i4.1 + IL_0045: conv.i8 + IL_0046: bge.un.s IL_004e + + IL_0048: call !!0[] [runtime]System.Array::Empty() + IL_004d: ret + + IL_004e: ldloc.1 + IL_004f: conv.ovf.i.un + IL_0050: newarr [runtime]System.Int32 + IL_0055: stloc.2 + IL_0056: ldc.i4.0 + IL_0057: conv.i8 + IL_0058: stloc.3 + IL_0059: ldc.i4.1 + IL_005a: stloc.s V_4 + IL_005c: br.s IL_0073 + + IL_005e: ldloc.2 + IL_005f: ldloc.3 + IL_0060: conv.i + IL_0061: ldloc.s V_4 + IL_0063: stloc.s V_5 + IL_0065: ldloc.s V_5 + IL_0067: stelem.i4 + IL_0068: ldloc.s V_4 + IL_006a: ldarg.0 + IL_006b: add + IL_006c: stloc.s V_4 + IL_006e: ldloc.3 + IL_006f: ldc.i4.1 + IL_0070: conv.i8 + IL_0071: add + IL_0072: stloc.3 + IL_0073: ldloc.3 + IL_0074: ldloc.0 + IL_0075: blt.un.s IL_005e + + IL_0077: ldloc.2 + IL_0078: ret + } + + .method public static int32[] f18(int32 start, + int32 step, + int32 finish) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (uint64 V_0, + uint64 V_1, + int32[] V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: brtrue.s IL_0010 + + IL_0004: ldarg.0 + IL_0005: ldarg.1 + IL_0006: ldarg.2 + IL_0007: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_000c: pop + IL_000d: nop + IL_000e: br.s IL_0011 + + IL_0010: nop + IL_0011: ldc.i4.0 + IL_0012: ldarg.1 + IL_0013: bge.s IL_002a + + IL_0015: ldarg.2 + IL_0016: ldarg.0 + IL_0017: bge.s IL_001e + + IL_0019: ldc.i4.0 + IL_001a: conv.i8 + IL_001b: nop + IL_001c: br.s IL_0040 + + IL_001e: ldarg.2 + IL_001f: ldarg.0 + IL_0020: sub + IL_0021: ldarg.1 + IL_0022: div.un + IL_0023: conv.i8 + IL_0024: ldc.i4.1 + IL_0025: conv.i8 + IL_0026: add + IL_0027: nop + IL_0028: br.s IL_0040 + + IL_002a: ldarg.0 + IL_002b: ldarg.2 + IL_002c: bge.s IL_0033 + + IL_002e: ldc.i4.0 + IL_002f: conv.i8 + IL_0030: nop + IL_0031: br.s IL_0040 + + IL_0033: ldarg.0 + IL_0034: ldarg.2 + IL_0035: sub + IL_0036: ldarg.1 + IL_0037: not + IL_0038: ldc.i4.1 + IL_0039: add + IL_003a: div.un + IL_003b: conv.i8 + IL_003c: ldc.i4.1 + IL_003d: conv.i8 + IL_003e: add + IL_003f: nop + IL_0040: stloc.0 + IL_0041: ldloc.0 + IL_0042: stloc.1 + IL_0043: ldloc.1 + IL_0044: ldc.i4.1 + IL_0045: conv.i8 + IL_0046: bge.un.s IL_004e + + IL_0048: call !!0[] [runtime]System.Array::Empty() + IL_004d: ret + + IL_004e: ldloc.1 + IL_004f: conv.ovf.i.un + IL_0050: newarr [runtime]System.Int32 + IL_0055: stloc.2 + IL_0056: ldc.i4.0 + IL_0057: conv.i8 + IL_0058: stloc.3 + IL_0059: ldarg.0 + IL_005a: stloc.s V_4 + IL_005c: br.s IL_0073 + + IL_005e: ldloc.2 + IL_005f: ldloc.3 + IL_0060: conv.i + IL_0061: ldloc.s V_4 + IL_0063: stloc.s V_5 + IL_0065: ldloc.s V_5 + IL_0067: stelem.i4 + IL_0068: ldloc.s V_4 + IL_006a: ldarg.1 + IL_006b: add + IL_006c: stloc.s V_4 + IL_006e: ldloc.3 + IL_006f: ldc.i4.1 + IL_0070: conv.i8 + IL_0071: add + IL_0072: stloc.3 + IL_0073: ldloc.3 + IL_0074: ldloc.0 + IL_0075: blt.un.s IL_005e + + IL_0077: ldloc.2 + IL_0078: ret + } + + .method public static int32[] f19(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + + .maxstack 5 + .locals init (int32 V_0, + uint64 V_1, + uint64 V_2, + int32[] V_3, + uint64 V_4, + int32 V_5, + int32 V_6) + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0007: stloc.0 + IL_0008: ldc.i4.s 10 + IL_000a: ldloc.0 + IL_000b: bge.s IL_0012 + + IL_000d: ldc.i4.0 + IL_000e: conv.i8 + IL_000f: nop + IL_0010: br.s IL_001b + + IL_0012: ldc.i4.s 10 + IL_0014: ldloc.0 + IL_0015: sub + IL_0016: conv.i8 + IL_0017: ldc.i4.1 + IL_0018: conv.i8 + IL_0019: add + IL_001a: nop + IL_001b: stloc.1 + IL_001c: ldloc.1 + IL_001d: stloc.2 + IL_001e: ldloc.2 + IL_001f: ldc.i4.1 + IL_0020: conv.i8 + IL_0021: bge.un.s IL_0029 + + IL_0023: call !!0[] [runtime]System.Array::Empty() + IL_0028: ret + + IL_0029: ldloc.2 + IL_002a: conv.ovf.i.un + IL_002b: newarr [runtime]System.Int32 + IL_0030: stloc.3 + IL_0031: ldc.i4.0 + IL_0032: conv.i8 + IL_0033: stloc.s V_4 + IL_0035: ldloc.0 + IL_0036: stloc.s V_5 + IL_0038: br.s IL_0052 + + IL_003a: ldloc.3 + IL_003b: ldloc.s V_4 + IL_003d: conv.i + IL_003e: ldloc.s V_5 + IL_0040: stloc.s V_6 + IL_0042: ldloc.s V_6 + IL_0044: stelem.i4 + IL_0045: ldloc.s V_5 + IL_0047: ldc.i4.1 + IL_0048: add + IL_0049: stloc.s V_5 + IL_004b: ldloc.s V_4 + IL_004d: ldc.i4.1 + IL_004e: conv.i8 + IL_004f: add + IL_0050: stloc.s V_4 + IL_0052: ldloc.s V_4 + IL_0054: ldloc.1 + IL_0055: blt.un.s IL_003a + + IL_0057: ldloc.3 + IL_0058: ret + } + + .method public static int32[] f20(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + + .maxstack 5 + .locals init (int32 V_0, + uint64 V_1, + uint64 V_2, + int32[] V_3, + uint64 V_4, + int32 V_5, + int32 V_6) + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0007: stloc.0 + IL_0008: ldloc.0 + IL_0009: ldc.i4.1 + IL_000a: bge.s IL_0011 + + IL_000c: ldc.i4.0 + IL_000d: conv.i8 + IL_000e: nop + IL_000f: br.s IL_0019 + + IL_0011: ldloc.0 + IL_0012: ldc.i4.1 + IL_0013: sub + IL_0014: conv.i8 + IL_0015: ldc.i4.1 + IL_0016: conv.i8 + IL_0017: add + IL_0018: nop + IL_0019: stloc.1 + IL_001a: ldloc.1 + IL_001b: stloc.2 + IL_001c: ldloc.2 + IL_001d: ldc.i4.1 + IL_001e: conv.i8 + IL_001f: bge.un.s IL_0027 + + IL_0021: call !!0[] [runtime]System.Array::Empty() + IL_0026: ret + + IL_0027: ldloc.2 + IL_0028: conv.ovf.i.un + IL_0029: newarr [runtime]System.Int32 + IL_002e: stloc.3 + IL_002f: ldc.i4.0 + IL_0030: conv.i8 + IL_0031: stloc.s V_4 + IL_0033: ldc.i4.1 + IL_0034: stloc.s V_5 + IL_0036: br.s IL_0050 + + IL_0038: ldloc.3 + IL_0039: ldloc.s V_4 + IL_003b: conv.i + IL_003c: ldloc.s V_5 + IL_003e: stloc.s V_6 + IL_0040: ldloc.s V_6 + IL_0042: stelem.i4 + IL_0043: ldloc.s V_5 + IL_0045: ldc.i4.1 + IL_0046: add + IL_0047: stloc.s V_5 + IL_0049: ldloc.s V_4 + IL_004b: ldc.i4.1 + IL_004c: conv.i8 + IL_004d: add + IL_004e: stloc.s V_4 + IL_0050: ldloc.s V_4 + IL_0052: ldloc.1 + IL_0053: blt.un.s IL_0038 + + IL_0055: ldloc.3 + IL_0056: ret + } + + .method public static int32[] f21(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 5 + .locals init (int32 V_0, + int32 V_1, + uint64 V_2, + uint64 V_3, + int32[] V_4, + uint64 V_5, + int32 V_6, + int32 V_7) + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0007: stloc.0 + IL_0008: ldarg.1 + IL_0009: ldnull + IL_000a: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_000f: stloc.1 + IL_0010: ldloc.1 + IL_0011: ldloc.0 + IL_0012: bge.s IL_0019 + + IL_0014: ldc.i4.0 + IL_0015: conv.i8 + IL_0016: nop + IL_0017: br.s IL_0021 + + IL_0019: ldloc.1 + IL_001a: ldloc.0 + IL_001b: sub + IL_001c: conv.i8 + IL_001d: ldc.i4.1 + IL_001e: conv.i8 + IL_001f: add + IL_0020: nop + IL_0021: stloc.2 + IL_0022: ldloc.2 + IL_0023: stloc.3 + IL_0024: ldloc.3 + IL_0025: ldc.i4.1 + IL_0026: conv.i8 + IL_0027: bge.un.s IL_002f + + IL_0029: call !!0[] [runtime]System.Array::Empty() + IL_002e: ret + + IL_002f: ldloc.3 + IL_0030: conv.ovf.i.un + IL_0031: newarr [runtime]System.Int32 + IL_0036: stloc.s V_4 + IL_0038: ldc.i4.0 + IL_0039: conv.i8 + IL_003a: stloc.s V_5 + IL_003c: ldloc.0 + IL_003d: stloc.s V_6 + IL_003f: br.s IL_005a + + IL_0041: ldloc.s V_4 + IL_0043: ldloc.s V_5 + IL_0045: conv.i + IL_0046: ldloc.s V_6 + IL_0048: stloc.s V_7 + IL_004a: ldloc.s V_7 + IL_004c: stelem.i4 + IL_004d: ldloc.s V_6 + IL_004f: ldc.i4.1 + IL_0050: add + IL_0051: stloc.s V_6 + IL_0053: ldloc.s V_5 + IL_0055: ldc.i4.1 + IL_0056: conv.i8 + IL_0057: add + IL_0058: stloc.s V_5 + IL_005a: ldloc.s V_5 + IL_005c: ldloc.2 + IL_005d: blt.un.s IL_0041 + + IL_005f: ldloc.s V_4 + IL_0061: ret + } + + .method public static int32[] f22(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + + .maxstack 5 + .locals init (int32 V_0, + uint64 V_1, + uint64 V_2, + int32[] V_3, + uint64 V_4, + int32 V_5, + int32 V_6) + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0007: stloc.0 + IL_0008: ldc.i4.s 10 + IL_000a: ldloc.0 + IL_000b: bge.s IL_0012 + + IL_000d: ldc.i4.0 + IL_000e: conv.i8 + IL_000f: nop + IL_0010: br.s IL_001b + + IL_0012: ldc.i4.s 10 + IL_0014: ldloc.0 + IL_0015: sub + IL_0016: conv.i8 + IL_0017: ldc.i4.1 + IL_0018: conv.i8 + IL_0019: add + IL_001a: nop + IL_001b: stloc.1 + IL_001c: ldloc.1 + IL_001d: stloc.2 + IL_001e: ldloc.2 + IL_001f: ldc.i4.1 + IL_0020: conv.i8 + IL_0021: bge.un.s IL_0029 + + IL_0023: call !!0[] [runtime]System.Array::Empty() + IL_0028: ret + + IL_0029: ldloc.2 + IL_002a: conv.ovf.i.un + IL_002b: newarr [runtime]System.Int32 + IL_0030: stloc.3 + IL_0031: ldc.i4.0 + IL_0032: conv.i8 + IL_0033: stloc.s V_4 + IL_0035: ldloc.0 + IL_0036: stloc.s V_5 + IL_0038: br.s IL_0052 + + IL_003a: ldloc.3 + IL_003b: ldloc.s V_4 + IL_003d: conv.i + IL_003e: ldloc.s V_5 + IL_0040: stloc.s V_6 + IL_0042: ldloc.s V_6 + IL_0044: stelem.i4 + IL_0045: ldloc.s V_5 + IL_0047: ldc.i4.1 + IL_0048: add + IL_0049: stloc.s V_5 + IL_004b: ldloc.s V_4 + IL_004d: ldc.i4.1 + IL_004e: conv.i8 + IL_004f: add + IL_0050: stloc.s V_4 + IL_0052: ldloc.s V_4 + IL_0054: ldloc.1 + IL_0055: blt.un.s IL_003a + + IL_0057: ldloc.3 + IL_0058: ret + } + + .method public static int32[] f23(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + + .maxstack 5 + .locals init (int32 V_0, + uint64 V_1, + uint64 V_2, + int32[] V_3, + uint64 V_4, + int32 V_5, + int32 V_6) + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0007: stloc.0 + IL_0008: ldloc.0 + IL_0009: brtrue.s IL_0018 + + IL_000b: ldc.i4.1 + IL_000c: ldloc.0 + IL_000d: ldc.i4.s 10 + IL_000f: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_0014: pop + IL_0015: nop + IL_0016: br.s IL_0019 + + IL_0018: nop + IL_0019: ldc.i4.0 + IL_001a: ldloc.0 + IL_001b: bge.s IL_0034 + + IL_001d: ldc.i4.s 10 + IL_001f: ldc.i4.1 + IL_0020: bge.s IL_0027 + + IL_0022: ldc.i4.0 + IL_0023: conv.i8 + IL_0024: nop + IL_0025: br.s IL_004c + + IL_0027: ldc.i4.s 10 + IL_0029: ldc.i4.1 + IL_002a: sub + IL_002b: ldloc.0 + IL_002c: div.un + IL_002d: conv.i8 + IL_002e: ldc.i4.1 + IL_002f: conv.i8 + IL_0030: add + IL_0031: nop + IL_0032: br.s IL_004c + + IL_0034: ldc.i4.1 + IL_0035: ldc.i4.s 10 + IL_0037: bge.s IL_003e + + IL_0039: ldc.i4.0 + IL_003a: conv.i8 + IL_003b: nop + IL_003c: br.s IL_004c + + IL_003e: ldc.i4.1 + IL_003f: ldc.i4.s 10 + IL_0041: sub + IL_0042: ldloc.0 + IL_0043: not + IL_0044: ldc.i4.1 + IL_0045: add + IL_0046: div.un + IL_0047: conv.i8 + IL_0048: ldc.i4.1 + IL_0049: conv.i8 + IL_004a: add + IL_004b: nop + IL_004c: stloc.1 + IL_004d: ldloc.1 + IL_004e: stloc.2 + IL_004f: ldloc.2 + IL_0050: ldc.i4.1 + IL_0051: conv.i8 + IL_0052: bge.un.s IL_005a + + IL_0054: call !!0[] [runtime]System.Array::Empty() + IL_0059: ret + + IL_005a: ldloc.2 + IL_005b: conv.ovf.i.un + IL_005c: newarr [runtime]System.Int32 + IL_0061: stloc.3 + IL_0062: ldc.i4.0 + IL_0063: conv.i8 + IL_0064: stloc.s V_4 + IL_0066: ldc.i4.1 + IL_0067: stloc.s V_5 + IL_0069: br.s IL_0083 + + IL_006b: ldloc.3 + IL_006c: ldloc.s V_4 + IL_006e: conv.i + IL_006f: ldloc.s V_5 + IL_0071: stloc.s V_6 + IL_0073: ldloc.s V_6 + IL_0075: stelem.i4 + IL_0076: ldloc.s V_5 + IL_0078: ldloc.0 + IL_0079: add + IL_007a: stloc.s V_5 + IL_007c: ldloc.s V_4 + IL_007e: ldc.i4.1 + IL_007f: conv.i8 + IL_0080: add + IL_0081: stloc.s V_4 + IL_0083: ldloc.s V_4 + IL_0085: ldloc.1 + IL_0086: blt.un.s IL_006b + + IL_0088: ldloc.3 + IL_0089: ret + } + + .method public static int32[] f24(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + + .maxstack 5 + .locals init (int32 V_0, + uint64 V_1, + uint64 V_2, + int32[] V_3, + uint64 V_4, + int32 V_5, + int32 V_6) + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0007: stloc.0 + IL_0008: ldloc.0 + IL_0009: ldc.i4.1 + IL_000a: bge.s IL_0011 + + IL_000c: ldc.i4.0 + IL_000d: conv.i8 + IL_000e: nop + IL_000f: br.s IL_0019 + + IL_0011: ldloc.0 + IL_0012: ldc.i4.1 + IL_0013: sub + IL_0014: conv.i8 + IL_0015: ldc.i4.1 + IL_0016: conv.i8 + IL_0017: add + IL_0018: nop + IL_0019: stloc.1 + IL_001a: ldloc.1 + IL_001b: stloc.2 + IL_001c: ldloc.2 + IL_001d: ldc.i4.1 + IL_001e: conv.i8 + IL_001f: bge.un.s IL_0027 + + IL_0021: call !!0[] [runtime]System.Array::Empty() + IL_0026: ret + + IL_0027: ldloc.2 + IL_0028: conv.ovf.i.un + IL_0029: newarr [runtime]System.Int32 + IL_002e: stloc.3 + IL_002f: ldc.i4.0 + IL_0030: conv.i8 + IL_0031: stloc.s V_4 + IL_0033: ldc.i4.1 + IL_0034: stloc.s V_5 + IL_0036: br.s IL_0050 + + IL_0038: ldloc.3 + IL_0039: ldloc.s V_4 + IL_003b: conv.i + IL_003c: ldloc.s V_5 + IL_003e: stloc.s V_6 + IL_0040: ldloc.s V_6 + IL_0042: stelem.i4 + IL_0043: ldloc.s V_5 + IL_0045: ldc.i4.1 + IL_0046: add + IL_0047: stloc.s V_5 + IL_0049: ldloc.s V_4 + IL_004b: ldc.i4.1 + IL_004c: conv.i8 + IL_004d: add + IL_004e: stloc.s V_4 + IL_0050: ldloc.s V_4 + IL_0052: ldloc.1 + IL_0053: blt.un.s IL_0038 + + IL_0055: ldloc.3 + IL_0056: ret + } + + .method public static int32[] f25(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 h) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (int32 V_0, + int32 V_1, + int32 V_2, + uint64 V_3, + uint64 V_4, + int32[] V_5, + uint64 V_6, + int32 V_7, + int32 V_8) + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0007: stloc.0 + IL_0008: ldarg.1 + IL_0009: ldnull + IL_000a: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_000f: stloc.1 + IL_0010: ldarg.2 + IL_0011: ldnull + IL_0012: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0017: stloc.2 + IL_0018: ldloc.1 + IL_0019: brtrue.s IL_0027 + + IL_001b: ldloc.0 + IL_001c: ldloc.1 + IL_001d: ldloc.2 + IL_001e: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_0023: pop + IL_0024: nop + IL_0025: br.s IL_0028 + + IL_0027: nop + IL_0028: ldc.i4.0 + IL_0029: ldloc.1 + IL_002a: bge.s IL_0041 + + IL_002c: ldloc.2 + IL_002d: ldloc.0 + IL_002e: bge.s IL_0035 + + IL_0030: ldc.i4.0 + IL_0031: conv.i8 + IL_0032: nop + IL_0033: br.s IL_0057 + + IL_0035: ldloc.2 + IL_0036: ldloc.0 + IL_0037: sub + IL_0038: ldloc.1 + IL_0039: div.un + IL_003a: conv.i8 + IL_003b: ldc.i4.1 + IL_003c: conv.i8 + IL_003d: add + IL_003e: nop + IL_003f: br.s IL_0057 + + IL_0041: ldloc.0 + IL_0042: ldloc.2 + IL_0043: bge.s IL_004a + + IL_0045: ldc.i4.0 + IL_0046: conv.i8 + IL_0047: nop + IL_0048: br.s IL_0057 + + IL_004a: ldloc.0 + IL_004b: ldloc.2 + IL_004c: sub + IL_004d: ldloc.1 + IL_004e: not + IL_004f: ldc.i4.1 + IL_0050: add + IL_0051: div.un + IL_0052: conv.i8 + IL_0053: ldc.i4.1 + IL_0054: conv.i8 + IL_0055: add + IL_0056: nop + IL_0057: stloc.3 + IL_0058: ldloc.3 + IL_0059: stloc.s V_4 + IL_005b: ldloc.s V_4 + IL_005d: ldc.i4.1 + IL_005e: conv.i8 + IL_005f: bge.un.s IL_0067 + + IL_0061: call !!0[] [runtime]System.Array::Empty() + IL_0066: ret + + IL_0067: ldloc.s V_4 + IL_0069: conv.ovf.i.un + IL_006a: newarr [runtime]System.Int32 + IL_006f: stloc.s V_5 + IL_0071: ldc.i4.0 + IL_0072: conv.i8 + IL_0073: stloc.s V_6 + IL_0075: ldloc.0 + IL_0076: stloc.s V_7 + IL_0078: br.s IL_0093 + + IL_007a: ldloc.s V_5 + IL_007c: ldloc.s V_6 + IL_007e: conv.i + IL_007f: ldloc.s V_7 + IL_0081: stloc.s V_8 + IL_0083: ldloc.s V_8 + IL_0085: stelem.i4 + IL_0086: ldloc.s V_7 + IL_0088: ldloc.1 + IL_0089: add + IL_008a: stloc.s V_7 + IL_008c: ldloc.s V_6 + IL_008e: ldc.i4.1 + IL_008f: conv.i8 + IL_0090: add + IL_0091: stloc.s V_6 + IL_0093: ldloc.s V_6 + IL_0095: ldloc.3 + IL_0096: blt.un.s IL_007a + + IL_0098: ldloc.s V_5 + IL_009a: ret + } + + .method public static class [runtime]System.Tuple`2[] + f26(int32 start, + int32 step, + int32 finish) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 6 + .locals init (uint64 V_0, + uint64 V_1, + class [runtime]System.Tuple`2[] V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: brtrue.s IL_0010 + + IL_0004: ldarg.0 + IL_0005: ldarg.1 + IL_0006: ldarg.2 + IL_0007: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_000c: pop + IL_000d: nop + IL_000e: br.s IL_0011 + + IL_0010: nop + IL_0011: ldc.i4.0 + IL_0012: ldarg.1 + IL_0013: bge.s IL_002a + + IL_0015: ldarg.2 + IL_0016: ldarg.0 + IL_0017: bge.s IL_001e + + IL_0019: ldc.i4.0 + IL_001a: conv.i8 + IL_001b: nop + IL_001c: br.s IL_0040 + + IL_001e: ldarg.2 + IL_001f: ldarg.0 + IL_0020: sub + IL_0021: ldarg.1 + IL_0022: div.un + IL_0023: conv.i8 + IL_0024: ldc.i4.1 + IL_0025: conv.i8 + IL_0026: add + IL_0027: nop + IL_0028: br.s IL_0040 + + IL_002a: ldarg.0 + IL_002b: ldarg.2 + IL_002c: bge.s IL_0033 + + IL_002e: ldc.i4.0 + IL_002f: conv.i8 + IL_0030: nop + IL_0031: br.s IL_0040 + + IL_0033: ldarg.0 + IL_0034: ldarg.2 + IL_0035: sub + IL_0036: ldarg.1 + IL_0037: not + IL_0038: ldc.i4.1 + IL_0039: add + IL_003a: div.un + IL_003b: conv.i8 + IL_003c: ldc.i4.1 + IL_003d: conv.i8 + IL_003e: add + IL_003f: nop + IL_0040: stloc.0 + IL_0041: ldloc.0 + IL_0042: stloc.1 + IL_0043: ldloc.1 + IL_0044: ldc.i4.1 + IL_0045: conv.i8 + IL_0046: bge.un.s IL_004e + + IL_0048: call !!0[] [runtime]System.Array::Empty>() + IL_004d: ret + + IL_004e: ldloc.1 + IL_004f: conv.ovf.i.un + IL_0050: newarr class [runtime]System.Tuple`2 + IL_0055: stloc.2 + IL_0056: ldc.i4.0 + IL_0057: conv.i8 + IL_0058: stloc.3 + IL_0059: ldarg.0 + IL_005a: stloc.s V_4 + IL_005c: br.s IL_007f + + IL_005e: ldloc.2 + IL_005f: ldloc.3 + IL_0060: conv.i + IL_0061: ldloc.s V_4 + IL_0063: stloc.s V_5 + IL_0065: ldloc.s V_5 + IL_0067: ldloc.s V_5 + IL_0069: conv.r8 + IL_006a: newobj instance void class [runtime]System.Tuple`2::.ctor(!0, + !1) + IL_006f: stelem class [runtime]System.Tuple`2 + IL_0074: ldloc.s V_4 + IL_0076: ldarg.1 + IL_0077: add + IL_0078: stloc.s V_4 + IL_007a: ldloc.3 + IL_007b: ldc.i4.1 + IL_007c: conv.i8 + IL_007d: add + IL_007e: stloc.3 + IL_007f: ldloc.3 + IL_0080: ldloc.0 + IL_0081: blt.un.s IL_005e + + IL_0083: ldloc.2 + IL_0084: ret + } + + .method public static valuetype [runtime]System.ValueTuple`2[] + f27(int32 start, + int32 step, + int32 finish) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 6 + .locals init (uint64 V_0, + uint64 V_1, + valuetype [runtime]System.ValueTuple`2[] V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: brtrue.s IL_0010 + + IL_0004: ldarg.0 + IL_0005: ldarg.1 + IL_0006: ldarg.2 + IL_0007: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_000c: pop + IL_000d: nop + IL_000e: br.s IL_0011 + + IL_0010: nop + IL_0011: ldc.i4.0 + IL_0012: ldarg.1 + IL_0013: bge.s IL_002a + + IL_0015: ldarg.2 + IL_0016: ldarg.0 + IL_0017: bge.s IL_001e + + IL_0019: ldc.i4.0 + IL_001a: conv.i8 + IL_001b: nop + IL_001c: br.s IL_0040 + + IL_001e: ldarg.2 + IL_001f: ldarg.0 + IL_0020: sub + IL_0021: ldarg.1 + IL_0022: div.un + IL_0023: conv.i8 + IL_0024: ldc.i4.1 + IL_0025: conv.i8 + IL_0026: add + IL_0027: nop + IL_0028: br.s IL_0040 + + IL_002a: ldarg.0 + IL_002b: ldarg.2 + IL_002c: bge.s IL_0033 + + IL_002e: ldc.i4.0 + IL_002f: conv.i8 + IL_0030: nop + IL_0031: br.s IL_0040 + + IL_0033: ldarg.0 + IL_0034: ldarg.2 + IL_0035: sub + IL_0036: ldarg.1 + IL_0037: not + IL_0038: ldc.i4.1 + IL_0039: add + IL_003a: div.un + IL_003b: conv.i8 + IL_003c: ldc.i4.1 + IL_003d: conv.i8 + IL_003e: add + IL_003f: nop + IL_0040: stloc.0 + IL_0041: ldloc.0 + IL_0042: stloc.1 + IL_0043: ldloc.1 + IL_0044: ldc.i4.1 + IL_0045: conv.i8 + IL_0046: bge.un.s IL_004e + + IL_0048: call !!0[] [runtime]System.Array::Empty>() + IL_004d: ret + + IL_004e: ldloc.1 + IL_004f: conv.ovf.i.un + IL_0050: newarr valuetype [runtime]System.ValueTuple`2 + IL_0055: stloc.2 + IL_0056: ldc.i4.0 + IL_0057: conv.i8 + IL_0058: stloc.3 + IL_0059: ldarg.0 + IL_005a: stloc.s V_4 + IL_005c: br.s IL_007f + + IL_005e: ldloc.2 + IL_005f: ldloc.3 + IL_0060: conv.i + IL_0061: ldloc.s V_4 + IL_0063: stloc.s V_5 + IL_0065: ldloc.s V_5 + IL_0067: ldloc.s V_5 + IL_0069: conv.r8 + IL_006a: newobj instance void valuetype [runtime]System.ValueTuple`2::.ctor(!0, + !1) + IL_006f: stelem valuetype [runtime]System.ValueTuple`2 + IL_0074: ldloc.s V_4 + IL_0076: ldarg.1 + IL_0077: add + IL_0078: stloc.s V_4 + IL_007a: ldloc.3 + IL_007b: ldc.i4.1 + IL_007c: conv.i8 + IL_007d: add + IL_007e: stloc.3 + IL_007f: ldloc.3 + IL_0080: ldloc.0 + IL_0081: blt.un.s IL_005e + + IL_0083: ldloc.2 + IL_0084: ret + } + + .method public static int32[] f28(int32 start, + int32 step, + int32 finish) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 6 + .locals init (uint64 V_0, + uint64 V_1, + int32[] V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: brtrue.s IL_0010 + + IL_0004: ldarg.0 + IL_0005: ldarg.1 + IL_0006: ldarg.2 + IL_0007: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_000c: pop + IL_000d: nop + IL_000e: br.s IL_0011 + + IL_0010: nop + IL_0011: ldc.i4.0 + IL_0012: ldarg.1 + IL_0013: bge.s IL_002a + + IL_0015: ldarg.2 + IL_0016: ldarg.0 + IL_0017: bge.s IL_001e + + IL_0019: ldc.i4.0 + IL_001a: conv.i8 + IL_001b: nop + IL_001c: br.s IL_0040 + + IL_001e: ldarg.2 + IL_001f: ldarg.0 + IL_0020: sub + IL_0021: ldarg.1 + IL_0022: div.un + IL_0023: conv.i8 + IL_0024: ldc.i4.1 + IL_0025: conv.i8 + IL_0026: add + IL_0027: nop + IL_0028: br.s IL_0040 + + IL_002a: ldarg.0 + IL_002b: ldarg.2 + IL_002c: bge.s IL_0033 + + IL_002e: ldc.i4.0 + IL_002f: conv.i8 + IL_0030: nop + IL_0031: br.s IL_0040 + + IL_0033: ldarg.0 + IL_0034: ldarg.2 + IL_0035: sub + IL_0036: ldarg.1 + IL_0037: not + IL_0038: ldc.i4.1 + IL_0039: add + IL_003a: div.un + IL_003b: conv.i8 + IL_003c: ldc.i4.1 + IL_003d: conv.i8 + IL_003e: add + IL_003f: nop + IL_0040: stloc.0 + IL_0041: ldloc.0 + IL_0042: stloc.1 + IL_0043: ldloc.1 + IL_0044: ldc.i4.1 + IL_0045: conv.i8 + IL_0046: bge.un.s IL_004e + + IL_0048: call !!0[] [runtime]System.Array::Empty() + IL_004d: ret + + IL_004e: ldloc.1 + IL_004f: conv.ovf.i.un + IL_0050: newarr [runtime]System.Int32 + IL_0055: stloc.2 + IL_0056: ldc.i4.0 + IL_0057: conv.i8 + IL_0058: stloc.3 + IL_0059: ldarg.0 + IL_005a: stloc.s V_4 + IL_005c: br.s IL_0077 + + IL_005e: ldloc.2 + IL_005f: ldloc.3 + IL_0060: conv.i + IL_0061: ldloc.s V_4 + IL_0063: stloc.s V_5 + IL_0065: nop + IL_0066: ldloc.s V_5 + IL_0068: ldloc.s V_5 + IL_006a: mul + IL_006b: stelem.i4 + IL_006c: ldloc.s V_4 + IL_006e: ldarg.1 + IL_006f: add + IL_0070: stloc.s V_4 + IL_0072: ldloc.3 + IL_0073: ldc.i4.1 + IL_0074: conv.i8 + IL_0075: add + IL_0076: stloc.3 + IL_0077: ldloc.3 + IL_0078: ldloc.0 + IL_0079: blt.un.s IL_005e + + IL_007b: ldloc.2 + IL_007c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeLists.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeLists.fs new file mode 100644 index 00000000000..3562a5bfa71 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeLists.fs @@ -0,0 +1,32 @@ +let f0 f = [for n in 1..10 do f (); yield n] +let f00 f g = [|for n in 1..10 do f (); g (); yield n|] +let f000 f = [for n in 1..10 do f (); yield n; yield n + 1] +let f0000 () = [for n in 1..10 do yield n] +let f1 () = [for n in 1..10 -> n] +let f2 () = [for n in 10..1 -> n] +let f3 () = [for n in 1..1..10 -> n] +let f4 () = [for n in 1..2..10 -> n] +let f5 () = [for n in 10..1..1 -> n] +let f6 () = [for n in 1..-1..10 -> n] +let f7 () = [for n in 10..-1..1 -> n] +let f8 () = [for n in 10..-2..1 -> n] +let f9 start = [for n in start..10 -> n] +let f10 finish = [for n in 1..finish -> n] +let f11 start finish = [for n in start..finish -> n] +let f12 start = [for n in start..1..10 -> n] +let f13 step = [for n in 1..step..10 -> n] +let f14 finish = [for n in 1..1..finish -> n] +let f15 start step = [for n in start..step..10 -> n] +let f16 start finish = [for n in start..1..finish -> n] +let f17 step finish = [for n in 1..step..finish -> n] +let f18 start step finish = [for n in start..step..finish -> n] +let f19 f = [for n in f ()..10 -> n] +let f20 f = [for n in 1..f () -> n] +let f21 f g = [for n in f ()..g() -> n] +let f22 f = [for n in f ()..1..10 -> n] +let f23 f = [for n in 1..f ()..10 -> n] +let f24 f = [for n in 1..1..f () -> n] +let f25 f g h = [for n in f ()..g ()..h () -> n] +let f26 start step finish = [for n in start..step..finish -> n, float n] +let f27 start step finish = [for n in start..step..finish -> struct (n, float n)] +let f28 start step finish = [for n in start..step..finish -> let x = n + 1 in n * n] diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeLists.fs.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeLists.fs.il.bsl new file mode 100644 index 00000000000..e5a3adcb69c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeLists.fs.il.bsl @@ -0,0 +1,2166 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.mresource public FSharpSignatureData.assembly +{ + + +} +.mresource public FSharpOptimizationData.assembly +{ + + +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f0(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.0 + IL_0001: conv.i8 + IL_0002: stloc.1 + IL_0003: ldc.i4.1 + IL_0004: stloc.2 + IL_0005: br.s IL_0023 + + IL_0007: ldloca.s V_0 + IL_0009: ldloc.2 + IL_000a: stloc.3 + IL_000b: ldarg.0 + IL_000c: ldnull + IL_000d: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0012: pop + IL_0013: ldloc.3 + IL_0014: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0019: nop + IL_001a: ldloc.2 + IL_001b: ldc.i4.1 + IL_001c: add + IL_001d: stloc.2 + IL_001e: ldloc.1 + IL_001f: ldc.i4.1 + IL_0020: conv.i8 + IL_0021: add + IL_0022: stloc.1 + IL_0023: ldloc.1 + IL_0024: ldc.i4.s 10 + IL_0026: conv.i8 + IL_0027: blt.un.s IL_0007 + + IL_0029: ldloca.s V_0 + IL_002b: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0030: ret + } + + .method public static int32[] f00(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 6 + .locals init (int32[] V_0, + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.s 10 + IL_0002: conv.i8 + IL_0003: conv.ovf.i.un + IL_0004: newarr [runtime]System.Int32 + IL_0009: stloc.0 + IL_000a: ldc.i4.0 + IL_000b: conv.i8 + IL_000c: stloc.1 + IL_000d: ldc.i4.1 + IL_000e: stloc.2 + IL_000f: br.s IL_0031 + + IL_0011: ldloc.0 + IL_0012: ldloc.1 + IL_0013: conv.i + IL_0014: ldloc.2 + IL_0015: stloc.3 + IL_0016: ldarg.0 + IL_0017: ldnull + IL_0018: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001d: pop + IL_001e: ldarg.1 + IL_001f: ldnull + IL_0020: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0025: pop + IL_0026: ldloc.3 + IL_0027: stelem.i4 + IL_0028: ldloc.2 + IL_0029: ldc.i4.1 + IL_002a: add + IL_002b: stloc.2 + IL_002c: ldloc.1 + IL_002d: ldc.i4.1 + IL_002e: conv.i8 + IL_002f: add + IL_0030: stloc.1 + IL_0031: ldloc.1 + IL_0032: ldc.i4.s 10 + IL_0034: conv.i8 + IL_0035: blt.un.s IL_0011 + + IL_0037: ldloc.0 + IL_0038: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f000(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + class [runtime]System.Collections.Generic.IEnumerator`1 V_1, + class [runtime]System.Collections.Generic.IEnumerable`1 V_2, + int32 V_3, + class [runtime]System.IDisposable V_4) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: ldc.i4.1 + IL_0003: ldc.i4.s 10 + IL_0005: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_000a: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_000f: stloc.1 + .try + { + IL_0010: br.s IL_0035 + + IL_0012: ldloc.1 + IL_0013: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0018: stloc.3 + IL_0019: ldarg.0 + IL_001a: ldnull + IL_001b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0020: pop + IL_0021: ldloca.s V_0 + IL_0023: ldloc.3 + IL_0024: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0029: nop + IL_002a: ldloca.s V_0 + IL_002c: ldloc.3 + IL_002d: ldc.i4.1 + IL_002e: add + IL_002f: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0034: nop + IL_0035: ldloc.1 + IL_0036: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_003b: brtrue.s IL_0012 + + IL_003d: ldnull + IL_003e: stloc.2 + IL_003f: leave.s IL_0056 + + } + finally + { + IL_0041: ldloc.1 + IL_0042: isinst [runtime]System.IDisposable + IL_0047: stloc.s V_4 + IL_0049: ldloc.s V_4 + IL_004b: brfalse.s IL_0055 + + IL_004d: ldloc.s V_4 + IL_004f: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_0054: endfinally + IL_0055: endfinally + } + IL_0056: ldloc.2 + IL_0057: pop + IL_0058: ldloca.s V_0 + IL_005a: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_005f: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f0000() cil managed + { + + .maxstack 4 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.0 + IL_0001: conv.i8 + IL_0002: stloc.1 + IL_0003: ldc.i4.1 + IL_0004: stloc.2 + IL_0005: br.s IL_001b + + IL_0007: ldloca.s V_0 + IL_0009: ldloc.2 + IL_000a: stloc.3 + IL_000b: ldloc.3 + IL_000c: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0011: nop + IL_0012: ldloc.2 + IL_0013: ldc.i4.1 + IL_0014: add + IL_0015: stloc.2 + IL_0016: ldloc.1 + IL_0017: ldc.i4.1 + IL_0018: conv.i8 + IL_0019: add + IL_001a: stloc.1 + IL_001b: ldloc.1 + IL_001c: ldc.i4.s 10 + IL_001e: conv.i8 + IL_001f: blt.un.s IL_0007 + + IL_0021: ldloca.s V_0 + IL_0023: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0028: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f1() cil managed + { + + .maxstack 4 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.0 + IL_0001: conv.i8 + IL_0002: stloc.1 + IL_0003: ldc.i4.1 + IL_0004: stloc.2 + IL_0005: br.s IL_001b + + IL_0007: ldloca.s V_0 + IL_0009: ldloc.2 + IL_000a: stloc.3 + IL_000b: ldloc.3 + IL_000c: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0011: nop + IL_0012: ldloc.2 + IL_0013: ldc.i4.1 + IL_0014: add + IL_0015: stloc.2 + IL_0016: ldloc.1 + IL_0017: ldc.i4.1 + IL_0018: conv.i8 + IL_0019: add + IL_001a: stloc.1 + IL_001b: ldloc.1 + IL_001c: ldc.i4.s 10 + IL_001e: conv.i8 + IL_001f: blt.un.s IL_0007 + + IL_0021: ldloca.s V_0 + IL_0023: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0028: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f2() cil managed + { + + .maxstack 8 + IL_0000: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_0005: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f3() cil managed + { + + .maxstack 4 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.0 + IL_0001: conv.i8 + IL_0002: stloc.1 + IL_0003: ldc.i4.1 + IL_0004: stloc.2 + IL_0005: br.s IL_001b + + IL_0007: ldloca.s V_0 + IL_0009: ldloc.2 + IL_000a: stloc.3 + IL_000b: ldloc.3 + IL_000c: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0011: nop + IL_0012: ldloc.2 + IL_0013: ldc.i4.1 + IL_0014: add + IL_0015: stloc.2 + IL_0016: ldloc.1 + IL_0017: ldc.i4.1 + IL_0018: conv.i8 + IL_0019: add + IL_001a: stloc.1 + IL_001b: ldloc.1 + IL_001c: ldc.i4.s 10 + IL_001e: conv.i8 + IL_001f: blt.un.s IL_0007 + + IL_0021: ldloca.s V_0 + IL_0023: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0028: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f4() cil managed + { + + .maxstack 4 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.0 + IL_0001: conv.i8 + IL_0002: stloc.1 + IL_0003: ldc.i4.1 + IL_0004: stloc.2 + IL_0005: br.s IL_001b + + IL_0007: ldloca.s V_0 + IL_0009: ldloc.2 + IL_000a: stloc.3 + IL_000b: ldloc.3 + IL_000c: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0011: nop + IL_0012: ldloc.2 + IL_0013: ldc.i4.2 + IL_0014: add + IL_0015: stloc.2 + IL_0016: ldloc.1 + IL_0017: ldc.i4.1 + IL_0018: conv.i8 + IL_0019: add + IL_001a: stloc.1 + IL_001b: ldloc.1 + IL_001c: ldc.i4.5 + IL_001d: conv.i8 + IL_001e: blt.un.s IL_0007 + + IL_0020: ldloca.s V_0 + IL_0022: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0027: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f5() cil managed + { + + .maxstack 8 + IL_0000: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_0005: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f6() cil managed + { + + .maxstack 8 + IL_0000: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_0005: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f7() cil managed + { + + .maxstack 4 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.0 + IL_0001: conv.i8 + IL_0002: stloc.1 + IL_0003: ldc.i4.s 10 + IL_0005: stloc.2 + IL_0006: br.s IL_001c + + IL_0008: ldloca.s V_0 + IL_000a: ldloc.2 + IL_000b: stloc.3 + IL_000c: ldloc.3 + IL_000d: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0012: nop + IL_0013: ldloc.2 + IL_0014: ldc.i4.m1 + IL_0015: add + IL_0016: stloc.2 + IL_0017: ldloc.1 + IL_0018: ldc.i4.1 + IL_0019: conv.i8 + IL_001a: add + IL_001b: stloc.1 + IL_001c: ldloc.1 + IL_001d: ldc.i4.s 10 + IL_001f: conv.i8 + IL_0020: blt.un.s IL_0008 + + IL_0022: ldloca.s V_0 + IL_0024: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0029: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f8() cil managed + { + + .maxstack 4 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.0 + IL_0001: conv.i8 + IL_0002: stloc.1 + IL_0003: ldc.i4.s 10 + IL_0005: stloc.2 + IL_0006: br.s IL_001d + + IL_0008: ldloca.s V_0 + IL_000a: ldloc.2 + IL_000b: stloc.3 + IL_000c: ldloc.3 + IL_000d: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0012: nop + IL_0013: ldloc.2 + IL_0014: ldc.i4.s -2 + IL_0016: add + IL_0017: stloc.2 + IL_0018: ldloc.1 + IL_0019: ldc.i4.1 + IL_001a: conv.i8 + IL_001b: add + IL_001c: stloc.1 + IL_001d: ldloc.1 + IL_001e: ldc.i4.5 + IL_001f: conv.i8 + IL_0020: blt.un.s IL_0008 + + IL_0022: ldloca.s V_0 + IL_0024: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0029: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f9(int32 start) cil managed + { + + .maxstack 4 + .locals init (uint64 V_0, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_1, + uint64 V_2, + int32 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldc.i4.s 10 + IL_0003: ldarg.0 + IL_0004: bge.s IL_000b + + IL_0006: ldc.i4.0 + IL_0007: conv.i8 + IL_0008: nop + IL_0009: br.s IL_0014 + + IL_000b: ldc.i4.s 10 + IL_000d: ldarg.0 + IL_000e: sub + IL_000f: conv.i8 + IL_0010: ldc.i4.1 + IL_0011: conv.i8 + IL_0012: add + IL_0013: nop + IL_0014: stloc.0 + IL_0015: ldc.i4.0 + IL_0016: conv.i8 + IL_0017: stloc.2 + IL_0018: ldarg.0 + IL_0019: stloc.3 + IL_001a: br.s IL_0032 + + IL_001c: ldloca.s V_1 + IL_001e: ldloc.3 + IL_001f: stloc.s V_4 + IL_0021: ldloc.s V_4 + IL_0023: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0028: nop + IL_0029: ldloc.3 + IL_002a: ldc.i4.1 + IL_002b: add + IL_002c: stloc.3 + IL_002d: ldloc.2 + IL_002e: ldc.i4.1 + IL_002f: conv.i8 + IL_0030: add + IL_0031: stloc.2 + IL_0032: ldloc.2 + IL_0033: ldloc.0 + IL_0034: blt.un.s IL_001c + + IL_0036: ldloca.s V_1 + IL_0038: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_003d: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f10(int32 finish) cil managed + { + + .maxstack 4 + .locals init (uint64 V_0, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_1, + uint64 V_2, + int32 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.1 + IL_0003: bge.s IL_000a + + IL_0005: ldc.i4.0 + IL_0006: conv.i8 + IL_0007: nop + IL_0008: br.s IL_0012 + + IL_000a: ldarg.0 + IL_000b: ldc.i4.1 + IL_000c: sub + IL_000d: conv.i8 + IL_000e: ldc.i4.1 + IL_000f: conv.i8 + IL_0010: add + IL_0011: nop + IL_0012: stloc.0 + IL_0013: ldc.i4.0 + IL_0014: conv.i8 + IL_0015: stloc.2 + IL_0016: ldc.i4.1 + IL_0017: stloc.3 + IL_0018: br.s IL_0030 + + IL_001a: ldloca.s V_1 + IL_001c: ldloc.3 + IL_001d: stloc.s V_4 + IL_001f: ldloc.s V_4 + IL_0021: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0026: nop + IL_0027: ldloc.3 + IL_0028: ldc.i4.1 + IL_0029: add + IL_002a: stloc.3 + IL_002b: ldloc.2 + IL_002c: ldc.i4.1 + IL_002d: conv.i8 + IL_002e: add + IL_002f: stloc.2 + IL_0030: ldloc.2 + IL_0031: ldloc.0 + IL_0032: blt.un.s IL_001a + + IL_0034: ldloca.s V_1 + IL_0036: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_003b: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f11(int32 start, + int32 finish) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 4 + .locals init (uint64 V_0, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_1, + uint64 V_2, + int32 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.0 + IL_0003: bge.s IL_000a + + IL_0005: ldc.i4.0 + IL_0006: conv.i8 + IL_0007: nop + IL_0008: br.s IL_0012 + + IL_000a: ldarg.1 + IL_000b: ldarg.0 + IL_000c: sub + IL_000d: conv.i8 + IL_000e: ldc.i4.1 + IL_000f: conv.i8 + IL_0010: add + IL_0011: nop + IL_0012: stloc.0 + IL_0013: ldc.i4.0 + IL_0014: conv.i8 + IL_0015: stloc.2 + IL_0016: ldarg.0 + IL_0017: stloc.3 + IL_0018: br.s IL_0030 + + IL_001a: ldloca.s V_1 + IL_001c: ldloc.3 + IL_001d: stloc.s V_4 + IL_001f: ldloc.s V_4 + IL_0021: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0026: nop + IL_0027: ldloc.3 + IL_0028: ldc.i4.1 + IL_0029: add + IL_002a: stloc.3 + IL_002b: ldloc.2 + IL_002c: ldc.i4.1 + IL_002d: conv.i8 + IL_002e: add + IL_002f: stloc.2 + IL_0030: ldloc.2 + IL_0031: ldloc.0 + IL_0032: blt.un.s IL_001a + + IL_0034: ldloca.s V_1 + IL_0036: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_003b: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f12(int32 start) cil managed + { + + .maxstack 4 + .locals init (uint64 V_0, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_1, + uint64 V_2, + int32 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldc.i4.s 10 + IL_0003: ldarg.0 + IL_0004: bge.s IL_000b + + IL_0006: ldc.i4.0 + IL_0007: conv.i8 + IL_0008: nop + IL_0009: br.s IL_0014 + + IL_000b: ldc.i4.s 10 + IL_000d: ldarg.0 + IL_000e: sub + IL_000f: conv.i8 + IL_0010: ldc.i4.1 + IL_0011: conv.i8 + IL_0012: add + IL_0013: nop + IL_0014: stloc.0 + IL_0015: ldc.i4.0 + IL_0016: conv.i8 + IL_0017: stloc.2 + IL_0018: ldarg.0 + IL_0019: stloc.3 + IL_001a: br.s IL_0032 + + IL_001c: ldloca.s V_1 + IL_001e: ldloc.3 + IL_001f: stloc.s V_4 + IL_0021: ldloc.s V_4 + IL_0023: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0028: nop + IL_0029: ldloc.3 + IL_002a: ldc.i4.1 + IL_002b: add + IL_002c: stloc.3 + IL_002d: ldloc.2 + IL_002e: ldc.i4.1 + IL_002f: conv.i8 + IL_0030: add + IL_0031: stloc.2 + IL_0032: ldloc.2 + IL_0033: ldloc.0 + IL_0034: blt.un.s IL_001c + + IL_0036: ldloca.s V_1 + IL_0038: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_003d: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f13(int32 step) cil managed + { + + .maxstack 5 + .locals init (uint64 V_0, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_1, + uint64 V_2, + int32 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: brtrue.s IL_0011 + + IL_0004: ldc.i4.1 + IL_0005: ldarg.0 + IL_0006: ldc.i4.s 10 + IL_0008: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_000d: pop + IL_000e: nop + IL_000f: br.s IL_0012 + + IL_0011: nop + IL_0012: ldc.i4.0 + IL_0013: ldarg.0 + IL_0014: bge.s IL_002d + + IL_0016: ldc.i4.s 10 + IL_0018: ldc.i4.1 + IL_0019: bge.s IL_0020 + + IL_001b: ldc.i4.0 + IL_001c: conv.i8 + IL_001d: nop + IL_001e: br.s IL_0045 + + IL_0020: ldc.i4.s 10 + IL_0022: ldc.i4.1 + IL_0023: sub + IL_0024: ldarg.0 + IL_0025: div.un + IL_0026: conv.i8 + IL_0027: ldc.i4.1 + IL_0028: conv.i8 + IL_0029: add + IL_002a: nop + IL_002b: br.s IL_0045 + + IL_002d: ldc.i4.1 + IL_002e: ldc.i4.s 10 + IL_0030: bge.s IL_0037 + + IL_0032: ldc.i4.0 + IL_0033: conv.i8 + IL_0034: nop + IL_0035: br.s IL_0045 + + IL_0037: ldc.i4.1 + IL_0038: ldc.i4.s 10 + IL_003a: sub + IL_003b: ldarg.0 + IL_003c: not + IL_003d: ldc.i4.1 + IL_003e: add + IL_003f: div.un + IL_0040: conv.i8 + IL_0041: ldc.i4.1 + IL_0042: conv.i8 + IL_0043: add + IL_0044: nop + IL_0045: stloc.0 + IL_0046: ldc.i4.0 + IL_0047: conv.i8 + IL_0048: stloc.2 + IL_0049: ldc.i4.1 + IL_004a: stloc.3 + IL_004b: br.s IL_0063 + + IL_004d: ldloca.s V_1 + IL_004f: ldloc.3 + IL_0050: stloc.s V_4 + IL_0052: ldloc.s V_4 + IL_0054: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0059: nop + IL_005a: ldloc.3 + IL_005b: ldarg.0 + IL_005c: add + IL_005d: stloc.3 + IL_005e: ldloc.2 + IL_005f: ldc.i4.1 + IL_0060: conv.i8 + IL_0061: add + IL_0062: stloc.2 + IL_0063: ldloc.2 + IL_0064: ldloc.0 + IL_0065: blt.un.s IL_004d + + IL_0067: ldloca.s V_1 + IL_0069: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_006e: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f14(int32 finish) cil managed + { + + .maxstack 4 + .locals init (uint64 V_0, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_1, + uint64 V_2, + int32 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.1 + IL_0003: bge.s IL_000a + + IL_0005: ldc.i4.0 + IL_0006: conv.i8 + IL_0007: nop + IL_0008: br.s IL_0012 + + IL_000a: ldarg.0 + IL_000b: ldc.i4.1 + IL_000c: sub + IL_000d: conv.i8 + IL_000e: ldc.i4.1 + IL_000f: conv.i8 + IL_0010: add + IL_0011: nop + IL_0012: stloc.0 + IL_0013: ldc.i4.0 + IL_0014: conv.i8 + IL_0015: stloc.2 + IL_0016: ldc.i4.1 + IL_0017: stloc.3 + IL_0018: br.s IL_0030 + + IL_001a: ldloca.s V_1 + IL_001c: ldloc.3 + IL_001d: stloc.s V_4 + IL_001f: ldloc.s V_4 + IL_0021: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0026: nop + IL_0027: ldloc.3 + IL_0028: ldc.i4.1 + IL_0029: add + IL_002a: stloc.3 + IL_002b: ldloc.2 + IL_002c: ldc.i4.1 + IL_002d: conv.i8 + IL_002e: add + IL_002f: stloc.2 + IL_0030: ldloc.2 + IL_0031: ldloc.0 + IL_0032: blt.un.s IL_001a + + IL_0034: ldloca.s V_1 + IL_0036: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_003b: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f15(int32 start, + int32 step) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 5 + .locals init (uint64 V_0, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_1, + uint64 V_2, + int32 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: brtrue.s IL_0011 + + IL_0004: ldarg.0 + IL_0005: ldarg.1 + IL_0006: ldc.i4.s 10 + IL_0008: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_000d: pop + IL_000e: nop + IL_000f: br.s IL_0012 + + IL_0011: nop + IL_0012: ldc.i4.0 + IL_0013: ldarg.1 + IL_0014: bge.s IL_002d + + IL_0016: ldc.i4.s 10 + IL_0018: ldarg.0 + IL_0019: bge.s IL_0020 + + IL_001b: ldc.i4.0 + IL_001c: conv.i8 + IL_001d: nop + IL_001e: br.s IL_0045 + + IL_0020: ldc.i4.s 10 + IL_0022: ldarg.0 + IL_0023: sub + IL_0024: ldarg.1 + IL_0025: div.un + IL_0026: conv.i8 + IL_0027: ldc.i4.1 + IL_0028: conv.i8 + IL_0029: add + IL_002a: nop + IL_002b: br.s IL_0045 + + IL_002d: ldarg.0 + IL_002e: ldc.i4.s 10 + IL_0030: bge.s IL_0037 + + IL_0032: ldc.i4.0 + IL_0033: conv.i8 + IL_0034: nop + IL_0035: br.s IL_0045 + + IL_0037: ldarg.0 + IL_0038: ldc.i4.s 10 + IL_003a: sub + IL_003b: ldarg.1 + IL_003c: not + IL_003d: ldc.i4.1 + IL_003e: add + IL_003f: div.un + IL_0040: conv.i8 + IL_0041: ldc.i4.1 + IL_0042: conv.i8 + IL_0043: add + IL_0044: nop + IL_0045: stloc.0 + IL_0046: ldc.i4.0 + IL_0047: conv.i8 + IL_0048: stloc.2 + IL_0049: ldarg.0 + IL_004a: stloc.3 + IL_004b: br.s IL_0063 + + IL_004d: ldloca.s V_1 + IL_004f: ldloc.3 + IL_0050: stloc.s V_4 + IL_0052: ldloc.s V_4 + IL_0054: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0059: nop + IL_005a: ldloc.3 + IL_005b: ldarg.1 + IL_005c: add + IL_005d: stloc.3 + IL_005e: ldloc.2 + IL_005f: ldc.i4.1 + IL_0060: conv.i8 + IL_0061: add + IL_0062: stloc.2 + IL_0063: ldloc.2 + IL_0064: ldloc.0 + IL_0065: blt.un.s IL_004d + + IL_0067: ldloca.s V_1 + IL_0069: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_006e: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f16(int32 start, + int32 finish) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 4 + .locals init (uint64 V_0, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_1, + uint64 V_2, + int32 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.0 + IL_0003: bge.s IL_000a + + IL_0005: ldc.i4.0 + IL_0006: conv.i8 + IL_0007: nop + IL_0008: br.s IL_0012 + + IL_000a: ldarg.1 + IL_000b: ldarg.0 + IL_000c: sub + IL_000d: conv.i8 + IL_000e: ldc.i4.1 + IL_000f: conv.i8 + IL_0010: add + IL_0011: nop + IL_0012: stloc.0 + IL_0013: ldc.i4.0 + IL_0014: conv.i8 + IL_0015: stloc.2 + IL_0016: ldarg.0 + IL_0017: stloc.3 + IL_0018: br.s IL_0030 + + IL_001a: ldloca.s V_1 + IL_001c: ldloc.3 + IL_001d: stloc.s V_4 + IL_001f: ldloc.s V_4 + IL_0021: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0026: nop + IL_0027: ldloc.3 + IL_0028: ldc.i4.1 + IL_0029: add + IL_002a: stloc.3 + IL_002b: ldloc.2 + IL_002c: ldc.i4.1 + IL_002d: conv.i8 + IL_002e: add + IL_002f: stloc.2 + IL_0030: ldloc.2 + IL_0031: ldloc.0 + IL_0032: blt.un.s IL_001a + + IL_0034: ldloca.s V_1 + IL_0036: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_003b: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f17(int32 step, + int32 finish) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 5 + .locals init (uint64 V_0, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_1, + uint64 V_2, + int32 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: brtrue.s IL_0010 + + IL_0004: ldc.i4.1 + IL_0005: ldarg.0 + IL_0006: ldarg.1 + IL_0007: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_000c: pop + IL_000d: nop + IL_000e: br.s IL_0011 + + IL_0010: nop + IL_0011: ldc.i4.0 + IL_0012: ldarg.0 + IL_0013: bge.s IL_002a + + IL_0015: ldarg.1 + IL_0016: ldc.i4.1 + IL_0017: bge.s IL_001e + + IL_0019: ldc.i4.0 + IL_001a: conv.i8 + IL_001b: nop + IL_001c: br.s IL_0040 + + IL_001e: ldarg.1 + IL_001f: ldc.i4.1 + IL_0020: sub + IL_0021: ldarg.0 + IL_0022: div.un + IL_0023: conv.i8 + IL_0024: ldc.i4.1 + IL_0025: conv.i8 + IL_0026: add + IL_0027: nop + IL_0028: br.s IL_0040 + + IL_002a: ldc.i4.1 + IL_002b: ldarg.1 + IL_002c: bge.s IL_0033 + + IL_002e: ldc.i4.0 + IL_002f: conv.i8 + IL_0030: nop + IL_0031: br.s IL_0040 + + IL_0033: ldc.i4.1 + IL_0034: ldarg.1 + IL_0035: sub + IL_0036: ldarg.0 + IL_0037: not + IL_0038: ldc.i4.1 + IL_0039: add + IL_003a: div.un + IL_003b: conv.i8 + IL_003c: ldc.i4.1 + IL_003d: conv.i8 + IL_003e: add + IL_003f: nop + IL_0040: stloc.0 + IL_0041: ldc.i4.0 + IL_0042: conv.i8 + IL_0043: stloc.2 + IL_0044: ldc.i4.1 + IL_0045: stloc.3 + IL_0046: br.s IL_005e + + IL_0048: ldloca.s V_1 + IL_004a: ldloc.3 + IL_004b: stloc.s V_4 + IL_004d: ldloc.s V_4 + IL_004f: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0054: nop + IL_0055: ldloc.3 + IL_0056: ldarg.0 + IL_0057: add + IL_0058: stloc.3 + IL_0059: ldloc.2 + IL_005a: ldc.i4.1 + IL_005b: conv.i8 + IL_005c: add + IL_005d: stloc.2 + IL_005e: ldloc.2 + IL_005f: ldloc.0 + IL_0060: blt.un.s IL_0048 + + IL_0062: ldloca.s V_1 + IL_0064: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0069: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f18(int32 start, + int32 step, + int32 finish) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (uint64 V_0, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_1, + uint64 V_2, + int32 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: brtrue.s IL_0010 + + IL_0004: ldarg.0 + IL_0005: ldarg.1 + IL_0006: ldarg.2 + IL_0007: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_000c: pop + IL_000d: nop + IL_000e: br.s IL_0011 + + IL_0010: nop + IL_0011: ldc.i4.0 + IL_0012: ldarg.1 + IL_0013: bge.s IL_002a + + IL_0015: ldarg.2 + IL_0016: ldarg.0 + IL_0017: bge.s IL_001e + + IL_0019: ldc.i4.0 + IL_001a: conv.i8 + IL_001b: nop + IL_001c: br.s IL_0040 + + IL_001e: ldarg.2 + IL_001f: ldarg.0 + IL_0020: sub + IL_0021: ldarg.1 + IL_0022: div.un + IL_0023: conv.i8 + IL_0024: ldc.i4.1 + IL_0025: conv.i8 + IL_0026: add + IL_0027: nop + IL_0028: br.s IL_0040 + + IL_002a: ldarg.0 + IL_002b: ldarg.2 + IL_002c: bge.s IL_0033 + + IL_002e: ldc.i4.0 + IL_002f: conv.i8 + IL_0030: nop + IL_0031: br.s IL_0040 + + IL_0033: ldarg.0 + IL_0034: ldarg.2 + IL_0035: sub + IL_0036: ldarg.1 + IL_0037: not + IL_0038: ldc.i4.1 + IL_0039: add + IL_003a: div.un + IL_003b: conv.i8 + IL_003c: ldc.i4.1 + IL_003d: conv.i8 + IL_003e: add + IL_003f: nop + IL_0040: stloc.0 + IL_0041: ldc.i4.0 + IL_0042: conv.i8 + IL_0043: stloc.2 + IL_0044: ldarg.0 + IL_0045: stloc.3 + IL_0046: br.s IL_005e + + IL_0048: ldloca.s V_1 + IL_004a: ldloc.3 + IL_004b: stloc.s V_4 + IL_004d: ldloc.s V_4 + IL_004f: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0054: nop + IL_0055: ldloc.3 + IL_0056: ldarg.1 + IL_0057: add + IL_0058: stloc.3 + IL_0059: ldloc.2 + IL_005a: ldc.i4.1 + IL_005b: conv.i8 + IL_005c: add + IL_005d: stloc.2 + IL_005e: ldloc.2 + IL_005f: ldloc.0 + IL_0060: blt.un.s IL_0048 + + IL_0062: ldloca.s V_1 + IL_0064: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0069: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f19(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + + .maxstack 4 + .locals init (int32 V_0, + uint64 V_1, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0007: stloc.0 + IL_0008: ldc.i4.s 10 + IL_000a: ldloc.0 + IL_000b: bge.s IL_0012 + + IL_000d: ldc.i4.0 + IL_000e: conv.i8 + IL_000f: nop + IL_0010: br.s IL_001b + + IL_0012: ldc.i4.s 10 + IL_0014: ldloc.0 + IL_0015: sub + IL_0016: conv.i8 + IL_0017: ldc.i4.1 + IL_0018: conv.i8 + IL_0019: add + IL_001a: nop + IL_001b: stloc.1 + IL_001c: ldc.i4.0 + IL_001d: conv.i8 + IL_001e: stloc.3 + IL_001f: ldloc.0 + IL_0020: stloc.s V_4 + IL_0022: br.s IL_003d + + IL_0024: ldloca.s V_2 + IL_0026: ldloc.s V_4 + IL_0028: stloc.s V_5 + IL_002a: ldloc.s V_5 + IL_002c: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0031: nop + IL_0032: ldloc.s V_4 + IL_0034: ldc.i4.1 + IL_0035: add + IL_0036: stloc.s V_4 + IL_0038: ldloc.3 + IL_0039: ldc.i4.1 + IL_003a: conv.i8 + IL_003b: add + IL_003c: stloc.3 + IL_003d: ldloc.3 + IL_003e: ldloc.1 + IL_003f: blt.un.s IL_0024 + + IL_0041: ldloca.s V_2 + IL_0043: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0048: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f20(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + + .maxstack 4 + .locals init (int32 V_0, + uint64 V_1, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0007: stloc.0 + IL_0008: ldloc.0 + IL_0009: ldc.i4.1 + IL_000a: bge.s IL_0011 + + IL_000c: ldc.i4.0 + IL_000d: conv.i8 + IL_000e: nop + IL_000f: br.s IL_0019 + + IL_0011: ldloc.0 + IL_0012: ldc.i4.1 + IL_0013: sub + IL_0014: conv.i8 + IL_0015: ldc.i4.1 + IL_0016: conv.i8 + IL_0017: add + IL_0018: nop + IL_0019: stloc.1 + IL_001a: ldc.i4.0 + IL_001b: conv.i8 + IL_001c: stloc.3 + IL_001d: ldc.i4.1 + IL_001e: stloc.s V_4 + IL_0020: br.s IL_003b + + IL_0022: ldloca.s V_2 + IL_0024: ldloc.s V_4 + IL_0026: stloc.s V_5 + IL_0028: ldloc.s V_5 + IL_002a: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_002f: nop + IL_0030: ldloc.s V_4 + IL_0032: ldc.i4.1 + IL_0033: add + IL_0034: stloc.s V_4 + IL_0036: ldloc.3 + IL_0037: ldc.i4.1 + IL_0038: conv.i8 + IL_0039: add + IL_003a: stloc.3 + IL_003b: ldloc.3 + IL_003c: ldloc.1 + IL_003d: blt.un.s IL_0022 + + IL_003f: ldloca.s V_2 + IL_0041: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0046: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f21(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 4 + .locals init (int32 V_0, + int32 V_1, + uint64 V_2, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_3, + uint64 V_4, + int32 V_5, + int32 V_6) + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0007: stloc.0 + IL_0008: ldarg.1 + IL_0009: ldnull + IL_000a: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_000f: stloc.1 + IL_0010: ldloc.1 + IL_0011: ldloc.0 + IL_0012: bge.s IL_0019 + + IL_0014: ldc.i4.0 + IL_0015: conv.i8 + IL_0016: nop + IL_0017: br.s IL_0021 + + IL_0019: ldloc.1 + IL_001a: ldloc.0 + IL_001b: sub + IL_001c: conv.i8 + IL_001d: ldc.i4.1 + IL_001e: conv.i8 + IL_001f: add + IL_0020: nop + IL_0021: stloc.2 + IL_0022: ldc.i4.0 + IL_0023: conv.i8 + IL_0024: stloc.s V_4 + IL_0026: ldloc.0 + IL_0027: stloc.s V_5 + IL_0029: br.s IL_0046 + + IL_002b: ldloca.s V_3 + IL_002d: ldloc.s V_5 + IL_002f: stloc.s V_6 + IL_0031: ldloc.s V_6 + IL_0033: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0038: nop + IL_0039: ldloc.s V_5 + IL_003b: ldc.i4.1 + IL_003c: add + IL_003d: stloc.s V_5 + IL_003f: ldloc.s V_4 + IL_0041: ldc.i4.1 + IL_0042: conv.i8 + IL_0043: add + IL_0044: stloc.s V_4 + IL_0046: ldloc.s V_4 + IL_0048: ldloc.2 + IL_0049: blt.un.s IL_002b + + IL_004b: ldloca.s V_3 + IL_004d: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0052: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f22(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + + .maxstack 4 + .locals init (int32 V_0, + uint64 V_1, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0007: stloc.0 + IL_0008: ldc.i4.s 10 + IL_000a: ldloc.0 + IL_000b: bge.s IL_0012 + + IL_000d: ldc.i4.0 + IL_000e: conv.i8 + IL_000f: nop + IL_0010: br.s IL_001b + + IL_0012: ldc.i4.s 10 + IL_0014: ldloc.0 + IL_0015: sub + IL_0016: conv.i8 + IL_0017: ldc.i4.1 + IL_0018: conv.i8 + IL_0019: add + IL_001a: nop + IL_001b: stloc.1 + IL_001c: ldc.i4.0 + IL_001d: conv.i8 + IL_001e: stloc.3 + IL_001f: ldloc.0 + IL_0020: stloc.s V_4 + IL_0022: br.s IL_003d + + IL_0024: ldloca.s V_2 + IL_0026: ldloc.s V_4 + IL_0028: stloc.s V_5 + IL_002a: ldloc.s V_5 + IL_002c: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0031: nop + IL_0032: ldloc.s V_4 + IL_0034: ldc.i4.1 + IL_0035: add + IL_0036: stloc.s V_4 + IL_0038: ldloc.3 + IL_0039: ldc.i4.1 + IL_003a: conv.i8 + IL_003b: add + IL_003c: stloc.3 + IL_003d: ldloc.3 + IL_003e: ldloc.1 + IL_003f: blt.un.s IL_0024 + + IL_0041: ldloca.s V_2 + IL_0043: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0048: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f23(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + + .maxstack 5 + .locals init (int32 V_0, + uint64 V_1, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0007: stloc.0 + IL_0008: ldloc.0 + IL_0009: brtrue.s IL_0018 + + IL_000b: ldc.i4.1 + IL_000c: ldloc.0 + IL_000d: ldc.i4.s 10 + IL_000f: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_0014: pop + IL_0015: nop + IL_0016: br.s IL_0019 + + IL_0018: nop + IL_0019: ldc.i4.0 + IL_001a: ldloc.0 + IL_001b: bge.s IL_0034 + + IL_001d: ldc.i4.s 10 + IL_001f: ldc.i4.1 + IL_0020: bge.s IL_0027 + + IL_0022: ldc.i4.0 + IL_0023: conv.i8 + IL_0024: nop + IL_0025: br.s IL_004c + + IL_0027: ldc.i4.s 10 + IL_0029: ldc.i4.1 + IL_002a: sub + IL_002b: ldloc.0 + IL_002c: div.un + IL_002d: conv.i8 + IL_002e: ldc.i4.1 + IL_002f: conv.i8 + IL_0030: add + IL_0031: nop + IL_0032: br.s IL_004c + + IL_0034: ldc.i4.1 + IL_0035: ldc.i4.s 10 + IL_0037: bge.s IL_003e + + IL_0039: ldc.i4.0 + IL_003a: conv.i8 + IL_003b: nop + IL_003c: br.s IL_004c + + IL_003e: ldc.i4.1 + IL_003f: ldc.i4.s 10 + IL_0041: sub + IL_0042: ldloc.0 + IL_0043: not + IL_0044: ldc.i4.1 + IL_0045: add + IL_0046: div.un + IL_0047: conv.i8 + IL_0048: ldc.i4.1 + IL_0049: conv.i8 + IL_004a: add + IL_004b: nop + IL_004c: stloc.1 + IL_004d: ldc.i4.0 + IL_004e: conv.i8 + IL_004f: stloc.3 + IL_0050: ldc.i4.1 + IL_0051: stloc.s V_4 + IL_0053: br.s IL_006e + + IL_0055: ldloca.s V_2 + IL_0057: ldloc.s V_4 + IL_0059: stloc.s V_5 + IL_005b: ldloc.s V_5 + IL_005d: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0062: nop + IL_0063: ldloc.s V_4 + IL_0065: ldloc.0 + IL_0066: add + IL_0067: stloc.s V_4 + IL_0069: ldloc.3 + IL_006a: ldc.i4.1 + IL_006b: conv.i8 + IL_006c: add + IL_006d: stloc.3 + IL_006e: ldloc.3 + IL_006f: ldloc.1 + IL_0070: blt.un.s IL_0055 + + IL_0072: ldloca.s V_2 + IL_0074: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0079: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f24(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + + .maxstack 4 + .locals init (int32 V_0, + uint64 V_1, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_2, + uint64 V_3, + int32 V_4, + int32 V_5) + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0007: stloc.0 + IL_0008: ldloc.0 + IL_0009: ldc.i4.1 + IL_000a: bge.s IL_0011 + + IL_000c: ldc.i4.0 + IL_000d: conv.i8 + IL_000e: nop + IL_000f: br.s IL_0019 + + IL_0011: ldloc.0 + IL_0012: ldc.i4.1 + IL_0013: sub + IL_0014: conv.i8 + IL_0015: ldc.i4.1 + IL_0016: conv.i8 + IL_0017: add + IL_0018: nop + IL_0019: stloc.1 + IL_001a: ldc.i4.0 + IL_001b: conv.i8 + IL_001c: stloc.3 + IL_001d: ldc.i4.1 + IL_001e: stloc.s V_4 + IL_0020: br.s IL_003b + + IL_0022: ldloca.s V_2 + IL_0024: ldloc.s V_4 + IL_0026: stloc.s V_5 + IL_0028: ldloc.s V_5 + IL_002a: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_002f: nop + IL_0030: ldloc.s V_4 + IL_0032: ldc.i4.1 + IL_0033: add + IL_0034: stloc.s V_4 + IL_0036: ldloc.3 + IL_0037: ldc.i4.1 + IL_0038: conv.i8 + IL_0039: add + IL_003a: stloc.3 + IL_003b: ldloc.3 + IL_003c: ldloc.1 + IL_003d: blt.un.s IL_0022 + + IL_003f: ldloca.s V_2 + IL_0041: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0046: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f25(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 h) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (int32 V_0, + int32 V_1, + int32 V_2, + uint64 V_3, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_4, + uint64 V_5, + int32 V_6, + int32 V_7) + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0007: stloc.0 + IL_0008: ldarg.1 + IL_0009: ldnull + IL_000a: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_000f: stloc.1 + IL_0010: ldarg.2 + IL_0011: ldnull + IL_0012: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0017: stloc.2 + IL_0018: ldloc.1 + IL_0019: brtrue.s IL_0027 + + IL_001b: ldloc.0 + IL_001c: ldloc.1 + IL_001d: ldloc.2 + IL_001e: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_0023: pop + IL_0024: nop + IL_0025: br.s IL_0028 + + IL_0027: nop + IL_0028: ldc.i4.0 + IL_0029: ldloc.1 + IL_002a: bge.s IL_0041 + + IL_002c: ldloc.2 + IL_002d: ldloc.0 + IL_002e: bge.s IL_0035 + + IL_0030: ldc.i4.0 + IL_0031: conv.i8 + IL_0032: nop + IL_0033: br.s IL_0057 + + IL_0035: ldloc.2 + IL_0036: ldloc.0 + IL_0037: sub + IL_0038: ldloc.1 + IL_0039: div.un + IL_003a: conv.i8 + IL_003b: ldc.i4.1 + IL_003c: conv.i8 + IL_003d: add + IL_003e: nop + IL_003f: br.s IL_0057 + + IL_0041: ldloc.0 + IL_0042: ldloc.2 + IL_0043: bge.s IL_004a + + IL_0045: ldc.i4.0 + IL_0046: conv.i8 + IL_0047: nop + IL_0048: br.s IL_0057 + + IL_004a: ldloc.0 + IL_004b: ldloc.2 + IL_004c: sub + IL_004d: ldloc.1 + IL_004e: not + IL_004f: ldc.i4.1 + IL_0050: add + IL_0051: div.un + IL_0052: conv.i8 + IL_0053: ldc.i4.1 + IL_0054: conv.i8 + IL_0055: add + IL_0056: nop + IL_0057: stloc.3 + IL_0058: ldc.i4.0 + IL_0059: conv.i8 + IL_005a: stloc.s V_5 + IL_005c: ldloc.0 + IL_005d: stloc.s V_6 + IL_005f: br.s IL_007c + + IL_0061: ldloca.s V_4 + IL_0063: ldloc.s V_6 + IL_0065: stloc.s V_7 + IL_0067: ldloc.s V_7 + IL_0069: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_006e: nop + IL_006f: ldloc.s V_6 + IL_0071: ldloc.1 + IL_0072: add + IL_0073: stloc.s V_6 + IL_0075: ldloc.s V_5 + IL_0077: ldc.i4.1 + IL_0078: conv.i8 + IL_0079: add + IL_007a: stloc.s V_5 + IL_007c: ldloc.s V_5 + IL_007e: ldloc.3 + IL_007f: blt.un.s IL_0061 + + IL_0081: ldloca.s V_4 + IL_0083: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0088: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> + f26(int32 start, + int32 step, + int32 finish) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (uint64 V_0, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1> V_1, + uint64 V_2, + int32 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: brtrue.s IL_0010 + + IL_0004: ldarg.0 + IL_0005: ldarg.1 + IL_0006: ldarg.2 + IL_0007: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_000c: pop + IL_000d: nop + IL_000e: br.s IL_0011 + + IL_0010: nop + IL_0011: ldc.i4.0 + IL_0012: ldarg.1 + IL_0013: bge.s IL_002a + + IL_0015: ldarg.2 + IL_0016: ldarg.0 + IL_0017: bge.s IL_001e + + IL_0019: ldc.i4.0 + IL_001a: conv.i8 + IL_001b: nop + IL_001c: br.s IL_0040 + + IL_001e: ldarg.2 + IL_001f: ldarg.0 + IL_0020: sub + IL_0021: ldarg.1 + IL_0022: div.un + IL_0023: conv.i8 + IL_0024: ldc.i4.1 + IL_0025: conv.i8 + IL_0026: add + IL_0027: nop + IL_0028: br.s IL_0040 + + IL_002a: ldarg.0 + IL_002b: ldarg.2 + IL_002c: bge.s IL_0033 + + IL_002e: ldc.i4.0 + IL_002f: conv.i8 + IL_0030: nop + IL_0031: br.s IL_0040 + + IL_0033: ldarg.0 + IL_0034: ldarg.2 + IL_0035: sub + IL_0036: ldarg.1 + IL_0037: not + IL_0038: ldc.i4.1 + IL_0039: add + IL_003a: div.un + IL_003b: conv.i8 + IL_003c: ldc.i4.1 + IL_003d: conv.i8 + IL_003e: add + IL_003f: nop + IL_0040: stloc.0 + IL_0041: ldc.i4.0 + IL_0042: conv.i8 + IL_0043: stloc.2 + IL_0044: ldarg.0 + IL_0045: stloc.3 + IL_0046: br.s IL_0066 + + IL_0048: ldloca.s V_1 + IL_004a: ldloc.3 + IL_004b: stloc.s V_4 + IL_004d: ldloc.s V_4 + IL_004f: ldloc.s V_4 + IL_0051: conv.r8 + IL_0052: newobj instance void class [runtime]System.Tuple`2::.ctor(!0, + !1) + IL_0057: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1>::Add(!0) + IL_005c: nop + IL_005d: ldloc.3 + IL_005e: ldarg.1 + IL_005f: add + IL_0060: stloc.3 + IL_0061: ldloc.2 + IL_0062: ldc.i4.1 + IL_0063: conv.i8 + IL_0064: add + IL_0065: stloc.2 + IL_0066: ldloc.2 + IL_0067: ldloc.0 + IL_0068: blt.un.s IL_0048 + + IL_006a: ldloca.s V_1 + IL_006c: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1>::Close() + IL_0071: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> + f27(int32 start, + int32 step, + int32 finish) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (uint64 V_0, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1> V_1, + uint64 V_2, + int32 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: brtrue.s IL_0010 + + IL_0004: ldarg.0 + IL_0005: ldarg.1 + IL_0006: ldarg.2 + IL_0007: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_000c: pop + IL_000d: nop + IL_000e: br.s IL_0011 + + IL_0010: nop + IL_0011: ldc.i4.0 + IL_0012: ldarg.1 + IL_0013: bge.s IL_002a + + IL_0015: ldarg.2 + IL_0016: ldarg.0 + IL_0017: bge.s IL_001e + + IL_0019: ldc.i4.0 + IL_001a: conv.i8 + IL_001b: nop + IL_001c: br.s IL_0040 + + IL_001e: ldarg.2 + IL_001f: ldarg.0 + IL_0020: sub + IL_0021: ldarg.1 + IL_0022: div.un + IL_0023: conv.i8 + IL_0024: ldc.i4.1 + IL_0025: conv.i8 + IL_0026: add + IL_0027: nop + IL_0028: br.s IL_0040 + + IL_002a: ldarg.0 + IL_002b: ldarg.2 + IL_002c: bge.s IL_0033 + + IL_002e: ldc.i4.0 + IL_002f: conv.i8 + IL_0030: nop + IL_0031: br.s IL_0040 + + IL_0033: ldarg.0 + IL_0034: ldarg.2 + IL_0035: sub + IL_0036: ldarg.1 + IL_0037: not + IL_0038: ldc.i4.1 + IL_0039: add + IL_003a: div.un + IL_003b: conv.i8 + IL_003c: ldc.i4.1 + IL_003d: conv.i8 + IL_003e: add + IL_003f: nop + IL_0040: stloc.0 + IL_0041: ldc.i4.0 + IL_0042: conv.i8 + IL_0043: stloc.2 + IL_0044: ldarg.0 + IL_0045: stloc.3 + IL_0046: br.s IL_0066 + + IL_0048: ldloca.s V_1 + IL_004a: ldloc.3 + IL_004b: stloc.s V_4 + IL_004d: ldloc.s V_4 + IL_004f: ldloc.s V_4 + IL_0051: conv.r8 + IL_0052: newobj instance void valuetype [runtime]System.ValueTuple`2::.ctor(!0, + !1) + IL_0057: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1>::Add(!0) + IL_005c: nop + IL_005d: ldloc.3 + IL_005e: ldarg.1 + IL_005f: add + IL_0060: stloc.3 + IL_0061: ldloc.2 + IL_0062: ldc.i4.1 + IL_0063: conv.i8 + IL_0064: add + IL_0065: stloc.2 + IL_0066: ldloc.2 + IL_0067: ldloc.0 + IL_0068: blt.un.s IL_0048 + + IL_006a: ldloca.s V_1 + IL_006c: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1>::Close() + IL_0071: ret + } + + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f28(int32 start, + int32 step, + int32 finish) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 5 + .locals init (uint64 V_0, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_1, + uint64 V_2, + int32 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: brtrue.s IL_0010 + + IL_0004: ldarg.0 + IL_0005: ldarg.1 + IL_0006: ldarg.2 + IL_0007: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_000c: pop + IL_000d: nop + IL_000e: br.s IL_0011 + + IL_0010: nop + IL_0011: ldc.i4.0 + IL_0012: ldarg.1 + IL_0013: bge.s IL_002a + + IL_0015: ldarg.2 + IL_0016: ldarg.0 + IL_0017: bge.s IL_001e + + IL_0019: ldc.i4.0 + IL_001a: conv.i8 + IL_001b: nop + IL_001c: br.s IL_0040 + + IL_001e: ldarg.2 + IL_001f: ldarg.0 + IL_0020: sub + IL_0021: ldarg.1 + IL_0022: div.un + IL_0023: conv.i8 + IL_0024: ldc.i4.1 + IL_0025: conv.i8 + IL_0026: add + IL_0027: nop + IL_0028: br.s IL_0040 + + IL_002a: ldarg.0 + IL_002b: ldarg.2 + IL_002c: bge.s IL_0033 + + IL_002e: ldc.i4.0 + IL_002f: conv.i8 + IL_0030: nop + IL_0031: br.s IL_0040 + + IL_0033: ldarg.0 + IL_0034: ldarg.2 + IL_0035: sub + IL_0036: ldarg.1 + IL_0037: not + IL_0038: ldc.i4.1 + IL_0039: add + IL_003a: div.un + IL_003b: conv.i8 + IL_003c: ldc.i4.1 + IL_003d: conv.i8 + IL_003e: add + IL_003f: nop + IL_0040: stloc.0 + IL_0041: ldc.i4.0 + IL_0042: conv.i8 + IL_0043: stloc.2 + IL_0044: ldarg.0 + IL_0045: stloc.3 + IL_0046: br.s IL_0062 + + IL_0048: ldloca.s V_1 + IL_004a: ldloc.3 + IL_004b: stloc.s V_4 + IL_004d: nop + IL_004e: ldloc.s V_4 + IL_0050: ldloc.s V_4 + IL_0052: mul + IL_0053: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0058: nop + IL_0059: ldloc.3 + IL_005a: ldarg.1 + IL_005b: add + IL_005c: stloc.3 + IL_005d: ldloc.2 + IL_005e: ldc.i4.1 + IL_005f: conv.i8 + IL_0060: add + IL_0061: stloc.2 + IL_0062: ldloc.2 + IL_0063: ldloc.0 + IL_0064: blt.un.s IL_0048 + + IL_0066: ldloca.s V_1 + IL_0068: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_006d: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter01.fs.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter01.fs.il.bsl index d2116eb9df4..9cf19fe503d 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter01.fs.il.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter01.fs.il.bsl @@ -43,65 +43,46 @@ extends [runtime]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 - squaresOfOneToTen() cil managed + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 squaresOfOneToTen() cil managed { .maxstack 5 .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, - class [runtime]System.Collections.Generic.IEnumerator`1 V_1, - class [runtime]System.Collections.Generic.IEnumerable`1 V_2, - int32 V_3, - class [runtime]System.IDisposable V_4) - IL_0000: nop - IL_0001: ldc.i4.0 - IL_0002: ldc.i4.1 - IL_0003: ldc.i4.2 - IL_0004: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, - int32, - int32) - IL_0009: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_000e: stloc.1 - .try - { - IL_000f: br.s IL_0023 - - IL_0011: ldloc.1 - IL_0012: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0017: stloc.3 - IL_0018: ldloca.s V_0 - IL_001a: ldloc.3 - IL_001b: ldloc.3 - IL_001c: mul - IL_001d: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) - IL_0022: nop - IL_0023: ldloc.1 - IL_0024: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() - IL_0029: brtrue.s IL_0011 - - IL_002b: ldnull - IL_002c: stloc.2 - IL_002d: leave.s IL_0044 - - } - finally - { - IL_002f: ldloc.1 - IL_0030: isinst [runtime]System.IDisposable - IL_0035: stloc.s V_4 - IL_0037: ldloc.s V_4 - IL_0039: brfalse.s IL_0043 - - IL_003b: ldloc.s V_4 - IL_003d: callvirt instance void [runtime]System.IDisposable::Dispose() - IL_0042: endfinally - IL_0043: endfinally - } - IL_0044: ldloc.2 - IL_0045: pop - IL_0046: ldloca.s V_0 - IL_0048: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() - IL_004d: ret + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.0 + IL_0001: conv.i8 + IL_0002: stloc.1 + IL_0003: ldc.i4.0 + IL_0004: stloc.2 + IL_0005: br.s IL_001d + + IL_0007: ldloca.s V_0 + IL_0009: ldloc.2 + IL_000a: stloc.3 + IL_000b: ldloc.3 + IL_000c: ldloc.3 + IL_000d: mul + IL_000e: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0013: nop + IL_0014: ldloc.2 + IL_0015: ldc.i4.1 + IL_0016: add + IL_0017: stloc.2 + IL_0018: ldloc.1 + IL_0019: ldc.i4.1 + IL_001a: conv.i8 + IL_001b: add + IL_001c: stloc.1 + IL_001d: ldloc.1 + IL_001e: ldc.i4.3 + IL_001f: conv.i8 + IL_0020: blt.un.s IL_0007 + + IL_0022: ldloca.s V_0 + IL_0024: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0029: ret } } diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter02.fs.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter02.fs.il.bsl index abae1939447..a29c41f8c95 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter02.fs.il.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter02.fs.il.bsl @@ -43,69 +43,50 @@ extends [runtime]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 - squaresOfOneToTenB() cil managed + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 squaresOfOneToTenB() cil managed { .maxstack 5 .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, - class [runtime]System.Collections.Generic.IEnumerator`1 V_1, - class [runtime]System.Collections.Generic.IEnumerable`1 V_2, - int32 V_3, - class [runtime]System.IDisposable V_4) - IL_0000: nop - IL_0001: ldc.i4.0 - IL_0002: ldc.i4.1 - IL_0003: ldc.i4.2 - IL_0004: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, - int32, - int32) - IL_0009: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_000e: stloc.1 - .try - { - IL_000f: br.s IL_0033 - - IL_0011: ldloc.1 - IL_0012: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0017: stloc.3 - IL_0018: ldstr "hello" - IL_001d: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0022: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0027: pop - IL_0028: ldloca.s V_0 - IL_002a: ldloc.3 - IL_002b: ldloc.3 - IL_002c: mul - IL_002d: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) - IL_0032: nop - IL_0033: ldloc.1 - IL_0034: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() - IL_0039: brtrue.s IL_0011 - - IL_003b: ldnull - IL_003c: stloc.2 - IL_003d: leave.s IL_0054 - - } - finally - { - IL_003f: ldloc.1 - IL_0040: isinst [runtime]System.IDisposable - IL_0045: stloc.s V_4 - IL_0047: ldloc.s V_4 - IL_0049: brfalse.s IL_0053 - - IL_004b: ldloc.s V_4 - IL_004d: callvirt instance void [runtime]System.IDisposable::Dispose() - IL_0052: endfinally - IL_0053: endfinally - } - IL_0054: ldloc.2 - IL_0055: pop - IL_0056: ldloca.s V_0 - IL_0058: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() - IL_005d: ret + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.0 + IL_0001: conv.i8 + IL_0002: stloc.1 + IL_0003: ldc.i4.0 + IL_0004: stloc.2 + IL_0005: br.s IL_002d + + IL_0007: ldloca.s V_0 + IL_0009: ldloc.2 + IL_000a: stloc.3 + IL_000b: ldstr "hello" + IL_0010: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0015: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_001a: pop + IL_001b: ldloc.3 + IL_001c: ldloc.3 + IL_001d: mul + IL_001e: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0023: nop + IL_0024: ldloc.2 + IL_0025: ldc.i4.1 + IL_0026: add + IL_0027: stloc.2 + IL_0028: ldloc.1 + IL_0029: ldc.i4.1 + IL_002a: conv.i8 + IL_002b: add + IL_002c: stloc.1 + IL_002d: ldloc.1 + IL_002e: ldc.i4.3 + IL_002f: conv.i8 + IL_0030: blt.un.s IL_0007 + + IL_0032: ldloca.s V_0 + IL_0034: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0039: ret } } diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter03.fs.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter03.fs.il.bsl index 7a3d0ce3812..2f8d1ce09f2 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter03.fs.il.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter03.fs.il.bsl @@ -43,65 +43,46 @@ extends [runtime]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 - squaresOfOneToTenC() cil managed + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 squaresOfOneToTenC() cil managed { .maxstack 5 .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, - class [runtime]System.Collections.Generic.IEnumerator`1 V_1, - class [runtime]System.Collections.Generic.IEnumerable`1 V_2, - int32 V_3, - class [runtime]System.IDisposable V_4) - IL_0000: nop - IL_0001: ldc.i4.0 - IL_0002: ldc.i4.1 - IL_0003: ldc.i4.s 10 - IL_0005: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, - int32, - int32) - IL_000a: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_000f: stloc.1 - .try - { - IL_0010: br.s IL_0024 - - IL_0012: ldloc.1 - IL_0013: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0018: stloc.3 - IL_0019: ldloca.s V_0 - IL_001b: ldloc.3 - IL_001c: ldloc.3 - IL_001d: mul - IL_001e: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) - IL_0023: nop - IL_0024: ldloc.1 - IL_0025: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() - IL_002a: brtrue.s IL_0012 - - IL_002c: ldnull - IL_002d: stloc.2 - IL_002e: leave.s IL_0045 - - } - finally - { - IL_0030: ldloc.1 - IL_0031: isinst [runtime]System.IDisposable - IL_0036: stloc.s V_4 - IL_0038: ldloc.s V_4 - IL_003a: brfalse.s IL_0044 - - IL_003c: ldloc.s V_4 - IL_003e: callvirt instance void [runtime]System.IDisposable::Dispose() - IL_0043: endfinally - IL_0044: endfinally - } - IL_0045: ldloc.2 - IL_0046: pop - IL_0047: ldloca.s V_0 - IL_0049: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() - IL_004e: ret + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.0 + IL_0001: conv.i8 + IL_0002: stloc.1 + IL_0003: ldc.i4.0 + IL_0004: stloc.2 + IL_0005: br.s IL_001d + + IL_0007: ldloca.s V_0 + IL_0009: ldloc.2 + IL_000a: stloc.3 + IL_000b: ldloc.3 + IL_000c: ldloc.3 + IL_000d: mul + IL_000e: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0013: nop + IL_0014: ldloc.2 + IL_0015: ldc.i4.1 + IL_0016: add + IL_0017: stloc.2 + IL_0018: ldloc.1 + IL_0019: ldc.i4.1 + IL_001a: conv.i8 + IL_001b: add + IL_001c: stloc.1 + IL_001d: ldloc.1 + IL_001e: ldc.i4.s 11 + IL_0020: conv.i8 + IL_0021: blt.un.s IL_0007 + + IL_0023: ldloca.s V_0 + IL_0025: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_002a: ret } } diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter04_RealInternalSignatureOff.fs.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter04_RealInternalSignatureOff.fs.il.bsl index 8ff1796aaff..2d319d672ea 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter04_RealInternalSignatureOff.fs.il.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter04_RealInternalSignatureOff.fs.il.bsl @@ -75,62 +75,44 @@ .maxstack 5 .locals init (class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_0, valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_1, - class [runtime]System.Collections.Generic.IEnumerator`1 V_2, - class [runtime]System.Collections.Generic.IEnumerable`1 V_3, - int32 V_4, - class [runtime]System.IDisposable V_5) - IL_0000: nop - IL_0001: ldc.i4.0 - IL_0002: ldc.i4.1 - IL_0003: ldc.i4.s 10 - IL_0005: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, - int32, - int32) - IL_000a: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_000f: stloc.2 - .try - { - IL_0010: br.s IL_0027 - - IL_0012: ldloc.2 - IL_0013: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0018: stloc.s V_4 - IL_001a: ldloca.s V_1 - IL_001c: ldloc.s V_4 - IL_001e: ldloc.s V_4 - IL_0020: mul - IL_0021: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) - IL_0026: nop - IL_0027: ldloc.2 - IL_0028: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() - IL_002d: brtrue.s IL_0012 - - IL_002f: ldnull - IL_0030: stloc.3 - IL_0031: leave.s IL_0048 - - } - finally - { - IL_0033: ldloc.2 - IL_0034: isinst [runtime]System.IDisposable - IL_0039: stloc.s V_5 - IL_003b: ldloc.s V_5 - IL_003d: brfalse.s IL_0047 - - IL_003f: ldloc.s V_5 - IL_0041: callvirt instance void [runtime]System.IDisposable::Dispose() - IL_0046: endfinally - IL_0047: endfinally - } - IL_0048: ldloc.3 - IL_0049: pop - IL_004a: ldloca.s V_1 - IL_004c: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() - IL_0051: dup - IL_0052: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$assembly::squaresOfOneToTenD@4 - IL_0057: stloc.0 - IL_0058: ret + uint64 V_2, + int32 V_3, + int32 V_4) + IL_0000: ldc.i4.0 + IL_0001: conv.i8 + IL_0002: stloc.2 + IL_0003: ldc.i4.0 + IL_0004: stloc.3 + IL_0005: br.s IL_0020 + + IL_0007: ldloca.s V_1 + IL_0009: ldloc.3 + IL_000a: stloc.s V_4 + IL_000c: ldloc.s V_4 + IL_000e: ldloc.s V_4 + IL_0010: mul + IL_0011: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0016: nop + IL_0017: ldloc.3 + IL_0018: ldc.i4.1 + IL_0019: add + IL_001a: stloc.3 + IL_001b: ldloc.2 + IL_001c: ldc.i4.1 + IL_001d: conv.i8 + IL_001e: add + IL_001f: stloc.2 + IL_0020: ldloc.2 + IL_0021: ldc.i4.s 11 + IL_0023: conv.i8 + IL_0024: blt.un.s IL_0007 + + IL_0026: ldloca.s V_1 + IL_0028: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_002d: dup + IL_002e: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$assembly::squaresOfOneToTenD@4 + IL_0033: stloc.0 + IL_0034: ret } } diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter04_RealInternalSignatureOn.fs.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter04_RealInternalSignatureOn.fs.il.bsl index 84e9c999f30..e5b5501f20d 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter04_RealInternalSignatureOn.fs.il.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GenIter04_RealInternalSignatureOn.fs.il.bsl @@ -69,60 +69,42 @@ .maxstack 5 .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, - class [runtime]System.Collections.Generic.IEnumerator`1 V_1, - class [runtime]System.Collections.Generic.IEnumerable`1 V_2, - int32 V_3, - class [runtime]System.IDisposable V_4) - IL_0000: nop - IL_0001: ldc.i4.0 - IL_0002: ldc.i4.1 - IL_0003: ldc.i4.s 10 - IL_0005: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, - int32, - int32) - IL_000a: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_000f: stloc.1 - .try - { - IL_0010: br.s IL_0024 - - IL_0012: ldloc.1 - IL_0013: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0018: stloc.3 - IL_0019: ldloca.s V_0 - IL_001b: ldloc.3 - IL_001c: ldloc.3 - IL_001d: mul - IL_001e: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) - IL_0023: nop - IL_0024: ldloc.1 - IL_0025: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() - IL_002a: brtrue.s IL_0012 - - IL_002c: ldnull - IL_002d: stloc.2 - IL_002e: leave.s IL_0045 - - } - finally - { - IL_0030: ldloc.1 - IL_0031: isinst [runtime]System.IDisposable - IL_0036: stloc.s V_4 - IL_0038: ldloc.s V_4 - IL_003a: brfalse.s IL_0044 - - IL_003c: ldloc.s V_4 - IL_003e: callvirt instance void [runtime]System.IDisposable::Dispose() - IL_0043: endfinally - IL_0044: endfinally - } - IL_0045: ldloc.2 - IL_0046: pop - IL_0047: ldloca.s V_0 - IL_0049: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() - IL_004e: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 assembly::squaresOfOneToTenD@4 - IL_0053: ret + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.0 + IL_0001: conv.i8 + IL_0002: stloc.1 + IL_0003: ldc.i4.0 + IL_0004: stloc.2 + IL_0005: br.s IL_001d + + IL_0007: ldloca.s V_0 + IL_0009: ldloc.2 + IL_000a: stloc.3 + IL_000b: ldloc.3 + IL_000c: ldloc.3 + IL_000d: mul + IL_000e: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0013: nop + IL_0014: ldloc.2 + IL_0015: ldc.i4.1 + IL_0016: add + IL_0017: stloc.2 + IL_0018: ldloc.1 + IL_0019: ldc.i4.1 + IL_001a: conv.i8 + IL_001b: add + IL_001c: stloc.1 + IL_001d: ldloc.1 + IL_001e: ldc.i4.s 11 + IL_0020: conv.i8 + IL_0021: blt.un.s IL_0007 + + IL_0023: ldloca.s V_0 + IL_0025: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_002a: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 assembly::squaresOfOneToTenD@4 + IL_002f: ret } .property class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GeneratedIterators.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GeneratedIterators.fs index 68899c67afe..4d19bbec2f6 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GeneratedIterators.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GeneratedIterators/GeneratedIterators.fs @@ -10,6 +10,7 @@ module GeneratedIterators = compilation |> withOptions [ "--test:EmitFeeFeeAs100001" ] |> asExe + |> withLangVersionPreview // TODO https://github.com/dotnet/fsharp/issues/16739: Remove this when LanguageFeature.LowerIntegralRangesToFastLoops is out of preview. |> withNoOptimize |> withEmbeddedPdb |> withEmbedAllSource diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest07.fs.RealInternalSignatureOff.il.net472.release.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest07.fs.RealInternalSignatureOff.il.net472.release.bsl index 155ad0265cc..0b0542bcd06 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest07.fs.RealInternalSignatureOff.il.net472.release.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest07.fs.RealInternalSignatureOff.il.net472.release.bsl @@ -679,63 +679,45 @@ .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ListExpressionSteppingTest7() cil managed { - .maxstack 5 + .maxstack 4 .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, - class [runtime]System.Collections.Generic.IEnumerator`1 V_1, - class [runtime]System.Collections.Generic.IEnumerable`1 V_2, - int32 V_3, - class [runtime]System.IDisposable V_4) - IL_0000: nop - IL_0001: ldc.i4.1 - IL_0002: ldc.i4.1 - IL_0003: ldc.i4.4 - IL_0004: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, - int32, - int32) - IL_0009: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_000e: stloc.1 - .try - { - IL_000f: br.s IL_0031 - - IL_0011: ldloc.1 - IL_0012: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0017: stloc.3 - IL_0018: ldstr "hello" - IL_001d: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0022: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0027: pop - IL_0028: ldloca.s V_0 - IL_002a: ldloc.3 - IL_002b: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) - IL_0030: nop - IL_0031: ldloc.1 - IL_0032: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() - IL_0037: brtrue.s IL_0011 - - IL_0039: ldnull - IL_003a: stloc.2 - IL_003b: leave.s IL_0052 + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.0 + IL_0001: conv.i8 + IL_0002: stloc.1 + IL_0003: ldc.i4.1 + IL_0004: stloc.2 + IL_0005: br.s IL_002b + + IL_0007: ldloca.s V_0 + IL_0009: ldloc.2 + IL_000a: stloc.3 + IL_000b: ldstr "hello" + IL_0010: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0015: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_001a: pop + IL_001b: ldloc.3 + IL_001c: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0021: nop + IL_0022: ldloc.2 + IL_0023: ldc.i4.1 + IL_0024: add + IL_0025: stloc.2 + IL_0026: ldloc.1 + IL_0027: ldc.i4.1 + IL_0028: conv.i8 + IL_0029: add + IL_002a: stloc.1 + IL_002b: ldloc.1 + IL_002c: ldc.i4.4 + IL_002d: conv.i8 + IL_002e: blt.un.s IL_0007 - } - finally - { - IL_003d: ldloc.1 - IL_003e: isinst [runtime]System.IDisposable - IL_0043: stloc.s V_4 - IL_0045: ldloc.s V_4 - IL_0047: brfalse.s IL_0051 - - IL_0049: ldloc.s V_4 - IL_004b: callvirt instance void [runtime]System.IDisposable::Dispose() - IL_0050: endfinally - IL_0051: endfinally - } - IL_0052: ldloc.2 - IL_0053: pop - IL_0054: ldloca.s V_0 - IL_0056: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() - IL_005b: ret + IL_0030: ldloca.s V_0 + IL_0032: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0037: ret } .property int32 r() diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest07.fs.RealInternalSignatureOff.il.netcore.release.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest07.fs.RealInternalSignatureOff.il.netcore.release.bsl index 3d78a971d68..885135c69e6 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest07.fs.RealInternalSignatureOff.il.netcore.release.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest07.fs.RealInternalSignatureOff.il.netcore.release.bsl @@ -680,63 +680,45 @@ .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ListExpressionSteppingTest7() cil managed { - .maxstack 5 + .maxstack 4 .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, - class [runtime]System.Collections.Generic.IEnumerator`1 V_1, - class [runtime]System.Collections.Generic.IEnumerable`1 V_2, - int32 V_3, - class [runtime]System.IDisposable V_4) - IL_0000: nop - IL_0001: ldc.i4.1 - IL_0002: ldc.i4.1 - IL_0003: ldc.i4.4 - IL_0004: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, - int32, - int32) - IL_0009: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_000e: stloc.1 - .try - { - IL_000f: br.s IL_0031 - - IL_0011: ldloc.1 - IL_0012: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0017: stloc.3 - IL_0018: ldstr "hello" - IL_001d: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0022: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0027: pop - IL_0028: ldloca.s V_0 - IL_002a: ldloc.3 - IL_002b: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) - IL_0030: nop - IL_0031: ldloc.1 - IL_0032: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() - IL_0037: brtrue.s IL_0011 - - IL_0039: ldnull - IL_003a: stloc.2 - IL_003b: leave.s IL_0052 + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.0 + IL_0001: conv.i8 + IL_0002: stloc.1 + IL_0003: ldc.i4.1 + IL_0004: stloc.2 + IL_0005: br.s IL_002b + + IL_0007: ldloca.s V_0 + IL_0009: ldloc.2 + IL_000a: stloc.3 + IL_000b: ldstr "hello" + IL_0010: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0015: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_001a: pop + IL_001b: ldloc.3 + IL_001c: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0021: nop + IL_0022: ldloc.2 + IL_0023: ldc.i4.1 + IL_0024: add + IL_0025: stloc.2 + IL_0026: ldloc.1 + IL_0027: ldc.i4.1 + IL_0028: conv.i8 + IL_0029: add + IL_002a: stloc.1 + IL_002b: ldloc.1 + IL_002c: ldc.i4.4 + IL_002d: conv.i8 + IL_002e: blt.un.s IL_0007 - } - finally - { - IL_003d: ldloc.1 - IL_003e: isinst [runtime]System.IDisposable - IL_0043: stloc.s V_4 - IL_0045: ldloc.s V_4 - IL_0047: brfalse.s IL_0051 - - IL_0049: ldloc.s V_4 - IL_004b: callvirt instance void [runtime]System.IDisposable::Dispose() - IL_0050: endfinally - IL_0051: endfinally - } - IL_0052: ldloc.2 - IL_0053: pop - IL_0054: ldloca.s V_0 - IL_0056: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() - IL_005b: ret + IL_0030: ldloca.s V_0 + IL_0032: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0037: ret } .property int32 r() diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest07.fs.RealInternalSignatureOn.il.net472.release.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest07.fs.RealInternalSignatureOn.il.net472.release.bsl index 66a9fd3e0d5..0022e910a22 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest07.fs.RealInternalSignatureOn.il.net472.release.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest07.fs.RealInternalSignatureOn.il.net472.release.bsl @@ -681,63 +681,45 @@ .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ListExpressionSteppingTest7() cil managed { - .maxstack 5 + .maxstack 4 .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, - class [runtime]System.Collections.Generic.IEnumerator`1 V_1, - class [runtime]System.Collections.Generic.IEnumerable`1 V_2, - int32 V_3, - class [runtime]System.IDisposable V_4) - IL_0000: nop - IL_0001: ldc.i4.1 - IL_0002: ldc.i4.1 - IL_0003: ldc.i4.4 - IL_0004: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, - int32, - int32) - IL_0009: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_000e: stloc.1 - .try - { - IL_000f: br.s IL_0031 - - IL_0011: ldloc.1 - IL_0012: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0017: stloc.3 - IL_0018: ldstr "hello" - IL_001d: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0022: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0027: pop - IL_0028: ldloca.s V_0 - IL_002a: ldloc.3 - IL_002b: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) - IL_0030: nop - IL_0031: ldloc.1 - IL_0032: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() - IL_0037: brtrue.s IL_0011 - - IL_0039: ldnull - IL_003a: stloc.2 - IL_003b: leave.s IL_0052 + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.0 + IL_0001: conv.i8 + IL_0002: stloc.1 + IL_0003: ldc.i4.1 + IL_0004: stloc.2 + IL_0005: br.s IL_002b + + IL_0007: ldloca.s V_0 + IL_0009: ldloc.2 + IL_000a: stloc.3 + IL_000b: ldstr "hello" + IL_0010: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0015: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_001a: pop + IL_001b: ldloc.3 + IL_001c: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0021: nop + IL_0022: ldloc.2 + IL_0023: ldc.i4.1 + IL_0024: add + IL_0025: stloc.2 + IL_0026: ldloc.1 + IL_0027: ldc.i4.1 + IL_0028: conv.i8 + IL_0029: add + IL_002a: stloc.1 + IL_002b: ldloc.1 + IL_002c: ldc.i4.4 + IL_002d: conv.i8 + IL_002e: blt.un.s IL_0007 - } - finally - { - IL_003d: ldloc.1 - IL_003e: isinst [runtime]System.IDisposable - IL_0043: stloc.s V_4 - IL_0045: ldloc.s V_4 - IL_0047: brfalse.s IL_0051 - - IL_0049: ldloc.s V_4 - IL_004b: callvirt instance void [runtime]System.IDisposable::Dispose() - IL_0050: endfinally - IL_0051: endfinally - } - IL_0052: ldloc.2 - IL_0053: pop - IL_0054: ldloca.s V_0 - IL_0056: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() - IL_005b: ret + IL_0030: ldloca.s V_0 + IL_0032: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0037: ret } .method private specialname rtspecialname static void .cctor() cil managed diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest07.fs.RealInternalSignatureOn.il.netcore.release.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest07.fs.RealInternalSignatureOn.il.netcore.release.bsl index 9be862b2fd6..64016951d4d 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest07.fs.RealInternalSignatureOn.il.netcore.release.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest07.fs.RealInternalSignatureOn.il.netcore.release.bsl @@ -682,63 +682,45 @@ .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ListExpressionSteppingTest7() cil managed { - .maxstack 5 + .maxstack 4 .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, - class [runtime]System.Collections.Generic.IEnumerator`1 V_1, - class [runtime]System.Collections.Generic.IEnumerable`1 V_2, - int32 V_3, - class [runtime]System.IDisposable V_4) - IL_0000: nop - IL_0001: ldc.i4.1 - IL_0002: ldc.i4.1 - IL_0003: ldc.i4.4 - IL_0004: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, - int32, - int32) - IL_0009: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_000e: stloc.1 - .try - { - IL_000f: br.s IL_0031 - - IL_0011: ldloc.1 - IL_0012: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0017: stloc.3 - IL_0018: ldstr "hello" - IL_001d: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0022: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0027: pop - IL_0028: ldloca.s V_0 - IL_002a: ldloc.3 - IL_002b: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) - IL_0030: nop - IL_0031: ldloc.1 - IL_0032: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() - IL_0037: brtrue.s IL_0011 - - IL_0039: ldnull - IL_003a: stloc.2 - IL_003b: leave.s IL_0052 + uint64 V_1, + int32 V_2, + int32 V_3) + IL_0000: ldc.i4.0 + IL_0001: conv.i8 + IL_0002: stloc.1 + IL_0003: ldc.i4.1 + IL_0004: stloc.2 + IL_0005: br.s IL_002b + + IL_0007: ldloca.s V_0 + IL_0009: ldloc.2 + IL_000a: stloc.3 + IL_000b: ldstr "hello" + IL_0010: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0015: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_001a: pop + IL_001b: ldloc.3 + IL_001c: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0021: nop + IL_0022: ldloc.2 + IL_0023: ldc.i4.1 + IL_0024: add + IL_0025: stloc.2 + IL_0026: ldloc.1 + IL_0027: ldc.i4.1 + IL_0028: conv.i8 + IL_0029: add + IL_002a: stloc.1 + IL_002b: ldloc.1 + IL_002c: ldc.i4.4 + IL_002d: conv.i8 + IL_002e: blt.un.s IL_0007 - } - finally - { - IL_003d: ldloc.1 - IL_003e: isinst [runtime]System.IDisposable - IL_0043: stloc.s V_4 - IL_0045: ldloc.s V_4 - IL_0047: brfalse.s IL_0051 - - IL_0049: ldloc.s V_4 - IL_004b: callvirt instance void [runtime]System.IDisposable::Dispose() - IL_0050: endfinally - IL_0051: endfinally - } - IL_0052: ldloc.2 - IL_0053: pop - IL_0054: ldloca.s V_0 - IL_0056: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() - IL_005b: ret + IL_0030: ldloca.s V_0 + IL_0032: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0037: ret } .method private specialname rtspecialname static void .cctor() cil managed From a5763f149b91b9d2590f763f2df15b2aa05bbd91 Mon Sep 17 00:00:00 2001 From: Rustam Date: Wed, 20 Mar 2024 16:25:17 +0300 Subject: [PATCH 14/19] Fix receiving and processing mailbox after Dispose (#13036) * Fix receiving and processing mailbox after Dispose * Refactor * Refactoring * refactor * Add option to throw exception * Update 8.0.300.md * Update mailbox.fsi --------- Co-authored-by: Vlad Zarytovskii Co-authored-by: Petr --- docs/release-notes/.FSharp.Core/8.0.300.md | 4 +- src/FSharp.Core/mailbox.fs | 45 ++++++++-- src/FSharp.Core/mailbox.fsi | 61 +++++++++++++ ...p.Core.SurfaceArea.netstandard20.debug.bsl | 3 + ...Core.SurfaceArea.netstandard20.release.bsl | 3 + ...p.Core.SurfaceArea.netstandard21.debug.bsl | 3 + ...Core.SurfaceArea.netstandard21.release.bsl | 3 + .../MailboxProcessorType.fs | 90 ++++++++++++++++++- .../Tests.LanguageService.Completion.fs | 2 +- 9 files changed, 205 insertions(+), 9 deletions(-) diff --git a/docs/release-notes/.FSharp.Core/8.0.300.md b/docs/release-notes/.FSharp.Core/8.0.300.md index f1f8588d65b..be97542e410 100644 --- a/docs/release-notes/.FSharp.Core/8.0.300.md +++ b/docs/release-notes/.FSharp.Core/8.0.300.md @@ -2,10 +2,12 @@ * Minor tweaks to inline specifications to support Visibility PR ([PR #15484](https://github.com/dotnet/fsharp/pull/15484), [#PR 16427](https://github.com/dotnet/fsharp/pull/15484) * Optimize equality in generic contexts. ([PR #16615](https://github.com/dotnet/fsharp/pull/16615)) +* Add a constructor for `MailboxProcessor` with a flag denoting that an exception will be thrown when `Post` is called after the `MailboxProcessor` has been disposed. ([PR #13036](https://github.com/dotnet/fsharp/pull/13036)) ### Fixed * Preserve original stack traces in resumable state machines generated code if available. ([PR #16568](https://github.com/dotnet/fsharp/pull/16568)) +* Fix receiving and processing mailbox after Dispose. ([PR #13036](https://github.com/dotnet/fsharp/pull/13036)) * Enforce AttributeTargets on structs and classes. Also update `RequireQualifiedAccessAttribute` and `AutoOpenAttribute` to use `AttributeTargets.Struct` ([PR #16790](https://github.com/dotnet/fsharp/pull/16790)) * Enforce AttributeTargets on enums. Also update `RequireQualifiedAccessAttribute` to use `AttributeTargets.Enum` ([PR #16887](https://github.com/dotnet/fsharp/pull/16887)) -* Enforce AttributeTargets on delegates. Also update `ReflectedDefinitionAttribute` to use `AttributeTargets.Delegate` ([PR #16891](https://github.com/dotnet/fsharp/pull/16891)) \ No newline at end of file +* Enforce AttributeTargets on delegates. Also update `ReflectedDefinitionAttribute` to use `AttributeTargets.Delegate` ([PR #16891](https://github.com/dotnet/fsharp/pull/16891)) diff --git a/src/FSharp.Core/mailbox.fs b/src/FSharp.Core/mailbox.fs index 699e40153b3..a743afc3f41 100644 --- a/src/FSharp.Core/mailbox.fs +++ b/src/FSharp.Core/mailbox.fs @@ -60,7 +60,8 @@ module AsyncHelpers = [] [] -type Mailbox<'Msg>(cancellationSupported: bool) = +type Mailbox<'Msg>(cancellationSupported: bool, isThrowExceptionAfterDisposed: bool) = + let mutable isDisposed = false let mutable inboxStore = null let arrivals = Queue<'Msg>() let syncRoot = arrivals @@ -174,9 +175,12 @@ type Mailbox<'Msg>(cancellationSupported: bool) = member x.Post msg = lock syncRoot (fun () -> - - // Add the message to the arrivals queue - arrivals.Enqueue msg + if isDisposed then + if isThrowExceptionAfterDisposed then + raise (ObjectDisposedException(nameof Mailbox)) + else + // Add the message to the arrivals queue + arrivals.Enqueue msg // Cooperatively unblock any waiting reader. If there is no waiting // reader we just leave the message in the incoming queue @@ -331,6 +335,13 @@ type Mailbox<'Msg>(cancellationSupported: bool) = interface System.IDisposable with member _.Dispose() = + lock syncRoot (fun () -> + if isNotNull inboxStore then + inboxStore.Clear() + + arrivals.Clear() + isDisposed <- true) + if isNotNull pulse then (pulse :> IDisposable).Dispose() @@ -347,15 +358,23 @@ type AsyncReplyChannel<'Reply>(replyf: 'Reply -> unit) = [] [] [] -type MailboxProcessor<'Msg>(body, ?cancellationToken) = +type MailboxProcessor<'Msg>(body, isThrowExceptionAfterDisposed, ?cancellationToken) = let cancellationSupported = cancellationToken.IsSome let cancellationToken = defaultArg cancellationToken Async.DefaultCancellationToken - let mailbox = new Mailbox<'Msg>(cancellationSupported) + + let mailbox = + new Mailbox<'Msg>(cancellationSupported, isThrowExceptionAfterDisposed) + let mutable defaultTimeout = Threading.Timeout.Infinite let mutable started = false let errorEvent = new Event() + new(body, ?cancellationToken: CancellationToken) = + match cancellationToken with + | None -> new MailboxProcessor<'Msg>(body, false) + | Some ct -> new MailboxProcessor<'Msg>(body, false, ct) + member _.CurrentQueueLength = mailbox.CurrentQueueLength // nb. unprotected access gives an approximation of the queue length member _.DefaultTimeout @@ -506,9 +525,23 @@ type MailboxProcessor<'Msg>(body, ?cancellationToken) = mailboxProcessor.Start() mailboxProcessor + static member Start(body, isThrowExceptionAfterDisposed, ?cancellationToken) = + let mailboxProcessor = + new MailboxProcessor<'Msg>(body, isThrowExceptionAfterDisposed, ?cancellationToken = cancellationToken) + + mailboxProcessor.Start() + mailboxProcessor + static member StartImmediate(body, ?cancellationToken) = let mailboxProcessor = new MailboxProcessor<'Msg>(body, ?cancellationToken = cancellationToken) mailboxProcessor.StartImmediate() mailboxProcessor + + static member StartImmediate(body, isThrowExceptionAfterDisposed, ?cancellationToken) = + let mailboxProcessor = + new MailboxProcessor<'Msg>(body, isThrowExceptionAfterDisposed, ?cancellationToken = cancellationToken) + + mailboxProcessor.StartImmediate() + mailboxProcessor diff --git a/src/FSharp.Core/mailbox.fsi b/src/FSharp.Core/mailbox.fsi index ae245d8ace0..740ab77080a 100644 --- a/src/FSharp.Core/mailbox.fsi +++ b/src/FSharp.Core/mailbox.fsi @@ -43,6 +43,27 @@ type MailboxProcessor<'Msg> = /// new: body: (MailboxProcessor<'Msg> -> Async) * ?cancellationToken: CancellationToken -> MailboxProcessor<'Msg> + /// Creates an agent. The body function is used to generate the asynchronous + /// computation executed by the agent. This function is not executed until + /// Start is called. + /// + /// The function to produce an asynchronous computation that will be executed + /// as the read loop for the MailboxProcessor when Start is called. + /// A flag denoting that an exception will be thrown + /// when is called + /// after has been disposed. + /// An optional cancellation token for the body. + /// Defaults to Async.DefaultCancellationToken. + /// + /// The created MailboxProcessor. + /// + /// + new: + body: (MailboxProcessor<'Msg> -> Async) * + isThrowExceptionAfterDisposed: bool * + ?cancellationToken: CancellationToken -> + MailboxProcessor<'Msg> + /// Creates and starts an agent. The body function is used to generate the asynchronous /// computation executed by the agent. /// @@ -57,6 +78,26 @@ type MailboxProcessor<'Msg> = static member Start: body: (MailboxProcessor<'Msg> -> Async) * ?cancellationToken: CancellationToken -> MailboxProcessor<'Msg> + /// Creates and starts an agent. The body function is used to generate the asynchronous + /// computation executed by the agent. + /// + /// The function to produce an asynchronous computation that will be executed + /// as the read loop for the MailboxProcessor when Start is called. + /// A flag denoting that an exception will be thrown + /// when is called + /// after has been disposed. + /// An optional cancellation token for the body. + /// Defaults to Async.DefaultCancellationToken. + /// + /// The created MailboxProcessor. + /// + /// + static member Start: + body: (MailboxProcessor<'Msg> -> Async) * + isThrowExceptionAfterDisposed: bool * + ?cancellationToken: CancellationToken -> + MailboxProcessor<'Msg> + /// Creates and starts an agent immediately on the current operating system thread. The body /// function is used to generate the asynchronous computation executed by the agent. /// @@ -71,6 +112,26 @@ type MailboxProcessor<'Msg> = static member StartImmediate: body: (MailboxProcessor<'Msg> -> Async) * ?cancellationToken: CancellationToken -> MailboxProcessor<'Msg> + /// Creates and starts an agent immediately on the current operating system thread. The body + /// function is used to generate the asynchronous computation executed by the agent. + /// + /// The function to produce an asynchronous computation that will be executed + /// as the read loop for the MailboxProcessor when StartImmediately is called. + /// A flag denotes will be thrown exception + /// when is called + /// after disposed. + /// An optional cancellation token for the body. + /// Defaults to Async.DefaultCancellationToken. + /// + /// The created MailboxProcessor. + /// + /// + static member StartImmediate: + body: (MailboxProcessor<'Msg> -> Async) * + isThrowExceptionAfterDisposed: bool * + ?cancellationToken: CancellationToken -> + MailboxProcessor<'Msg> + /// Posts a message to the message queue of the MailboxProcessor, asynchronously. /// /// The message to post. diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl index e156eba4598..f50a8c62300 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl @@ -671,10 +671,13 @@ Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Contro Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[TReply] PostAndAsyncReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[T] Scan[T](Microsoft.FSharp.Core.FSharpFunc`2[TMsg,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpHandler`1[System.Exception] Error +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] Start(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] Start(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] StartImmediate(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] StartImmediate(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Core.FSharpOption`1[TReply] TryPostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: TReply PostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Dispose() Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Post(TMsg) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl index b4cb84825db..964805cfa2e 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl @@ -671,10 +671,13 @@ Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Contro Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[TReply] PostAndAsyncReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[T] Scan[T](Microsoft.FSharp.Core.FSharpFunc`2[TMsg,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpHandler`1[System.Exception] Error +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] Start(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] Start(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] StartImmediate(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] StartImmediate(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Core.FSharpOption`1[TReply] TryPostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: TReply PostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Dispose() Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Post(TMsg) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl index adc21566d87..9efe28bb17c 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl @@ -671,10 +671,13 @@ Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Contro Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[TReply] PostAndAsyncReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[T] Scan[T](Microsoft.FSharp.Core.FSharpFunc`2[TMsg,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpHandler`1[System.Exception] Error +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] Start(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] Start(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] StartImmediate(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] StartImmediate(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Core.FSharpOption`1[TReply] TryPostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: TReply PostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Dispose() Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Post(TMsg) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl index eba99c47dec..eefd052ca17 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl @@ -671,10 +671,13 @@ Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Contro Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[TReply] PostAndAsyncReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[T] Scan[T](Microsoft.FSharp.Core.FSharpFunc`2[TMsg,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpHandler`1[System.Exception] Error +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] Start(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] Start(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] StartImmediate(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] StartImmediate(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Core.FSharpOption`1[TReply] TryPostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: TReply PostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Dispose() Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Post(TMsg) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs index 6325e04c887..8c686a8a213 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs @@ -6,8 +6,9 @@ namespace FSharp.Core.UnitTests.Control open System -open Xunit open System.Threading +open System.Threading.Tasks +open Xunit type Message = | Increment of int @@ -311,6 +312,93 @@ type MailboxProcessorType() = finishedEv.Reset() |> ignore + [] + member this.``After dispose is called, mailbox should stop receiving and processing messages``() = task { + let mutable isSkip = false + let mutable actualSkipMessagesCount = 0 + let mutable actualMessagesCount = 0 + let sleepDueTime = 100 + let expectedMessagesCount = 2 + use mre = new ManualResetEventSlim(false) + let mb = + MailboxProcessor.Start(fun b -> + let rec loop() = + async { + match! b.Receive() with + | Increment _ -> + if isSkip then + actualSkipMessagesCount <- actualSkipMessagesCount + 1 + return! loop() + else + do! Async.Sleep sleepDueTime + if not isSkip then + actualMessagesCount <- actualMessagesCount + 1 + if actualMessagesCount = expectedMessagesCount then mre.Set() + do! Async.Sleep sleepDueTime + return! loop() + | _ -> () + } + loop() + ) + let post() = Increment 1 |> mb.Post + + [1..4] |> Seq.iter (fun x -> post()) + do! task { + mre.Wait() + isSkip <- true + (mb :> IDisposable).Dispose() + post() + } + + Assert.Equal(expectedMessagesCount, actualMessagesCount) + Assert.Equal(0, actualSkipMessagesCount) + Assert.Equal(0, mb.CurrentQueueLength) + } + + [] + member this.``After dispose is called, mailbox should stop receiving and processing messages with exception``() = task { + let mutable isSkip = false + let mutable actualSkipMessagesCount = 0 + let mutable actualMessagesCount = 0 + let sleepDueTime = 100 + let expectedMessagesCount = 2 + use mre = new ManualResetEventSlim(false) + let mb = + MailboxProcessor.Start((fun b -> + let rec loop() = + async { + match! b.Receive() with + | Increment _ -> + if isSkip then + actualSkipMessagesCount <- actualSkipMessagesCount + 1 + return! loop() + else + do! Async.Sleep sleepDueTime + if not isSkip then + actualMessagesCount <- actualMessagesCount + 1 + if actualMessagesCount = expectedMessagesCount then mre.Set() + do! Async.Sleep sleepDueTime + return! loop() + | _ -> () + } + loop()), + true + ) + let post() = Increment 1 |> mb.Post + + [1..4] |> Seq.iter (fun x -> post()) + do! task { + mre.Wait() + isSkip <- true + (mb :> IDisposable).Dispose() + Assert.Throws(fun _ -> post()) |> ignore + } + + Assert.Equal(expectedMessagesCount, actualMessagesCount) + Assert.Equal(0, actualSkipMessagesCount) + Assert.Equal(0, mb.CurrentQueueLength) + } + [] member this.Dispose() = diff --git a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Completion.fs b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Completion.fs index a88ce83e903..9cc1ed259d9 100644 --- a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Completion.fs +++ b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Completion.fs @@ -4392,7 +4392,7 @@ let x = query { for bbbb in abbbbc(*D0*) do // Get description for Expr.Var let (CompletionItem(_, _, _, descrFunc, _)) = completions |> Array.find (fun (CompletionItem(name, _, _, _, _)) -> name = "Start") let occurrences = this.CountMethodOccurrences(descrFunc(), "Start") - AssertEqualWithMessage(1, occurrences, sprintf "Found wrong number of overloads for 'MailboxProcessor.Start'. Found %A." completions) + AssertEqualWithMessage(2, occurrences, sprintf "Found wrong number of overloads for 'MailboxProcessor.Start'. Found %A." completions) [] member public this.``WithinMatchClause.Bug1603``() = From e4e709f64fa0376bfa1fbb2e1a895680378fd58d Mon Sep 17 00:00:00 2001 From: Florian Verdonck Date: Wed, 20 Mar 2024 17:14:16 +0100 Subject: [PATCH 15/19] Parse sourcetext endpoint (#16899) * Update ParseFile in TransparentCompiler * Add unit tests * Decrease cache size --- src/Compiler/Facilities/Hashing.fs | 7 ++ src/Compiler/Facilities/Hashing.fsi | 4 ++ src/Compiler/Service/TransparentCompiler.fs | 71 ++++++++++++++++++- src/Compiler/Service/TransparentCompiler.fsi | 2 + src/Compiler/Service/service.fsi | 2 +- .../FSharpChecker/TransparentCompiler.fs | 43 ++++++++++- 6 files changed, 125 insertions(+), 4 deletions(-) diff --git a/src/Compiler/Facilities/Hashing.fs b/src/Compiler/Facilities/Hashing.fs index 2dfbb38b7ee..dd58495c59e 100644 --- a/src/Compiler/Facilities/Hashing.fs +++ b/src/Compiler/Facilities/Hashing.fs @@ -78,4 +78,11 @@ module internal Md5Hasher = let addDateTimes (dts: System.DateTime seq) (s: byte array) = s |> addSeq dts addDateTime + let addInt (i: int) (s: byte array) = + i |> BitConverter.GetBytes |> addBytes <| s + + let addIntegers (items: int seq) (s: byte array) = addSeq items addInt s + + let addBooleans (items: bool seq) (s: byte array) = addSeq items addBool s + let toString (bytes: byte array) = bytes |> System.BitConverter.ToString diff --git a/src/Compiler/Facilities/Hashing.fsi b/src/Compiler/Facilities/Hashing.fsi index 121afb29eb2..c154fd66078 100644 --- a/src/Compiler/Facilities/Hashing.fsi +++ b/src/Compiler/Facilities/Hashing.fsi @@ -43,4 +43,8 @@ module internal Md5Hasher = val addDateTimes: dts: System.DateTime seq -> s: byte array -> byte array + val addIntegers: items: int seq -> s: byte array -> byte array + + val addBooleans: items: bool seq -> s: byte array -> byte array + val toString: bytes: byte array -> string diff --git a/src/Compiler/Service/TransparentCompiler.fs b/src/Compiler/Service/TransparentCompiler.fs index e206971eaad..679c0d46d3f 100644 --- a/src/Compiler/Service/TransparentCompiler.fs +++ b/src/Compiler/Service/TransparentCompiler.fs @@ -267,6 +267,9 @@ type internal CompilerCaches(sizeFactor: int) = member val ParseFile = AsyncMemoize(keepStrongly = 50 * sf, keepWeakly = 20 * sf, name = "ParseFile") + member val ParseFileWithoutProject = + AsyncMemoize(keepStrongly = 5 * sf, keepWeakly = 2 * sf, name = "ParseFileWithoutProject") + member val ParseAndCheckFileInProject = AsyncMemoize(sf, 2 * sf, name = "ParseAndCheckFileInProject") member val ParseAndCheckAllFilesInProject = AsyncMemoizeDisabled(sf, 2 * sf, name = "ParseAndCheckFullProject") @@ -1999,6 +2002,70 @@ type internal TransparentCompiler return parseResult } + member _.ParseFileWithoutProject + ( + fileName: string, + sourceText: ISourceText, + options: FSharpParsingOptions, + cache: bool, + flatErrors: bool, + userOpName: string + ) : Async = + let parseFileAsync = + async { + let! ct = Async.CancellationToken + + let diagnostics, parsedInput, anyErrors = + ParseAndCheckFile.parseFile (sourceText, fileName, options, userOpName, false, flatErrors, false, ct) + + return FSharpParseFileResults(diagnostics, parsedInput, anyErrors, Array.empty) + } + + if not cache then + parseFileAsync + else + let cacheKey = + let sourceText = SourceTextNew.ofISourceText sourceText + + { new ICacheKey<_, _> with + member _.GetLabel() = shortPath fileName + + member _.GetKey() = fileName + + member _.GetVersion() = + Md5Hasher.empty + |> Md5Hasher.addStrings + [ + yield fileName + yield! options.ConditionalDefines + yield! options.SourceFiles + yield options.LangVersionText + ] + |> Md5Hasher.addBytes (sourceText.GetChecksum().ToArray()) + |> Md5Hasher.addIntegers + [ + yield options.DiagnosticOptions.WarnLevel + yield! options.DiagnosticOptions.WarnOff + yield! options.DiagnosticOptions.WarnOn + yield! options.DiagnosticOptions.WarnAsError + yield! options.DiagnosticOptions.WarnAsWarn + ] + |> Md5Hasher.addBooleans + [ + yield options.ApplyLineDirectives + yield options.DiagnosticOptions.GlobalWarnAsError + yield options.IsInteractive + yield! (Option.toList options.IndentationAwareSyntax) + yield! (Option.toList options.StrictIndentation) + yield options.CompilingFSharpCore + yield options.IsExe + ] + |> Md5Hasher.toString + } + + caches.ParseFileWithoutProject.Get(cacheKey, NodeCode.AwaitAsync parseFileAsync) + |> Async.AwaitNodeCode + member _.ParseAndCheckFileInProject(fileName: string, projectSnapshot: ProjectSnapshot, userOpName: string) = ignore userOpName ComputeParseAndCheckFileInProject fileName projectSnapshot @@ -2450,8 +2517,8 @@ type internal TransparentCompiler cache: bool, flatErrors: bool, userOpName: string - ) = - backgroundCompiler.ParseFile(fileName, sourceText, options, cache, flatErrors, userOpName) + ) : Async = + this.ParseFileWithoutProject(fileName, sourceText, options, cache, flatErrors, userOpName) member this.TryGetRecentCheckResultsForFile ( diff --git a/src/Compiler/Service/TransparentCompiler.fsi b/src/Compiler/Service/TransparentCompiler.fsi index 8e581872d84..906ba4d698a 100644 --- a/src/Compiler/Service/TransparentCompiler.fsi +++ b/src/Compiler/Service/TransparentCompiler.fsi @@ -125,6 +125,8 @@ type internal CompilerCaches = member ParseFile: AsyncMemoize<((string * string) * string), (string * string * bool), ProjectSnapshot.FSharpParsedFile> + member ParseFileWithoutProject: AsyncMemoize + member ProjectExtras: AsyncMemoizeDisabled member SemanticClassification: AsyncMemoize<(string * (string * string)), string, SemanticClassificationView option> diff --git a/src/Compiler/Service/service.fsi b/src/Compiler/Service/service.fsi index a15c208c26c..5e78154d77e 100644 --- a/src/Compiler/Service/service.fsi +++ b/src/Compiler/Service/service.fsi @@ -97,7 +97,7 @@ type public FSharpChecker = /// The path for the file. The file name is used as a module name for implicit top level modules (e.g. in scripts). /// The source to be parsed. /// Parsing options for the project or script. - /// Store the parse in a size-limited cache assocaited with the FSharpChecker. Default: true + /// Store the parse in a size-limited cache associated with the FSharpChecker. Default: true /// An optional string used for tracing compiler operations associated with this request. member ParseFile: fileName: string * sourceText: ISourceText * options: FSharpParsingOptions * ?cache: bool * ?userOpName: string -> diff --git a/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs b/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs index c7e7777fd98..cbc0c8a34e8 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs +++ b/tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs @@ -1125,4 +1125,45 @@ let ``The script load closure should always be evaluated`` useTransparentCompile | FSharpCheckFileAnswer.Succeeded checkFileResults -> Assert.Equal(0, checkFileResults.Diagnostics.Length) finally FileSystemAutoOpens.FileSystem <- currentFileSystem - } \ No newline at end of file + } + +[] +let ``Parsing without cache and without project snapshot`` () = + async { + let checker = FSharpChecker.Create(useTransparentCompiler = true) + let fileName = "Temp.fs" + let sourceText = "let a = 0" |> SourceText.ofString + let parsingOptions = { FSharpParsingOptions.Default with SourceFiles = [| fileName |]; IsExe = true } + let! parseResult = checker.ParseFile(fileName, sourceText, parsingOptions, cache = false) + Assert.False(parseResult.ParseHadErrors) + Assert.True(Array.isEmpty parseResult.Diagnostics) + Assert.Equal(0, checker.Caches.ParseFile.Count) + Assert.Equal(0, checker.Caches.ParseFileWithoutProject.Count) + } + +// In this scenario, the user is typing something in file B.fs. +// The idea is that the IDE will introduce an additional (fake) identifier in order to have a potential complete syntax tree. +// The user never wrote this code so we need to ensure nothing is added to checker.Caches.ParseFile +[] +let ``Parsing with cache and without project snapshot`` () = + async { + let checker = FSharpChecker.Create(useTransparentCompiler = true) + let fileName = "B.fs" + let parsingOptions = { FSharpParsingOptions.Default with SourceFiles = [| "A.fs"; fileName; "C.fs" |] } + let sourceText = + SourceText.ofString """ +module B + +let b : int = ExtraIdentUserNeverWroteRulezzz +""" + let! parseResult = checker.ParseFile(fileName, sourceText, parsingOptions, cache = true) + Assert.False(parseResult.ParseHadErrors) + Assert.True(Array.isEmpty parseResult.Diagnostics) + + let! parseAgainResult = checker.ParseFile(fileName, sourceText, parsingOptions, cache = true) + Assert.False(parseAgainResult.ParseHadErrors) + Assert.True(Array.isEmpty parseAgainResult.Diagnostics) + + Assert.Equal(0, checker.Caches.ParseFile.Count) + Assert.Equal(1, checker.Caches.ParseFileWithoutProject.Count) + } From dff5ebac71670a934bf1e228913f8a1d219a381d Mon Sep 17 00:00:00 2001 From: Brian Rourke Boll Date: Wed, 20 Mar 2024 12:15:45 -0400 Subject: [PATCH 16/19] Don't blow the stack when traversing deeply nested sequential expressions (#16882) * Don't blow stack when traversing deep sequentials * Sequential expressions are more likely than most other expression kinds to be deeply nested, e.g., in very large list or array expressions. Since `traverseSynExpr` is not tail-recursive, we must treat them specially to avoid blowing the stack. * Update release notes * Only when actually nested * Update comments * Only alloc seq when needed * Add very big array test for AST traversal --------- Co-authored-by: Vlad Zarytovskii --- .../.FSharp.Compiler.Service/8.0.300.md | 1 + src/Compiler/Service/ServiceParseTreeWalk.fs | 35 +- .../FSharp.Compiler.UnitTests.fsproj | 1 + ...edInputModuleTests.VeryBigArrayExprTest.fs | 5024 +++++++++++++++++ .../ParsedInputModuleTests.fs | 2 +- 5 files changed, 5061 insertions(+), 2 deletions(-) create mode 100644 tests/FSharp.Compiler.UnitTests/ParsedInputModuleTests.VeryBigArrayExprTest.fs diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index afade2e0dc0..df52d62e7f2 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -1,5 +1,6 @@ ### Fixed +* Don't blow the stack when traversing deeply nested sequential expressions. ([PR #16882](https://github.com/dotnet/fsharp/pull/16882)) * Fix wrong range start of INTERP_STRING_END. ([PR #16774](https://github.com/dotnet/fsharp/pull/16774), [PR #16785](https://github.com/dotnet/fsharp/pull/16785)) * Fix missing warning for recursive calls in list comprehensions. ([PR #16652](https://github.com/dotnet/fsharp/pull/16652)) * Code generated files with > 64K methods and generated symbols crash when loaded. Use infered sequence points for debugging. ([Issue #16399](https://github.com/dotnet/fsharp/issues/16399), [#PR 16514](https://github.com/dotnet/fsharp/pull/16514)) diff --git a/src/Compiler/Service/ServiceParseTreeWalk.fs b/src/Compiler/Service/ServiceParseTreeWalk.fs index d0c0132dc6b..c395c9422d2 100644 --- a/src/Compiler/Service/ServiceParseTreeWalk.fs +++ b/src/Compiler/Service/ServiceParseTreeWalk.fs @@ -379,6 +379,31 @@ module SyntaxTraversal = and traverseSynExpr origPath (expr: SynExpr) = let pick = pick expr.Range + /// Sequential expressions are more likely than + /// most other expression kinds to be deeply nested, + /// e.g., in very large list or array expressions. + /// We treat them specially to avoid blowing the stack, + /// since traverseSynExpr itself is not tail-recursive. + let rec traverseSequentials path expr = + seq { + match expr with + | SynExpr.Sequential(expr1 = expr1; expr2 = SynExpr.Sequential _ as expr2) -> + // It's a nested sequential expression. + // Visit it, but make defaultTraverse do nothing, + // since we're going to traverse its descendants ourselves. + yield dive expr expr.Range (fun expr -> visitor.VisitExpr(path, traverseSynExpr path, (fun _ -> None), expr)) + + // Now traverse its descendants. + let path = SyntaxNode.SynExpr expr :: path + yield dive expr1 expr1.Range (traverseSynExpr path) + yield! traverseSequentials path expr2 + + | _ -> + // It's not a nested sequential expression. + // Traverse it normally. + yield dive expr expr.Range (traverseSynExpr path) + } + let defaultTraverse e = let path = SyntaxNode.SynExpr e :: origPath let traverseSynExpr = traverseSynExpr path @@ -680,11 +705,19 @@ module SyntaxTraversal = ] |> pick expr + // Nested sequentials. + | SynExpr.Sequential(expr1 = synExpr1; expr2 = synExpr2 & SynExpr.Sequential _) -> + [ + dive synExpr1 synExpr1.Range traverseSynExpr + yield! traverseSequentials path synExpr2 + ] + |> pick expr + + | SynExpr.Sequential(expr1 = synExpr1; expr2 = synExpr2) | SynExpr.Set(targetExpr = synExpr1; rhsExpr = synExpr2) | SynExpr.DotSet(targetExpr = synExpr1; rhsExpr = synExpr2) | SynExpr.TryFinally(tryExpr = synExpr1; finallyExpr = synExpr2) | SynExpr.SequentialOrImplicitYield(expr1 = synExpr1; expr2 = synExpr2) - | SynExpr.Sequential(expr1 = synExpr1; expr2 = synExpr2) | SynExpr.While(whileExpr = synExpr1; doExpr = synExpr2) | SynExpr.WhileBang(whileExpr = synExpr1; doExpr = synExpr2) | SynExpr.DotIndexedGet(objectExpr = synExpr1; indexArgs = synExpr2) diff --git a/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj b/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj index dd3e21cea91..4b6e9a9fe4a 100644 --- a/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj +++ b/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj @@ -75,6 +75,7 @@ + diff --git a/tests/FSharp.Compiler.UnitTests/ParsedInputModuleTests.VeryBigArrayExprTest.fs b/tests/FSharp.Compiler.UnitTests/ParsedInputModuleTests.VeryBigArrayExprTest.fs new file mode 100644 index 00000000000..084417882d1 --- /dev/null +++ b/tests/FSharp.Compiler.UnitTests/ParsedInputModuleTests.VeryBigArrayExprTest.fs @@ -0,0 +1,5024 @@ +module Tests.Service.ParsedInputModule.VeryBigArrayExprTest + +#if !DEBUG +open FSharp.Compiler.Service.Tests.Common +open FSharp.Compiler.Syntax +open Xunit + +[] +let ``fold doesn't blow the stack when traversing very big arrays`` () = + let source = """ +module M + +let _ = + [| + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + (fun () -> 2 + 2) + |] +""" + + let parseTree = parseSourceCode ("C:\\test.fs", source) + + do + ((), parseTree) + ||> ParsedInput.fold (fun () path node -> ignore (path, node)) +#endif diff --git a/tests/FSharp.Compiler.UnitTests/ParsedInputModuleTests.fs b/tests/FSharp.Compiler.UnitTests/ParsedInputModuleTests.fs index 635c000f4af..ead03f14402 100644 --- a/tests/FSharp.Compiler.UnitTests/ParsedInputModuleTests.fs +++ b/tests/FSharp.Compiler.UnitTests/ParsedInputModuleTests.fs @@ -1,4 +1,4 @@ -module Tests.Service.ParsedInputModuleTests +module Tests.Service.ParsedInputModule.Tests open FSharp.Compiler.Service.Tests.Common open FSharp.Compiler.Syntax From 447639eebb5231a8e14941a2a3f50e6cad54817c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 20 Mar 2024 17:21:17 +0100 Subject: [PATCH 17/19] Update dependencies from https://github.com/dotnet/arcade build (#16905) Microsoft.DotNet.Arcade.Sdk From Version 8.0.0-beta.24161.1 -> To Version 8.0.0-beta.24165.4 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/common/templates-official/job/job.yml | 18 +++++++++++------- .../job/publish-build-assets.yml | 10 ++++++---- global.json | 2 +- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 2663ee62f5b..af49e78651f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -30,9 +30,9 @@ - + https://github.com/dotnet/arcade - 5c3fdd3b5aaaa32b24383ec12a60b37ebff13079 + f311667e0587f19c3fa9553a909975662107a351 diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml index 647e3f92e5f..a2709d10562 100644 --- a/eng/common/templates-official/job/job.yml +++ b/eng/common/templates-official/job/job.yml @@ -206,9 +206,11 @@ jobs: continueOnError: true condition: always() - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: - - publish: artifacts/log - artifact: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }} - displayName: Publish logs + - task: 1ES.PublishPipelineArtifact@1 + inputs: + targetPath: 'artifacts/log' + artifactName: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }} + displayName: 'Publish logs' continueOnError: true condition: always() @@ -253,7 +255,9 @@ jobs: IgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} - ${{ if eq(parameters.enableBuildRetry, 'true') }}: - - publish: $(Build.SourcesDirectory)\eng\common\BuildConfiguration - artifact: BuildConfiguration - displayName: Publish build retry configuration - continueOnError: true + - task: 1ES.PublishPipelineArtifact@1 + inputs: + targetPath: '$(Build.SourcesDirectory)\eng\common\BuildConfiguration' + artifactName: 'BuildConfiguration' + displayName: 'Publish build retry configuration' + continueOnError: true \ No newline at end of file diff --git a/eng/common/templates-official/job/publish-build-assets.yml b/eng/common/templates-official/job/publish-build-assets.yml index ea5104625fa..53138622fe7 100644 --- a/eng/common/templates-official/job/publish-build-assets.yml +++ b/eng/common/templates-official/job/publish-build-assets.yml @@ -94,14 +94,16 @@ jobs: inputs: targetType: inline script: | - Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(BARBuildId) - Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value "$(DefaultChannels)" - Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(IsStableBuild) + New-Item -Path "$(Build.StagingDirectory)/ReleaseConfigs" -ItemType Directory -Force + $filePath = "$(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt" + Add-Content -Path $filePath -Value $(BARBuildId) + Add-Content -Path $filePath -Value "$(DefaultChannels)" + Add-Content -Path $filePath -Value $(IsStableBuild) - task: 1ES.PublishBuildArtifacts@1 displayName: Publish ReleaseConfigs Artifact inputs: - PathtoPublish: '$(Build.StagingDirectory)/ReleaseConfigs.txt' + PathtoPublish: '$(Build.StagingDirectory)/ReleaseConfigs' PublishLocation: Container ArtifactName: ReleaseConfigs diff --git a/global.json b/global.json index ca474949fc3..65c9d9b762d 100644 --- a/global.json +++ b/global.json @@ -17,7 +17,7 @@ "perl": "5.38.0.1" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24161.1", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24165.4", "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23255.2" } } From 1be52aa0843278636c2a33c9b42adc46231ff064 Mon Sep 17 00:00:00 2001 From: Vlad Zarytovskii Date: Thu, 21 Mar 2024 12:08:10 +0100 Subject: [PATCH 18/19] Fix StackOverflow in non-recursive bindings checker (#16908) * Fix StackOverflow in non-recursive bindings checker * Release notes * Automated command ran: fantomas Co-authored-by: vzarytovskii <1260985+vzarytovskii@users.noreply.github.com> * Update src/Compiler/Checking/CheckDeclarations.fs Remove commented-out code --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../.FSharp.Compiler.Service/8.0.300.md | 2 +- src/Compiler/Checking/CheckDeclarations.fs | 66 +++++++++++-------- src/Compiler/Facilities/DiagnosticsLogger.fs | 22 ++++++- src/Compiler/Facilities/DiagnosticsLogger.fsi | 9 ++- src/Compiler/Utilities/Activity.fs | 12 ++++ src/Compiler/Utilities/Activity.fsi | 6 ++ 6 files changed, 87 insertions(+), 30 deletions(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index df52d62e7f2..1ec3b5add20 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -25,7 +25,7 @@ * Enforce AttributeTargets on enums ([PR #16887](https://github.com/dotnet/fsharp/pull/16887)) * Completion: fix for unfinished record field decl ([PR #16893](https://github.com/dotnet/fsharp/pull/16893)) * Enforce AttributeTargets on delegates ([PR #16891](https://github.com/dotnet/fsharp/pull/16891)) - +* Fix StackOverflow when checking non-recursive bindings in module or namespace in `fscAnyCpu`/`fsiAnyCpu`. ([PR #16908](https://github.com/dotnet/fsharp/pull/16908)) ### Added diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index d64c1b648f5..f1037f7f1bb 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -4,6 +4,7 @@ module internal FSharp.Compiler.CheckDeclarations open System open System.Collections.Generic +open System.Threading open FSharp.Compiler.Diagnostics open Internal.Utilities.Collections @@ -5330,22 +5331,29 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv: cenv) parent typeNames scopem } /// The non-mutually recursive case for a sequence of declarations -and TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm (defsSoFar, env, envAtEnd) (moreDefs: SynModuleDecl list) = - cancellable { - match moreDefs with - | firstDef :: otherDefs -> - // Lookahead one to find out the scope of the next declaration. - let scopem = - if isNil otherDefs then unionRanges firstDef.Range endm - else unionRanges (List.head otherDefs).Range endm +and [] TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm (defsSoFar, env, envAtEnd) (moreDefs: SynModuleDecl list) (ct: CancellationToken) = + + if ct.IsCancellationRequested then + ValueOrCancelled.Cancelled (OperationCanceledException()) + else + match moreDefs with + | [] -> + ValueOrCancelled.Value (List.rev defsSoFar, envAtEnd) + | firstDef :: otherDefs -> + // Lookahead one to find out the scope of the next declaration. + let scopem = + if isNil otherDefs then + unionRanges firstDef.Range endm + else + unionRanges (List.head otherDefs).Range endm - let! firstDef, env, envAtEnd = TcModuleOrNamespaceElementNonMutRec cenv parent typeNames scopem env firstDef + let result = Cancellable.run ct (TcModuleOrNamespaceElementNonMutRec cenv parent typeNames scopem env firstDef) - // tail recursive - return! TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm ( (firstDef :: defsSoFar), env, envAtEnd) otherDefs - | [] -> - return List.rev defsSoFar, envAtEnd - } + match result with + | ValueOrCancelled.Cancelled x -> + ValueOrCancelled.Cancelled x + | ValueOrCancelled.Value(firstDef, env, envAtEnd) -> + TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm ((firstDef :: defsSoFar), env, envAtEnd) otherDefs ct /// The mutually recursive case for a sequence of declarations (and nested modules) and TcModuleOrNamespaceElementsMutRec (cenv: cenv) parent typeNames m envInitial mutRecNSInfo (defs: SynModuleDecl list) = @@ -5470,20 +5478,24 @@ and TcModuleOrNamespaceElements cenv parent endm env xml mutRecNSInfo openDecls0 escapeCheck() return (moduleContents, topAttrsNew, envAtEnd) - | None -> - - let! compiledDefs, envAtEnd = TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm ([], env, env) synModuleDecls - - // Apply the functions for each declaration to build the overall expression-builder - let moduleDefs = List.collect p13 compiledDefs - let moduleDefs = match openDecls0 with [] -> moduleDefs | _ -> TMDefOpens openDecls0 :: moduleDefs - let moduleContents = TMDefs moduleDefs + | None -> + let! ct = Cancellable.token () + let result = TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm ([], env, env) synModuleDecls ct + + match result with + | ValueOrCancelled.Value(compiledDefs, envAtEnd) -> + // Apply the functions for each declaration to build the overall expression-builder + let moduleDefs = List.collect p13 compiledDefs + let moduleDefs = match openDecls0 with [] -> moduleDefs | _ -> TMDefOpens openDecls0 :: moduleDefs + let moduleContents = TMDefs moduleDefs + + // Collect up the attributes that are global to the file + let topAttrsNew = List.collect p33 compiledDefs + return (moduleContents, topAttrsNew, envAtEnd) + | ValueOrCancelled.Cancelled x -> + return! Cancellable(fun _ -> ValueOrCancelled.Cancelled x) + } - // Collect up the attributes that are global to the file - let topAttrsNew = compiledDefs |> List.collect p33 - return (moduleContents, topAttrsNew, envAtEnd) - } - //-------------------------------------------------------------------------- // CheckOneImplFile - Typecheck all the namespace fragments in a file. diff --git a/src/Compiler/Facilities/DiagnosticsLogger.fs b/src/Compiler/Facilities/DiagnosticsLogger.fs index 75dfaaef39e..d93a3a60b6c 100644 --- a/src/Compiler/Facilities/DiagnosticsLogger.fs +++ b/src/Compiler/Facilities/DiagnosticsLogger.fs @@ -11,6 +11,8 @@ open System open System.Diagnostics open System.Reflection open System.Threading +open System.Runtime.CompilerServices +open System.Runtime.InteropServices open Internal.Utilities.Library open Internal.Utilities.Library.Extras open System.Collections.Concurrent @@ -853,7 +855,25 @@ type StackGuard(maxDepth: int, name: string) = let mutable depth = 1 [] - member _.Guard(f) = + member _.Guard + ( + f, + [] memberName: string, + [] path: string, + [] line: int + ) = + use _ = + Activity.start + "DiagnosticsLogger.StackGuard.Guard" + [| + Activity.Tags.stackGuardName, name + Activity.Tags.stackGuardCurrentDepth, string depth + Activity.Tags.stackGuardMaxDepth, string maxDepth + Activity.Tags.callerMemberName, memberName + Activity.Tags.callerFilePath, path + Activity.Tags.callerLineNumber, string line + |] + depth <- depth + 1 try diff --git a/src/Compiler/Facilities/DiagnosticsLogger.fsi b/src/Compiler/Facilities/DiagnosticsLogger.fsi index bcbdd197b73..ec2d37bc040 100644 --- a/src/Compiler/Facilities/DiagnosticsLogger.fsi +++ b/src/Compiler/Facilities/DiagnosticsLogger.fsi @@ -6,6 +6,8 @@ open System open FSharp.Compiler.Diagnostics open FSharp.Compiler.Features open FSharp.Compiler.Text +open System.Runtime.CompilerServices +open System.Runtime.InteropServices /// Represents the style being used to format errors [] @@ -448,7 +450,12 @@ type StackGuard = new: maxDepth: int * name: string -> StackGuard /// Execute the new function, on a new thread if necessary - member Guard: f: (unit -> 'T) -> 'T + member Guard: + f: (unit -> 'T) * + [] memberName: string * + [] path: string * + [] line: int -> + 'T static member GetDepthOption: string -> int diff --git a/src/Compiler/Utilities/Activity.fs b/src/Compiler/Utilities/Activity.fs index 5f1d9c3354f..ebc08633021 100644 --- a/src/Compiler/Utilities/Activity.fs +++ b/src/Compiler/Utilities/Activity.fs @@ -34,6 +34,12 @@ module internal Activity = let outputDllFile = "outputDllFile" let buildPhase = "buildPhase" let version = "version" + let stackGuardName = "stackGuardName" + let stackGuardCurrentDepth = "stackGuardCurrentDepth" + let stackGuardMaxDepth = "stackGuardMaxDepth" + let callerMemberName = "callerMemberName" + let callerFilePath = "callerFilePath" + let callerLineNumber = "callerLineNumber" let AllKnownTags = [| @@ -50,6 +56,12 @@ module internal Activity = gc2 outputDllFile buildPhase + stackGuardName + stackGuardCurrentDepth + stackGuardMaxDepth + callerMemberName + callerFilePath + callerLineNumber |] module Events = diff --git a/src/Compiler/Utilities/Activity.fsi b/src/Compiler/Utilities/Activity.fsi index afce0f3b554..ec6a9fbf6f8 100644 --- a/src/Compiler/Utilities/Activity.fsi +++ b/src/Compiler/Utilities/Activity.fsi @@ -29,6 +29,12 @@ module internal Activity = val cache: string val buildPhase: string val version: string + val stackGuardName: string + val stackGuardCurrentDepth: string + val stackGuardMaxDepth: string + val callerMemberName: string + val callerFilePath: string + val callerLineNumber: string module Events = val cacheHit: string From c7fcbf638052efbed3e00eec1682b50b0d3bab98 Mon Sep 17 00:00:00 2001 From: Brian Rourke Boll Date: Thu, 21 Mar 2024 12:40:44 -0400 Subject: [PATCH 19/19] Parens: more fixes (#16901) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix a few more paren corner cases * Match-like exprs in `if` exprs, `while` exprs, and `for` exprs. Also `let` exprs. * Nested, dangling `as` patterns. * Outlaw `match` exprs (where the first `|` is leftward of the `m` in `match) * Single-line comments (`//`, `///`). Multiline comments (`(*…*)`) would be… rather more difficult to handle. * Double-parenthesized tuples in method applications, since we can't tell purely syntactically whether the tuple might be the first parameter of a method whose next parameter is an implied outref parameter: `x.TryGetValue ((y, z))` i.e., `x.TryGetValue ((y, z), &value)` * Multiline tuple patterns in `let`-bindings. These need parens if the bound expression starts on the same column. * Handle typed pats in getters & setters * Double parens oddities * Sometimes we can't tell just by looking at the untyped AST whether we need parens, since their necessity may be dictated by type information located elsewhere. Compare, e.g., https://github.com/dotnet/fsharp/issues/16254, which probably has a similar underlying cause. * Keep parens for parenzed app preceded by prefix op * Keep parens around tuple in interp string * More nested match fun * No space when expr would reparse as prefix op * No space when expr would reparse as prefix op * No space when expr would reparse as prefix op * Update release notes * Remove unfinished multiline comment stuff * Keep parens around dot-get that would be adjacent * E.g., removing parens in place from ```fsharp Debug.Assert((xT.DeclaringType :?> ProvidedTypeDefinition).BelongsToTargetModel) ``` would result in the the argument to `Assert` becoming `(xT.DeclaringType :?> ProvidedTypeDefinition)`. The `.BelongsToTargetModel` would then be parsed as a get on the return value of _that_ call. * Fantomas --- .../.FSharp.Compiler.Service/8.0.300.md | 2 +- docs/release-notes/.VisualStudio/17.10.md | 2 +- src/Compiler/Service/SynExpr.fs | 77 ++++- src/Compiler/Service/SynPat.fs | 72 ++++- .../CodeFixes/RemoveUnnecessaryParentheses.fs | 101 +++++-- .../RemoveUnnecessaryParenthesesTests.fs | 278 ++++++++++++++++++ 6 files changed, 486 insertions(+), 46 deletions(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index 1ec3b5add20..d055d7c988b 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -6,7 +6,7 @@ * Code generated files with > 64K methods and generated symbols crash when loaded. Use infered sequence points for debugging. ([Issue #16399](https://github.com/dotnet/fsharp/issues/16399), [#PR 16514](https://github.com/dotnet/fsharp/pull/16514)) * `nameof Module` expressions and patterns are processed to link files in `--test:GraphBasedChecking`. ([PR #16550](https://github.com/dotnet/fsharp/pull/16550), [PR #16743](https://github.com/dotnet/fsharp/pull/16743)) * Graph Based Checking doesn't throw on invalid parsed input so it can be used for IDE scenarios ([PR #16575](https://github.com/dotnet/fsharp/pull/16575), [PR #16588](https://github.com/dotnet/fsharp/pull/16588), [PR #16643](https://github.com/dotnet/fsharp/pull/16643)) -* Various parenthesization API fixes. ([PR #16578](https://github.com/dotnet/fsharp/pull/16578), [PR #16666](https://github.com/dotnet/fsharp/pull/16666)) +* Various parenthesization API fixes. ([PR #16578](https://github.com/dotnet/fsharp/pull/16578), [PR #16666](https://github.com/dotnet/fsharp/pull/16666), [PR #16901](https://github.com/dotnet/fsharp/pull/16901)) * Keep parens for problematic exprs (`if`, `match`, etc.) in `$"{(…):N0}"`, `$"{(…),-3}"`, etc. ([PR #16578](https://github.com/dotnet/fsharp/pull/16578)) * Fix crash in DOTNET_SYSTEM_GLOBALIZATION_INVARIANT mode [#PR 16471](https://github.com/dotnet/fsharp/pull/16471)) * Fix16572 - Fixed the preview feature enabling Is properties for union case did not work correctly with let .rec and .fsi files ([PR #16657](https://github.com/dotnet/fsharp/pull/16657)) diff --git a/docs/release-notes/.VisualStudio/17.10.md b/docs/release-notes/.VisualStudio/17.10.md index 6c27a8fcfd1..3059b1b8868 100644 --- a/docs/release-notes/.VisualStudio/17.10.md +++ b/docs/release-notes/.VisualStudio/17.10.md @@ -1,7 +1,7 @@ ### Fixed * Show signature help mid-pipeline in more scenarios. ([PR #16462](https://github.com/dotnet/fsharp/pull/16462)) -* Various unneeded parentheses code fix improvements. ([PR #16578](https://github.com/dotnet/fsharp/pull/16578), [PR #16666](https://github.com/dotnet/fsharp/pull/16666), [PR #16789](https://github.com/dotnet/fsharp/pull/16789)) +* Various unneeded parentheses code fix improvements. ([PR #16578](https://github.com/dotnet/fsharp/pull/16578), [PR #16666](https://github.com/dotnet/fsharp/pull/16666), [PR #16789](https://github.com/dotnet/fsharp/pull/16789), [PR #16901](https://github.com/dotnet/fsharp/pull/16901)) ### Changed diff --git a/src/Compiler/Service/SynExpr.fs b/src/Compiler/Service/SynExpr.fs index 07321ce1646..db284ac36f7 100644 --- a/src/Compiler/Service/SynExpr.fs +++ b/src/Compiler/Service/SynExpr.fs @@ -344,6 +344,7 @@ module SynExpr = | InfixApp(prec, side) -> ValueSome(prec, side) | SynExpr.App(argExpr = SynExpr.ComputationExpr _) -> ValueSome(UnaryPrefix, Left) | SynExpr.App(funcExpr = SynExpr.Paren(expr = SynExpr.App _)) -> ValueSome(Apply, Left) + | SynExpr.App(flag = ExprAtomicFlag.Atomic) -> ValueSome(Dot, Non) | SynExpr.App _ -> ValueSome(Apply, Non) | SynExpr.DotSet(targetExpr = SynExpr.Paren(expr = Is inner)) -> ValueSome(Dot, Left) | SynExpr.DotSet(rhsExpr = SynExpr.Paren(expr = Is inner)) -> ValueSome(Set, Right) @@ -437,6 +438,14 @@ module SynExpr = | SynExpr.IfThenElse _ as expr -> Some expr | _ -> None) + /// Matches a dangling let or use construct. + [] + let (|LetOrUse|_|) = + dangling (function + | SynExpr.LetOrUse _ + | SynExpr.LetOrUseBang _ as expr -> Some expr + | _ -> None) + /// Matches a dangling sequential expression. [] let (|Sequential|_|) = @@ -610,13 +619,26 @@ module SynExpr = // // o.M((x = y)) // o.N((x = y), z) + // + // Likewise, double parens must stay around a tuple, since we don't know whether + // the method being invoked might have a signature like + // + // val TryGetValue : 'Key * outref<'Value> -> bool + // + // where 'Key is 'a * 'b, in which case the double parens are required. | SynExpr.Paren(expr = InfixApp(Relational(OriginalNotation "="), _)), - SyntaxNode.SynExpr(SynExpr.App(funcExpr = SynExpr.LongIdent _)) :: _ + SyntaxNode.SynExpr(SynExpr.App(funcExpr = SynExpr.LongIdent _ | SynExpr.DotGet _ | SynExpr.Ident _)) :: _ | InfixApp(Relational(OriginalNotation "="), _), - SyntaxNode.SynExpr(SynExpr.Paren _) :: SyntaxNode.SynExpr(SynExpr.App(funcExpr = SynExpr.LongIdent _)) :: _ + SyntaxNode.SynExpr(SynExpr.Paren _) :: SyntaxNode.SynExpr(SynExpr.App( + funcExpr = SynExpr.LongIdent _ | SynExpr.DotGet _ | SynExpr.Ident _)) :: _ | InfixApp(Relational(OriginalNotation "="), _), SyntaxNode.SynExpr(SynExpr.Tuple(isStruct = false)) :: SyntaxNode.SynExpr(SynExpr.Paren _) :: SyntaxNode.SynExpr(SynExpr.App( - funcExpr = SynExpr.LongIdent _)) :: _ -> true + funcExpr = SynExpr.LongIdent _ | SynExpr.DotGet _ | SynExpr.Ident _)) :: _ + | SynExpr.Paren(expr = SynExpr.Tuple(isStruct = false)), + SyntaxNode.SynExpr(SynExpr.App(funcExpr = SynExpr.LongIdent _ | SynExpr.DotGet _ | SynExpr.Ident _)) :: _ + | SynExpr.Tuple(isStruct = false), + SyntaxNode.SynExpr(SynExpr.Paren _) :: SyntaxNode.SynExpr(SynExpr.App( + funcExpr = SynExpr.LongIdent _ | SynExpr.DotGet _ | SynExpr.Ident _)) :: _ -> true // Already parenthesized. | _, SyntaxNode.SynExpr(SynExpr.Paren _) :: _ -> false @@ -676,6 +698,15 @@ module SynExpr = SyntaxNode.SynExpr(SynExpr.App _) :: SyntaxNode.SynExpr(HighPrecedenceApp | SynExpr.Assert _ | SynExpr.InferredUpcast _ | SynExpr.InferredDowncast _) :: _ -> true + // Parens must be kept in a scenario like + // + // !x.M(y) + // ~~~x.M(y) + // + // since prefix ! or ~~~ (with no space) have higher + // precedence than regular function application. + | _, SyntaxNode.SynExpr(SynExpr.App _) :: SyntaxNode.SynExpr(PrefixApp High) :: _ -> true + // Parens are never required around suffixed or infixed numeric literals, e.g., // // (1l).ToString() @@ -794,13 +825,17 @@ module SynExpr = match outer, inner with | ConfusableWithTypeApp, _ -> true - | SynExpr.IfThenElse _, Dangling.Sequential _ -> true + | SynExpr.IfThenElse(trivia = trivia), Dangling.LetOrUse letOrUse -> + Position.posLt letOrUse.Range.Start trivia.ThenKeyword.Start - | SynExpr.IfThenElse(trivia = trivia), Dangling.IfThen ifThenElse when - problematic ifThenElse.Range trivia.ThenKeyword - || trivia.ElseKeyword |> Option.exists (problematic ifThenElse.Range) - -> - true + | SynExpr.IfThenElse(trivia = trivia), Dangling.IfThen dangling + | SynExpr.IfThenElse(trivia = trivia), Dangling.Match dangling -> + problematic dangling.Range trivia.ThenKeyword + || trivia.ElseKeyword |> Option.exists (problematic dangling.Range) + + | SynExpr.IfThenElse(ifExpr = expr), Dangling.Sequential dangling + | SynExpr.While(whileExpr = expr), Dangling.Problematic dangling + | SynExpr.ForEach(enumExpr = expr), Dangling.Problematic dangling -> Range.rangeContainsRange expr.Range dangling.Range | SynExpr.TryFinally(trivia = trivia), Dangling.Try tryExpr when problematic tryExpr.Range trivia.FinallyKeyword -> true @@ -824,6 +859,25 @@ module SynExpr = -> true + // A match-like construct could be problematically nested like this: + // + // match () with + // | _ when + // p && + // let x = f () + // (let y = z + // match x with + // | 3 | _ -> y) -> () + // | _ -> () + | _, Dangling.Match matchOrTry when + let line = getSourceLineStr matchOrTry.Range.EndLine + let endCol = matchOrTry.Range.EndColumn + + line.Length > endCol + 1 + && line.AsSpan(endCol + 1).TrimStart(' ').StartsWith("->".AsSpan()) + -> + true + | SynExpr.Sequential(expr1 = SynExpr.Paren(expr = Is inner); expr2 = expr2), Dangling.Problematic _ when problematic inner.Range expr2.Range -> @@ -842,9 +896,10 @@ module SynExpr = | SynExpr.Sequential(expr1 = SynExpr.Paren(expr = Is inner); expr2 = expr2), _ when innerBindingsWouldShadowOuter inner expr2 -> true - | SynExpr.InterpolatedString _, SynExpr.Sequential _ -> true + | SynExpr.InterpolatedString _, SynExpr.Sequential _ + | SynExpr.InterpolatedString _, SynExpr.Tuple(isStruct = false) -> true - | SynExpr.InterpolatedString(contents = contents), (SynExpr.Tuple(isStruct = false) | Dangling.Problematic _) -> + | SynExpr.InterpolatedString(contents = contents), Dangling.Problematic _ -> contents |> List.exists (function | SynInterpolatedStringPart.FillExpr(qualifiers = Some _) -> true diff --git a/src/Compiler/Service/SynPat.fs b/src/Compiler/Service/SynPat.fs index 53212cf17dc..0016acb26d0 100644 --- a/src/Compiler/Service/SynPat.fs +++ b/src/Compiler/Service/SynPat.fs @@ -55,6 +55,24 @@ module SynPat = | SynPat.Tuple(isStruct = false; elementPats = Last(Rightmost pat)) -> pat | pat -> pat + /// Matches a nested as pattern. + [] + let rec (|DanglingAs|_|) pat = + let (|AnyDanglingAs|_|) = + List.tryPick (function + | DanglingAs -> Some() + | _ -> None) + + match pat with + | SynPat.As _ -> ValueSome() + | SynPat.Or(lhsPat = DanglingAs) + | SynPat.Or(rhsPat = DanglingAs) + | SynPat.ListCons(lhsPat = DanglingAs) + | SynPat.ListCons(rhsPat = DanglingAs) + | SynPat.Ands(pats = AnyDanglingAs) + | SynPat.Tuple(isStruct = false; elementPats = AnyDanglingAs) -> ValueSome() + | _ -> ValueNone + /// Matches if the given pattern is atomic. [] let (|Atomic|_|) pat = @@ -88,6 +106,7 @@ module SynPat = // fun (x, y, …) -> … // fun (x: …) -> … // fun (Pattern …) -> … + // set (x: …, y: …) = … | SynPat.Typed _, SyntaxNode.SynPat(Rightmost(SynPat.Paren(Is pat, _))) :: SyntaxNode.SynMatchClause _ :: _ | Rightmost(SynPat.Typed _), SyntaxNode.SynMatchClause _ :: _ | SynPat.Typed _, SyntaxNode.SynExpr(SynExpr.LetOrUseBang _) :: _ @@ -98,23 +117,62 @@ module SynPat = | SynPat.LongIdent(argPats = SynArgPats.Pats(_ :: _)), SyntaxNode.SynBinding _ :: _ | SynPat.LongIdent(argPats = SynArgPats.Pats(_ :: _)), SyntaxNode.SynExpr(SynExpr.Lambda _) :: _ | SynPat.Tuple(isStruct = false), SyntaxNode.SynExpr(SynExpr.Lambda(parsedData = Some _)) :: _ - | SynPat.Typed _, SyntaxNode.SynExpr(SynExpr.Lambda(parsedData = Some _)) :: _ -> true + | SynPat.Typed _, SyntaxNode.SynExpr(SynExpr.Lambda(parsedData = Some _)) :: _ + | SynPat.Typed _, + SyntaxNode.SynPat(SynPat.Tuple(isStruct = false)) :: SyntaxNode.SynPat(SynPat.LongIdent _) :: SyntaxNode.SynBinding _ :: SyntaxNode.SynMemberDefn(SynMemberDefn.GetSetMember _) :: _ + | SynPat.Typed _, + SyntaxNode.SynPat(SynPat.Tuple(isStruct = false)) :: SyntaxNode.SynPat(SynPat.LongIdent _) :: SyntaxNode.SynBinding(SynBinding( + valData = SynValData( + memberFlags = Some { + MemberKind = SynMemberKind.PropertyGetSet | SynMemberKind.PropertyGet | SynMemberKind.PropertySet + }))) :: _ -> true // () is parsed as this. | SynPat.Const(SynConst.Unit, _), _ -> true // (()) is required when overriding a generic member - // where unit is the generic type argument: + // where unit or a tuple type is the generic type argument: // // type C<'T> = abstract M : 'T -> unit // let _ = { new C with override _.M (()) = () } - | SynPat.Paren(SynPat.Const(SynConst.Unit, _), _), + // let _ = { new C with override _.M ((x, y)) = () } + | SynPat.Paren((SynPat.Const(SynConst.Unit, _) | SynPat.Tuple(isStruct = false)), _), SyntaxNode.SynPat(SynPat.LongIdent _) :: SyntaxNode.SynBinding _ :: SyntaxNode.SynExpr(SynExpr.ObjExpr( objType = SynType.App(typeArgs = _ :: _) | SynType.LongIdentApp(typeArgs = _ :: _))) :: _ - | SynPat.Paren(SynPat.Const(SynConst.Unit, _), _), + | SynPat.Tuple(isStruct = false), + SyntaxNode.SynPat(SynPat.Paren _) :: SyntaxNode.SynPat(SynPat.LongIdent _) :: SyntaxNode.SynBinding _ :: SyntaxNode.SynExpr(SynExpr.ObjExpr( + objType = SynType.App(typeArgs = _ :: _) | SynType.LongIdentApp(typeArgs = _ :: _))) :: _ + | SynPat.Paren((SynPat.Const(SynConst.Unit, _) | SynPat.Tuple(isStruct = false)), _), SyntaxNode.SynPat(SynPat.LongIdent _) :: SyntaxNode.SynBinding _ :: SyntaxNode.SynMemberDefn _ :: SyntaxNode.SynTypeDefn(SynTypeDefn( typeRepr = SynTypeDefnRepr.ObjectModel(members = AnyGenericInheritOrInterfaceImpl))) :: _ -> true + // Not required: + // + // let (a, + // b, + // c) = … + // + // Required: + // + // let (a, + // b, + // c) = + // … + | SynPat.Tuple(isStruct = false; range = innerRange), SyntaxNode.SynBinding(SynBinding(expr = body)) :: _ -> + innerRange.StartLine <> innerRange.EndLine + && innerRange.StartLine < body.Range.StartLine + && body.Range.StartColumn <= innerRange.StartColumn + + // The parens could be required by a signature file like this: + // + // type SemanticClassificationItem = + // new: (range * SemanticClassificationType) -> SemanticClassificationItem + | SynPat.Paren(SynPat.Tuple(isStruct = false), _), + SyntaxNode.SynPat(SynPat.LongIdent(longDotId = SynLongIdent(id = [ Ident "new" ]))) :: SyntaxNode.SynBinding _ :: SyntaxNode.SynMemberDefn _ :: SyntaxNode.SynTypeDefn _ :: _ + | SynPat.Tuple(isStruct = false), + SyntaxNode.SynPat(SynPat.Paren _) :: SyntaxNode.SynPat(SynPat.LongIdent(longDotId = SynLongIdent(id = [ Ident "new" ]))) :: SyntaxNode.SynBinding _ :: SyntaxNode.SynMemberDefn _ :: SyntaxNode.SynTypeDefn _ :: _ -> + true + // Parens are required around the atomic argument of // any additional `new` constructor that is not the last. // @@ -204,9 +262,9 @@ module SynPat = // A | (B as C) // A & (B as C) // A, (B as C) - | SynPat.Or _, SynPat.As _ - | SynPat.Ands _, SynPat.As _ - | SynPat.Tuple _, SynPat.As _ + | SynPat.Or _, (SynPat.As _ | DanglingAs) + | SynPat.Ands _, (SynPat.As _ | DanglingAs) + | SynPat.Tuple _, (SynPat.As _ | DanglingAs) // x, (y, z) // x & (y, z) diff --git a/vsintegration/src/FSharp.Editor/CodeFixes/RemoveUnnecessaryParentheses.fs b/vsintegration/src/FSharp.Editor/CodeFixes/RemoveUnnecessaryParentheses.fs index b55fbb26139..d072d2154b3 100644 --- a/vsintegration/src/FSharp.Editor/CodeFixes/RemoveUnnecessaryParentheses.fs +++ b/vsintegration/src/FSharp.Editor/CodeFixes/RemoveUnnecessaryParentheses.fs @@ -15,6 +15,27 @@ open CancellableTasks module private Patterns = let inline toPat f x = if f x then ValueSome() else ValueNone + /// Starts with //. + [] + let (|StartsWithSingleLineComment|_|) (s: string) = + if s.AsSpan().TrimStart(' ').StartsWith("//".AsSpan()) then + ValueSome StartsWithSingleLineComment + else + ValueNone + + /// Starts with match, e.g., + /// + /// (match … with + /// | … -> …) + [] + let (|StartsWithMatch|_|) (s: string) = + let s = s.AsSpan().TrimStart ' ' + + if s.StartsWith("match".AsSpan()) && (s.Length = 5 || s[5] = ' ') then + ValueSome StartsWithMatch + else + ValueNone + [] module Char = [] @@ -137,11 +158,17 @@ type internal FSharpRemoveUnnecessaryParenthesesCodeFixProvider [ loop innerOffsides (lineNo + 1) 0 | i -> - match innerOffsides with - | NoneYet -> loop (FirstLine(i + startCol)) (lineNo + 1) 0 - | FirstLine innerOffsides -> loop (FollowingLine(innerOffsides, i + startCol)) (lineNo + 1) 0 - | FollowingLine(firstLine, innerOffsides) -> - loop (FollowingLine(firstLine, min innerOffsides (i + startCol))) (lineNo + 1) 0 + match line[i + startCol ..] with + | StartsWithMatch + | StartsWithSingleLineComment -> loop innerOffsides (lineNo + 1) 0 + | _ -> + match innerOffsides with + | NoneYet -> loop (FirstLine(i + startCol)) (lineNo + 1) 0 + + | FirstLine inner -> loop (FollowingLine(inner, i + startCol)) (lineNo + 1) 0 + + | FollowingLine(firstLine, innerOffsides) -> + loop (FollowingLine(firstLine, min innerOffsides (i + startCol))) (lineNo + 1) 0 else innerOffsides @@ -165,21 +192,24 @@ type internal FSharpRemoveUnnecessaryParenthesesCodeFixProvider [ None - | '[', '|', (Punctuation | LetterOrDigit) -> None - | _, '[', '<' -> Some ShouldPutSpaceBefore - | _, ('(' | '[' | '{'), _ -> None - | _, '>', _ -> Some ShouldPutSpaceBefore - | ' ', '=', _ -> Some ShouldPutSpaceBefore - | _, '=', ('(' | '[' | '{') -> None - | _, '=', (Punctuation | Symbol) -> Some ShouldPutSpaceBefore - | _, LetterOrDigit, '(' -> None - | _, (LetterOrDigit | '`'), _ -> Some ShouldPutSpaceBefore - | _, (Punctuation | Symbol), (Punctuation | Symbol) -> Some ShouldPutSpaceBefore - | _ -> None + match s with + | StartsWithMatch -> None + | _ -> + // ……(……) + // ↑↑ ↑ + match sourceText[max (context.Span.Start - 2) 0], sourceText[max (context.Span.Start - 1) 0], s[0] with + | _, _, ('\n' | '\r') -> None + | '[', '|', (Punctuation | LetterOrDigit) -> None + | _, '[', '<' -> Some ShouldPutSpaceBefore + | _, ('(' | '[' | '{'), _ -> None + | _, '>', _ -> Some ShouldPutSpaceBefore + | ' ', '=', _ -> Some ShouldPutSpaceBefore + | _, '=', ('(' | '[' | '{') -> None + | _, '=', (Punctuation | Symbol) -> Some ShouldPutSpaceBefore + | _, LetterOrDigit, '(' -> None + | _, (LetterOrDigit | '`'), _ -> Some ShouldPutSpaceBefore + | _, (Punctuation | Symbol), (Punctuation | Symbol) -> Some ShouldPutSpaceBefore + | _ -> None let (|ShouldPutSpaceAfter|_|) (s: string) = // (……)… @@ -187,23 +217,42 @@ type internal FSharpRemoveUnnecessaryParenthesesCodeFixProvider [', ('|' | ']') -> Some ShouldPutSpaceAfter | _, (')' | ']' | '[' | '}' | '.' | ';' | ',' | '|') -> None + | _, ('+' | '-' | '%' | '&' | '!' | '~') -> None | (Punctuation | Symbol), (Punctuation | Symbol | LetterOrDigit) -> Some ShouldPutSpaceAfter | LetterOrDigit, LetterOrDigit -> Some ShouldPutSpaceAfter | _ -> None + let (|WouldTurnInfixIntoPrefix|_|) (s: string) = + // (……)… + // ↑ ↑ + match s[s.Length - 1], sourceText[min context.Span.End (sourceText.Length - 1)] with + | (Punctuation | Symbol), ('+' | '-' | '%' | '&' | '!' | '~') -> + let linePos = sourceText.Lines.GetLinePosition context.Span.End + let line = sourceText.Lines[linePos.Line].ToString() + + // (……)+… + // ↑ + match line.AsSpan(linePos.Character).IndexOfAnyExcept("*/%-+:^@><=!|$.?".AsSpan()) with + | -1 -> None + | i when line[linePos.Character + i] <> ' ' -> Some WouldTurnInfixIntoPrefix + | _ -> None + | _ -> None + match adjusted with - | ShouldPutSpaceBefore & ShouldPutSpaceAfter -> " " + adjusted + " " - | ShouldPutSpaceBefore -> " " + adjusted - | ShouldPutSpaceAfter -> adjusted + " " - | adjusted -> adjusted + | WouldTurnInfixIntoPrefix -> ValueNone + | ShouldPutSpaceBefore & ShouldPutSpaceAfter -> ValueSome(" " + adjusted + " ") + | ShouldPutSpaceBefore -> ValueSome(" " + adjusted) + | ShouldPutSpaceAfter -> ValueSome(adjusted + " ") + | adjusted -> ValueSome adjusted return - ValueSome + newText + |> ValueOption.map (fun newText -> { Name = CodeFix.RemoveUnnecessaryParentheses Message = title Changes = [ TextChange(context.Span, newText) ] - } + }) | notParens -> System.Diagnostics.Debug.Fail $"%A{notParens} <> ('(', ')')" diff --git a/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/RemoveUnnecessaryParenthesesTests.fs b/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/RemoveUnnecessaryParenthesesTests.fs index 8808871f497..13227d8eb42 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/RemoveUnnecessaryParenthesesTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/RemoveUnnecessaryParenthesesTests.fs @@ -151,6 +151,42 @@ let _ = 1 " + " + let (a, + b, + c, + d, + e, + f) = g + ", + " + let a, + b, + c, + d, + e, + f = g + " + + " + let (a, + b, + c, + d, + e, + f) = + g + ", + " + let (a, + b, + c, + d, + e, + f) = + g + " + // AnonymousRecord "{| A = (1) |}", "{| A = 1 |}" "{| A = (1); B = 2 |}", "{| A = 1; B = 2 |}" @@ -188,6 +224,7 @@ let _ = // While "while (true) do ()", "while true do ()" "while true do (ignore 3)", "while true do ignore 3" + "while (match () with _ -> true) do ()", "while (match () with _ -> true) do ()" // For "for x = (0) to 1 do ()", "for x = 0 to 1 do ()" @@ -200,6 +237,7 @@ let _ = "for (x) in [] do ()", "for x in [] do ()" "for x in ([]) do ()", "for x in [] do ()" "for x in [] do (ignore 3)", "for x in [] do ignore 3" + "for x in (try [] with _ -> []) do ()", "for x in (try [] with _ -> []) do ()" // ArrayOrListComputed "[1; 2; (if x then 3 else 4); 5]", "[1; 2; (if x then 3 else 4); 5]" @@ -293,6 +331,63 @@ let _ = | _ -> 3 " + " + 3 > ( match x with + | 1 + | _ -> 3) + ", + " + 3 > match x with + | 1 + | _ -> 3 + " + + " + 3 > (match x with + | 1 + | _ -> 3) + ", + " + 3 > match x with + | 1 + | _ -> 3 + " + + " + 3 > (match x with + // Lol. + | 1 + | _ -> 3) + ", + " + 3 > match x with + // Lol. + | 1 + | _ -> 3 + " + + " + 3 >(match x with + | 1 + | _ -> 3) + ", + " + 3 >match x with + | 1 + | _ -> 3 + " + + " + f(match x with + | 1 + | _ -> 3) + ", + " + f(match x with + | 1 + | _ -> 3) + " + // Do "do (ignore 3)", "do ignore 3" @@ -903,6 +998,11 @@ in x () """ + "if (match () with _ -> true) then ()", "if (match () with _ -> true) then ()" + + "if (match () with _ -> true) && (match () with _ -> true) then ()", + "if (match () with _ -> true) && (match () with _ -> true) then ()" + // LongIdent "(|Failure|_|) null", "(|Failure|_|) null" @@ -913,6 +1013,15 @@ in x "([]).Length", "[].Length" "([] : int list).Length", "([] : int list).Length" + "Debug.Assert((xT.DeclaringType :?> ProvidedTypeDefinition).BelongsToTargetModel)", + "Debug.Assert((xT.DeclaringType :?> ProvidedTypeDefinition).BelongsToTargetModel)" + + "Debug.Assert ((xT.DeclaringType :?> ProvidedTypeDefinition).BelongsToTargetModel)", + "Debug.Assert (xT.DeclaringType :?> ProvidedTypeDefinition).BelongsToTargetModel" + + "Assert((xT.DeclaringType :?> ProvidedTypeDefinition).BelongsToTargetModel)", + "Assert((xT.DeclaringType :?> ProvidedTypeDefinition).BelongsToTargetModel)" + // DotLambda """_.ToString("x")""", """_.ToString("x")""" """_.ToString(("x"))""", """_.ToString("x")""" @@ -1097,6 +1206,7 @@ in x "$\"{-(3)}\"", "$\"{-3}\"" "$\"{(id 3)}\"", "$\"{id 3}\"" "$\"{(x)}\"", "$\"{x}\"" + "$\"{(x, y)}\"", "$\"{(x, y)}\"" "$\"{(if true then 1 else 0)}\"", "$\"{if true then 1 else 0}\"" "$\"{(if true then 1 else 0):N0}\"", "$\"{(if true then 1 else 0):N0}\"" @@ -1238,6 +1348,20 @@ in x "id (struct (x, y))", "id struct (x, y)" "id (x, y)", "id (x, y)" + // We can't tell syntactically whether the method might have the signature + // + // val TryGetValue : 'Key * outref<'Value> -> bool + // + // where 'Key is 'a * 'b, in which case the double parens are required. + // We could look this up in the typed tree, but we don't currently. + "x.TryGetValue((y, z))", "x.TryGetValue((y, z))" + + "valInfosForFslib.Force(g).TryGetValue((vref, vref.Deref.GetLinkageFullKey()))", + "valInfosForFslib.Force(g).TryGetValue((vref, vref.Deref.GetLinkageFullKey()))" + + "SemanticClassificationItem((m, SemanticClassificationType.Printf))", + "SemanticClassificationItem((m, SemanticClassificationType.Printf))" + // AnonRecd "id ({||})", "id {||}" "{| A = (fun () -> ()) |}", "{| A = fun () -> () |}" @@ -1417,6 +1541,65 @@ in x "(id <| match x with _ -> x) |> id", "(id <| match x with _ -> x) |> id" "id <| (match x with _ -> x) |> id", "id <| (match x with _ -> x) |> id" + " + match () with + | _ when + (true && + let x = 3 + match x with + | 3 | _ -> true) -> () + | _ -> () + ", + " + match () with + | _ when + (true && + let x = 3 + match x with + | 3 | _ -> true) -> () + | _ -> () + " + + " + match () with + | _ when + true && + let x = 3 + (match x with + | 3 | _ -> true) -> () + | _ -> () + ", + " + match () with + | _ when + true && + let x = 3 + (match x with + | 3 | _ -> true) -> () + | _ -> () + " + + " + match () with + | _ when + true && + let x = 3 + (let y = false + match x with + | 3 | _ -> y) -> () + | _ -> () + ", + " + match () with + | _ when + true && + let x = 3 + (let y = false + match x with + | 3 | _ -> y) -> () + | _ -> () + " + // Do "id (do ())", "id (do ())" @@ -1513,6 +1696,7 @@ in x """(id("x")).Length""", """(id "x").Length""" """(id "x").Length""", """(id "x").Length""" """(3L.ToString("x")).Length""", """(3L.ToString "x").Length""" + "~~TypedResults.Ok(maybe.Value)", "~~TypedResults.Ok(maybe.Value)" // DotLambda "[{| A = x |}] |> List.map (_.A)", "[{| A = x |}] |> List.map _.A" @@ -1611,6 +1795,22 @@ in x // Miscellaneous "System.Threading.Tasks.Task.CompletedTask.ConfigureAwait((x = x))", "System.Threading.Tasks.Task.CompletedTask.ConfigureAwait((x = x))" + + "x.M(y).N((z = z))", "x.M(y).N((z = z))" + + """ + dprintn ("The local method '"+(String.concat "." (tenc@[tname]))+"'::'"+mdkey.Name+"' was referenced but not declared") + """, + """ + dprintn ("The local method '"+(String.concat "." (tenc@[tname]))+"'::'"+mdkey.Name+"' was referenced but not declared") + """ + + """ + ""+(Unchecked.defaultof)+"" + """, + """ + ""+(Unchecked.defaultof)+"" + """ } [] @@ -2552,6 +2752,84 @@ module Patterns = new (x, y, z) = T (x, y) member _.Z = x + y " + + // The parens could be required by a signature file like this: + // + // type SemanticClassificationItem = + // val Range: range + // val Type: SemanticClassificationType + // new: (range * SemanticClassificationType) -> SemanticClassificationItem + " + type SemanticClassificationItem = + val Range: range + val Type: SemanticClassificationType + new((range, ty)) = { Range = range; Type = ty } + ", + " + type SemanticClassificationItem = + val Range: range + val Type: SemanticClassificationType + new((range, ty)) = { Range = range; Type = ty } + " + + " + match 1, 2 with + | _, (1 | 2 as x) -> () + | _ -> () + ", + " + match 1, 2 with + | _, (1 | 2 as x) -> () + | _ -> () + " + + " + match 1, [2] with + | _, (1 | 2 as x :: _) -> () + | _ -> () + ", + " + match 1, [2] with + | _, (1 | 2 as x :: _) -> () + | _ -> () + " + + " + match 1, [2] with + | _, (1 as x :: _ :: _) -> () + | _ -> () + ", + " + match 1, [2] with + | _, (1 as x :: _ :: _) -> () + | _ -> () + " + + " + type T () = + member this.Item + with get (y : int) = 3 + and set (x : int) (y : int) = ignore (x, y) + ", + " + type T () = + member this.Item + with get (y : int) = 3 + and set (x : int) (y : int) = ignore (x, y) + " + + " + let _ = + { new IEquatable with + member this.GetHashCode ((x, y, z)) = x + y + z + member this.Equals ((x, y, z), (x', y', z')) = false } + ", + " + let _ = + { new IEquatable with + member this.GetHashCode ((x, y, z)) = x + y + z + member this.Equals ((x, y, z), (x', y', z')) = false } + " } []