diff --git a/Directory.Build.props b/Directory.Build.props
index 3dd057f702b..e8e24051b1d 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -6,6 +6,7 @@
true
net8.0
+
+ $(OtherFlags) --realsig-
+ $(OtherFlags) --realsig+
+
+
diff --git a/FSharp.Compiler.Service.sln.DotSettings b/FSharp.Compiler.Service.sln.DotSettings
index 59e0b85499d..9dc83c0360c 100644
--- a/FSharp.Compiler.Service.sln.DotSettings
+++ b/FSharp.Compiler.Service.sln.DotSettings
@@ -426,7 +426,7 @@
True
True
True
- True
+ True
True
True
True
diff --git a/FSharpBuild.Directory.Build.props b/FSharpBuild.Directory.Build.props
index d0b155bb410..f991ba6b072 100644
--- a/FSharpBuild.Directory.Build.props
+++ b/FSharpBuild.Directory.Build.props
@@ -114,7 +114,7 @@
+
+GenericEquality x y
+
+--inline-->
+
+GenericEqualityFast x y
+
+--inline-->
+
+GenericEqualityIntrinsic x y
+
+--devirtualize-->
+
+x.Equals(box y, LanguagePrimitives.GenericEqualityComparer);
+```
+
+The struct type has these generated methods:
+```csharp
+ override bool Equals(object y)
+ override bool Equals(SomeStruct obj)
+ override bool Equals(object obj, IEqualityComparer comp) //with EqualsVal
+```
+
+These call each other in sequence, boxing then unboxing then boxing. We do NOT generate this method, we probably should:
+
+```csharp
+ override bool Equals(SomeStruct obj, IEqualityComparer comp) //with EqualsValUnboxed
+```
+
+If we did, the devirtualizing optimization should reduce to this directly, which would result in no boxing.
+
+
+
+### array type (byte[], int[], some-struct-type[], ...)
+
+* Semantics: User expects structural
+* Perf expected: User expects perf is sum of constituent parts
+* Compilation today: `GenericEqualityIntrinsic`
+* Perf today: hand-optimized ([here](https://github.com/dotnet/fsharp/blob/611e4f350e119a4173a2b235eac65539ac2b61b6/src/FSharp.Core/prim-types.fs#L1562)) for some primitive element types ✅ but boxes each element if "other" is struct or generic, see Problem3 ❌, Problem4 ❌
+* [sharplab for `byte[]`](https://sharplab.io/#v2:DYLgZgzgPgsAUMApgFwARlQCgB4lQIwE9lEBtAXQEpVDUBeLbemy+IA=)
+* Note: ([#16615](https://github.com/dotnet/fsharp/pull/16615)) will improve this compiling to either ``FSharpEqualityComparer_PER`1::get_EqualityComparer().Equals(...)`` or ``FSharpEqualityComparer_PER`1::get_EqualityComparer().Equals(...)``
+
+### F# large reference record/union type
+
+Here "large" means the compiler-generated structural equality is NOT inlined.
+
+* Semantics: User expects structural by default
+* Perf expected: User expects perf is sum of constituent parts, type-specialized if generic
+* Compilation today: direct call to `Equals(T)`
+* Perf today: the call to `Equals(T)` has specialized code but boxes fields if struct or generic, see Problem3 ❌, Problem4 ❌
+
+### F# tiny reference (anonymous) record or union type
+
+Here "tiny" means the compiler-generated structural equality IS inlined.
+
+* Semantics: User expects structural by default
+* Perf expected: User expects perf is sum of constituent parts, type-specialized if generic
+* Compilation today: flattened, calling `GenericEqualityERIntrinsic` on struct and generic fields
+* Perf today: boxes on struct and generic fields, see Problem3 ❌, Problem4 ❌
+* Note: [#16615](https://github.com/dotnet/fsharp/pull/16615) will help, compiling to ``FSharpEqualityComparer_ER`1::get_EqualityComparer().Equals(...)`` on struct and generic fields
+
+### Generic `'T` in non-inlined generic code
+
+* Semantics: User expects the PER equality semantics of whatever `'T` actually is
+* Perf expected: User expects no boxing
+* Compilation today: `GenericEqualityERIntrinsic`
+* Perf today: boxes if `'T` is any non-reference type (Problem4 ❌)
+* Note: [#16615](https://github.com/dotnet/fsharp/pull/16615) will improve this compiling to ``FSharpEqualityComparer_ER`1::get_EqualityComparer().Equals(...)``
+
+### Generic `'T` in recursive position in structural comparison
+
+This case happens in structural equality for tuple types and other structural types
+
+* Semantics: User expects the PER equality semantics of whatever `'T` actually is
+* Perf: User expects no boxing
+* Compilation today: `GenericEqualityWithComparerIntrinsic LanguagePrimitives.GenericComparer`
+* Perf today: boxes for if `'T` is any non-reference type (Problem4 ❌)
+* [Sharplab](https://sharplab.io/#v2:DYLgZgzgPgsAUMApgFwARlQCgB4iwSwDs0AqVAEwHsBXAIyVTIHIAVASjdQE9UBeLbH25t48TCVFxB/LpIC0cosCJEA5goB8kgOKJCiAE74AxgFEAjtQCGy5D0Gy48BUpWF1crU7gAJKxAALAGFKAFsABysDRAA6XX0jM0sbfDsAMX80B1R5RUJlQjVNHT1DEwtrWy4ASWIjQggTAB4WAEZGVBYAJg6WAGYNVAdcgHlw5HxQ/AAvQ00sckQAN3wDNHiypMrUmrqiRuMRbwyIZAqbCBZqcKQ+1AAZK3drVUQABSMpiaXECDjSxIhCJRQwCVoAGmwXUhfU4mC4EK40K4sNyrkK7mK3iQaGMYUi0QMQkezysrw+k1S+B+fw2gPxIIM8Dp5WSVQA6qlggzCSdcTzQdh2gjUAAyUXMgGs7Z2TnIbnA3mZVB4xWCnpIsUSuAsrYpWVcoEEwx8lUConYO4o3KDSQ4s1qon8EmqF7vT5Umn/BImI2M+DGRDmIbC9rigNBoYanrhnVSvUcw3m2rIeoHB3Gi1WvqSEhHeBAA==)
+* Note: [#16615](https://github.com/dotnet/fsharp/pull/16615) will compile to ``FSharpEqualityComparer_ER`1::get_EqualityComparer().Equals(...)`` and avoid boxing in many cases
+
+## Techniques available to us
+
+1. Flatten and inline
+2. RCG: Use reflective code generation internally in FSharp.Core
+3. KFS: Rely on known semantics of F# structural types and treat those as special
+4. TS: Hand-code type-specializations using static optimization conditions in FSharp.Core
+5. TT: Type-indexed tables of baked (poss by reflection) equality comparers and functions, where some pre-computation is done
+6. DV: De-virtualization
+7. DEQ: Use `EqualityComparer<'T>.Default` where possible
+
+## Notes on previous attempts to improve things
+
+### [#5112](https://github.com/dotnet/fsharp/pull/5112)
+
+* Uses TT, DEQ, KFS, DV
+* Focuses on solving Problem4
+* 99% not breaking, apart from the case of value types with custom equality implemented differently than the `EqualityComparer.Default` - the change would lead to the usage of the custom implementation which is reasonable
+
+Note: this included [changes to the optimizer to reduce GenericEqualityIntrinsic](https://github.com/dotnet/fsharp/pull/5112/files#diff-be48dbef2f0baca27a783ac4a31ec0aedb2704c7f42ea3a2b8228513f9904cfbR2360-R2363) down to a type-indexed table lookup fetching an `IEqualityComparer` and calling it. These hand-coded reductions appear unnecessary as the reduction doesn't open up any further optimizations.
\ No newline at end of file
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 5507157222e..83a1b23aa9f 100644
--- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md
+++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md
@@ -1,6 +1,6 @@
### Fixed
-* Fix wrong range start of INTERP_STRING_END. ([PR #16774](https://github.com/dotnet/fsharp/pull/16774))
+* 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))
* `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))
@@ -14,6 +14,7 @@
* Allow calling method with both Optional and ParamArray. ([#PR 16688](https://github.com/dotnet/fsharp/pull/16688), [suggestions #1120](https://github.com/fsharp/fslang-suggestions/issues/1120))
* Fix release inline optimization, which leads to MethodAccessException if used with `assembly:InternalsVisibleTo`` attribute. ([Issue #16105](https://github.com/dotnet/fsharp/issues/16105), ([PR #16737](https://github.com/dotnet/fsharp/pull/16737))
* 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))
### Added
@@ -21,6 +22,7 @@
* Parser recovers on complex primary constructor patterns, better tree representation for primary constructor patterns. ([PR #16425](https://github.com/dotnet/fsharp/pull/16425))
* Name resolution: keep type vars in subsequent checks ([PR #16456](https://github.com/dotnet/fsharp/pull/16456))
* Higher-order-function-based API for working with the untyped abstract syntax tree. ([PR #16462](https://github.com/dotnet/fsharp/pull/16462))
+* 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))
diff --git a/docs/release-notes/.FSharp.Core/8.0.300.md b/docs/release-notes/.FSharp.Core/8.0.300.md
index 9acf7d07635..7c3911ae98f 100644
--- a/docs/release-notes/.FSharp.Core/8.0.300.md
+++ b/docs/release-notes/.FSharp.Core/8.0.300.md
@@ -1,3 +1,8 @@
+### Added
+
+* 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))
+
### Fixed
-* Preserve original stack traces in resumable state machines generated code if available. ([PR #16568](https://github.com/dotnet/fsharp/pull/16568))
\ No newline at end of file
+* Preserve original stack traces in resumable state machines generated code if available. ([PR #16568](https://github.com/dotnet/fsharp/pull/16568))
diff --git a/docs/release-notes/.Language/preview.md b/docs/release-notes/.Language/preview.md
index f39dd172561..a4dd48f213d 100644
--- a/docs/release-notes/.Language/preview.md
+++ b/docs/release-notes/.Language/preview.md
@@ -9,6 +9,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))
### Changed
diff --git a/docs/release-notes/.VisualStudio/17.10.md b/docs/release-notes/.VisualStudio/17.10.md
index a4b0a8a9f0d..6c27a8fcfd1 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))
+* 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))
### Changed
diff --git a/eng/Build.ps1 b/eng/Build.ps1
index 049ba91217d..bb449e05665 100644
--- a/eng/Build.ps1
+++ b/eng/Build.ps1
@@ -69,6 +69,7 @@ param (
[switch]$sourceBuild,
[switch]$skipBuild,
[switch]$compressAllMetadata,
+ [switch]$norealsig,
[switch]$verifypackageshipstatus = $false,
[parameter(ValueFromRemainingArguments = $true)][string[]]$properties)
@@ -131,7 +132,8 @@ function Print-Usage() {
Write-Host " -sourceBuild Simulate building for source-build."
Write-Host " -skipbuild Skip building product"
Write-Host " -compressAllMetadata Build product with compressed metadata"
- Write-Host " -verifypackageshipstatus Verify whether the packages we are building have already shipped to nuget"
+ Write-Host " -norealsig Build product with realsig- (default use realsig+)"
+ Write-Host " -verifypackageshipstatus Verify whether the packages we are building have already shipped to nuget"
Write-Host ""
Write-Host "Command line arguments starting with '/p:' are passed through to MSBuild."
}
@@ -210,6 +212,12 @@ function Process-Arguments() {
$script:compressAllMetadata = $True;
}
+ if ($norealsig) {
+ $script:realsig = $False;
+ }
+ else {
+ $script:realsig = $True;
+ }
if ($verifypackageshipstatus) {
$script:verifypackageshipstatus = $True;
}
@@ -288,6 +296,7 @@ function BuildSolution([string] $solutionName, $nopack) {
/p:TestTargetFrameworks=$testTargetFrameworks `
/p:DotNetBuildFromSource=$sourceBuild `
/p:CompressAllMetadata=$CompressAllMetadata `
+ /p:TestingLegacyInternalSignature=$realsig `
/v:$verbosity `
$suppressExtensionDeployment `
@properties
@@ -671,7 +680,7 @@ try {
}
if ($testAOT) {
- Push-Location "$RepoRoot\tests\AheadOfTime\Trimming"
+ Push-Location "$RepoRoot\tests\AheadOfTime"
./check.cmd
Pop-Location
}
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 31ab30f9652..e683f21d846 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -30,9 +30,9 @@
-
+
https://github.com/dotnet/arcade
- 042763a811fd94dc3556253d4c64118dd665216e
+ cbb61c3a9a42e7c3cce17ee453ff5ecdc7f69282
diff --git a/eng/build.sh b/eng/build.sh
index 6e5d09b79d5..f8db4462ff7 100755
--- a/eng/build.sh
+++ b/eng/build.sh
@@ -34,6 +34,7 @@ usage()
echo " --skipBuild Do not run the build"
echo " --prepareMachine Prepare machine for CI run, clean up processes after build"
echo " --sourceBuild Simulate building for source-build"
+ echo " --norealsig Build product with realsig- (default use realsig+)"
echo " --tfm Override the default target framework"
echo ""
echo "Command line arguments starting with '/p:' are passed through to MSBuild."
@@ -68,6 +69,7 @@ skip_analyzers=false
skip_build=false
prepare_machine=false
source_build=false
+realsig=true
properties=""
docker=false
@@ -152,6 +154,9 @@ while [[ $# > 0 ]]; do
--sourcebuild)
source_build=true
;;
+ --norealsig)
+ realsig=false
+ ;;
--tfm)
tfm=$2
shift
@@ -308,6 +313,7 @@ function BuildSolution {
/p:QuietRestore=$quiet_restore \
/p:QuietRestoreBinaryLog="$binary_log" \
/p:ArcadeBuildFromSource=$source_build \
+ /p:TestingLegacyInternalSignature=$realsig \
$properties
fi
}
diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml
new file mode 100644
index 00000000000..9e7bebe9af8
--- /dev/null
+++ b/eng/common/templates-official/job/job.yml
@@ -0,0 +1,255 @@
+# Internal resources (telemetry, microbuild) can only be accessed from non-public projects,
+# and some (Microbuild) should only be applied to non-PR cases for internal builds.
+
+parameters:
+# Job schema parameters - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
+ cancelTimeoutInMinutes: ''
+ condition: ''
+ container: ''
+ continueOnError: false
+ dependsOn: ''
+ displayName: ''
+ pool: ''
+ steps: []
+ strategy: ''
+ timeoutInMinutes: ''
+ variables: []
+ workspace: ''
+
+# Job base template specific parameters
+ # See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md
+ artifacts: ''
+ enableMicrobuild: false
+ enablePublishBuildArtifacts: false
+ enablePublishBuildAssets: false
+ enablePublishTestResults: false
+ enablePublishUsingPipelines: false
+ enableBuildRetry: false
+ disableComponentGovernance: ''
+ componentGovernanceIgnoreDirectories: ''
+ mergeTestResults: false
+ testRunTitle: ''
+ testResultsFormat: ''
+ name: ''
+ preSteps: []
+ runAsPublic: false
+# Sbom related params
+ enableSbom: true
+ PackageVersion: 7.0.0
+ BuildDropPath: '$(Build.SourcesDirectory)/artifacts'
+
+jobs:
+- job: ${{ parameters.name }}
+
+ ${{ if ne(parameters.cancelTimeoutInMinutes, '') }}:
+ cancelTimeoutInMinutes: ${{ parameters.cancelTimeoutInMinutes }}
+
+ ${{ if ne(parameters.condition, '') }}:
+ condition: ${{ parameters.condition }}
+
+ ${{ if ne(parameters.container, '') }}:
+ container: ${{ parameters.container }}
+
+ ${{ if ne(parameters.continueOnError, '') }}:
+ continueOnError: ${{ parameters.continueOnError }}
+
+ ${{ if ne(parameters.dependsOn, '') }}:
+ dependsOn: ${{ parameters.dependsOn }}
+
+ ${{ if ne(parameters.displayName, '') }}:
+ displayName: ${{ parameters.displayName }}
+
+ ${{ if ne(parameters.pool, '') }}:
+ pool: ${{ parameters.pool }}
+
+ ${{ if ne(parameters.strategy, '') }}:
+ strategy: ${{ parameters.strategy }}
+
+ ${{ if ne(parameters.timeoutInMinutes, '') }}:
+ timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
+
+ variables:
+ - ${{ if ne(parameters.enableTelemetry, 'false') }}:
+ - name: DOTNET_CLI_TELEMETRY_PROFILE
+ value: '$(Build.Repository.Uri)'
+ - ${{ if eq(parameters.enableRichCodeNavigation, 'true') }}:
+ - name: EnableRichCodeNavigation
+ value: 'true'
+ # Retry signature validation up to three times, waiting 2 seconds between attempts.
+ # See https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu3028#retry-untrusted-root-failures
+ - name: NUGET_EXPERIMENTAL_CHAIN_BUILD_RETRY_POLICY
+ value: 3,2000
+ - ${{ each variable in parameters.variables }}:
+ # handle name-value variable syntax
+ # example:
+ # - name: [key]
+ # value: [value]
+ - ${{ if ne(variable.name, '') }}:
+ - name: ${{ variable.name }}
+ value: ${{ variable.value }}
+
+ # handle variable groups
+ - ${{ if ne(variable.group, '') }}:
+ - group: ${{ variable.group }}
+
+ # handle template variable syntax
+ # example:
+ # - template: path/to/template.yml
+ # parameters:
+ # [key]: [value]
+ - ${{ if ne(variable.template, '') }}:
+ - template: ${{ variable.template }}
+ ${{ if ne(variable.parameters, '') }}:
+ parameters: ${{ variable.parameters }}
+
+ # handle key-value variable syntax.
+ # example:
+ # - [key]: [value]
+ - ${{ if and(eq(variable.name, ''), eq(variable.group, ''), eq(variable.template, '')) }}:
+ - ${{ each pair in variable }}:
+ - name: ${{ pair.key }}
+ value: ${{ pair.value }}
+
+ # DotNet-HelixApi-Access provides 'HelixApiAccessToken' for internal builds
+ - ${{ if and(eq(parameters.enableTelemetry, 'true'), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - group: DotNet-HelixApi-Access
+
+ ${{ if ne(parameters.workspace, '') }}:
+ workspace: ${{ parameters.workspace }}
+
+ steps:
+ - ${{ if ne(parameters.preSteps, '') }}:
+ - ${{ each preStep in parameters.preSteps }}:
+ - ${{ preStep }}
+
+ - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - ${{ if eq(parameters.enableMicrobuild, 'true') }}:
+ - task: MicroBuildSigningPlugin@3
+ displayName: Install MicroBuild plugin
+ inputs:
+ signType: $(_SignType)
+ zipSources: false
+ feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json
+ env:
+ TeamName: $(_TeamName)
+ continueOnError: ${{ parameters.continueOnError }}
+ condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT'))
+
+ - ${{ if and(eq(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'internal')) }}:
+ - task: NuGetAuthenticate@1
+
+ - ${{ if and(ne(parameters.artifacts.download, 'false'), ne(parameters.artifacts.download, '')) }}:
+ - task: DownloadPipelineArtifact@2
+ inputs:
+ buildType: current
+ artifactName: ${{ coalesce(parameters.artifacts.download.name, 'Artifacts_$(Agent.OS)_$(_BuildConfig)') }}
+ targetPath: ${{ coalesce(parameters.artifacts.download.path, 'artifacts') }}
+ itemPattern: ${{ coalesce(parameters.artifacts.download.pattern, '**') }}
+
+ - ${{ each step in parameters.steps }}:
+ - ${{ step }}
+
+ - ${{ if eq(parameters.enableRichCodeNavigation, true) }}:
+ - task: RichCodeNavIndexer@0
+ displayName: RichCodeNav Upload
+ inputs:
+ languages: ${{ coalesce(parameters.richCodeNavigationLanguage, 'csharp') }}
+ environment: ${{ coalesce(parameters.richCodeNavigationEnvironment, 'production') }}
+ richNavLogOutputDirectory: $(Build.SourcesDirectory)/artifacts/bin
+ uploadRichNavArtifacts: ${{ coalesce(parameters.richCodeNavigationUploadArtifacts, false) }}
+ continueOnError: true
+
+ - template: /eng/common/templates-official/steps/component-governance.yml
+ parameters:
+ ${{ if eq(parameters.disableComponentGovernance, '') }}:
+ ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}:
+ disableComponentGovernance: false
+ ${{ else }}:
+ disableComponentGovernance: true
+ ${{ else }}:
+ disableComponentGovernance: ${{ parameters.disableComponentGovernance }}
+ componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}
+
+ - ${{ if eq(parameters.enableMicrobuild, 'true') }}:
+ - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - task: MicroBuildCleanup@1
+ displayName: Execute Microbuild cleanup tasks
+ condition: and(always(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT'))
+ continueOnError: ${{ parameters.continueOnError }}
+ env:
+ TeamName: $(_TeamName)
+
+ - ${{ if ne(parameters.artifacts.publish, '') }}:
+ - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}:
+ - task: CopyFiles@2
+ displayName: Gather binaries for publish to artifacts
+ inputs:
+ SourceFolder: 'artifacts/bin'
+ Contents: '**'
+ TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/bin'
+ - task: CopyFiles@2
+ displayName: Gather packages for publish to artifacts
+ inputs:
+ SourceFolder: 'artifacts/packages'
+ Contents: '**'
+ TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/packages'
+ - task: 1ES.PublishBuildArtifacts@1
+ displayName: Publish pipeline artifacts
+ inputs:
+ PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts'
+ PublishLocation: Container
+ ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }}
+ 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
+ continueOnError: true
+ condition: always()
+
+ - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}:
+ - task: 1ES.PublishBuildArtifacts@1
+ displayName: Publish Logs
+ inputs:
+ PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)'
+ PublishLocation: Container
+ ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }}
+ continueOnError: true
+ condition: always()
+
+ - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'xunit')) }}:
+ - task: PublishTestResults@2
+ displayName: Publish XUnit Test Results
+ inputs:
+ testResultsFormat: 'xUnit'
+ testResultsFiles: '*.xml'
+ searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'
+ testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit
+ mergeTestResults: ${{ parameters.mergeTestResults }}
+ continueOnError: true
+ condition: always()
+ - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'vstest')) }}:
+ - task: PublishTestResults@2
+ displayName: Publish TRX Test Results
+ inputs:
+ testResultsFormat: 'VSTest'
+ testResultsFiles: '*.trx'
+ searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'
+ testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx
+ mergeTestResults: ${{ parameters.mergeTestResults }}
+ continueOnError: true
+ condition: always()
+
+ - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}:
+ - template: /eng/common/templates-official/steps/generate-sbom.yml
+ parameters:
+ PackageVersion: ${{ parameters.packageVersion}}
+ BuildDropPath: ${{ parameters.buildDropPath }}
+ IgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}
+
+ - ${{ if eq(parameters.enableBuildRetry, 'true') }}:
+ - publish: $(Build.SourcesDirectory)\eng\common\BuildConfiguration
+ artifact: BuildConfiguration
+ displayName: Publish build retry configuration
+ continueOnError: true
diff --git a/eng/common/templates-official/job/onelocbuild.yml b/eng/common/templates-official/job/onelocbuild.yml
new file mode 100644
index 00000000000..ba9ba493032
--- /dev/null
+++ b/eng/common/templates-official/job/onelocbuild.yml
@@ -0,0 +1,112 @@
+parameters:
+ # Optional: dependencies of the job
+ dependsOn: ''
+
+ # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool
+ pool: ''
+
+ CeapexPat: $(dn-bot-ceapex-package-r) # PAT for the loc AzDO instance https://dev.azure.com/ceapex
+ GithubPat: $(BotAccount-dotnet-bot-repo-PAT)
+
+ SourcesDirectory: $(Build.SourcesDirectory)
+ CreatePr: true
+ AutoCompletePr: false
+ ReusePr: true
+ UseLfLineEndings: true
+ UseCheckedInLocProjectJson: false
+ SkipLocProjectJsonGeneration: false
+ LanguageSet: VS_Main_Languages
+ LclSource: lclFilesInRepo
+ LclPackageId: ''
+ RepoType: gitHub
+ GitHubOrg: dotnet
+ MirrorRepo: ''
+ MirrorBranch: main
+ condition: ''
+ JobNameSuffix: ''
+
+jobs:
+- job: OneLocBuild${{ parameters.JobNameSuffix }}
+
+ dependsOn: ${{ parameters.dependsOn }}
+
+ displayName: OneLocBuild${{ parameters.JobNameSuffix }}
+
+ variables:
+ - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat
+ - name: _GenerateLocProjectArguments
+ value: -SourcesDirectory ${{ parameters.SourcesDirectory }}
+ -LanguageSet "${{ parameters.LanguageSet }}"
+ -CreateNeutralXlfs
+ - ${{ if eq(parameters.UseCheckedInLocProjectJson, 'true') }}:
+ - name: _GenerateLocProjectArguments
+ value: ${{ variables._GenerateLocProjectArguments }} -UseCheckedInLocProjectJson
+ - template: /eng/common/templates-official/variables/pool-providers.yml
+
+ ${{ if ne(parameters.pool, '') }}:
+ pool: ${{ parameters.pool }}
+ ${{ if eq(parameters.pool, '') }}:
+ pool:
+ # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
+ ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
+ name: AzurePipelines-EO
+ image: 1ESPT-Windows2022
+ demands: Cmd
+ os: windows
+ # If it's not devdiv, it's dnceng
+ ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
+ name: $(DncEngInternalBuildPool)
+ image: 1es-windows-2022-pt
+ os: windows
+
+ steps:
+ - ${{ if ne(parameters.SkipLocProjectJsonGeneration, 'true') }}:
+ - task: Powershell@2
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/generate-locproject.ps1
+ arguments: $(_GenerateLocProjectArguments)
+ displayName: Generate LocProject.json
+ condition: ${{ parameters.condition }}
+
+ - task: OneLocBuild@2
+ displayName: OneLocBuild
+ env:
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ inputs:
+ locProj: eng/Localize/LocProject.json
+ outDir: $(Build.ArtifactStagingDirectory)
+ lclSource: ${{ parameters.LclSource }}
+ lclPackageId: ${{ parameters.LclPackageId }}
+ isCreatePrSelected: ${{ parameters.CreatePr }}
+ isAutoCompletePrSelected: ${{ parameters.AutoCompletePr }}
+ ${{ if eq(parameters.CreatePr, true) }}:
+ isUseLfLineEndingsSelected: ${{ parameters.UseLfLineEndings }}
+ ${{ if eq(parameters.RepoType, 'gitHub') }}:
+ isShouldReusePrSelected: ${{ parameters.ReusePr }}
+ packageSourceAuth: patAuth
+ patVariable: ${{ parameters.CeapexPat }}
+ ${{ if eq(parameters.RepoType, 'gitHub') }}:
+ repoType: ${{ parameters.RepoType }}
+ gitHubPatVariable: "${{ parameters.GithubPat }}"
+ ${{ if ne(parameters.MirrorRepo, '') }}:
+ isMirrorRepoSelected: true
+ gitHubOrganization: ${{ parameters.GitHubOrg }}
+ mirrorRepo: ${{ parameters.MirrorRepo }}
+ mirrorBranch: ${{ parameters.MirrorBranch }}
+ condition: ${{ parameters.condition }}
+
+ - task: 1ES.PublishBuildArtifacts@1
+ displayName: Publish Localization Files
+ inputs:
+ PathtoPublish: '$(Build.ArtifactStagingDirectory)/loc'
+ PublishLocation: Container
+ ArtifactName: Loc
+ condition: ${{ parameters.condition }}
+
+ - task: 1ES.PublishBuildArtifacts@1
+ displayName: Publish LocProject.json
+ inputs:
+ PathtoPublish: '$(Build.SourcesDirectory)/eng/Localize/'
+ PublishLocation: Container
+ ArtifactName: Loc
+ condition: ${{ parameters.condition }}
\ 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
new file mode 100644
index 00000000000..ea5104625fa
--- /dev/null
+++ b/eng/common/templates-official/job/publish-build-assets.yml
@@ -0,0 +1,153 @@
+parameters:
+ configuration: 'Debug'
+
+ # Optional: condition for the job to run
+ condition: ''
+
+ # Optional: 'true' if future jobs should run even if this job fails
+ continueOnError: false
+
+ # Optional: dependencies of the job
+ dependsOn: ''
+
+ # Optional: Include PublishBuildArtifacts task
+ enablePublishBuildArtifacts: false
+
+ # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool
+ pool: {}
+
+ # Optional: should run as a public build even in the internal project
+ # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects.
+ runAsPublic: false
+
+ # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing
+ publishUsingPipelines: false
+
+ # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing
+ publishAssetsImmediately: false
+
+ artifactsPublishingAdditionalParameters: ''
+
+ signingValidationAdditionalParameters: ''
+
+jobs:
+- job: Asset_Registry_Publish
+
+ dependsOn: ${{ parameters.dependsOn }}
+ timeoutInMinutes: 150
+
+ ${{ if eq(parameters.publishAssetsImmediately, 'true') }}:
+ displayName: Publish Assets
+ ${{ else }}:
+ displayName: Publish to Build Asset Registry
+
+ variables:
+ - template: /eng/common/templates-official/variables/pool-providers.yml
+ - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - group: Publish-Build-Assets
+ - group: AzureDevOps-Artifact-Feeds-Pats
+ - name: runCodesignValidationInjection
+ value: false
+ - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}:
+ - template: /eng/common/templates-official/post-build/common-variables.yml
+
+ pool:
+ # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
+ ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
+ name: AzurePipelines-EO
+ image: 1ESPT-Windows2022
+ demands: Cmd
+ os: windows
+ # If it's not devdiv, it's dnceng
+ ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
+ name: $(DncEngInternalBuildPool)
+ image: 1es-windows-2022-pt
+ os: windows
+ steps:
+ - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download artifact
+ inputs:
+ artifactName: AssetManifests
+ downloadPath: '$(Build.StagingDirectory)/Download'
+ checkDownloadedFiles: true
+ condition: ${{ parameters.condition }}
+ continueOnError: ${{ parameters.continueOnError }}
+
+ - task: NuGetAuthenticate@1
+
+ - task: PowerShell@2
+ displayName: Publish Build Assets
+ inputs:
+ filePath: eng\common\sdk-task.ps1
+ arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet
+ /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests'
+ /p:BuildAssetRegistryToken=$(MaestroAccessToken)
+ /p:MaestroApiEndpoint=https://maestro-prod.westus2.cloudapp.azure.com
+ /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }}
+ /p:OfficialBuildId=$(Build.BuildNumber)
+ condition: ${{ parameters.condition }}
+ continueOnError: ${{ parameters.continueOnError }}
+
+ - task: powershell@2
+ displayName: Create ReleaseConfigs Artifact
+ 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)
+
+ - task: 1ES.PublishBuildArtifacts@1
+ displayName: Publish ReleaseConfigs Artifact
+ inputs:
+ PathtoPublish: '$(Build.StagingDirectory)/ReleaseConfigs.txt'
+ PublishLocation: Container
+ ArtifactName: ReleaseConfigs
+
+ - task: powershell@2
+ displayName: Check if SymbolPublishingExclusionsFile.txt exists
+ inputs:
+ targetType: inline
+ script: |
+ $symbolExclusionfile = "$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt"
+ if(Test-Path -Path $symbolExclusionfile)
+ {
+ Write-Host "SymbolExclusionFile exists"
+ Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]true"
+ }
+ else{
+ Write-Host "Symbols Exclusion file does not exists"
+ Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]false"
+ }
+
+ - task: 1ES.PublishBuildArtifacts@1
+ displayName: Publish SymbolPublishingExclusionsFile Artifact
+ condition: eq(variables['SymbolExclusionFile'], 'true')
+ inputs:
+ PathtoPublish: '$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt'
+ PublishLocation: Container
+ ArtifactName: ReleaseConfigs
+
+ - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}:
+ - template: /eng/common/templates-official/post-build/setup-maestro-vars.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+
+ - task: PowerShell@2
+ displayName: Publish Using Darc
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1
+ arguments: -BuildId $(BARBuildId)
+ -PublishingInfraVersion 3
+ -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)'
+ -MaestroToken '$(MaestroApiAccessToken)'
+ -WaitPublishingFinish true
+ -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}'
+ -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'
+
+ - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}:
+ - template: /eng/common/templates-official/steps/publish-logs.yml
+ parameters:
+ JobLabel: 'Publish_Artifacts_Logs'
diff --git a/eng/common/templates-official/job/source-build.yml b/eng/common/templates-official/job/source-build.yml
new file mode 100644
index 00000000000..8aba3b44bb2
--- /dev/null
+++ b/eng/common/templates-official/job/source-build.yml
@@ -0,0 +1,67 @@
+parameters:
+ # This template adds arcade-powered source-build to CI. The template produces a server job with a
+ # default ID 'Source_Build_Complete' to put in a dependency list if necessary.
+
+ # Specifies the prefix for source-build jobs added to pipeline. Use this if disambiguation needed.
+ jobNamePrefix: 'Source_Build'
+
+ # Defines the platform on which to run the job. By default, a linux-x64 machine, suitable for
+ # managed-only repositories. This is an object with these properties:
+ #
+ # name: ''
+ # The name of the job. This is included in the job ID.
+ # targetRID: ''
+ # The name of the target RID to use, instead of the one auto-detected by Arcade.
+ # nonPortable: false
+ # Enables non-portable mode. This means a more specific RID (e.g. fedora.32-x64 rather than
+ # linux-x64), and compiling against distro-provided packages rather than portable ones.
+ # skipPublishValidation: false
+ # Disables publishing validation. By default, a check is performed to ensure no packages are
+ # published by source-build.
+ # container: ''
+ # A container to use. Runs in docker.
+ # pool: {}
+ # A pool to use. Runs directly on an agent.
+ # buildScript: ''
+ # Specifies the build script to invoke to perform the build in the repo. The default
+ # './build.sh' should work for typical Arcade repositories, but this is customizable for
+ # difficult situations.
+ # jobProperties: {}
+ # A list of job properties to inject at the top level, for potential extensibility beyond
+ # container and pool.
+ platform: {}
+
+jobs:
+- job: ${{ parameters.jobNamePrefix }}_${{ parameters.platform.name }}
+ displayName: Source-Build (${{ parameters.platform.name }})
+
+ ${{ each property in parameters.platform.jobProperties }}:
+ ${{ property.key }}: ${{ property.value }}
+
+ ${{ if ne(parameters.platform.container, '') }}:
+ container: ${{ parameters.platform.container }}
+
+ ${{ if eq(parameters.platform.pool, '') }}:
+ # The default VM host AzDO pool. This should be capable of running Docker containers: almost all
+ # source-build builds run in Docker, including the default managed platform.
+ # /eng/common/templates-official/variables/pool-providers.yml can't be used here (some customers declare variables already), so duplicate its logic
+ pool:
+ ${{ if eq(variables['System.TeamProject'], 'public') }}:
+ name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore-Svc-Public' ), False, 'NetCore-Public')]
+ demands: ImageOverride -equals Build.Ubuntu.1804.Amd64.Open
+
+ ${{ if eq(variables['System.TeamProject'], 'internal') }}:
+ name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')]
+ image: 1es-mariner-2-pt
+ os: linux
+
+ ${{ if ne(parameters.platform.pool, '') }}:
+ pool: ${{ parameters.platform.pool }}
+
+ workspace:
+ clean: all
+
+ steps:
+ - template: /eng/common/templates-official/steps/source-build.yml
+ parameters:
+ platform: ${{ parameters.platform }}
diff --git a/eng/common/templates-official/job/source-index-stage1.yml b/eng/common/templates-official/job/source-index-stage1.yml
new file mode 100644
index 00000000000..4b633739170
--- /dev/null
+++ b/eng/common/templates-official/job/source-index-stage1.yml
@@ -0,0 +1,68 @@
+parameters:
+ runAsPublic: false
+ sourceIndexPackageVersion: 1.0.1-20230228.2
+ sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json
+ sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci"
+ preSteps: []
+ binlogPath: artifacts/log/Debug/Build.binlog
+ condition: ''
+ dependsOn: ''
+ pool: ''
+
+jobs:
+- job: SourceIndexStage1
+ dependsOn: ${{ parameters.dependsOn }}
+ condition: ${{ parameters.condition }}
+ variables:
+ - name: SourceIndexPackageVersion
+ value: ${{ parameters.sourceIndexPackageVersion }}
+ - name: SourceIndexPackageSource
+ value: ${{ parameters.sourceIndexPackageSource }}
+ - name: BinlogPath
+ value: ${{ parameters.binlogPath }}
+ - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - group: source-dot-net stage1 variables
+ - template: /eng/common/templates-official/variables/pool-providers.yml
+
+ ${{ if ne(parameters.pool, '') }}:
+ pool: ${{ parameters.pool }}
+ ${{ if eq(parameters.pool, '') }}:
+ pool:
+ ${{ if eq(variables['System.TeamProject'], 'public') }}:
+ name: $(DncEngPublicBuildPool)
+ demands: ImageOverride -equals windows.vs2019.amd64.open
+ ${{ if eq(variables['System.TeamProject'], 'internal') }}:
+ name: $(DncEngInternalBuildPool)
+ image: 1es-windows-2022-pt
+ os: windows
+
+ steps:
+ - ${{ each preStep in parameters.preSteps }}:
+ - ${{ preStep }}
+
+ - task: UseDotNet@2
+ displayName: Use .NET Core SDK 6
+ inputs:
+ packageType: sdk
+ version: 6.0.x
+ installationPath: $(Agent.TempDirectory)/dotnet
+ workingDirectory: $(Agent.TempDirectory)
+
+ - script: |
+ $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools
+ $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools
+ displayName: Download Tools
+ # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk.
+ workingDirectory: $(Agent.TempDirectory)
+
+ - script: ${{ parameters.sourceIndexBuildCommand }}
+ displayName: Build Repository
+
+ - script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i $(BinlogPath) -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output
+ displayName: Process Binlog into indexable sln
+
+ - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name)
+ displayName: Upload stage1 artifacts to source index
+ env:
+ BLOB_CONTAINER_URL: $(source-dot-net-stage1-blob-container-url)
diff --git a/eng/common/templates-official/jobs/codeql-build.yml b/eng/common/templates-official/jobs/codeql-build.yml
new file mode 100644
index 00000000000..b68d3c2f319
--- /dev/null
+++ b/eng/common/templates-official/jobs/codeql-build.yml
@@ -0,0 +1,31 @@
+parameters:
+ # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md
+ continueOnError: false
+ # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
+ jobs: []
+ # Optional: if specified, restore and use this version of Guardian instead of the default.
+ overrideGuardianVersion: ''
+
+jobs:
+- template: /eng/common/templates-official/jobs/jobs.yml
+ parameters:
+ enableMicrobuild: false
+ enablePublishBuildArtifacts: false
+ enablePublishTestResults: false
+ enablePublishBuildAssets: false
+ enablePublishUsingPipelines: false
+ enableTelemetry: true
+
+ variables:
+ - group: Publish-Build-Assets
+ # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in
+ # sync with the packages.config file.
+ - name: DefaultGuardianVersion
+ value: 0.109.0
+ - name: GuardianPackagesConfigFile
+ value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config
+ - name: GuardianVersion
+ value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }}
+
+ jobs: ${{ parameters.jobs }}
+
diff --git a/eng/common/templates-official/jobs/jobs.yml b/eng/common/templates-official/jobs/jobs.yml
new file mode 100644
index 00000000000..857a0f8ba43
--- /dev/null
+++ b/eng/common/templates-official/jobs/jobs.yml
@@ -0,0 +1,97 @@
+parameters:
+ # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md
+ continueOnError: false
+
+ # Optional: Include PublishBuildArtifacts task
+ enablePublishBuildArtifacts: false
+
+ # Optional: Enable publishing using release pipelines
+ enablePublishUsingPipelines: false
+
+ # Optional: Enable running the source-build jobs to build repo from source
+ enableSourceBuild: false
+
+ # Optional: Parameters for source-build template.
+ # See /eng/common/templates-official/jobs/source-build.yml for options
+ sourceBuildParameters: []
+
+ graphFileGeneration:
+ # Optional: Enable generating the graph files at the end of the build
+ enabled: false
+ # Optional: Include toolset dependencies in the generated graph files
+ includeToolset: false
+
+ # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
+ jobs: []
+
+ # Optional: Override automatically derived dependsOn value for "publish build assets" job
+ publishBuildAssetsDependsOn: ''
+
+ # Optional: Publish the assets as soon as the publish to BAR stage is complete, rather doing so in a separate stage.
+ publishAssetsImmediately: false
+
+ # Optional: If using publishAssetsImmediately and additional parameters are needed, can be used to send along additional parameters (normally sent to post-build.yml)
+ artifactsPublishingAdditionalParameters: ''
+ signingValidationAdditionalParameters: ''
+
+ # Optional: should run as a public build even in the internal project
+ # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects.
+ runAsPublic: false
+
+ enableSourceIndex: false
+ sourceIndexParams: {}
+
+# Internal resources (telemetry, microbuild) can only be accessed from non-public projects,
+# and some (Microbuild) should only be applied to non-PR cases for internal builds.
+
+jobs:
+- ${{ each job in parameters.jobs }}:
+ - template: ../job/job.yml
+ parameters:
+ # pass along parameters
+ ${{ each parameter in parameters }}:
+ ${{ if ne(parameter.key, 'jobs') }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
+
+ # pass along job properties
+ ${{ each property in job }}:
+ ${{ if ne(property.key, 'job') }}:
+ ${{ property.key }}: ${{ property.value }}
+
+ name: ${{ job.job }}
+
+- ${{ if eq(parameters.enableSourceBuild, true) }}:
+ - template: /eng/common/templates-official/jobs/source-build.yml
+ parameters:
+ allCompletedJobId: Source_Build_Complete
+ ${{ each parameter in parameters.sourceBuildParameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
+
+- ${{ if eq(parameters.enableSourceIndex, 'true') }}:
+ - template: ../job/source-index-stage1.yml
+ parameters:
+ runAsPublic: ${{ parameters.runAsPublic }}
+ ${{ each parameter in parameters.sourceIndexParams }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
+
+- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - ${{ if or(eq(parameters.enablePublishBuildAssets, true), eq(parameters.artifacts.publish.manifests, 'true'), ne(parameters.artifacts.publish.manifests, '')) }}:
+ - template: ../job/publish-build-assets.yml
+ parameters:
+ continueOnError: ${{ parameters.continueOnError }}
+ dependsOn:
+ - ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}:
+ - ${{ each job in parameters.publishBuildAssetsDependsOn }}:
+ - ${{ job.job }}
+ - ${{ if eq(parameters.publishBuildAssetsDependsOn, '') }}:
+ - ${{ each job in parameters.jobs }}:
+ - ${{ job.job }}
+ - ${{ if eq(parameters.enableSourceBuild, true) }}:
+ - Source_Build_Complete
+
+ runAsPublic: ${{ parameters.runAsPublic }}
+ publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }}
+ publishAssetsImmediately: ${{ parameters.publishAssetsImmediately }}
+ enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ signingValidationAdditionalParameters: ${{ parameters.signingValidationAdditionalParameters }}
diff --git a/eng/common/templates-official/jobs/source-build.yml b/eng/common/templates-official/jobs/source-build.yml
new file mode 100644
index 00000000000..08e5db9bb11
--- /dev/null
+++ b/eng/common/templates-official/jobs/source-build.yml
@@ -0,0 +1,46 @@
+parameters:
+ # This template adds arcade-powered source-build to CI. A job is created for each platform, as
+ # well as an optional server job that completes when all platform jobs complete.
+
+ # The name of the "join" job for all source-build platforms. If set to empty string, the job is
+ # not included. Existing repo pipelines can use this job depend on all source-build jobs
+ # completing without maintaining a separate list of every single job ID: just depend on this one
+ # server job. By default, not included. Recommended name if used: 'Source_Build_Complete'.
+ allCompletedJobId: ''
+
+ # See /eng/common/templates-official/job/source-build.yml
+ jobNamePrefix: 'Source_Build'
+
+ # This is the default platform provided by Arcade, intended for use by a managed-only repo.
+ defaultManagedPlatform:
+ name: 'Managed'
+ container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8'
+
+ # Defines the platforms on which to run build jobs. One job is created for each platform, and the
+ # object in this array is sent to the job template as 'platform'. If no platforms are specified,
+ # one job runs on 'defaultManagedPlatform'.
+ platforms: []
+
+jobs:
+
+- ${{ if ne(parameters.allCompletedJobId, '') }}:
+ - job: ${{ parameters.allCompletedJobId }}
+ displayName: Source-Build Complete
+ pool: server
+ dependsOn:
+ - ${{ each platform in parameters.platforms }}:
+ - ${{ parameters.jobNamePrefix }}_${{ platform.name }}
+ - ${{ if eq(length(parameters.platforms), 0) }}:
+ - ${{ parameters.jobNamePrefix }}_${{ parameters.defaultManagedPlatform.name }}
+
+- ${{ each platform in parameters.platforms }}:
+ - template: /eng/common/templates-official/job/source-build.yml
+ parameters:
+ jobNamePrefix: ${{ parameters.jobNamePrefix }}
+ platform: ${{ platform }}
+
+- ${{ if eq(length(parameters.platforms), 0) }}:
+ - template: /eng/common/templates-official/job/source-build.yml
+ parameters:
+ jobNamePrefix: ${{ parameters.jobNamePrefix }}
+ platform: ${{ parameters.defaultManagedPlatform }}
diff --git a/eng/common/templates-official/post-build/common-variables.yml b/eng/common/templates-official/post-build/common-variables.yml
new file mode 100644
index 00000000000..c24193acfc9
--- /dev/null
+++ b/eng/common/templates-official/post-build/common-variables.yml
@@ -0,0 +1,22 @@
+variables:
+ - group: Publish-Build-Assets
+
+ # Whether the build is internal or not
+ - name: IsInternalBuild
+ value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }}
+
+ # Default Maestro++ API Endpoint and API Version
+ - name: MaestroApiEndPoint
+ value: "https://maestro-prod.westus2.cloudapp.azure.com"
+ - name: MaestroApiAccessToken
+ value: $(MaestroAccessToken)
+ - name: MaestroApiVersion
+ value: "2020-02-20"
+
+ - name: SourceLinkCLIVersion
+ value: 3.0.0
+ - name: SymbolToolVersion
+ value: 1.0.1
+
+ - name: runCodesignValidationInjection
+ value: false
diff --git a/eng/common/templates-official/post-build/post-build.yml b/eng/common/templates-official/post-build/post-build.yml
new file mode 100644
index 00000000000..5c98fe1c0f3
--- /dev/null
+++ b/eng/common/templates-official/post-build/post-build.yml
@@ -0,0 +1,285 @@
+parameters:
+ # Which publishing infra should be used. THIS SHOULD MATCH THE VERSION ON THE BUILD MANIFEST.
+ # Publishing V1 is no longer supported
+ # Publishing V2 is no longer supported
+ # Publishing V3 is the default
+ - name: publishingInfraVersion
+ displayName: Which version of publishing should be used to promote the build definition?
+ type: number
+ default: 3
+ values:
+ - 3
+
+ - name: BARBuildId
+ displayName: BAR Build Id
+ type: number
+ default: 0
+
+ - name: PromoteToChannelIds
+ displayName: Channel to promote BARBuildId to
+ type: string
+ default: ''
+
+ - name: enableSourceLinkValidation
+ displayName: Enable SourceLink validation
+ type: boolean
+ default: false
+
+ - name: enableSigningValidation
+ displayName: Enable signing validation
+ type: boolean
+ default: true
+
+ - name: enableSymbolValidation
+ displayName: Enable symbol validation
+ type: boolean
+ default: false
+
+ - name: enableNugetValidation
+ displayName: Enable NuGet validation
+ type: boolean
+ default: true
+
+ - name: publishInstallersAndChecksums
+ displayName: Publish installers and checksums
+ type: boolean
+ default: true
+
+ - name: SDLValidationParameters
+ type: object
+ default:
+ enable: false
+ publishGdn: false
+ continueOnError: false
+ params: ''
+ artifactNames: ''
+ downloadArtifacts: true
+
+ # These parameters let the user customize the call to sdk-task.ps1 for publishing
+ # symbols & general artifacts as well as for signing validation
+ - name: symbolPublishingAdditionalParameters
+ displayName: Symbol publishing additional parameters
+ type: string
+ default: ''
+
+ - name: artifactsPublishingAdditionalParameters
+ displayName: Artifact publishing additional parameters
+ type: string
+ default: ''
+
+ - name: signingValidationAdditionalParameters
+ displayName: Signing validation additional parameters
+ type: string
+ default: ''
+
+ # Which stages should finish execution before post-build stages start
+ - name: validateDependsOn
+ type: object
+ default:
+ - build
+
+ - name: publishDependsOn
+ type: object
+ default:
+ - Validate
+
+ # Optional: Call asset publishing rather than running in a separate stage
+ - name: publishAssetsImmediately
+ type: boolean
+ default: false
+
+stages:
+- ${{ if or(eq( parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}:
+ - stage: Validate
+ dependsOn: ${{ parameters.validateDependsOn }}
+ displayName: Validate Build Assets
+ variables:
+ - template: common-variables.yml
+ - template: /eng/common/templates-official/variables/pool-providers.yml
+ jobs:
+ - job:
+ displayName: NuGet Validation
+ condition: and(succeededOrFailed(), eq( ${{ parameters.enableNugetValidation }}, 'true'))
+ pool:
+ # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
+ ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
+ name: AzurePipelines-EO
+ image: 1ESPT-Windows2022
+ demands: Cmd
+ os: windows
+ # If it's not devdiv, it's dnceng
+ ${{ else }}:
+ name: $(DncEngInternalBuildPool)
+ image: 1es-windows-2022-pt
+ os: windows
+
+ steps:
+ - template: setup-maestro-vars.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Package Artifacts
+ inputs:
+ buildType: specific
+ buildVersionToDownload: specific
+ project: $(AzDOProjectName)
+ pipeline: $(AzDOPipelineId)
+ buildId: $(AzDOBuildId)
+ artifactName: PackageArtifacts
+ checkDownloadedFiles: true
+
+ - task: PowerShell@2
+ displayName: Validate
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1
+ arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/
+ -ToolDestinationPath $(Agent.BuildDirectory)/Extract/
+
+ - job:
+ displayName: Signing Validation
+ condition: and( eq( ${{ parameters.enableSigningValidation }}, 'true'), ne( variables['PostBuildSign'], 'true'))
+ pool:
+ # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
+ ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
+ name: AzurePipelines-EO
+ image: 1ESPT-Windows2022
+ demands: Cmd
+ os: windows
+ # If it's not devdiv, it's dnceng
+ ${{ else }}:
+ name: $(DncEngInternalBuildPool)
+ image: 1es-windows-2022-pt
+ os: windows
+ steps:
+ - template: setup-maestro-vars.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Package Artifacts
+ inputs:
+ buildType: specific
+ buildVersionToDownload: specific
+ project: $(AzDOProjectName)
+ pipeline: $(AzDOPipelineId)
+ buildId: $(AzDOBuildId)
+ artifactName: PackageArtifacts
+ checkDownloadedFiles: true
+ itemPattern: |
+ **
+ !**/Microsoft.SourceBuild.Intermediate.*.nupkg
+
+ # This is necessary whenever we want to publish/restore to an AzDO private feed
+ # Since sdk-task.ps1 tries to restore packages we need to do this authentication here
+ # otherwise it'll complain about accessing a private feed.
+ - task: NuGetAuthenticate@1
+ displayName: 'Authenticate to AzDO Feeds'
+
+ # Signing validation will optionally work with the buildmanifest file which is downloaded from
+ # Azure DevOps above.
+ - task: PowerShell@2
+ displayName: Validate
+ inputs:
+ filePath: eng\common\sdk-task.ps1
+ arguments: -task SigningValidation -restore -msbuildEngine vs
+ /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts'
+ /p:SignCheckExclusionsFile='$(Build.SourcesDirectory)/eng/SignCheckExclusionsFile.txt'
+ ${{ parameters.signingValidationAdditionalParameters }}
+
+ - template: ../steps/publish-logs.yml
+ parameters:
+ StageLabel: 'Validation'
+ JobLabel: 'Signing'
+ BinlogToolVersion: $(BinlogToolVersion)
+
+ - job:
+ displayName: SourceLink Validation
+ condition: eq( ${{ parameters.enableSourceLinkValidation }}, 'true')
+ pool:
+ # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
+ ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
+ name: AzurePipelines-EO
+ image: 1ESPT-Windows2022
+ demands: Cmd
+ os: windows
+ # If it's not devdiv, it's dnceng
+ ${{ else }}:
+ name: $(DncEngInternalBuildPool)
+ image: 1es-windows-2022-pt
+ os: windows
+ steps:
+ - template: setup-maestro-vars.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Blob Artifacts
+ inputs:
+ buildType: specific
+ buildVersionToDownload: specific
+ project: $(AzDOProjectName)
+ pipeline: $(AzDOPipelineId)
+ buildId: $(AzDOBuildId)
+ artifactName: BlobArtifacts
+ checkDownloadedFiles: true
+
+ - task: PowerShell@2
+ displayName: Validate
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/sourcelink-validation.ps1
+ arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/
+ -ExtractPath $(Agent.BuildDirectory)/Extract/
+ -GHRepoName $(Build.Repository.Name)
+ -GHCommit $(Build.SourceVersion)
+ -SourcelinkCliVersion $(SourceLinkCLIVersion)
+ continueOnError: true
+
+- ${{ if ne(parameters.publishAssetsImmediately, 'true') }}:
+ - stage: publish_using_darc
+ ${{ if or(eq(parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}:
+ dependsOn: ${{ parameters.publishDependsOn }}
+ ${{ else }}:
+ dependsOn: ${{ parameters.validateDependsOn }}
+ displayName: Publish using Darc
+ variables:
+ - template: common-variables.yml
+ - template: /eng/common/templates-official/variables/pool-providers.yml
+ jobs:
+ - job:
+ displayName: Publish Using Darc
+ timeoutInMinutes: 120
+ pool:
+ # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
+ ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
+ name: AzurePipelines-EO
+ image: 1ESPT-Windows2022
+ demands: Cmd
+ os: windows
+ # If it's not devdiv, it's dnceng
+ ${{ else }}:
+ name: $(DncEngInternalBuildPool)
+ image: 1es-windows-2022-pt
+ os: windows
+ steps:
+ - template: setup-maestro-vars.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+
+ - task: NuGetAuthenticate@1
+
+ - task: PowerShell@2
+ displayName: Publish Using Darc
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1
+ arguments: -BuildId $(BARBuildId)
+ -PublishingInfraVersion ${{ parameters.publishingInfraVersion }}
+ -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)'
+ -MaestroToken '$(MaestroApiAccessToken)'
+ -WaitPublishingFinish true
+ -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}'
+ -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'
diff --git a/eng/common/templates-official/post-build/setup-maestro-vars.yml b/eng/common/templates-official/post-build/setup-maestro-vars.yml
new file mode 100644
index 00000000000..0c87f149a4a
--- /dev/null
+++ b/eng/common/templates-official/post-build/setup-maestro-vars.yml
@@ -0,0 +1,70 @@
+parameters:
+ BARBuildId: ''
+ PromoteToChannelIds: ''
+
+steps:
+ - ${{ if eq(coalesce(parameters.PromoteToChannelIds, 0), 0) }}:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Release Configs
+ inputs:
+ buildType: current
+ artifactName: ReleaseConfigs
+ checkDownloadedFiles: true
+
+ - task: PowerShell@2
+ name: setReleaseVars
+ displayName: Set Release Configs Vars
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ try {
+ if (!$Env:PromoteToMaestroChannels -or $Env:PromoteToMaestroChannels.Trim() -eq '') {
+ $Content = Get-Content $(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt
+
+ $BarId = $Content | Select -Index 0
+ $Channels = $Content | Select -Index 1
+ $IsStableBuild = $Content | Select -Index 2
+
+ $AzureDevOpsProject = $Env:System_TeamProject
+ $AzureDevOpsBuildDefinitionId = $Env:System_DefinitionId
+ $AzureDevOpsBuildId = $Env:Build_BuildId
+ }
+ else {
+ $buildApiEndpoint = "${Env:MaestroApiEndPoint}/api/builds/${Env:BARBuildId}?api-version=${Env:MaestroApiVersion}"
+
+ $apiHeaders = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]'
+ $apiHeaders.Add('Accept', 'application/json')
+ $apiHeaders.Add('Authorization',"Bearer ${Env:MAESTRO_API_TOKEN}")
+
+ $buildInfo = try { Invoke-WebRequest -Method Get -Uri $buildApiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" }
+
+ $BarId = $Env:BARBuildId
+ $Channels = $Env:PromoteToMaestroChannels -split ","
+ $Channels = $Channels -join "]["
+ $Channels = "[$Channels]"
+
+ $IsStableBuild = $buildInfo.stable
+ $AzureDevOpsProject = $buildInfo.azureDevOpsProject
+ $AzureDevOpsBuildDefinitionId = $buildInfo.azureDevOpsBuildDefinitionId
+ $AzureDevOpsBuildId = $buildInfo.azureDevOpsBuildId
+ }
+
+ Write-Host "##vso[task.setvariable variable=BARBuildId]$BarId"
+ Write-Host "##vso[task.setvariable variable=TargetChannels]$Channels"
+ Write-Host "##vso[task.setvariable variable=IsStableBuild]$IsStableBuild"
+
+ Write-Host "##vso[task.setvariable variable=AzDOProjectName]$AzureDevOpsProject"
+ Write-Host "##vso[task.setvariable variable=AzDOPipelineId]$AzureDevOpsBuildDefinitionId"
+ Write-Host "##vso[task.setvariable variable=AzDOBuildId]$AzureDevOpsBuildId"
+ }
+ catch {
+ Write-Host $_
+ Write-Host $_.Exception
+ Write-Host $_.ScriptStackTrace
+ exit 1
+ }
+ env:
+ MAESTRO_API_TOKEN: $(MaestroApiAccessToken)
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToMaestroChannels: ${{ parameters.PromoteToChannelIds }}
diff --git a/eng/common/templates-official/post-build/trigger-subscription.yml b/eng/common/templates-official/post-build/trigger-subscription.yml
new file mode 100644
index 00000000000..da669030daf
--- /dev/null
+++ b/eng/common/templates-official/post-build/trigger-subscription.yml
@@ -0,0 +1,13 @@
+parameters:
+ ChannelId: 0
+
+steps:
+- task: PowerShell@2
+ displayName: Triggering subscriptions
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/trigger-subscriptions.ps1
+ arguments: -SourceRepo $(Build.Repository.Uri)
+ -ChannelId ${{ parameters.ChannelId }}
+ -MaestroApiAccessToken $(MaestroAccessToken)
+ -MaestroApiEndPoint $(MaestroApiEndPoint)
+ -MaestroApiVersion $(MaestroApiVersion)
diff --git a/eng/common/templates-official/steps/add-build-to-channel.yml b/eng/common/templates-official/steps/add-build-to-channel.yml
new file mode 100644
index 00000000000..f67a210d62f
--- /dev/null
+++ b/eng/common/templates-official/steps/add-build-to-channel.yml
@@ -0,0 +1,13 @@
+parameters:
+ ChannelId: 0
+
+steps:
+- task: PowerShell@2
+ displayName: Add Build to Channel
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/add-build-to-channel.ps1
+ arguments: -BuildId $(BARBuildId)
+ -ChannelId ${{ parameters.ChannelId }}
+ -MaestroApiAccessToken $(MaestroApiAccessToken)
+ -MaestroApiEndPoint $(MaestroApiEndPoint)
+ -MaestroApiVersion $(MaestroApiVersion)
diff --git a/eng/common/templates-official/steps/build-reason.yml b/eng/common/templates-official/steps/build-reason.yml
new file mode 100644
index 00000000000..eba58109b52
--- /dev/null
+++ b/eng/common/templates-official/steps/build-reason.yml
@@ -0,0 +1,12 @@
+# build-reason.yml
+# Description: runs steps if build.reason condition is valid. conditions is a string of valid build reasons
+# to include steps (',' separated).
+parameters:
+ conditions: ''
+ steps: []
+
+steps:
+ - ${{ if and( not(startsWith(parameters.conditions, 'not')), contains(parameters.conditions, variables['build.reason'])) }}:
+ - ${{ parameters.steps }}
+ - ${{ if and( startsWith(parameters.conditions, 'not'), not(contains(parameters.conditions, variables['build.reason']))) }}:
+ - ${{ parameters.steps }}
diff --git a/eng/common/templates-official/steps/component-governance.yml b/eng/common/templates-official/steps/component-governance.yml
new file mode 100644
index 00000000000..0ecec47b0c9
--- /dev/null
+++ b/eng/common/templates-official/steps/component-governance.yml
@@ -0,0 +1,13 @@
+parameters:
+ disableComponentGovernance: false
+ componentGovernanceIgnoreDirectories: ''
+
+steps:
+- ${{ if eq(parameters.disableComponentGovernance, 'true') }}:
+ - script: "echo ##vso[task.setvariable variable=skipComponentGovernanceDetection]true"
+ displayName: Set skipComponentGovernanceDetection variable
+- ${{ if ne(parameters.disableComponentGovernance, 'true') }}:
+ - task: ComponentGovernanceComponentDetection@0
+ continueOnError: true
+ inputs:
+ ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}
\ No newline at end of file
diff --git a/eng/common/templates-official/steps/execute-codeql.yml b/eng/common/templates-official/steps/execute-codeql.yml
new file mode 100644
index 00000000000..9b4a5ffa30a
--- /dev/null
+++ b/eng/common/templates-official/steps/execute-codeql.yml
@@ -0,0 +1,32 @@
+parameters:
+ # Language that should be analyzed. Defaults to csharp
+ language: csharp
+ # Build Commands
+ buildCommands: ''
+ overrideParameters: '' # Optional: to override values for parameters.
+ additionalParameters: '' # Optional: parameters that need user specific values eg: '-SourceToolsList @("abc","def") -ArtifactToolsList @("ghi","jkl")'
+ # Optional: if specified, restore and use this version of Guardian instead of the default.
+ overrideGuardianVersion: ''
+ # Optional: if true, publish the '.gdn' folder as a pipeline artifact. This can help with in-depth
+ # diagnosis of problems with specific tool configurations.
+ publishGuardianDirectoryToPipeline: false
+ # The script to run to execute all SDL tools. Use this if you want to use a script to define SDL
+ # parameters rather than relying on YAML. It may be better to use a local script, because you can
+ # reproduce results locally without piecing together a command based on the YAML.
+ executeAllSdlToolsScript: 'eng/common/sdl/execute-all-sdl-tools.ps1'
+ # There is some sort of bug (has been reported) in Azure DevOps where if this parameter is named
+ # 'continueOnError', the parameter value is not correctly picked up.
+ # This can also be remedied by the caller (post-build.yml) if it does not use a nested parameter
+ # optional: determines whether to continue the build if the step errors;
+ sdlContinueOnError: false
+
+steps:
+- template: /eng/common/templates-official/steps/execute-sdl.yml
+ parameters:
+ overrideGuardianVersion: ${{ parameters.overrideGuardianVersion }}
+ executeAllSdlToolsScript: ${{ parameters.executeAllSdlToolsScript }}
+ overrideParameters: ${{ parameters.overrideParameters }}
+ additionalParameters: '${{ parameters.additionalParameters }}
+ -CodeQLAdditionalRunConfigParams @("BuildCommands < ${{ parameters.buildCommands }}", "Language < ${{ parameters.language }}")'
+ publishGuardianDirectoryToPipeline: ${{ parameters.publishGuardianDirectoryToPipeline }}
+ sdlContinueOnError: ${{ parameters.sdlContinueOnError }}
\ No newline at end of file
diff --git a/eng/common/templates-official/steps/execute-sdl.yml b/eng/common/templates-official/steps/execute-sdl.yml
new file mode 100644
index 00000000000..07426fde05d
--- /dev/null
+++ b/eng/common/templates-official/steps/execute-sdl.yml
@@ -0,0 +1,88 @@
+parameters:
+ overrideGuardianVersion: ''
+ executeAllSdlToolsScript: ''
+ overrideParameters: ''
+ additionalParameters: ''
+ publishGuardianDirectoryToPipeline: false
+ sdlContinueOnError: false
+ condition: ''
+
+steps:
+- task: NuGetAuthenticate@1
+ inputs:
+ nuGetServiceConnections: GuardianConnect
+
+- task: NuGetToolInstaller@1
+ displayName: 'Install NuGet.exe'
+
+- ${{ if ne(parameters.overrideGuardianVersion, '') }}:
+ - pwsh: |
+ Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl
+ . .\sdl.ps1
+ $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts -Version ${{ parameters.overrideGuardianVersion }}
+ Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation"
+ displayName: Install Guardian (Overridden)
+
+- ${{ if eq(parameters.overrideGuardianVersion, '') }}:
+ - pwsh: |
+ Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl
+ . .\sdl.ps1
+ $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts
+ Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation"
+ displayName: Install Guardian
+
+- ${{ if ne(parameters.overrideParameters, '') }}:
+ - powershell: ${{ parameters.executeAllSdlToolsScript }} ${{ parameters.overrideParameters }}
+ displayName: Execute SDL (Overridden)
+ continueOnError: ${{ parameters.sdlContinueOnError }}
+ condition: ${{ parameters.condition }}
+
+- ${{ if eq(parameters.overrideParameters, '') }}:
+ - powershell: ${{ parameters.executeAllSdlToolsScript }}
+ -GuardianCliLocation $(GuardianCliLocation)
+ -NugetPackageDirectory $(Build.SourcesDirectory)\.packages
+ -AzureDevOpsAccessToken $(dn-bot-dotnet-build-rw-code-rw)
+ ${{ parameters.additionalParameters }}
+ displayName: Execute SDL
+ continueOnError: ${{ parameters.sdlContinueOnError }}
+ condition: ${{ parameters.condition }}
+
+- ${{ if ne(parameters.publishGuardianDirectoryToPipeline, 'false') }}:
+ # We want to publish the Guardian results and configuration for easy diagnosis. However, the
+ # '.gdn' dir is a mix of configuration, results, extracted dependencies, and Guardian default
+ # tooling files. Some of these files are large and aren't useful during an investigation, so
+ # exclude them by simply deleting them before publishing. (As of writing, there is no documented
+ # way to selectively exclude a dir from the pipeline artifact publish task.)
+ - task: DeleteFiles@1
+ displayName: Delete Guardian dependencies to avoid uploading
+ inputs:
+ SourceFolder: $(Agent.BuildDirectory)/.gdn
+ Contents: |
+ c
+ i
+ condition: succeededOrFailed()
+
+ - publish: $(Agent.BuildDirectory)/.gdn
+ artifact: GuardianConfiguration
+ displayName: Publish GuardianConfiguration
+ condition: succeededOrFailed()
+
+ # Publish the SARIF files in a container named CodeAnalysisLogs to enable integration
+ # with the "SARIF SAST Scans Tab" Azure DevOps extension
+ - task: CopyFiles@2
+ displayName: Copy SARIF files
+ inputs:
+ flattenFolders: true
+ sourceFolder: $(Agent.BuildDirectory)/.gdn/rc/
+ contents: '**/*.sarif'
+ targetFolder: $(Build.SourcesDirectory)/CodeAnalysisLogs
+ condition: succeededOrFailed()
+
+ # Use PublishBuildArtifacts because the SARIF extension only checks this case
+ # see microsoft/sarif-azuredevops-extension#4
+ - task: PublishBuildArtifacts@1
+ displayName: Publish SARIF files to CodeAnalysisLogs container
+ inputs:
+ pathToPublish: $(Build.SourcesDirectory)/CodeAnalysisLogs
+ artifactName: CodeAnalysisLogs
+ condition: succeededOrFailed()
\ No newline at end of file
diff --git a/eng/common/templates-official/steps/generate-sbom.yml b/eng/common/templates-official/steps/generate-sbom.yml
new file mode 100644
index 00000000000..1bf43bf807a
--- /dev/null
+++ b/eng/common/templates-official/steps/generate-sbom.yml
@@ -0,0 +1,48 @@
+# BuildDropPath - The root folder of the drop directory for which the manifest file will be generated.
+# PackageName - The name of the package this SBOM represents.
+# PackageVersion - The version of the package this SBOM represents.
+# ManifestDirPath - The path of the directory where the generated manifest files will be placed
+# IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector.
+
+parameters:
+ PackageVersion: 8.0.0
+ BuildDropPath: '$(Build.SourcesDirectory)/artifacts'
+ PackageName: '.NET'
+ ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom
+ IgnoreDirectories: ''
+ sbomContinueOnError: true
+
+steps:
+- task: PowerShell@2
+ displayName: Prep for SBOM generation in (Non-linux)
+ condition: or(eq(variables['Agent.Os'], 'Windows_NT'), eq(variables['Agent.Os'], 'Darwin'))
+ inputs:
+ filePath: ./eng/common/generate-sbom-prep.ps1
+ arguments: ${{parameters.manifestDirPath}}
+
+# Chmodding is a workaround for https://github.com/dotnet/arcade/issues/8461
+- script: |
+ chmod +x ./eng/common/generate-sbom-prep.sh
+ ./eng/common/generate-sbom-prep.sh ${{parameters.manifestDirPath}}
+ displayName: Prep for SBOM generation in (Linux)
+ condition: eq(variables['Agent.Os'], 'Linux')
+ continueOnError: ${{ parameters.sbomContinueOnError }}
+
+- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
+ displayName: 'Generate SBOM manifest'
+ continueOnError: ${{ parameters.sbomContinueOnError }}
+ inputs:
+ PackageName: ${{ parameters.packageName }}
+ BuildDropPath: ${{ parameters.buildDropPath }}
+ PackageVersion: ${{ parameters.packageVersion }}
+ ManifestDirPath: ${{ parameters.manifestDirPath }}
+ ${{ if ne(parameters.IgnoreDirectories, '') }}:
+ AdditionalComponentDetectorArgs: '--IgnoreDirectories ${{ parameters.IgnoreDirectories }}'
+
+- task: 1ES.PublishPipelineArtifact@1
+ displayName: Publish SBOM manifest
+ continueOnError: ${{parameters.sbomContinueOnError}}
+ inputs:
+ targetPath: '${{parameters.manifestDirPath}}'
+ artifactName: $(ARTIFACT_NAME)
+
diff --git a/eng/common/templates-official/steps/publish-logs.yml b/eng/common/templates-official/steps/publish-logs.yml
new file mode 100644
index 00000000000..04012fed182
--- /dev/null
+++ b/eng/common/templates-official/steps/publish-logs.yml
@@ -0,0 +1,23 @@
+parameters:
+ StageLabel: ''
+ JobLabel: ''
+
+steps:
+- task: Powershell@2
+ displayName: Prepare Binlogs to Upload
+ inputs:
+ targetType: inline
+ script: |
+ New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/
+ Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/
+ continueOnError: true
+ condition: always()
+
+- task: 1ES.PublishBuildArtifacts@1
+ displayName: Publish Logs
+ inputs:
+ PathtoPublish: '$(Build.SourcesDirectory)/PostBuildLogs'
+ PublishLocation: Container
+ ArtifactName: PostBuildLogs
+ continueOnError: true
+ condition: always()
diff --git a/eng/common/templates-official/steps/retain-build.yml b/eng/common/templates-official/steps/retain-build.yml
new file mode 100644
index 00000000000..83d97a26a01
--- /dev/null
+++ b/eng/common/templates-official/steps/retain-build.yml
@@ -0,0 +1,28 @@
+parameters:
+ # Optional azure devops PAT with build execute permissions for the build's organization,
+ # only needed if the build that should be retained ran on a different organization than
+ # the pipeline where this template is executing from
+ Token: ''
+ # Optional BuildId to retain, defaults to the current running build
+ BuildId: ''
+ # Azure devops Organization URI for the build in the https://dev.azure.com/ format.
+ # Defaults to the organization the current pipeline is running on
+ AzdoOrgUri: '$(System.CollectionUri)'
+ # Azure devops project for the build. Defaults to the project the current pipeline is running on
+ AzdoProject: '$(System.TeamProject)'
+
+steps:
+ - task: powershell@2
+ inputs:
+ targetType: 'filePath'
+ filePath: eng/common/retain-build.ps1
+ pwsh: true
+ arguments: >
+ -AzdoOrgUri: ${{parameters.AzdoOrgUri}}
+ -AzdoProject ${{parameters.AzdoProject}}
+ -Token ${{coalesce(parameters.Token, '$env:SYSTEM_ACCESSTOKEN') }}
+ -BuildId ${{coalesce(parameters.BuildId, '$env:BUILD_ID')}}
+ displayName: Enable permanent build retention
+ env:
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ BUILD_ID: $(Build.BuildId)
\ No newline at end of file
diff --git a/eng/common/templates-official/steps/send-to-helix.yml b/eng/common/templates-official/steps/send-to-helix.yml
new file mode 100644
index 00000000000..3eb7e2d5f84
--- /dev/null
+++ b/eng/common/templates-official/steps/send-to-helix.yml
@@ -0,0 +1,91 @@
+# Please remember to update the documentation if you make changes to these parameters!
+parameters:
+ HelixSource: 'pr/default' # required -- sources must start with pr/, official/, prodcon/, or agent/
+ HelixType: 'tests/default/' # required -- Helix telemetry which identifies what type of data this is; should include "test" for clarity and must end in '/'
+ HelixBuild: $(Build.BuildNumber) # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number
+ HelixTargetQueues: '' # required -- semicolon-delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues
+ HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group
+ HelixConfiguration: '' # optional -- additional property attached to a job
+ HelixPreCommands: '' # optional -- commands to run before Helix work item execution
+ HelixPostCommands: '' # optional -- commands to run after Helix work item execution
+ WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects
+ WorkItemCommand: '' # optional -- a command to execute on the payload; requires WorkItemDirectory; incompatible with XUnitProjects
+ WorkItemTimeout: '' # optional -- a timeout in TimeSpan.Parse-ready value (e.g. 00:02:00) for the work item command; requires WorkItemDirectory; incompatible with XUnitProjects
+ CorrelationPayloadDirectory: '' # optional -- a directory to zip up and send to Helix as a correlation payload
+ XUnitProjects: '' # optional -- semicolon-delimited list of XUnitProjects to parse and send to Helix; requires XUnitRuntimeTargetFramework, XUnitPublishTargetFramework, XUnitRunnerVersion, and IncludeDotNetCli=true
+ XUnitWorkItemTimeout: '' # optional -- the workitem timeout in seconds for all workitems created from the xUnit projects specified by XUnitProjects
+ XUnitPublishTargetFramework: '' # optional -- framework to use to publish your xUnit projects
+ XUnitRuntimeTargetFramework: '' # optional -- framework to use for the xUnit console runner
+ XUnitRunnerVersion: '' # optional -- version of the xUnit nuget package you wish to use on Helix; required for XUnitProjects
+ IncludeDotNetCli: false # optional -- true will download a version of the .NET CLI onto the Helix machine as a correlation payload; requires DotNetCliPackageType and DotNetCliVersion
+ DotNetCliPackageType: '' # optional -- either 'sdk', 'runtime' or 'aspnetcore-runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json
+ DotNetCliVersion: '' # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json
+ WaitForWorkItemCompletion: true # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is "fire and forget."
+ IsExternal: false # [DEPRECATED] -- doesn't do anything, jobs are external if HelixAccessToken is empty and Creator is set
+ HelixBaseUri: 'https://helix.dot.net/' # optional -- sets the Helix API base URI (allows targeting https://helix.int-dot.net )
+ Creator: '' # optional -- if the build is external, use this to specify who is sending the job
+ DisplayNamePrefix: 'Run Tests' # optional -- rename the beginning of the displayName of the steps in AzDO
+ condition: succeeded() # optional -- condition for step to execute; defaults to succeeded()
+ continueOnError: false # optional -- determines whether to continue the build if the step errors; defaults to false
+
+steps:
+ - powershell: 'powershell "$env:BUILD_SOURCESDIRECTORY\eng\common\msbuild.ps1 $env:BUILD_SOURCESDIRECTORY\eng\common\helixpublish.proj /restore /p:TreatWarningsAsErrors=false /t:Test /bl:$env:BUILD_SOURCESDIRECTORY\artifacts\log\$env:BuildConfig\SendToHelix.binlog"'
+ displayName: ${{ parameters.DisplayNamePrefix }} (Windows)
+ env:
+ BuildConfig: $(_BuildConfig)
+ HelixSource: ${{ parameters.HelixSource }}
+ HelixType: ${{ parameters.HelixType }}
+ HelixBuild: ${{ parameters.HelixBuild }}
+ HelixConfiguration: ${{ parameters.HelixConfiguration }}
+ HelixTargetQueues: ${{ parameters.HelixTargetQueues }}
+ HelixAccessToken: ${{ parameters.HelixAccessToken }}
+ HelixPreCommands: ${{ parameters.HelixPreCommands }}
+ HelixPostCommands: ${{ parameters.HelixPostCommands }}
+ WorkItemDirectory: ${{ parameters.WorkItemDirectory }}
+ WorkItemCommand: ${{ parameters.WorkItemCommand }}
+ WorkItemTimeout: ${{ parameters.WorkItemTimeout }}
+ CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }}
+ XUnitProjects: ${{ parameters.XUnitProjects }}
+ XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }}
+ XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }}
+ XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }}
+ XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }}
+ IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }}
+ DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }}
+ DotNetCliVersion: ${{ parameters.DotNetCliVersion }}
+ WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }}
+ HelixBaseUri: ${{ parameters.HelixBaseUri }}
+ Creator: ${{ parameters.Creator }}
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT'))
+ continueOnError: ${{ parameters.continueOnError }}
+ - script: $BUILD_SOURCESDIRECTORY/eng/common/msbuild.sh $BUILD_SOURCESDIRECTORY/eng/common/helixpublish.proj /restore /p:TreatWarningsAsErrors=false /t:Test /bl:$BUILD_SOURCESDIRECTORY/artifacts/log/$BuildConfig/SendToHelix.binlog
+ displayName: ${{ parameters.DisplayNamePrefix }} (Unix)
+ env:
+ BuildConfig: $(_BuildConfig)
+ HelixSource: ${{ parameters.HelixSource }}
+ HelixType: ${{ parameters.HelixType }}
+ HelixBuild: ${{ parameters.HelixBuild }}
+ HelixConfiguration: ${{ parameters.HelixConfiguration }}
+ HelixTargetQueues: ${{ parameters.HelixTargetQueues }}
+ HelixAccessToken: ${{ parameters.HelixAccessToken }}
+ HelixPreCommands: ${{ parameters.HelixPreCommands }}
+ HelixPostCommands: ${{ parameters.HelixPostCommands }}
+ WorkItemDirectory: ${{ parameters.WorkItemDirectory }}
+ WorkItemCommand: ${{ parameters.WorkItemCommand }}
+ WorkItemTimeout: ${{ parameters.WorkItemTimeout }}
+ CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }}
+ XUnitProjects: ${{ parameters.XUnitProjects }}
+ XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }}
+ XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }}
+ XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }}
+ XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }}
+ IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }}
+ DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }}
+ DotNetCliVersion: ${{ parameters.DotNetCliVersion }}
+ WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }}
+ HelixBaseUri: ${{ parameters.HelixBaseUri }}
+ Creator: ${{ parameters.Creator }}
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT'))
+ continueOnError: ${{ parameters.continueOnError }}
diff --git a/eng/common/templates-official/steps/source-build.yml b/eng/common/templates-official/steps/source-build.yml
new file mode 100644
index 00000000000..829f17c34d1
--- /dev/null
+++ b/eng/common/templates-official/steps/source-build.yml
@@ -0,0 +1,129 @@
+parameters:
+ # This template adds arcade-powered source-build to CI.
+
+ # This is a 'steps' template, and is intended for advanced scenarios where the existing build
+ # infra has a careful build methodology that must be followed. For example, a repo
+ # (dotnet/runtime) might choose to clone the GitHub repo only once and store it as a pipeline
+ # artifact for all subsequent jobs to use, to reduce dependence on a strong network connection to
+ # GitHub. Using this steps template leaves room for that infra to be included.
+
+ # Defines the platform on which to run the steps. See 'eng/common/templates-official/job/source-build.yml'
+ # for details. The entire object is described in the 'job' template for simplicity, even though
+ # the usage of the properties on this object is split between the 'job' and 'steps' templates.
+ platform: {}
+
+steps:
+# Build. Keep it self-contained for simple reusability. (No source-build-specific job variables.)
+- script: |
+ set -x
+ df -h
+
+ # If building on the internal project, the artifact feeds variable may be available (usually only if needed)
+ # In that case, call the feed setup script to add internal feeds corresponding to public ones.
+ # In addition, add an msbuild argument to copy the WIP from the repo to the target build location.
+ # This is because SetupNuGetSources.sh will alter the current NuGet.config file, and we need to preserve those
+ # changes.
+ internalRestoreArgs=
+ if [ '$(dn-bot-dnceng-artifact-feeds-rw)' != '$''(dn-bot-dnceng-artifact-feeds-rw)' ]; then
+ # Temporarily work around https://github.com/dotnet/arcade/issues/7709
+ chmod +x $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh
+ $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh $(Build.SourcesDirectory)/NuGet.config $(dn-bot-dnceng-artifact-feeds-rw)
+ internalRestoreArgs='/p:CopyWipIntoInnerSourceBuildRepo=true'
+
+ # The 'Copy WIP' feature of source build uses git stash to apply changes from the original repo.
+ # This only works if there is a username/email configured, which won't be the case in most CI runs.
+ git config --get user.email
+ if [ $? -ne 0 ]; then
+ git config user.email dn-bot@microsoft.com
+ git config user.name dn-bot
+ fi
+ fi
+
+ # If building on the internal project, the internal storage variable may be available (usually only if needed)
+ # In that case, add variables to allow the download of internal runtimes if the specified versions are not found
+ # in the default public locations.
+ internalRuntimeDownloadArgs=
+ if [ '$(dotnetbuilds-internal-container-read-token-base64)' != '$''(dotnetbuilds-internal-container-read-token-base64)' ]; then
+ internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://dotnetbuilds.blob.core.windows.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)'
+ fi
+
+ buildConfig=Release
+ # Check if AzDO substitutes in a build config from a variable, and use it if so.
+ if [ '$(_BuildConfig)' != '$''(_BuildConfig)' ]; then
+ buildConfig='$(_BuildConfig)'
+ fi
+
+ officialBuildArgs=
+ if [ '${{ and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}' = 'True' ]; then
+ officialBuildArgs='/p:DotNetPublishUsingPipelines=true /p:OfficialBuildId=$(BUILD.BUILDNUMBER)'
+ fi
+
+ targetRidArgs=
+ if [ '${{ parameters.platform.targetRID }}' != '' ]; then
+ targetRidArgs='/p:TargetRid=${{ parameters.platform.targetRID }}'
+ fi
+
+ runtimeOsArgs=
+ if [ '${{ parameters.platform.runtimeOS }}' != '' ]; then
+ runtimeOsArgs='/p:RuntimeOS=${{ parameters.platform.runtimeOS }}'
+ fi
+
+ baseOsArgs=
+ if [ '${{ parameters.platform.baseOS }}' != '' ]; then
+ baseOsArgs='/p:BaseOS=${{ parameters.platform.baseOS }}'
+ fi
+
+ publishArgs=
+ if [ '${{ parameters.platform.skipPublishValidation }}' != 'true' ]; then
+ publishArgs='--publish'
+ fi
+
+ assetManifestFileName=SourceBuild_RidSpecific.xml
+ if [ '${{ parameters.platform.name }}' != '' ]; then
+ assetManifestFileName=SourceBuild_${{ parameters.platform.name }}.xml
+ fi
+
+ ${{ coalesce(parameters.platform.buildScript, './build.sh') }} --ci \
+ --configuration $buildConfig \
+ --restore --build --pack $publishArgs -bl \
+ $officialBuildArgs \
+ $internalRuntimeDownloadArgs \
+ $internalRestoreArgs \
+ $targetRidArgs \
+ $runtimeOsArgs \
+ $baseOsArgs \
+ /p:SourceBuildNonPortable=${{ parameters.platform.nonPortable }} \
+ /p:ArcadeBuildFromSource=true \
+ /p:AssetManifestFileName=$assetManifestFileName
+ displayName: Build
+
+# Upload build logs for diagnosis.
+- task: CopyFiles@2
+ displayName: Prepare BuildLogs staging directory
+ inputs:
+ SourceFolder: '$(Build.SourcesDirectory)'
+ Contents: |
+ **/*.log
+ **/*.binlog
+ artifacts/source-build/self/prebuilt-report/**
+ TargetFolder: '$(Build.StagingDirectory)/BuildLogs'
+ CleanTargetFolder: true
+ continueOnError: true
+ condition: succeededOrFailed()
+
+- task: 1ES.PublishPipelineArtifact@1
+ displayName: Publish BuildLogs
+ inputs:
+ targetPath: '$(Build.StagingDirectory)/BuildLogs'
+ artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt)
+ continueOnError: true
+ condition: succeededOrFailed()
+
+# Manually inject component detection so that we can ignore the source build upstream cache, which contains
+# a nupkg cache of input packages (a local feed).
+# This path must match the upstream cache path in property 'CurrentRepoSourceBuiltNupkgCacheDir'
+# in src\Microsoft.DotNet.Arcade.Sdk\tools\SourceBuild\SourceBuildArcade.targets
+- task: ComponentGovernanceComponentDetection@0
+ displayName: Component Detection (Exclude upstream cache)
+ inputs:
+ ignoreDirectories: '$(Build.SourcesDirectory)/artifacts/source-build/self/src/artifacts/obj/source-built-upstream-cache'
diff --git a/eng/common/templates-official/variables/pool-providers.yml b/eng/common/templates-official/variables/pool-providers.yml
new file mode 100644
index 00000000000..beab7d1bfba
--- /dev/null
+++ b/eng/common/templates-official/variables/pool-providers.yml
@@ -0,0 +1,45 @@
+# Select a pool provider based off branch name. Anything with branch name containing 'release' must go into an -Svc pool,
+# otherwise it should go into the "normal" pools. This separates out the queueing and billing of released branches.
+
+# Motivation:
+# Once a given branch of a repository's output has been officially "shipped" once, it is then considered to be COGS
+# (Cost of goods sold) and should be moved to a servicing pool provider. This allows both separation of queueing
+# (allowing release builds and main PR builds to not intefere with each other) and billing (required for COGS.
+# Additionally, the pool provider name itself may be subject to change when the .NET Core Engineering Services
+# team needs to move resources around and create new and potentially differently-named pools. Using this template
+# file from an Arcade-ified repo helps guard against both having to update one's release/* branches and renaming.
+
+# How to use:
+# This yaml assumes your shipped product branches use the naming convention "release/..." (which many do).
+# If we find alternate naming conventions in broad usage it can be added to the condition below.
+#
+# First, import the template in an arcade-ified repo to pick up the variables, e.g.:
+#
+# variables:
+# - template: /eng/common/templates-official/variables/pool-providers.yml
+#
+# ... then anywhere specifying the pool provider use the runtime variables,
+# $(DncEngInternalBuildPool)
+#
+# pool:
+# name: $(DncEngInternalBuildPool)
+# image: 1es-windows-2022-pt
+
+variables:
+ # Coalesce the target and source branches so we know when a PR targets a release branch
+ # If these variables are somehow missing, fall back to main (tends to have more capacity)
+
+ # Any new -Svc alternative pools should have variables added here to allow for splitting work
+
+ - name: DncEngInternalBuildPool
+ value: $[
+ replace(
+ replace(
+ eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'),
+ True,
+ 'NetCore1ESPool-Svc-Internal'
+ ),
+ False,
+ 'NetCore1ESPool-Internal'
+ )
+ ]
\ No newline at end of file
diff --git a/eng/common/templates-official/variables/sdl-variables.yml b/eng/common/templates-official/variables/sdl-variables.yml
new file mode 100644
index 00000000000..dbdd66d4a4b
--- /dev/null
+++ b/eng/common/templates-official/variables/sdl-variables.yml
@@ -0,0 +1,7 @@
+variables:
+# The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in
+# sync with the packages.config file.
+- name: DefaultGuardianVersion
+ value: 0.109.0
+- name: GuardianPackagesConfigFile
+ value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config
\ No newline at end of file
diff --git a/global.json b/global.json
index c784c02c369..599589eadff 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.24123.1",
+ "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24151.4",
"Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23255.2"
}
}
diff --git a/src/Compiler/Checking/CheckComputationExpressions.fs b/src/Compiler/Checking/CheckComputationExpressions.fs
index f0727c3fc5d..e13e56f2c4b 100644
--- a/src/Compiler/Checking/CheckComputationExpressions.fs
+++ b/src/Compiler/Checking/CheckComputationExpressions.fs
@@ -1838,7 +1838,7 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol
addVarsToVarSpace varSpace (fun mQueryOp env ->
// Normalize the bindings before detecting the bound variables
match (List.map (BindingNormalization.NormalizeBinding ValOrMemberBinding cenv env) binds) with
- | [ NormalizedBinding(kind = SynBindingKind.Normal; mustInline = false; isMutable = false; pat = pat) ] ->
+ | [ NormalizedBinding(kind = SynBindingKind.Normal; shouldInline = false; isMutable = false; pat = pat) ] ->
// successful case
use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink
diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs
index fc2e5e9d19b..c82a5edf6f3 100644
--- a/src/Compiler/Checking/CheckDeclarations.fs
+++ b/src/Compiler/Checking/CheckDeclarations.fs
@@ -305,7 +305,7 @@ let AddRootModuleOrNamespaceRefs g amap m env modrefs =
/// Adjust the TcEnv to make more things 'InternalsVisibleTo'
let addInternalsAccessibility env (ccu: CcuThunk) =
- let compPath = CompPath (ccu.ILScopeRef, [])
+ let compPath = CompPath (ccu.ILScopeRef, TypedTree.SyntaxAccess.Unknown, [])
let eInternalsVisibleCompPaths = compPath :: env.eInternalsVisibleCompPaths
{ env with
eAccessRights = ComputeAccessRights env.eAccessPath eInternalsVisibleCompPaths env.eFamilyType // update this computed field
@@ -418,8 +418,8 @@ module TcRecdUnionAndEnumDeclarations =
| ParentNone -> vis
| Parent tcref -> combineAccess vis tcref.TypeReprAccessibility
- let MakeRecdFieldSpec _cenv env parent (isStatic, konst, tyR, attrsForProperty, attrsForField, id, nameGenerated, isMutable, vol, xmldoc, vis, m) =
- let vis, _ = ComputeAccessAndCompPath env None m vis None parent
+ let MakeRecdFieldSpec g env parent (isStatic, konst, tyR, attrsForProperty, attrsForField, id, nameGenerated, isMutable, vol, xmldoc, vis, m) =
+ let vis, _ = ComputeAccessAndCompPath g env None m vis None parent
let vis = CombineReprAccess parent vis
Construct.NewRecdField isStatic konst id nameGenerated tyR isMutable vol attrsForProperty attrsForField xmldoc vis false
@@ -445,7 +445,7 @@ module TcRecdUnionAndEnumDeclarations =
let isPrivate = match vis with | Some (SynAccess.Private _) -> true | _ -> false
if isStatic && (not zeroInit || not isMutable || not isPrivate) then errorR(Error(FSComp.SR.tcStaticValFieldsMustBeMutableAndPrivate(), m))
let konst = if zeroInit then Some Const.Zero else None
- let rfspec = MakeRecdFieldSpec cenv env parent (isStatic, konst, tyR, attrsForProperty, attrsForField, id, nameGenerated, isMutable, isVolatile, xmldoc, vis, m)
+ let rfspec = MakeRecdFieldSpec g env parent (isStatic, konst, tyR, attrsForProperty, attrsForField, id, nameGenerated, isMutable, isVolatile, xmldoc, vis, m)
match parent with
| Parent tcref when useGenuineField tcref.Deref rfspec ->
// Recheck the attributes for errors if the definition only generates a field
@@ -511,8 +511,15 @@ module TcRecdUnionAndEnumDeclarations =
let TcUnionCaseDecl (cenv: cenv) env parent thisTy thisTyInst tpenv hasRQAAttribute (SynUnionCase(Attributes synAttrs, SynIdent(id, _), args, xmldoc, vis, m, _)) =
let g = cenv.g
- let attrs = TcAttributes cenv env AttributeTargets.UnionCaseDecl synAttrs // the attributes of a union case decl get attached to the generated "static factory" method
- let vis, _ = ComputeAccessAndCompPath env None m vis None parent
+ let attrs =
+ // The attributes of a union case decl get attached to the generated "static factory" method
+ // Enforce that the union-cases can only be targeted by attributes with AttributeTargets.Method
+ if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargetsUnionCaseDeclarations) then
+ TcAttributes cenv env AttributeTargets.Method synAttrs
+ else
+ TcAttributes cenv env AttributeTargets.UnionCaseDecl synAttrs
+
+ let vis, _ = ComputeAccessAndCompPath g env None m vis None parent
let vis = CombineReprAccess parent vis
CheckUnionCaseName cenv id hasRQAAttribute
@@ -551,7 +558,7 @@ module TcRecdUnionAndEnumDeclarations =
let rfields =
argTys |> List.mapi (fun i (argTy, argInfo) ->
let id = (match argInfo.Name with Some id -> id | None -> mkSynId m (mkUnionCaseFieldName nFields i))
- MakeRecdFieldSpec cenv env parent (false, None, argTy, [], [], id, argInfo.Name.IsNone, false, false, XmlDoc.Empty, None, m))
+ MakeRecdFieldSpec g env parent (false, None, argTy, [], [], id, argInfo.Name.IsNone, false, false, XmlDoc.Empty, None, m))
if not (typeEquiv g recordTy thisTy) then
error(Error(FSComp.SR.tcReturnTypesForUnionMustBeSameAsType(), m))
@@ -573,15 +580,15 @@ module TcRecdUnionAndEnumDeclarations =
|> List.map (TcUnionCaseDecl cenv env parent thisTy thisTyInst tpenv hasRQAAttribute)
unionCasesR |> CheckDuplicates (fun uc -> uc.Id) "union case"
- let MakeEnumCaseSpec cenv env parent attrs thisTy caseRange (caseIdent: Ident) (xmldoc: PreXmlDoc) value =
- let vis, _ = ComputeAccessAndCompPath env None caseRange None None parent
+ let MakeEnumCaseSpec g cenv env parent attrs thisTy caseRange (caseIdent: Ident) (xmldoc: PreXmlDoc) value =
+ let vis, _ = ComputeAccessAndCompPath g env None caseRange None None parent
let vis = CombineReprAccess parent vis
if caseIdent.idText = "value__" then errorR(Error(FSComp.SR.tcNotValidEnumCaseName(), caseIdent.idRange))
let checkXmlDocs = cenv.diagnosticOptions.CheckXmlDocs
let xmlDoc = xmldoc.ToXmlDoc(checkXmlDocs, Some [])
Construct.NewRecdField true (Some value) caseIdent false thisTy false false [] attrs xmlDoc vis false
- let TcEnumDecl cenv env tpenv parent thisTy fieldTy (SynEnumCase (attributes = Attributes synAttrs; ident = SynIdent (id, _); valueExpr = valueExpr; xmlDoc = xmldoc; range = caseRange)) =
+ let TcEnumDecl g cenv env tpenv parent thisTy fieldTy (SynEnumCase (attributes = Attributes synAttrs; ident = SynIdent (id, _); valueExpr = valueExpr; xmlDoc = xmldoc; range = caseRange)) =
let attrs = TcAttributes cenv env AttributeTargets.Field synAttrs
let valueRange = valueExpr.Range
@@ -590,19 +597,19 @@ module TcRecdUnionAndEnumDeclarations =
error(Error(FSComp.SR.tcInvalidEnumerationLiteral(), valueRange))
| SynExpr.Const (synConst, _) ->
let konst = TcConst cenv fieldTy valueRange env synConst
- MakeEnumCaseSpec cenv env parent attrs thisTy caseRange id xmldoc konst
+ MakeEnumCaseSpec g cenv env parent attrs thisTy caseRange id xmldoc konst
| _ ->
let expr, actualTy, _ = TcExprOfUnknownType cenv env tpenv valueExpr
UnifyTypes cenv env valueRange fieldTy actualTy
match EvalLiteralExprOrAttribArg cenv.g expr with
- | Expr.Const (konst, _, _) -> MakeEnumCaseSpec cenv env parent attrs thisTy caseRange id xmldoc konst
+ | Expr.Const (konst, _, _) -> MakeEnumCaseSpec g cenv env parent attrs thisTy caseRange id xmldoc konst
| _ -> error(Error(FSComp.SR.tcInvalidEnumerationLiteral(), valueRange))
let TcEnumDecls (cenv: cenv) env tpenv parent thisTy enumCases =
let g = cenv.g
let fieldTy = NewInferenceType g
- let enumCases' = enumCases |> List.map (TcEnumDecl cenv env tpenv parent thisTy fieldTy) |> CheckDuplicates (fun f -> f.Id) "enum element"
+ let enumCases' = enumCases |> List.map (TcEnumDecl g cenv env tpenv parent thisTy fieldTy) |> CheckDuplicates (fun f -> f.Id) "enum element"
fieldTy, enumCases'
//-------------------------------------------------------------------------
@@ -663,7 +670,7 @@ let TcOpenModuleOrNamespaceDecl tcSink g amap scopem env (longId, m) =
CheckNamespaceModuleOrTypeName g id
let IsPartiallyQualifiedNamespace (modref: ModuleOrNamespaceRef) =
- let (CompPath(_, p)) = modref.CompilationPath
+ let (CompPath(_, _, p)) = modref.CompilationPath
// Bug FSharp 1.0 3274: FSI paths don't count when determining this warning
let p =
match p with
@@ -2389,10 +2396,10 @@ let CheckForDuplicateModule env nm m =
/// Check 'exception' declarations in implementations and signatures
module TcExceptionDeclarations =
- let TcExnDefnCore_Phase1A cenv env parent (SynExceptionDefnRepr(Attributes synAttrs, SynUnionCase(ident= SynIdent(id,_)), _, xmlDoc, vis, m)) =
+ let TcExnDefnCore_Phase1A g cenv env parent (SynExceptionDefnRepr(Attributes synAttrs, SynUnionCase(ident= SynIdent(id,_)), _, xmlDoc, vis, m)) =
let attrs = TcAttributes cenv env AttributeTargets.ExnDecl synAttrs
if not (String.isLeadingIdentifierCharacterUpperCase id.idText) then errorR(NotUpperCaseConstructor id.idRange)
- let vis, cpath = ComputeAccessAndCompPath env None m vis None parent
+ let vis, cpath = ComputeAccessAndCompPath g env None m vis None parent
let vis = TcRecdUnionAndEnumDeclarations.CombineReprAccess parent vis
CheckForDuplicateConcreteType env (id.idText + "Exception") id.idRange
CheckForDuplicateConcreteType env id.idText id.idRange
@@ -2463,7 +2470,7 @@ module TcExceptionDeclarations =
let private TcExnDefnCore (cenv: cenv) env parent synExnDefnRepr =
let g = cenv.g
- let exnc = TcExnDefnCore_Phase1A cenv env parent synExnDefnRepr
+ let exnc = TcExnDefnCore_Phase1A g cenv env parent synExnDefnRepr
let args' = TcExnDefnCore_Phase1G_EstablishRepresentation cenv env parent exnc synExnDefnRepr
exnc.TypeContents.tcaug_super <- Some g.exn_ty
@@ -2730,7 +2737,7 @@ module EstablishTypeDefinitionCores =
let moduleKind = ComputeModuleOrNamespaceKind g true typeNames modAttrs id.idText
let modName = AdjustModuleName moduleKind id.idText
- let vis, _ = ComputeAccessAndCompPath envInitial None id.idRange vis None parent
+ let vis, _ = ComputeAccessAndCompPath g envInitial None id.idRange vis None parent
CheckForDuplicateModule envInitial id.idText id.idRange
let id = ident (modName, id.idRange)
@@ -2759,13 +2766,13 @@ module EstablishTypeDefinitionCores =
match synTyconRepr with
| SynTypeDefnSimpleRepr.Exception synExnDefnRepr ->
- TcExceptionDeclarations.TcExnDefnCore_Phase1A cenv env parent synExnDefnRepr
+ TcExceptionDeclarations.TcExnDefnCore_Phase1A g cenv env parent synExnDefnRepr
| _ ->
let id = ComputeTyconName (id, (match synTyconRepr with SynTypeDefnSimpleRepr.TypeAbbrev _ -> false | _ -> true), checkedTypars)
// Augmentations of type definitions are allowed within the same file as long as no new type representation or abbreviation is given
CheckForDuplicateConcreteType env id.idText id.idRange
- let vis, cpath = ComputeAccessAndCompPath env None id.idRange synVis None parent
+ let vis, cpath = ComputeAccessAndCompPath g env None id.idRange synVis None parent
// Establish the visibility of the representation, e.g.
// type R =
@@ -2782,7 +2789,8 @@ module EstablishTypeDefinitionCores =
| SynTypeDefnSimpleRepr.Enum _ -> None
| SynTypeDefnSimpleRepr.Exception _ -> None
- let visOfRepr, _ = ComputeAccessAndCompPath env None id.idRange synVisOfRepr None parent
+ let visOfRepr, _ = ComputeAccessAndCompPath g env None id.idRange synVisOfRepr None parent
+
let visOfRepr = combineAccess vis visOfRepr
// If we supported nested types and modules then additions would be needed here
let lmodTy = MaybeLazy.Strict (Construct.NewEmptyModuleOrNamespaceType ModuleOrType)
@@ -4818,7 +4826,7 @@ let rec TcSignatureElementNonMutRec (cenv: cenv) parent typeNames endm (env: TcE
return! TcSignatureElementsMutRec cenv parent typeNames endm None env [modDecl]
else
let id = ComputeModuleName longPath
- let vis, _ = ComputeAccessAndCompPath env None im vis None parent
+ let vis, _ = ComputeAccessAndCompPath g env None im vis None parent
let attribs = TcAttributes cenv env AttributeTargets.ModuleDecl attribs
CheckNamespaceModuleOrTypeName g id
let moduleKind = EstablishTypeDefinitionCores.ComputeModuleOrNamespaceKind g true typeNames attribs id.idText
@@ -5159,7 +5167,7 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv: cenv) parent typeNames scopem
let modName = EstablishTypeDefinitionCores.AdjustModuleName moduleKind id.idText
CheckForDuplicateConcreteType env modName im
CheckForDuplicateModule env id.idText id.idRange
- let vis, _ = ComputeAccessAndCompPath env None id.idRange vis None parent
+ let vis, _ = ComputeAccessAndCompPath g env None id.idRange vis None parent
let endm = m.EndRange
let id = ident (modName, id.idRange)
@@ -5673,7 +5681,10 @@ let CheckOneImplFile
|]
let cenv =
cenv.Create (g, isScript, amap, thisCcu, false, Option.isSome rootSigOpt,
- conditionalDefines, tcSink, (LightweightTcValForUsingInBuildMethodCall g), isInternalTestSpanStackReferring,
+ conditionalDefines,
+ tcSink,
+ LightweightTcValForUsingInBuildMethodCall g,
+ isInternalTestSpanStackReferring,
diagnosticOptions,
tcPat=TcPat,
tcSimplePats=TcSimplePats,
@@ -5766,7 +5777,7 @@ let CheckOneImplFile
Activity.Tags.qualifiedNameOfFile, qualNameOfFile.Text
|]
PostTypeCheckSemanticChecks.CheckImplFile
- (g, cenv.amap, reportErrors, cenv.infoReader,
+ (g, cenv.amap, reportErrors, cenv.infoReader,
env.eInternalsVisibleCompPaths, cenv.thisCcu, tcVal, envAtEnd.DisplayEnv,
implFileTy, implFileContents, extraAttribs, isLastCompiland,
isInternalTestSpanStackReferring)
@@ -5812,15 +5823,17 @@ let CheckOneSigFile (g, amap, thisCcu, checkForErrors, conditionalDefines, tcSin
Activity.Tags.qualifiedNameOfFile, sigFile.QualifiedName.Text
|]
let cenv =
- cenv.Create
- (g, false, amap, thisCcu, true, false, conditionalDefines, tcSink,
- (LightweightTcValForUsingInBuildMethodCall g), isInternalTestSpanStackReferring,
- diagnosticOptions,
- tcPat=TcPat,
- tcSimplePats=TcSimplePats,
- tcSequenceExpressionEntry=TcSequenceExpressionEntry,
- tcArrayOrListSequenceExpression=TcArrayOrListComputedExpression,
- tcComputationExpression=TcComputationExpression)
+ cenv.Create(g, false, amap, thisCcu, true, false,
+ conditionalDefines,
+ tcSink,
+ LightweightTcValForUsingInBuildMethodCall g,
+ isInternalTestSpanStackReferring,
+ diagnosticOptions,
+ tcPat=TcPat,
+ tcSimplePats=TcSimplePats,
+ tcSequenceExpressionEntry=TcSequenceExpressionEntry,
+ tcArrayOrListSequenceExpression=TcArrayOrListComputedExpression,
+ tcComputationExpression=TcComputationExpression)
let envinner, moduleTyAcc = MakeInitialEnv tcEnv
diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs
index 3e3e90a72fe..f7e048223bf 100644
--- a/src/Compiler/Checking/CheckExpressions.fs
+++ b/src/Compiler/Checking/CheckExpressions.fs
@@ -1177,7 +1177,7 @@ let CombineVisibilityAttribs vis1 vis2 m =
vis1
| _ -> vis2
-let ComputeAccessAndCompPath env (declKindOpt: DeclKind option) m vis overrideVis actualParent =
+let ComputeAccessAndCompPath (g:TcGlobals) env (declKindOpt: DeclKind option) m vis overrideVis actualParent =
let accessPath = env.eAccessPath
let accessModPermitted =
match declKindOpt with
@@ -1188,12 +1188,13 @@ let ComputeAccessAndCompPath env (declKindOpt: DeclKind option) m vis overrideVi
errorR(Error(FSComp.SR.tcMultipleVisibilityAttributesWithLet(), m))
let vis =
- match overrideVis, vis with
- | Some v, _ -> v
- | _, None -> taccessPublic (* a module or member binding defaults to "public" *)
- | _, Some (SynAccess.Public _) -> taccessPublic
- | _, Some (SynAccess.Private _) -> taccessPrivate accessPath
- | _, Some (SynAccess.Internal _) -> taccessInternal
+ match declKindOpt, overrideVis, vis with
+ | _, Some v, _ -> v
+ | Some (DeclKind.ClassLetBinding _), _, None when g.realsig -> taccessPrivate accessPath // a type binding defaults to "private"
+ | _, _, None -> taccessPublic // a module or member binding defaults to "public"
+ | _, _, Some (SynAccess.Public _) -> taccessPublic
+ | _, _, Some (SynAccess.Private _) -> taccessPrivate accessPath
+ | _, _, Some (SynAccess.Internal _) -> taccessInternal
let vis =
match actualParent with
@@ -1319,7 +1320,7 @@ let MakeAndPublishVal (cenv: cenv) env (altActualParent, inSig, declKind, valRec
Parent(memberInfo.ApparentEnclosingEntity), vis
| _ -> altActualParent, None
- let vis, _ = ComputeAccessAndCompPath env (Some declKind) id.idRange vis overrideVis actualParent
+ let vis, _ = ComputeAccessAndCompPath g env (Some declKind) id.idRange vis overrideVis actualParent
let inlineFlag =
if HasFSharpAttributeOpt g g.attrib_DllImportAttribute attrs then
@@ -2365,7 +2366,7 @@ type NormalizedBinding =
| NormalizedBinding of
visibility: SynAccess option *
kind: SynBindingKind *
- mustInline: bool *
+ shouldInline: bool *
isMutable: bool *
attribs: SynAttribute list *
xmlDoc: XmlDoc *
@@ -10874,17 +10875,31 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt
errorR(Error(FSComp.SR.tcLiteralCannotHaveGenericParameters(), mBinding))
if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargetsOnFunctions) && memberFlagsOpt.IsNone && not attrs.IsEmpty then
- let rhsIsFunction = isFunTy g overallPatTy
- let lhsIsFunction = isFunTy g overallExprTy
- let attrTgt =
- match rhsIsFunction, lhsIsFunction with
- | false, false when declaredTypars.IsEmpty -> AttributeTargets.Field ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue
- | _, _ -> AttributeTargets.Method ||| AttributeTargets.ReturnValue
-
- TcAttributesWithPossibleTargets false cenv env attrTgt attrs |> ignore
+ 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
+// Note:
+// - Let bound values can only have attributes that uses AttributeTargets.Field ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue
+// - Let function bindings can only have attributes that uses AttributeTargets.Method ||| AttributeTargets.ReturnValue
+and TcAttributeTargetsOnLetBindings (cenv: cenv) env attrs overallPatTy overallExprTy areTyparsDeclared =
+ let attrTgt =
+ if
+ // It's a type function:
+ // let x<'a> = …
+ areTyparsDeclared
+ // It's a regular function-valued binding:
+ // let f x = …
+ // let f = fun x -> …
+ || isFunTy cenv.g overallPatTy
+ || isFunTy cenv.g overallExprTy
+ then
+ AttributeTargets.ReturnValue ||| AttributeTargets.Method
+ else
+ AttributeTargets.ReturnValue ||| AttributeTargets.Field ||| AttributeTargets.Property
+
+ TcAttributes cenv env attrTgt attrs |> ignore
+
and TcLiteral (cenv: cenv) overallTy env tpenv (attrs, synLiteralValExpr) =
let g = cenv.g
@@ -11230,7 +11245,7 @@ and TcLetBinding (cenv: cenv) isUse env containerInfo declKind tpenv (synBinds,
when List.lengthsEqAndForall2 typarRefEq generalizedTypars generalizedTypars' ->
v, pat
- | _ when inlineFlag.MustInline ->
+ | _ when inlineFlag.ShouldInline ->
error(Error(FSComp.SR.tcInvalidInlineSpecification(), m))
| TPat_query _ when HasFSharpAttribute g g.attrib_LiteralAttribute attrs ->
diff --git a/src/Compiler/Checking/CheckExpressions.fsi b/src/Compiler/Checking/CheckExpressions.fsi
index 852fee213e6..cc136eba754 100644
--- a/src/Compiler/Checking/CheckExpressions.fsi
+++ b/src/Compiler/Checking/CheckExpressions.fsi
@@ -256,7 +256,7 @@ type NormalizedBinding =
| NormalizedBinding of
visibility: SynAccess option *
kind: SynBindingKind *
- mustInline: bool *
+ shouldInline: bool *
isMutable: bool *
attribs: SynAttribute list *
xmlDoc: XmlDoc *
@@ -430,6 +430,7 @@ val ComputeAccessRights:
/// Compute the available access rights and module/entity compilation path for a paricular location in code
val ComputeAccessAndCompPath:
+ g: TcGlobals ->
env: TcEnv ->
declKindOpt: DeclKind option ->
m: range ->
diff --git a/src/Compiler/Checking/CheckIncrementalClasses.fs b/src/Compiler/Checking/CheckIncrementalClasses.fs
index 85262e72a4c..1424a8ef7f3 100644
--- a/src/Compiler/Checking/CheckIncrementalClasses.fs
+++ b/src/Compiler/Checking/CheckIncrementalClasses.fs
@@ -291,13 +291,15 @@ type IncrClassReprInfo =
/// The vars forced to be fields due to static member bindings, instance initialization expressions or instance member bindings
/// The vars forced to be fields due to instance member bindings
///
+ ///
///
member localRep.ChooseRepresentation (cenv: cenv, env: TcEnv, isStatic, isCtorArg,
staticCtorInfo: StaticCtorInfo,
ctorInfoOpt: IncrClassCtorInfo option,
staticForcedFieldVars: FreeLocals,
instanceForcedFieldVars: FreeLocals,
- takenFieldNames: Set,
+ takenFieldNames: Set,
+ declKind: DeclKind,
bind: Binding) =
let g = cenv.g
let v = bind.Var
@@ -387,7 +389,7 @@ type IncrClassReprInfo =
// it a "member" in the F# sense, but the F# spec says it is generated and it is reasonable to reflect on it.
let memberValScheme = ValScheme(id, prelimTyschemeG, Some valReprInfo, None, Some memberInfo, false, ValInline.Never, NormalVal, None, true (* isCompilerGenerated *), true (* isIncrClass *), false, false)
- let methodVal = MakeAndPublishVal cenv env (Parent tcref, false, ModuleOrMemberBinding, ValNotInRecScope, memberValScheme, v.Attribs, XmlDoc.Empty, None, false)
+ let methodVal = MakeAndPublishVal cenv env (Parent tcref, false, declKind, ValNotInRecScope, memberValScheme, v.Attribs, XmlDoc.Empty, None, false)
reportIfUnused()
InMethod(isStatic, methodVal, valReprInfo)
@@ -395,9 +397,9 @@ type IncrClassReprInfo =
repr, takenFieldNames
/// Extend the known local representations by choosing a representation for a binding
- member localRep.ChooseAndAddRepresentation(cenv, env, isStatic, isCtorArg, staticCtorInfo, ctorInfoOpt, staticForcedFieldVars, instanceForcedFieldVars, bind: Binding) =
+ member localRep.ChooseAndAddRepresentation(cenv, env, isStatic, isCtorArg, staticCtorInfo, ctorInfoOpt, staticForcedFieldVars, instanceForcedFieldVars, declKind, bind: Binding) =
let v = bind.Var
- let repr, takenFieldNames = localRep.ChooseRepresentation (cenv, env, isStatic, isCtorArg, staticCtorInfo, ctorInfoOpt, staticForcedFieldVars, instanceForcedFieldVars, localRep.TakenFieldNames, bind )
+ let repr, takenFieldNames = localRep.ChooseRepresentation (cenv, env, isStatic, isCtorArg, staticCtorInfo, ctorInfoOpt, staticForcedFieldVars, instanceForcedFieldVars, localRep.TakenFieldNames, declKind, bind )
// OK, representation chosen, now add it
{localRep with
TakenFieldNames=takenFieldNames
@@ -677,11 +679,10 @@ let MakeCtorForIncrClassConstructionPhase2C(
(staticForcedFieldVars.FreeLocals, instanceForcedFieldVars.FreeLocals)
-
// Compute the implicit construction side effects of single
// 'let' or 'let rec' binding in the implicit class construction sequence
let TransBind (reps: IncrClassReprInfo) (TBind(v, rhsExpr, spBind)) =
- if v.MustInline then
+ if v.ShouldInline then
error(Error(FSComp.SR.tcLocalClassBindingsCannotBeInline(), v.Range))
let rhsExpr = reps.FixupIncrClassExprPhase2C cenv thisValOpt safeStaticInitInfo thisTyInst rhsExpr
@@ -772,7 +773,8 @@ let MakeCtorForIncrClassConstructionPhase2C(
match dec with
| IncrClassBindingGroup(binds, isStatic, isRec) ->
let actions, reps, methodBinds =
- let reps = (reps, binds) ||> List.fold (fun rep bind -> rep.ChooseAndAddRepresentation(cenv, env, isStatic, isCtorArg, staticCtorInfo, ctorInfoOpt, staticForcedFieldVars, instanceForcedFieldVars, bind)) // extend
+ // let reps = (reps, binds) ||> List.fold (fun rep bind -> rep.ChooseAndAddRepresentation(cenv, env, isStatic, isCtorArg, staticCtorInfo, ctorInfoOpt, staticForcedFieldVars, instanceForcedFieldVars, (ClassLetBinding isStatic), bind)) // extend
+ let reps = (reps, binds) ||> List.fold (fun rep bind -> rep.ChooseAndAddRepresentation(cenv, env, isStatic, isCtorArg, staticCtorInfo, ctorInfoOpt, staticForcedFieldVars, instanceForcedFieldVars, ModuleOrMemberBinding, bind)) // extend
if isRec then
// Note: the recursive calls are made via members on the object
// or via access to fields. This means the recursive loop is "broken",
diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs
index 985d3fbe22b..a09328222c4 100644
--- a/src/Compiler/Checking/NicePrint.fs
+++ b/src/Compiler/Checking/NicePrint.fs
@@ -495,7 +495,7 @@ module PrintTypes =
let layoutAccessibilityCore (denv: DisplayEnv) accessibility =
let isInternalCompPath x =
match x with
- | CompPath(ILScopeRef.Local, []) -> true
+ | CompPath(ILScopeRef.Local, _, []) -> true
| _ -> false
let (|Public|Internal|Private|) (TAccess p) =
match p with
@@ -1254,7 +1254,7 @@ module PrintTastMemberOrVals =
open PrintTypes
let mkInlineL denv (v: Val) nameL =
- if v.MustInline && not denv.suppressInlineKeyword then
+ if v.ShouldInline && not denv.suppressInlineKeyword then
WordL.keywordInline ++ nameL
else
nameL
diff --git a/src/Compiler/Checking/PostInferenceChecks.fs b/src/Compiler/Checking/PostInferenceChecks.fs
index e9dee56e748..e15d9e9463f 100644
--- a/src/Compiler/Checking/PostInferenceChecks.fs
+++ b/src/Compiler/Checking/PostInferenceChecks.fs
@@ -1970,7 +1970,8 @@ and AdjustAccess isHidden (cpath: unit -> CompilationPath) access =
let (TAccess l) = access
// FSharp 1.0 bug 1908: Values hidden by signatures are implicitly at least 'internal'
let scoref = cpath().ILScopeRef
- TAccess(CompPath(scoref, []) :: l)
+ let sa = cpath().SyntaxAccess
+ TAccess(CompPath(scoref, sa, []) :: l)
else
access
@@ -2076,7 +2077,7 @@ and CheckBinding cenv env alwaysCheckNoReraise ctxt (TBind(v, bindRhs, _) as bin
if cenv.reportErrors && isReturnsResumableCodeTy g v.TauType then
if not (g.langVersion.SupportsFeature LanguageFeature.ResumableStateMachines) then
error(Error(FSComp.SR.tcResumableCodeNotSupported(), bind.Var.Range))
- if not v.MustInline then
+ if not v.ShouldInline then
warning(Error(FSComp.SR.tcResumableCodeFunctionMustBeInline(), v.Range))
if isReturnsResumableCodeTy g v.TauType then
@@ -2084,7 +2085,7 @@ and CheckBinding cenv env alwaysCheckNoReraise ctxt (TBind(v, bindRhs, _) as bin
else
env
- CheckLambdas isTop (Some v) cenv env v.MustInline valReprInfo alwaysCheckNoReraise bindRhs v.Range v.Type ctxt
+ CheckLambdas isTop (Some v) cenv env v.ShouldInline valReprInfo alwaysCheckNoReraise bindRhs v.Range v.Type ctxt
and CheckBindings cenv env binds =
for bind in binds do
diff --git a/src/Compiler/Checking/SignatureConformance.fs b/src/Compiler/Checking/SignatureConformance.fs
index f24a93c5fc0..a058182c1a9 100644
--- a/src/Compiler/Checking/SignatureConformance.fs
+++ b/src/Compiler/Checking/SignatureConformance.fs
@@ -338,7 +338,7 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) =
elif (implVal.CompiledName g.CompilerGlobalState) <> (sigVal.CompiledName g.CompilerGlobalState) then (err denv FSComp.SR.ValueNotContainedMutabilityCompiledNamesDiffer)
elif implVal.DisplayName <> sigVal.DisplayName then (err denv FSComp.SR.ValueNotContainedMutabilityDisplayNamesDiffer)
elif isLessAccessible implVal.Accessibility sigVal.Accessibility then (err denv FSComp.SR.ValueNotContainedMutabilityAccessibilityMore)
- elif implVal.MustInline <> sigVal.MustInline then (err denv FSComp.SR.ValueNotContainedMutabilityInlineFlagsDiffer)
+ elif implVal.ShouldInline <> sigVal.ShouldInline then (err denv FSComp.SR.ValueNotContainedMutabilityInlineFlagsDiffer)
elif implVal.LiteralValue <> sigVal.LiteralValue then (err denv FSComp.SR.ValueNotContainedMutabilityLiteralConstantValuesDiffer)
elif implVal.IsTypeFunction <> sigVal.IsTypeFunction then (err denv FSComp.SR.ValueNotContainedMutabilityOneIsTypeFunction)
else
diff --git a/src/Compiler/Checking/SignatureHash.fs b/src/Compiler/Checking/SignatureHash.fs
index 156f64c5bdf..4acd53e0fad 100644
--- a/src/Compiler/Checking/SignatureHash.fs
+++ b/src/Compiler/Checking/SignatureHash.fs
@@ -113,7 +113,7 @@ module HashAccessibility =
let isHiddenToObserver (TAccess access) (observer: ObserverVisibility) =
let isInternalCompPath x =
match x with
- | CompPath(ILScopeRef.Local, []) -> true
+ | CompPath(ILScopeRef.Local, _, []) -> true
| _ -> false
match access with
diff --git a/src/Compiler/Checking/TailCallChecks.fs b/src/Compiler/Checking/TailCallChecks.fs
index ce6ab702bdc..aaeec0e81db 100644
--- a/src/Compiler/Checking/TailCallChecks.fs
+++ b/src/Compiler/Checking/TailCallChecks.fs
@@ -715,7 +715,7 @@ and CheckBinding cenv alwaysCheckNoReraise ctxt (TBind(v, bindRhs, _) as bind) :
| Some info -> info
| _ -> ValReprInfo.emptyValData
- CheckLambdas isTop (Some v) cenv v.MustInline valReprInfo tailCall alwaysCheckNoReraise bindRhs v.Range v.Type ctxt
+ CheckLambdas isTop (Some v) cenv v.ShouldInline valReprInfo tailCall alwaysCheckNoReraise bindRhs v.Range v.Type ctxt
and CheckBindings cenv binds =
for bind in binds do
diff --git a/src/Compiler/Checking/import.fs b/src/Compiler/Checking/import.fs
index 7f1f13efda2..70e07fb26ec 100644
--- a/src/Compiler/Checking/import.fs
+++ b/src/Compiler/Checking/import.fs
@@ -567,7 +567,7 @@ and ImportILTypeDefs amap m scoref cpath enc (tdefs: ILTypeDefs) =
/// the return ModuleOrNamespaceType will contain namespace entities for "System" and "Library", which in turn contain
/// type definition entities for ["Char"; "Int32"] and ["C"] respectively.
let ImportILAssemblyMainTypeDefs amap m scoref modul =
- modul.TypeDefs |> ImportILTypeDefs amap m scoref (CompPath(scoref, [])) []
+ modul.TypeDefs |> ImportILTypeDefs amap m scoref (CompPath(scoref, SyntaxAccess.Unknown, [])) []
/// Import the "exported types" table for multi-module assemblies.
let ImportILAssemblyExportedType amap m auxModLoader (scoref: ILScopeRef) (exportedType: ILExportedTypeOrForwarder) =
@@ -591,7 +591,7 @@ let ImportILAssemblyExportedType amap m auxModLoader (scoref: ILScopeRef) (expor
scoref, preTypeDef
)
- [ ImportILTypeDefList amap m (CompPath(scoref, [])) [] [(ns, (n, info))] ]
+ [ ImportILTypeDefList amap m (CompPath(scoref, SyntaxAccess.Unknown, [])) [] [(ns, (n, info))] ]
/// Import the "exported types" table for multi-module assemblies.
let ImportILAssemblyExportedTypes amap m auxModLoader scoref (exportedTypes: ILExportedTypesAndForwarders) =
diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs
index 6a574fadc14..976bba1c82f 100644
--- a/src/Compiler/CodeGen/IlxGen.fs
+++ b/src/Compiler/CodeGen/IlxGen.fs
@@ -215,15 +215,17 @@ let CountStaticFieldDef = NewCounter "IL field definitions corresponding to valu
let CountCallFuncInstructions = NewCounter "callfunc instructions (indirect calls)"
/// Non-local information related to internals of code generation within an assembly
-type IlxGenIntraAssemblyInfo =
- {
- /// A table recording the generated name of the static backing fields for each mutable top level value where
- /// we may need to take the address of that value, e.g. static mutable module-bound values which are structs. These are
- /// only accessible intra-assembly. Across assemblies, taking the address of static mutable module-bound values is not permitted.
- /// The key to the table is the method ref for the property getter for the value, which is a stable name for the Val's
- /// that come from both the signature and the implementation.
- StaticFieldInfo: ConcurrentDictionary
- }
+/// A table recording the generated name of the static backing fields for each mutable top level value where
+/// we may need to take the address of that value, e.g. static mutable module-bound values which are structs. These are
+/// only accessible intra-assembly. Across assemblies, taking the address of static mutable module-bound values is not permitted.
+/// The key to the table is the method ref for the property getter for the value, which is a stable name for the Val's
+/// that come from both the signature and the implementation.
+type IlxGenIntraAssemblyInfo(staticFieldInfo: ConcurrentDictionary) =
+
+ static member Create() =
+ new IlxGenIntraAssemblyInfo(new ConcurrentDictionary<_, _>(HashIdentity.Structural))
+
+ member _.GetOrAddStaticFieldInfo(info: ILMethodRef, f: System.Func) = staticFieldInfo.GetOrAdd(info, f)
/// Helper to make sure we take tailcalls in some situations
type FakeUnit = | Fake
@@ -316,9 +318,6 @@ type cenv =
/// Cache the generation of the "unit" type
mutable ilUnitTy: ILType option
- /// Other information from the emit of this assembly
- intraAssemblyInfo: IlxGenIntraAssemblyInfo
-
/// Cache methods with SecurityAttribute applied to them, to prevent unnecessary calls to ExistsInEntireHierarchyOfType
casApplied: IDictionary
@@ -410,7 +409,7 @@ let CompLocForSubModuleOrNamespace cloc (submod: ModuleOrNamespace) =
Namespace = Some(mkTopName cloc.Namespace n)
}
-let CompLocForFixedPath fragName qname (CompPath(sref, cpath)) =
+let CompLocForFixedPath fragName qname (CompPath(sref, _, cpath)) =
let ns, t =
cpath
|> List.takeUntil (fun (_, mkind) ->
@@ -490,23 +489,31 @@ let TypeRefForCompLoc cloc =
let mkILTyForCompLoc cloc =
mkILNonGenericBoxedTy (TypeRefForCompLoc cloc)
-let ComputeMemberAccess hidden =
- if hidden then
+/// Compute visibility for type members
+/// based on hidden and acessibility from the source code
+/// when hidden and realsig is specified then
+/// as typed in source code, I.e internal or public
+/// when hidden and not realsig is specified then
+/// then they are internal, old behaviour (anything not public is internal)
+/// otherwise it is public, by definition
+let ComputeMemberAccess hidden (accessibility: Accessibility) realsig =
+
+ if (not accessibility.IsPublic) && realsig then
+ accessibility.AsILMemberAccess()
+ elif hidden then
ILMemberAccess.Assembly
else
ILMemberAccess.Public
-// Under --publicasinternal change types from Public to Private (internal for types)
-let ComputePublicTypeAccess () = ILTypeDefAccess.Public
+let ComputeTypeAccess (tref: ILTypeRef) hidden (accessibility: Accessibility) realsig =
-let ComputeTypeAccess (tref: ILTypeRef) hidden =
match tref.Enclosing with
| [] ->
if hidden then
ILTypeDefAccess.Private
else
- ComputePublicTypeAccess()
- | _ -> ILTypeDefAccess.Nested(ComputeMemberAccess hidden)
+ ILTypeDefAccess.Public
+ | _ -> ILTypeDefAccess.Nested(ComputeMemberAccess hidden accessibility realsig)
//--------------------------------------------------------------------------
// TypeReprEnv
@@ -814,17 +821,22 @@ and GenTypeArgs cenv m tyenv tyargs = GenTypeArgsAux cenv m tyenv tyargs
// Computes the location where the static field for a value lives.
// - Literals go in their type/module.
// - For interactive code, we always place fields in their type/module with an accurate name
-let GenFieldSpecForStaticField (isInteractive, g, ilContainerTy, vspec: Val, nm, m, cloc, ilTy) =
- if isInteractive || HasFSharpAttribute g g.attrib_LiteralAttribute vspec.Attribs then
- let fieldName = vspec.CompiledName g.CompilerGlobalState
+let GenFieldSpecForStaticField (isInteractive, (g: TcGlobals), ilContainerTy, vspec: Val, nm, m, cloc, ilTy) =
- let fieldName =
- if isInteractive then
- CompilerGeneratedName fieldName
- else
- fieldName
+ let fieldName = vspec.CompiledName g.CompilerGlobalState
+ if HasFSharpAttribute g g.attrib_LiteralAttribute vspec.Attribs then
mkILFieldSpecInTy (ilContainerTy, fieldName, ilTy)
+ elif isInteractive then
+ mkILFieldSpecInTy (ilContainerTy, CompilerGeneratedName fieldName, ilTy)
+ elif g.realsig then
+ assert (g.CompilerGlobalState |> Option.isSome)
+
+ mkILFieldSpecInTy (
+ ilContainerTy,
+ CompilerGeneratedName(g.CompilerGlobalState.Value.IlxGenNiceNameGenerator.FreshCompilerGeneratedName(nm, m)),
+ ilTy
+ )
else
let fieldName =
// Ensure that we have an g.CompilerGlobalState
@@ -1150,6 +1162,18 @@ and IlxGenEnv =
/// Indicates the default "place" for stuff we're currently generating
cloc: CompileLocation
+ /// Indicates the default "place" for initialization stuff we're currently generating
+ initClassCompLoc: CompileLocation option
+
+ /// Per sourcefile initclass fieldspec
+ initClassFieldSpec: Lazy option
+
+ /// Indicates the name used for static initialization fields
+ initFieldName: string
+
+ /// Indicates the name used for static initialization method
+ staticInitializationName: string
+
/// The sequel to use for an "early exit" in a state machine, e.g. a return from the middle of an
/// async block
exitSequel: sequel
@@ -1194,6 +1218,11 @@ and IlxGenEnv =
/// Collection of code-gen functions where each inner array represents codegen (method bodies) functions for a single file
delayedFileGenReverse: list<(unit -> unit)[]>
+
+ /// Other information from the emit of this assembly
+ intraAssemblyInfo: IlxGenIntraAssemblyInfo
+
+ realsig: bool
}
override _.ToString() = ""
@@ -1217,6 +1246,15 @@ let EnvForTycon tps eenv =
tyenv = eenv.tyenv.ForTycon tps
}
+let AddEnclosingToEnv eenv enclosing name ns =
+ { eenv with
+ cloc =
+ { eenv.cloc with
+ Enclosing = enclosing @ [ name ]
+ Namespace = ns
+ }
+ }
+
let AddTyparsToEnv typars (eenv: IlxGenEnv) =
{ eenv with
tyenv = eenv.tyenv.Add typars
@@ -1454,20 +1492,23 @@ let ComputeFieldSpecForVal
match optIntraAssemblyInfo with
| None -> generate ()
- | Some iai -> iai.StaticFieldInfo.GetOrAdd(ilGetterMethRef, (fun _ -> generate ()))
+ | Some intraAssemblyInfo -> intraAssemblyInfo.GetOrAddStaticFieldInfo(ilGetterMethRef, (fun _ -> generate ()))
/// Compute the representation information for an F#-declared value (not a member nor a function).
/// Mutable and literal static fields must have stable names and live in the "public" location
-let ComputeStorageForFSharpValue amap (g: TcGlobals) cloc optIntraAssemblyInfo optShadowLocal isInteractive returnTy (vref: ValRef) m =
- let nm = vref.CompiledName g.CompilerGlobalState
+let ComputeStorageForFSharpValue cenv cloc optIntraAssemblyInfo optShadowLocal isInteractive returnTy (vref: ValRef) m =
+ let nm = vref.CompiledName cenv.g.CompilerGlobalState
let vspec = vref.Deref
let ilTy =
- GenType amap m TypeReprEnv.Empty returnTy (* TypeReprEnv.Empty ok: not a field in a generic class *)
+ GenType cenv m TypeReprEnv.Empty returnTy (* TypeReprEnv.Empty ok: not a field in a generic class *)
let ilTyForProperty = mkILTyForCompLoc cloc
let attribs = vspec.Attribs
- let hasLiteralAttr = HasFSharpAttribute g g.attrib_LiteralAttribute attribs
+
+ let hasLiteralAttr =
+ HasFSharpAttribute cenv.g cenv.g.attrib_LiteralAttribute attribs
+
let ilTypeRefForProperty = ilTyForProperty.TypeRef
let ilGetterMethRef =
@@ -1477,7 +1518,7 @@ let ComputeStorageForFSharpValue amap (g: TcGlobals) cloc optIntraAssemblyInfo o
mkILMethRef (ilTypeRefForProperty, ILCallingConv.Static, "set_" + nm, 0, [ ilTy ], ILType.Void)
let ilFieldSpec =
- ComputeFieldSpecForVal(optIntraAssemblyInfo, isInteractive, g, ilTyForProperty, vspec, nm, m, cloc, ilTy, ilGetterMethRef)
+ ComputeFieldSpecForVal(optIntraAssemblyInfo, isInteractive, cenv.g, ilTyForProperty, vspec, nm, m, cloc, ilTy, ilGetterMethRef)
StaticPropertyWithField(ilFieldSpec, vref, hasLiteralAttr, ilTyForProperty, nm, ilTy, ilGetterMethRef, ilSetterMethRef, optShadowLocal)
@@ -1539,7 +1580,6 @@ let IsFSharpValCompiledAsMethod g (v: Val) =
let ComputeStorageForValWithValReprInfo
(
cenv,
- g,
optIntraAssemblyInfo: IlxGenIntraAssemblyInfo option,
isInteractive,
optShadowLocal,
@@ -1547,7 +1587,11 @@ let ComputeStorageForValWithValReprInfo
cloc
) =
- if isUnitTy g vref.Type && not vref.IsMemberOrModuleBinding && not vref.IsMutable then
+ if
+ isUnitTy cenv.g vref.Type
+ && not vref.IsMemberOrModuleBinding
+ && not vref.IsMutable
+ then
Null
else
let valReprInfo =
@@ -1563,7 +1607,7 @@ let ComputeStorageForValWithValReprInfo
| Some a -> a
let m = vref.Range
- let nm = vref.CompiledName g.CompilerGlobalState
+ let nm = vref.CompiledName cenv.g.CompilerGlobalState
if vref.Deref.IsCompiledAsStaticPropertyWithoutField then
let nm = "get_" + nm
@@ -1579,35 +1623,34 @@ let ComputeStorageForValWithValReprInfo
//
// REVIEW: This call to GetValReprTypeInFSharpForm is only needed to determine if this is a (type) function or a value
// We should just look at the arity
- match GetValReprTypeInFSharpForm g valReprInfo vref.Type vref.Range with
+ match GetValReprTypeInFSharpForm cenv.g valReprInfo vref.Type vref.Range with
| [], [], returnTy, _ when not vref.IsMember ->
- ComputeStorageForFSharpValue cenv g cloc optIntraAssemblyInfo optShadowLocal isInteractive returnTy vref m
+ ComputeStorageForFSharpValue cenv cloc optIntraAssemblyInfo optShadowLocal isInteractive returnTy vref m
| _ ->
match vref.MemberInfo with
| Some memberInfo when not vref.IsExtensionMember -> ComputeStorageForFSharpMember cenv valReprInfo memberInfo vref m
| _ -> ComputeStorageForFSharpFunctionOrFSharpExtensionMember cenv cloc valReprInfo vref m
/// Determine how an F#-declared value, function or member is represented, if it is in the assembly being compiled.
-let ComputeAndAddStorageForLocalValWithValReprInfo (cenv, g, intraAssemblyFieldTable, isInteractive, optShadowLocal) cloc (v: Val) eenv =
+let ComputeAndAddStorageForLocalValWithValReprInfo (cenv, intraAssemblyFieldTable, isInteractive, optShadowLocal) cloc (v: Val) eenv =
let storage =
- ComputeStorageForValWithValReprInfo(cenv, g, Some intraAssemblyFieldTable, isInteractive, optShadowLocal, mkLocalValRef v, cloc)
+ ComputeStorageForValWithValReprInfo(cenv, Some intraAssemblyFieldTable, isInteractive, optShadowLocal, mkLocalValRef v, cloc)
- AddStorageForVal g (v, notlazy storage) eenv
+ AddStorageForVal cenv.g (v, notlazy storage) eenv
/// Determine how an F#-declared value, function or member is represented, if it is an external assembly.
-let ComputeStorageForNonLocalVal cenv g cloc modref (v: Val) =
+let ComputeStorageForNonLocalVal cenv cloc modref (v: Val) =
match v.ValReprInfo with
| None -> error (InternalError("ComputeStorageForNonLocalVal, expected an ValReprInfo for " + v.LogicalName, v.Range))
- | Some _ -> ComputeStorageForValWithValReprInfo(cenv, g, None, false, NoShadowLocal, mkNestedValRef modref v, cloc)
+ | Some _ -> ComputeStorageForValWithValReprInfo(cenv, None, false, NoShadowLocal, mkNestedValRef modref v, cloc)
/// Determine how all the F#-declared top level values, functions and members are represented, for an external module or namespace.
-let rec AddStorageForNonLocalModuleOrNamespaceRef cenv g cloc acc (modref: ModuleOrNamespaceRef) (modul: ModuleOrNamespace) =
+let rec AddStorageForNonLocalModuleOrNamespaceRef cenv cloc acc (modref: ModuleOrNamespaceRef) (modul: ModuleOrNamespace) =
let acc =
(acc, modul.ModuleOrNamespaceType.ModuleAndNamespaceDefinitions)
||> List.fold (fun acc smodul ->
AddStorageForNonLocalModuleOrNamespaceRef
cenv
- g
(CompLocForSubModuleOrNamespace cloc smodul)
acc
(modref.NestedTyconRef smodul)
@@ -1616,12 +1659,12 @@ let rec AddStorageForNonLocalModuleOrNamespaceRef cenv g cloc acc (modref: Modul
let acc =
(acc, modul.ModuleOrNamespaceType.AllValsAndMembers)
||> Seq.fold (fun acc v ->
- AddStorageForVal g (v, InterruptibleLazy(fun _ -> ComputeStorageForNonLocalVal cenv g cloc modref v)) acc)
+ AddStorageForVal cenv.g (v, InterruptibleLazy(fun _ -> ComputeStorageForNonLocalVal cenv cloc modref v)) acc)
acc
/// Determine how all the F#-declared top level values, functions and members are represented, for an external assembly.
-let AddStorageForExternalCcu cenv g eenv (ccu: CcuThunk) =
+let AddStorageForExternalCcu cenv eenv (ccu: CcuThunk) =
if not ccu.IsFSharp then
eenv
else
@@ -1632,7 +1675,7 @@ let AddStorageForExternalCcu cenv g eenv (ccu: CcuThunk) =
(fun smodul acc ->
let cloc = CompLocForSubModuleOrNamespace cloc smodul
let modref = mkNonLocalCcuRootEntityRef ccu smodul
- AddStorageForNonLocalModuleOrNamespaceRef cenv g cloc acc modref smodul)
+ AddStorageForNonLocalModuleOrNamespaceRef cenv cloc acc modref smodul)
ccu.RootModulesAndNamespaces
eenv
@@ -1641,7 +1684,7 @@ let AddStorageForExternalCcu cenv g eenv (ccu: CcuThunk) =
(eenv, ccu.Contents.ModuleOrNamespaceType.AllValsAndMembers)
||> Seq.fold (fun acc v ->
- AddStorageForVal g (v, InterruptibleLazy(fun _ -> ComputeStorageForNonLocalVal cenv g cloc eref v)) acc)
+ AddStorageForVal cenv.g (v, InterruptibleLazy(fun _ -> ComputeStorageForNonLocalVal cenv cloc eref v)) acc)
eenv
@@ -1662,8 +1705,8 @@ let rec AddBindingsForLocalModuleOrNamespaceType allocVal cloc eenv (mty: Module
eenv
/// Record how all the top level F#-declared values, functions and members are represented, for a set of referenced assemblies.
-let AddExternalCcusToIlxGenEnv cenv g eenv ccus =
- List.fold (AddStorageForExternalCcu cenv g) eenv ccus
+let AddExternalCcusToIlxGenEnv cenv eenv ccus =
+ List.fold (AddStorageForExternalCcu cenv) eenv ccus
/// Record how all the unrealized abstract slots are represented, for a type definition.
let AddBindingsForTycon allocVal (cloc: CompileLocation) (tycon: Tycon) eenv =
@@ -1759,21 +1802,11 @@ and AddBindingsForModuleOrNamespaceBinding allocVal cloc x eenv =
/// into the stored results for the whole CCU.
/// isIncrementalFragment = true --> "typed input"
/// isIncrementalFragment = false --> "#load"
-let AddIncrementalLocalAssemblyFragmentToIlxGenEnv
- (
- cenv: cenv,
- isIncrementalFragment,
- g,
- ccu,
- fragName,
- intraAssemblyInfo,
- eenv,
- implFiles
- ) =
+let AddIncrementalLocalAssemblyFragmentToIlxGenEnv (cenv: cenv, isIncrementalFragment, ccu, fragName, eenv, implFiles) =
let cloc = CompLocForFragment fragName ccu
let allocVal =
- ComputeAndAddStorageForLocalValWithValReprInfo(cenv, g, intraAssemblyInfo, true, NoShadowLocal)
+ ComputeAndAddStorageForLocalValWithValReprInfo(cenv, eenv.intraAssemblyInfo, true, NoShadowLocal)
(eenv, implFiles)
||> List.fold (fun eenv implFile ->
@@ -1928,6 +1961,8 @@ type TypeDefBuilder(tdef: ILTypeDef, tdefDiscards) =
this
+ member _.ILTypeDef = tdef
+
and TypeDefsBuilder() =
let tdefs =
@@ -2093,7 +2128,7 @@ type AnonTypeGenerationTable() =
let tycon =
let lmtyp = MaybeLazy.Strict(Construct.NewEmptyModuleOrNamespaceType ModuleOrType)
- let cpath = CompPath(ilTypeRef.Scope, [])
+ let cpath = CompPath(ilTypeRef.Scope, SyntaxAccess.Unknown, [])
Construct.NewTycon(
Some cpath,
@@ -2264,7 +2299,10 @@ and AssemblyBuilder(cenv: cenv, anonTypeTable: AnonTypeGenerationTable) as mgbuf
let vtdef = mkRawDataValueTypeDef g.iltyp_ValueType (name, size, 0us)
let vtref = NestedTypeRefForCompLoc cloc vtdef.Name
let vtspec = mkILTySpec (vtref, [])
- let vtdef = vtdef.WithAccess(ComputeTypeAccess vtref true)
+
+ let vtdef =
+ vtdef.WithAccess(ComputeTypeAccess vtref true taccessInternal cenv.g.realsig)
+
mgbuf.AddTypeDef(vtref, vtdef, false, true, None)
vtspec),
keyComparer = HashIdentity.Structural
@@ -2329,6 +2367,8 @@ and AssemblyBuilder(cenv: cenv, anonTypeTable: AnonTypeGenerationTable) as mgbuf
.FindNestedTypeDefsBuilder(tref.Enclosing)
.AddTypeDef(tdef, eliminateIfEmpty, addAtEnd, tdefDiscards)
+ member _.FindNestedTypeDefBuilder(tref: ILTypeRef) = gtdefs.FindNestedTypeDefBuilder(tref)
+
member _.GetCurrentFields(tref: ILTypeRef) =
gtdefs.FindNestedTypeDefBuilder(tref).GetCurrentFields()
@@ -6115,7 +6155,7 @@ and GenStructStateMachine cenv cgbuf eenvouter (res: LoweredStateMachine) sequel
) do
// Suppress the "ResumptionDynamicInfo" from generated state machines
if templateFld.LogicalName <> "ResumptionDynamicInfo" then
- let access = ComputeMemberAccess false
+ let access = ComputeMemberAccess false taccessPublic cenv.g.realsig
let fty = GenType cenv m eenvinner.tyenv templateFld.FieldType
let fdef =
@@ -6136,7 +6176,7 @@ and GenStructStateMachine cenv cgbuf eenvouter (res: LoweredStateMachine) sequel
// Fields for captured variables
for ilCloFreeVar in ilCloFreeVars do
- let access = ComputeMemberAccess false
+ let access = ComputeMemberAccess false taccessPublic cenv.g.realsig
let fdef =
ILFieldDef(
@@ -6181,7 +6221,7 @@ and GenStructStateMachine cenv cgbuf eenvouter (res: LoweredStateMachine) sequel
)
.WithSealed(true)
.WithSpecialName(true)
- .WithAccess(ComputeTypeAccess ilCloTypeRef true)
+ .WithAccess(ComputeTypeAccess ilCloTypeRef true taccessInternal cenv.g.realsig)
.WithLayout(ILTypeDefLayout.Auto)
.WithEncoding(ILDefaultPInvokeEncoding.Auto)
.WithInitSemantics(ILTypeInit.BeforeField)
@@ -6610,7 +6650,7 @@ and GenClosureTypeDefs
.WithSealed(true)
.WithSerializable(true)
.WithSpecialName(true)
- .WithAccess(ComputeTypeAccess tref true)
+ .WithAccess(ComputeTypeAccess tref true taccessInternal cenv.g.realsig)
.WithLayout(ILTypeDefLayout.Auto)
.WithEncoding(ILDefaultPInvokeEncoding.Auto)
.WithInitSemantics(ILTypeInit.BeforeField)
@@ -6797,13 +6837,12 @@ and GenFreevar cenv m eenvouter tyenvinner (fv: Val) =
#endif
| _ -> GenType cenv m tyenvinner fv.Type
-and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenvouter takenNames expr =
+and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenv takenNames expr =
let g = cenv.g
// Choose a base name for the closure
let basename =
- let boundv =
- eenvouter.letBoundVars |> List.tryFind (fun v -> not v.IsCompilerGenerated)
+ let boundv = eenv.letBoundVars |> List.tryFind (fun v -> not v.IsCompilerGenerated)
match boundv with
| Some v -> v.CompiledName cenv.g.CompilerGlobalState
@@ -6821,6 +6860,7 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenvouter takenN
let ilCloTypeRef =
// FSharp 1.0 bug 3404: System.Reflection doesn't like '.' and '`' in type names
let basenameSafeForUseAsTypename = CleanUpGeneratedTypeName basename
+
let suffixmark = expr.Range
let cloName =
@@ -6828,14 +6868,14 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenvouter takenN
assert (g.CompilerGlobalState |> Option.isSome)
g.CompilerGlobalState.Value.StableNameGenerator.GetUniqueCompilerGeneratedName(basenameSafeForUseAsTypename, suffixmark, uniq)
- NestedTypeRefForCompLoc eenvouter.cloc cloName
+ NestedTypeRefForCompLoc eenv.cloc cloName
// Collect the free variables of the closure
let cloFreeVarResults =
let opts = CollectTyparsAndLocalsWithStackGuard()
let opts =
- match eenvouter.tyenv.TemplateReplacement with
+ match eenv.tyenv.TemplateReplacement with
| None -> opts
| Some(tcref, _, typars, _) -> opts.WithTemplateReplacement(tyconRefEq g tcref, typars)
@@ -6850,7 +6890,7 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenvouter takenN
freeLocals
|> List.filter (fun fv ->
(thisVars |> List.forall (fun v -> not (valRefEq g (mkLocalValRef fv) v)))
- && (match StorageForVal m fv eenvouter with
+ && (match StorageForVal m fv eenv with
| StaticPropertyWithField _
| StaticProperty _
| Method _
@@ -6862,14 +6902,14 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenvouter takenN
let cloFreeTyvars =
(cloFreeVarResults.FreeTyvars, freeLocals)
||> List.fold (fun ftyvs fv ->
- match StorageForVal m fv eenvouter with
+ match StorageForVal m fv eenv with
| Env(_, _, Some(moreFtyvs, _))
| Local(_, _, Some(moreFtyvs, _)) -> unionFreeTyvars ftyvs moreFtyvs
| _ -> ftyvs)
let cloFreeTyvars = cloFreeTyvars.FreeTypars |> Zset.elements
- let eenvinner = eenvouter |> EnvForTypars cloFreeTyvars
+ let eenvinner = eenv |> EnvForTypars cloFreeTyvars
let ilCloTyInner =
let ilCloGenericParams = GenGenericParams cenv eenvinner cloFreeTyvars
@@ -6905,13 +6945,13 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenvouter takenN
(cloFreeVars, names)
||> List.map2 (fun fv nm ->
let localCloInfo =
- match StorageForVal m fv eenvouter with
+ match StorageForVal m fv eenv with
| Local(_, _, localCloInfo)
| Env(_, _, localCloInfo) -> localCloInfo
| _ -> None
let ilFv =
- mkILFreeVar (nm, fv.IsCompilerGenerated, GenFreevar cenv m eenvouter eenvinner.tyenv fv)
+ mkILFreeVar (nm, fv.IsCompilerGenerated, GenFreevar cenv m eenv eenvinner.tyenv fv)
let storage =
let ilField = mkILFieldSpecInTy (ilCloTyInner, ilFv.fvName, ilFv.fvType)
@@ -8074,7 +8114,7 @@ and GenLetRecFixup cenv cgbuf eenv (ilxCloSpec: IlxClosureSpec, e, ilField: ILFi
CG.EmitInstr cgbuf (pop 2) Push0 (mkNormalStfld (mkILFieldSpec (ilField.FieldRef, ilxCloSpec.ILType)))
/// Generate letrec bindings
-and GenLetRecBindings cenv (cgbuf: CodeGenBuffer) eenv (allBinds: Bindings, m) =
+and GenLetRecBindings cenv (cgbuf: CodeGenBuffer) eenv (allBinds: Bindings, m) (dict: Dictionary option) =
// 'let rec' bindings are always considered to be in loops, that is each may have backward branches for the
// tailcalls back to the entry point. This means we don't rely on zero-init of mutable locals
@@ -8146,6 +8186,23 @@ and GenLetRecBindings cenv (cgbuf: CodeGenBuffer) eenv (allBinds: Bindings, m) =
let fixups = ref []
+ let updateForwardReferenceSet (bind: Binding) (forwardReferenceSet: Zset) =
+ // Record the variable as defined
+ let forwardReferenceSet = Zset.remove bind.Var forwardReferenceSet
+
+ // Execute and discard any fixups that can now be committed
+ let newFixups =
+ fixups.Value
+ |> List.filter (fun (boundv, fv, action) ->
+ if (Zset.contains boundv forwardReferenceSet || Zset.contains fv forwardReferenceSet) then
+ true
+ else
+ action ()
+ false)
+
+ fixups.Value <- newFixups
+ forwardReferenceSet
+
let recursiveVars =
Zset.addList (bindsPossiblyRequiringFixup |> List.map (fun v -> v.Var)) (Zset.empty valOrder)
@@ -8164,39 +8221,74 @@ and GenLetRecBindings cenv (cgbuf: CodeGenBuffer) eenv (allBinds: Bindings, m) =
"internal error: should never need to set non-delayed recursive val: "
+ bind.Var.LogicalName
)))
+
// Record the variable as defined
let forwardReferenceSet = Zset.remove bind.Var forwardReferenceSet
forwardReferenceSet)
- // Generate the actual bindings
- let _ =
- (recursiveVars, allBinds)
- ||> List.fold (fun forwardReferenceSet (bind: Binding) ->
- GenBinding cenv cgbuf eenv bind false
+ let getStampForVal (v: Val) =
+ match v.HasDeclaringEntity with
+ | false -> 0L
+ | true -> v.DeclaringEntity.Deref.Stamp
- // Record the variable as defined
- let forwardReferenceSet = Zset.remove bind.Var forwardReferenceSet
+ let groupBinds =
+ let rec loopAllBinds bindings remainder =
+ match remainder with
+ | [] -> bindings |> List.rev
+ | _ ->
+ let stamp = remainder |> List.head |> (fun (TBind(v, _, _)) -> getStampForVal v)
- // Execute and discard any fixups that can now be committed
- let newFixups =
- fixups.Value
- |> List.filter (fun (boundv, fv, action) ->
- if (Zset.contains boundv forwardReferenceSet || Zset.contains fv forwardReferenceSet) then
- true
- else
- action ()
- false)
+ let taken =
+ remainder |> List.takeWhile (fun (TBind(v, _, _)) -> stamp = getStampForVal v)
- fixups.Value <- newFixups
+ let remainder =
+ remainder |> List.skipWhile (fun (TBind(v, _, _)) -> stamp = getStampForVal v)
- forwardReferenceSet)
+ loopAllBinds (taken :: bindings) remainder
+
+ loopAllBinds [ [] ] allBinds
+
+ let _ =
+ (recursiveVars, groupBinds)
+ ||> List.fold (fun forwardReferenceSet (binds: Binding list) ->
+ match dict, cenv.g.realsig, binds with
+ | _, false, _
+ | None, _, _
+ | _, _, [] ->
+ (forwardReferenceSet, binds)
+ ||> List.fold (fun forwardReferenceSet (bind: Binding) ->
+ GenBinding cenv cgbuf eenv bind false
+ updateForwardReferenceSet bind forwardReferenceSet)
+ | Some dict, true, _ ->
+ let (TBind(v, _, _)) = binds |> List.head
+
+ match dict.TryGetValue(getStampForVal v) with
+ | false, _ ->
+ (forwardReferenceSet, binds)
+ ||> List.fold (fun forwardReferenceSet (bind: Binding) ->
+ GenBinding cenv cgbuf eenv bind false
+ updateForwardReferenceSet bind forwardReferenceSet)
+ | true, tref ->
+ CodeGenInitMethod
+ cenv
+ cgbuf
+ (AddEnclosingToEnv eenv tref.Enclosing tref.Name None)
+ tref
+ (fun cgbuf eenv ->
+ // Generate chunks of non-nested bindings together to allow recursive fixups.
+ GenLetRecBindings cenv cgbuf eenv (binds, m) None
+ CG.EmitInstr cgbuf (pop 0) Push0 I_ret)
+ m
+
+ (forwardReferenceSet, binds)
+ ||> List.fold (fun forwardReferenceSet (bind: Binding) -> updateForwardReferenceSet bind forwardReferenceSet))
()
and GenLetRec cenv cgbuf eenv (binds, body, m) sequel =
let _, endMark as scopeMarks = StartLocalScope "letrec" cgbuf
let eenv = AllocStorageForBinds cenv cgbuf scopeMarks eenv binds
- GenLetRecBindings cenv cgbuf eenv (binds, m)
+ GenLetRecBindings cenv cgbuf eenv (binds, m) None
GenExpr cenv cgbuf eenv body (EndLocalScope(sequel, endMark))
//-------------------------------------------------------------------------
@@ -8212,17 +8304,22 @@ and GenBinding cenv cgbuf eenv (bind: Binding) (isStateVar: bool) =
GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar None
and ComputeMethodAccessRestrictedBySig eenv vspec =
+ let vspec =
+ if eenv.realsig then
+ DoRemapVal eenv.sigToImplRemapInfo vspec
+ else
+ vspec
+
+ let isHiddenBySignatureVal = IsHiddenVal eenv.sigToImplRemapInfo vspec
+
let isHidden =
- // Anything hidden by a signature gets assembly visibility
- IsHiddenVal eenv.sigToImplRemapInfo vspec
- ||
+ isHiddenBySignatureVal
// Anything that's not a module or member binding gets assembly visibility
- not vspec.IsMemberOrModuleBinding
- ||
+ || not vspec.IsMemberOrModuleBinding
// Compiler generated members for class function 'let' bindings get assembly visibility
- vspec.IsIncrClassGeneratedMember
+ || vspec.IsIncrClassGeneratedMember
- ComputeMemberAccess isHidden
+ ComputeMemberAccess isHidden vspec.Accessibility eenv.realsig
and GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar startMarkOpt =
let g = cenv.g
@@ -8249,12 +8346,13 @@ and GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar startMarkOpt =
let access = ComputeMethodAccessRestrictedBySig eenv vspec
+ // because of reflection back-compatability private constructors are treated the same as internal constructors
// Workaround for .NET and Visual Studio restriction w.r.t debugger type proxys
- // Mark internal constructors in internal classes as public.
+ // Mark internal and private constructors in internal classes as public.
let access =
+ // private and internal constructors from source are treated the same
if
- access = ILMemberAccess.Assembly
- && vspec.IsConstructor
+ vspec.IsConstructor
&& IsHiddenTycon eenv.sigToImplRemapInfo vspec.MemberApparentEntity.Deref
then
ILMemberAccess.Public
@@ -8407,8 +8505,9 @@ and GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar startMarkOpt =
/// Generate a static field definition...
let ilFieldDefs =
- let access =
- ComputeMemberAccess(not hasLiteralAttr || IsHiddenVal eenv.sigToImplRemapInfo vspec)
+ let hidden = not hasLiteralAttr || IsHiddenVal eenv.sigToImplRemapInfo vspec
+
+ let access = ComputeMemberAccess hidden vspec.Accessibility cenv.g.realsig
let ilFieldDef = mkILStaticField (fspec.Name, fty, None, None, access)
@@ -9718,17 +9817,15 @@ and AllocValForBind cenv cgbuf (scopeMarks: Mark * Mark) eenv (TBind(v, repr, _)
| Some _ -> None, AllocValReprWithinExpr cenv cgbuf (snd scopeMarks) eenv.cloc v eenv
and AllocValReprWithinExpr cenv cgbuf endMark cloc v eenv =
- let g = cenv.g
-
// decide whether to use a shadow local or not
let useShadowLocal =
cenv.options.generateDebugSymbols
&& not cenv.options.localOptimizationsEnabled
&& not v.IsCompilerGenerated
&& not v.IsMutable
- &&
// Don't use shadow locals for things like functions which are not compiled as static values/properties
- IsCompiledAsStaticProperty g v
+ && (not eenv.realsig)
+ && IsCompiledAsStaticProperty cenv.g v
let optShadowLocal, eenv =
if useShadowLocal then
@@ -9738,7 +9835,7 @@ and AllocValReprWithinExpr cenv cgbuf endMark cloc v eenv =
else
NoShadowLocal, eenv
- ComputeAndAddStorageForLocalValWithValReprInfo (cenv, g, cenv.intraAssemblyInfo, cenv.options.isInteractive, optShadowLocal) cloc v eenv
+ ComputeAndAddStorageForLocalValWithValReprInfo (cenv, eenv.intraAssemblyInfo, cenv.options.isInteractive, optShadowLocal) cloc v eenv
//--------------------------------------------------------------------------
// Generate stack save/restore and assertions - pulled into letrec by alloc*
@@ -9928,7 +10025,19 @@ and CreatePermissionSets cenv eenv (securityAttributes: Attrib list) =
//--------------------------------------------------------------------------
/// Generate a static class at the given cloc
-and GenTypeDefForCompLoc (cenv, eenv, mgbuf: AssemblyBuilder, cloc, hidden, attribs, initTrigger, eliminateIfEmpty, addAtEnd) =
+and GenTypeDefForCompLoc
+ (
+ cenv,
+ eenv,
+ mgbuf: AssemblyBuilder,
+ cloc,
+ hidden,
+ accessibility: Accessibility,
+ attribs,
+ initTrigger,
+ eliminateIfEmpty,
+ addAtEnd
+ ) =
let g = cenv.g
let tref = TypeRefForCompLoc cloc
@@ -9936,7 +10045,7 @@ and GenTypeDefForCompLoc (cenv, eenv, mgbuf: AssemblyBuilder, cloc, hidden, attr
mkILSimpleClass
g.ilg
(tref.Name,
- ComputeTypeAccess tref hidden,
+ ComputeTypeAccess tref hidden accessibility cenv.g.realsig,
emptyILMethods,
emptyILFields,
emptyILTypeDefs,
@@ -9980,16 +10089,69 @@ and GenImplFileContents cenv cgbuf qname lazyInitInfo eenv mty def =
let _eenvEnd = GenModuleOrNamespaceContents cenv cgbuf qname lazyInitInfo eenv def
())
+and CodeGenInitMethod cenv (cgbuf: CodeGenBuffer) eenv tref (codeGenInitFunc: CodeGenBuffer -> IlxGenEnv -> unit) m =
+
+ // Generate the declarations in the module and its initialization code
+ let _, body =
+ CodeGenMethod cenv cgbuf.mgbuf ([], eenv.staticInitializationName, eenv, 0, None, codeGenInitFunc, m)
+
+ if CheckCodeDoesSomething body.Code then
+ // We are here because the module we just grabbed has an interesting static initializer
+ let feefee, seqpt =
+ if body.Code.Instrs.Length > 0 then
+ match body.Code.Instrs[0] with
+ | I_seqpoint sp as i -> [ FeeFeeInstr cenv sp.Document ], [ i ]
+ | _ -> [], []
+ else
+ [], []
+
+ let ilDebugRange = GenPossibleILDebugRange cenv m
+
+ // Call global file initializer
+ match eenv.initClassFieldSpec with
+ | Some fs -> cgbuf.mgbuf.AddExplicitInitToCctor(tref, fs.Force(), ilDebugRange, eenv.imports, feefee, seqpt)
+ | None -> ()
+
+ // Add code to invoke envinner's class static initializer
+ let access = ComputeMemberAccess true taccessInternal eenv.realsig
+
+ let ilBody = MethodBody.IL(InterruptibleLazy.FromValue body)
+ let ilReturn = mkILReturn ILType.Void
+
+ let method =
+ (mkILNonGenericStaticMethod (eenv.staticInitializationName, access, [], ilReturn, ilBody))
+ .WithSpecialName
+
+ cgbuf.mgbuf.AddMethodDef(tref, method)
+ CountMethodDef()
+
+ let ty =
+ let td = cgbuf.mgbuf.FindNestedTypeDefBuilder(tref).ILTypeDef
+ let boxity = if td.IsStruct then ILBoxity.AsValue else ILBoxity.AsObject
+ mkILFormalNamedTy boxity tref td.GenericParams
+
+ let methodSpec =
+ mkILNonGenericStaticMethSpecInTy (ty, eenv.staticInitializationName, [], ILType.Void)
+
+ cgbuf.EmitInstr((pop 0), Push0, mkNormalCall (methodSpec))
+
and GenModuleOrNamespaceContents cenv (cgbuf: CodeGenBuffer) qname lazyInitInfo eenv x =
match x with
| TMDefRec(_isRec, opens, tycons, mbinds, m) ->
let eenvinner = AddDebugImportsToEnv cenv eenv opens
+ let dict = Some(Dictionary())
+
for tc in tycons do
- if tc.IsFSharpException then
- GenExnDef cenv cgbuf.mgbuf eenvinner m tc
- else
- GenTypeDef cenv cgbuf.mgbuf lazyInitInfo eenvinner m tc
+ let optTref =
+ if tc.IsFSharpException then
+ GenExnDef cenv cgbuf.mgbuf eenv m tc
+ else
+ GenTypeDef cenv cgbuf.mgbuf lazyInitInfo eenv m tc
+
+ match optTref with
+ | Some tref -> dict.Value.Add(tc.Stamp, tref)
+ | None -> ()
// Generate chunks of non-nested bindings together to allow recursive fixups.
let mutable bindsRemaining = mbinds
@@ -9997,6 +10159,7 @@ and GenModuleOrNamespaceContents cenv (cgbuf: CodeGenBuffer) qname lazyInitInfo
while not bindsRemaining.IsEmpty do
match bindsRemaining with
| ModuleOrNamespaceBinding.Binding _ :: _ ->
+
let recBinds =
bindsRemaining
|> List.takeWhile (function
@@ -10012,7 +10175,7 @@ and GenModuleOrNamespaceContents cenv (cgbuf: CodeGenBuffer) qname lazyInitInfo
| ModuleOrNamespaceBinding.Binding _ -> true
| _ -> false)
- GenLetRecBindings cenv cgbuf eenv (recBinds, m)
+ GenLetRecBindings cenv cgbuf eenv (recBinds, m) dict
bindsRemaining <- otherBinds
| (ModuleOrNamespaceBinding.Module _ as mbind) :: rest ->
GenModuleBinding cenv cgbuf qname lazyInitInfo eenvinner m mbind
@@ -10040,21 +10203,24 @@ and GenModuleOrNamespaceContents cenv (cgbuf: CodeGenBuffer) qname lazyInitInfo
// Generate a module binding
and GenModuleBinding cenv (cgbuf: CodeGenBuffer) (qname: QualifiedNameOfFile) lazyInitInfo eenv m x =
match x with
- | ModuleOrNamespaceBinding.Binding bind -> GenLetRecBindings cenv cgbuf eenv ([ bind ], m)
+ | ModuleOrNamespaceBinding.Binding bind -> GenLetRecBindings cenv cgbuf eenv ([ bind ], m) None
+
+ | ModuleOrNamespaceBinding.Module(mspec, mdef) when mspec.IsNamespace ->
+ // Generate the declarations in the namespace and its initialization code
+ GenModuleOrNamespaceContents cenv cgbuf qname lazyInitInfo eenv mdef |> ignore
| ModuleOrNamespaceBinding.Module(mspec, mdef) ->
+
+ // Evaluate bindings for module
let hidden = IsHiddenTycon eenv.sigToImplRemapInfo mspec
let eenvinner =
- if mspec.IsNamespace then
- eenv
- else
- { eenv with
- cloc = CompLocForFixedModule cenv.options.fragName qname.Text mspec
- initLocals =
- eenv.initLocals
- && not (HasFSharpAttribute cenv.g cenv.g.attrib_SkipLocalsInitAttribute mspec.Attribs)
- }
+ { eenv with
+ cloc = CompLocForFixedModule cenv.options.fragName qname.Text mspec
+ initLocals =
+ eenv.initLocals
+ && not (HasFSharpAttribute cenv.g cenv.g.attrib_SkipLocalsInitAttribute mspec.Attribs)
+ }
// Create the class to hold the contents of this module. No class needed if
// we're compiling it as a namespace.
@@ -10063,44 +10229,46 @@ and GenModuleBinding cenv (cgbuf: CodeGenBuffer) (qname: QualifiedNameOfFile) la
// However mutable static fields go into the class for the module itself.
// So this static class ends up with a .cctor if it has mutable fields.
//
- if not mspec.IsNamespace then
- // The use of ILTypeInit.OnAny prevents the execution of the cctor before the
- // "main" method in the case where the "main" method is implicit.
- let staticClassTrigger = (* if eenv.isFinalFile then *)
- ILTypeInit.OnAny (* else ILTypeInit.BeforeField *)
-
- GenTypeDefForCompLoc(
- cenv,
- eenvinner,
- cgbuf.mgbuf,
- eenvinner.cloc,
- hidden,
- mspec.Attribs,
- staticClassTrigger,
- false (* atEnd= *) ,
- true
- )
- // Generate the declarations in the module and its initialization code
- let _envAtEnd =
- GenModuleOrNamespaceContents cenv cgbuf qname lazyInitInfo eenvinner mdef
+ // The use of ILTypeInit.OnAny prevents the execution of the cctor before the
+ // "main" method in the case where the "main" method is implicit.
+ let staticClassTrigger = ILTypeInit.OnAny
+
+ GenTypeDefForCompLoc(
+ cenv,
+ eenvinner,
+ cgbuf.mgbuf,
+ eenvinner.cloc,
+ hidden,
+ mspec.Accessibility,
+ mspec.Attribs,
+ staticClassTrigger,
+ false (* atEnd= *) ,
+ true
+ )
- // If the module has a .cctor for some mutable fields, we need to ensure that when
- // those fields are "touched" the InitClass .cctor is forced. The InitClass .cctor will
- // then fill in the value of the mutable fields.
- if
- not mspec.IsNamespace
- && (cgbuf.mgbuf.GetCurrentFields(TypeRefForCompLoc eenvinner.cloc)
- |> Seq.isEmpty
- |> not)
- then
- GenForceWholeFileInitializationAsPartOfCCtor
+ let tref = TypeRefForCompLoc eenvinner.cloc
+
+ if eenv.realsig then
+ CodeGenInitMethod
cenv
- cgbuf.mgbuf
- lazyInitInfo
- (TypeRefForCompLoc eenvinner.cloc)
- eenv.imports
- mspec.Range
+ cgbuf
+ eenvinner
+ tref
+ (fun cgbuf eenv ->
+ GenModuleOrNamespaceContents cenv cgbuf qname lazyInitInfo eenv mdef |> ignore
+ CG.EmitInstr cgbuf (pop 0) Push0 I_ret //)
+ )
+ m
+ else
+ GenModuleOrNamespaceContents cenv cgbuf qname lazyInitInfo eenvinner mdef
+ |> ignore
+
+ // If the module has a .cctor for some mutable fields, we need to ensure that when
+ // those fields are "touched" the InitClass .cctor is forced. The InitClass .cctor will
+ // then fill in the value of the mutable fields.
+ if not (cgbuf.mgbuf.GetCurrentFields(tref) |> Seq.isEmpty) then
+ GenForceWholeFileInitializationAsPartOfCCtor cenv cgbuf.mgbuf lazyInitInfo tref eenv.imports mspec.Range
/// Generate the namespace fragments in a single file
and GenImplFile cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (implFile: CheckedImplFileAfterOptimization) =
@@ -10108,7 +10276,6 @@ and GenImplFile cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (implFile: Checke
implFile.ImplFile
let optimizeDuringCodeGen = implFile.OptimizeDuringCodeGen
- let g = cenv.g
let m = qname.Range
// Generate all the anonymous record types mentioned anywhere in this module
@@ -10130,21 +10297,38 @@ and GenImplFile cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (implFile: Checke
let initClassCompLoc = CompLocForInitClass eenv.cloc
let initClassTy = mkILTyForCompLoc initClassCompLoc
+ let initClassTrigger = ILTypeInit.OnAny
+
+ let initClassFieldSpec =
+ lazy
+ let ilFieldDef =
+ mkILStaticField (
+ eenv.initFieldName,
+ cenv.g.ilg.typ_Int32,
+ None,
+ None,
+ ComputeMemberAccess true taccessInternal cenv.g.realsig
+ )
+ |> cenv.g.AddFieldNeverAttributes
+ |> cenv.g.AddFieldGeneratedAttributes
- let initClassTrigger = (* if isFinalFile then *)
- ILTypeInit.OnAny (* else ILTypeInit.BeforeField *)
+ CountStaticFieldDef()
+ mgbuf.AddFieldDef(initClassTy.TypeRef, ilFieldDef)
+ mkILFieldSpecInTy (initClassTy, eenv.initFieldName, cenv.g.ilg.typ_Int32)
let eenv =
{ eenv with
cloc = initClassCompLoc
+ initClassCompLoc = Some initClassCompLoc
isFinalFile = isFinalFile
someTypeInThisAssembly = initClassTy
+ initClassFieldSpec = Some initClassFieldSpec
}
// Create the class to hold the initialization code and static fields for this file.
// internal static class $ {}
// Put it at the end since that gives an approximation of dependency order (to aid FSI.EXE's code generator - see FSharp 1.0 5548)
- GenTypeDefForCompLoc(cenv, eenv, mgbuf, initClassCompLoc, useHiddenInitCode, [], initClassTrigger, false, true)
+ GenTypeDefForCompLoc(cenv, eenv, mgbuf, initClassCompLoc, useHiddenInitCode, taccessInternal, [], initClassTrigger, false, true)
// lazyInitInfo is an accumulator of functions which add the forced initialization of the storage module to
// - mutable fields in public modules
@@ -10259,30 +10443,24 @@ and GenImplFile cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (implFile: Checke
// Create the field to act as the target for the forced initialization.
// Why do this for the final file?
// There is no need to do this for a final file with an implicit entry point. For an explicit entry point in lazyInitInfo.
- let initFieldName = CompilerGeneratedName "init"
-
- let ilFieldDef =
- mkILStaticField (initFieldName, g.ilg.typ_Int32, None, None, ComputeMemberAccess true)
- |> g.AddFieldNeverAttributes
- |> g.AddFieldGeneratedAttributes
-
- let fspec = mkILFieldSpecInTy (initClassTy, initFieldName, cenv.g.ilg.typ_Int32)
- CountStaticFieldDef()
- mgbuf.AddFieldDef(initClassTy.TypeRef, ilFieldDef)
+ initClassFieldSpec.Force() |> ignore
// Run the imperative (yuck!) actions that force the generation
// of references to the cctor for nested modules etc.
- lazyInitInfo |> Seq.iter (fun f -> f fspec feefee seqpt)
+ match eenv.initClassFieldSpec with
+ | Some fspec ->
+ lazyInitInfo |> Seq.iter (fun f -> f (fspec.Force()) feefee seqpt)
- if isScript && not isFinalFile then
- mgbuf.AddScriptInitFieldSpec(fspec, m)
+ if isScript && not isFinalFile then
+ mgbuf.AddScriptInitFieldSpec(fspec.Force(), m)
+ | None -> ()
// Compute the ilxgenEnv after the generation of the module, i.e. the residue need to generate anything that
// uses the constructs exported from this module.
// We add the module type all over again. Note no shadow locals for static fields needed here since they are only relevant to the main/.cctor
let eenvafter =
let allocVal =
- ComputeAndAddStorageForLocalValWithValReprInfo(cenv, g, cenv.intraAssemblyInfo, cenv.options.isInteractive, NoShadowLocal)
+ ComputeAndAddStorageForLocalValWithValReprInfo(cenv, eenv.intraAssemblyInfo, cenv.options.isInteractive, NoShadowLocal)
AddBindingsForLocalModuleOrNamespaceType allocVal clocCcu eenv signature
@@ -10528,12 +10706,12 @@ and GenPrintingMethod cenv eenv methName ilThisTy m =
| _ -> ()
]
-and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
+and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option =
let g = cenv.g
let tcref = mkLocalTyconRef tycon
if tycon.IsTypeAbbrev then
- ()
+ None
else
match tycon.TypeReprInfo with
#if !NO_TYPEPROVIDERS
@@ -10543,7 +10721,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
| TNoRepr
| TAsmRepr _
| TILObjectRepr _
- | TMeasureableRepr _ -> ()
+ | TMeasureableRepr _ -> None
| TFSharpTyconRepr _ ->
let eenvinner = EnvForTycon tycon eenv
let thisTy = generalizedTyconRef g tcref
@@ -10559,8 +10737,17 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
let ilTypeName = tref.Name
let hidden = IsHiddenTycon eenv.sigToImplRemapInfo tycon
+
let hiddenRepr = hidden || IsHiddenTyconRepr eenv.sigToImplRemapInfo tycon
- let access = ComputeTypeAccess tref hidden
+
+ let tyconAccess =
+ let tycon =
+ if eenv.realsig then
+ DoRemapTycon eenv.sigToImplRemapInfo tycon
+ else
+ tycon
+
+ ComputeTypeAccess tref hidden tycon.Accessibility cenv.g.realsig
// The implicit augmentation doesn't actually create CompareTo(object) or Object.Equals
// So we do it here.
@@ -10662,7 +10849,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
let tyconRepr = tycon.TypeReprInfo
- let reprAccess = ComputeMemberAccess hiddenRepr
+ let reprAccess = ComputeMemberAccess hiddenRepr taccessPublic cenv.g.realsig
// DebugDisplayAttribute gets copied to the subtypes generated as part of DU compilation
let debugDisplayAttrs, normalAttrs =
@@ -10828,7 +11015,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
[ g.CompilerGeneratedAttribute; g.DebuggerBrowsableNeverAttribute ]
| _ -> [] // don't hide fields in classes in debug display
- let access = ComputeMemberAccess isFieldHidden
+ let access = ComputeMemberAccess isFieldHidden taccessPublic cenv.g.realsig
let literalValue = Option.map (GenFieldInit m) fspec.LiteralValue
@@ -10898,7 +11085,9 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
if not useGenuineField then
let ilPropName = fspec.LogicalName
let ilMethName = "get_" + ilPropName
- let access = ComputeMemberAccess isPropHidden
+
+ let access = ComputeMemberAccess isPropHidden taccessPublic cenv.g.realsig
+
let isStruct = isStructTyconRef tcref
let attrs =
@@ -10921,7 +11110,8 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
let ilMethName = "set_" + ilPropName
let ilParams = [ mkILParamNamed ("value", ilPropType) ]
let ilReturn = mkILReturn ILType.Void
- let iLAccess = ComputeMemberAccess isPropHidden
+
+ let iLAccess = ComputeMemberAccess isPropHidden taccessPublic cenv.g.realsig
let ilMethodDef =
if isStatic then
@@ -11128,7 +11318,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
match tycon.TypeReprInfo with
| TILObjectRepr _ ->
- let tdef = tycon.ILTyconRawMetadata.WithAccess access
+ let tdef = tycon.ILTyconRawMetadata.WithAccess tyconAccess
let tdef =
tdef.With(customAttrs = mkILCustomAttrs ilCustomAttrs, genericParams = ilGenParams)
@@ -11170,7 +11360,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
let tdef =
mkILGenericClass (
ilTypeName,
- access,
+ tyconAccess,
ilGenParams,
ilBaseTy,
ilIntfTys,
@@ -11369,7 +11559,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
.WithSerializable(isSerializable)
.WithSealed(true)
.WithEncoding(ILDefaultPInvokeEncoding.Auto)
- .WithAccess(access)
+ .WithAccess(tyconAccess)
// If there are static fields in the union, use the same kind of trigger as
// for class types
.WithInitSemantics(
@@ -11428,26 +11618,39 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
// In this case, the .cctor for this type must force the .cctor of the backing static class for the file.
if
tycon.TyparsNoRange.IsEmpty
+ && not (eenv.realsig)
&& tycon.MembersOfFSharpTyconSorted
|> List.exists (fun vref -> vref.Deref.IsClassConstructor)
then
GenForceWholeFileInitializationAsPartOfCCtor cenv mgbuf lazyInitInfo tref eenv.imports m
+ Some tref
+
/// Generate the type for an F# exception declaration.
-and GenExnDef cenv mgbuf eenv m (exnc: Tycon) =
+and GenExnDef cenv mgbuf eenv m (exnc: Tycon) : ILTypeRef option =
let g = cenv.g
let exncref = mkLocalEntityRef exnc
match exnc.ExceptionInfo with
| TExnAbbrevRepr _
| TExnAsmRepr _
- | TExnNone -> ()
+ | TExnNone -> None
| TExnFresh _ ->
let ilThisTy = GenExnType cenv m eenv.tyenv exncref
let tref = ilThisTy.TypeRef
let isHidden = IsHiddenTycon eenv.sigToImplRemapInfo exnc
- let access = ComputeTypeAccess tref isHidden
- let reprAccess = ComputeMemberAccess isHidden
+
+ let access =
+ let tycon =
+ if eenv.realsig then
+ DoRemapTycon eenv.sigToImplRemapInfo exnc
+ else
+ exnc
+
+ ComputeTypeAccess tref isHidden tycon.Accessibility cenv.g.realsig
+
+ let reprAccess = ComputeMemberAccess isHidden taccessPublic cenv.g.realsig
+
let fspecs = exnc.TrueInstanceFieldsAsList
let ilMethodDefsForProperties, ilFieldDefs, ilPropertyDefs, fieldNamesAndTypes =
@@ -11579,6 +11782,7 @@ and GenExnDef cenv mgbuf eenv m (exnc: Tycon) =
let tdef = tdef.WithSerializable(true)
mgbuf.AddTypeDef(tref, tdef, false, false, None)
+ Some tref
let CodegenAssembly cenv eenv mgbuf implFiles =
match List.tryFrontAndBack implFiles with
@@ -11631,11 +11835,12 @@ let CodegenAssembly cenv eenv mgbuf implFiles =
//-------------------------------------------------------------------------
let GetEmptyIlxGenEnv (g: TcGlobals) ccu =
- let thisCompLoc = CompLocForCcu ccu
-
{
tyenv = TypeReprEnv.Empty
- cloc = thisCompLoc
+ cloc = CompLocForCcu ccu
+ initClassCompLoc = None
+ initFieldName = CompilerGeneratedName "init"
+ staticInitializationName = CompilerGeneratedName "staticInitialization"
exitSequel = Return
valsInScope = ValMap<_>.Empty
witnessesInScope = EmptyTraitWitnessInfoHashMap g
@@ -11652,6 +11857,9 @@ let GetEmptyIlxGenEnv (g: TcGlobals) ccu =
imports = None
delayCodeGen = true
delayedFileGenReverse = []
+ intraAssemblyInfo = IlxGenIntraAssemblyInfo.Create()
+ realsig = g.realsig
+ initClassFieldSpec = None
}
type IlxGenResults =
@@ -11722,6 +11930,7 @@ let GenerateCode (cenv, anonTypeTable, eenv, CheckedAssemblyAfterOptimization im
mgbuf,
CompLocForPrivateImplementationDetails eenv.cloc,
useHiddenInitCode,
+ taccessInternal,
[],
ILTypeInit.BeforeField,
true (* atEnd= *) ,
@@ -11879,26 +12088,21 @@ let ClearGeneratedValue (ctxt: ExecutionContext) eenv (v: Val) =
()
/// The published API from the ILX code generator
-type IlxAssemblyGenerator(amap: ImportMap, tcGlobals: TcGlobals, tcVal: ConstraintSolver.TcValF, ccu: CcuThunk) =
+type IlxAssemblyGenerator(amap: ImportMap, g: TcGlobals, tcVal: ConstraintSolver.TcValF, ccu: CcuThunk) =
// The incremental state held by the ILX code generator
- let mutable ilxGenEnv = GetEmptyIlxGenEnv tcGlobals ccu
+ let mutable ilxGenEnv = GetEmptyIlxGenEnv g ccu
let anonTypeTable = AnonTypeGenerationTable()
- let intraAssemblyInfo =
- {
- StaticFieldInfo = ConcurrentDictionary<_, _>(HashIdentity.Structural)
- }
-
let cenv =
{
- g = tcGlobals
+ g = g
ilxPubCloEnv =
EraseClosures.newIlxPubCloEnv (
- tcGlobals.ilg,
- tcGlobals.AddMethodGeneratedAttributes,
- tcGlobals.AddFieldGeneratedAttributes,
- tcGlobals.AddFieldNeverAttributes
+ g.ilg,
+ g.AddMethodGeneratedAttributes,
+ g.AddFieldGeneratedAttributes,
+ g.AddFieldNeverAttributes
)
tcVal = tcVal
viewCcu = ccu
@@ -11906,7 +12110,6 @@ type IlxAssemblyGenerator(amap: ImportMap, tcGlobals: TcGlobals, tcVal: Constrai
namedDebugPointsForInlinedCode = Map.empty
amap = amap
casApplied = ConcurrentDictionary()
- intraAssemblyInfo = intraAssemblyInfo
optionsOpt = None
optimizeDuringCodeGen = (fun _flag expr -> expr)
stackGuard = getEmptyStackGuard ()
@@ -11915,22 +12118,12 @@ type IlxAssemblyGenerator(amap: ImportMap, tcGlobals: TcGlobals, tcVal: Constrai
/// Register a set of referenced assemblies with the ILX code generator
member _.AddExternalCcus ccus =
- ilxGenEnv <- AddExternalCcusToIlxGenEnv cenv tcGlobals ilxGenEnv ccus
+ ilxGenEnv <- AddExternalCcusToIlxGenEnv cenv ilxGenEnv ccus
/// Register a fragment of the current assembly with the ILX code generator. If 'isIncrementalFragment' is true then the input
/// is assumed to be a fragment 'typed' into FSI.EXE, otherwise the input is assumed to be the result of a '#load'
member _.AddIncrementalLocalAssemblyFragment(isIncrementalFragment, fragName, typedImplFiles) =
- ilxGenEnv <-
- AddIncrementalLocalAssemblyFragmentToIlxGenEnv(
- cenv,
- isIncrementalFragment,
- tcGlobals,
- ccu,
- fragName,
- intraAssemblyInfo,
- ilxGenEnv,
- typedImplFiles
- )
+ ilxGenEnv <- AddIncrementalLocalAssemblyFragmentToIlxGenEnv(cenv, isIncrementalFragment, ccu, fragName, ilxGenEnv, typedImplFiles)
/// Generate ILX code for an assembly fragment
member _.GenerateCode(codeGenOpts, typedAssembly: CheckedAssemblyAfterOptimization, assemAttribs, moduleAttribs) =
diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs
index 32298c0cf05..54a69b05f8c 100644
--- a/src/Compiler/Driver/CompilerConfig.fs
+++ b/src/Compiler/Driver/CompilerConfig.fs
@@ -610,6 +610,8 @@ type TcConfigBuilder =
mutable typeCheckingConfig: TypeCheckingConfig
mutable dumpSignatureData: bool
+
+ mutable realsig: bool
}
// Directories to start probing in
@@ -817,6 +819,7 @@ type TcConfigBuilder =
DumpGraph = false
}
dumpSignatureData = false
+ realsig = false
strictIndentation = None
}
@@ -1360,6 +1363,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) =
member _.captureIdentifiersWhenParsing = data.captureIdentifiersWhenParsing
member _.typeCheckingConfig = data.typeCheckingConfig
member _.dumpSignatureData = data.dumpSignatureData
+ member _.realsig = data.realsig
static member Create(builder, validate) =
use _ = UseBuildPhase BuildPhase.Parameter
diff --git a/src/Compiler/Driver/CompilerConfig.fsi b/src/Compiler/Driver/CompilerConfig.fsi
index f59950f9e28..f5360fbb972 100644
--- a/src/Compiler/Driver/CompilerConfig.fsi
+++ b/src/Compiler/Driver/CompilerConfig.fsi
@@ -519,6 +519,8 @@ type TcConfigBuilder =
mutable typeCheckingConfig: TypeCheckingConfig
mutable dumpSignatureData: bool
+
+ mutable realsig: bool
}
static member CreateNew:
@@ -894,6 +896,8 @@ type TcConfig =
member dumpSignatureData: bool
+ member realsig: bool
+
/// Represents a computation to return a TcConfig. Normally this is just a constant immutable TcConfig,
/// but for F# Interactive it may be based on an underlying mutable TcConfigBuilder.
[]
diff --git a/src/Compiler/Driver/CompilerImports.fs b/src/Compiler/Driver/CompilerImports.fs
index d8d9ccd9866..090e5597440 100644
--- a/src/Compiler/Driver/CompilerImports.fs
+++ b/src/Compiler/Driver/CompilerImports.fs
@@ -1667,6 +1667,7 @@ and [] TcImports
let cpath =
CompPath(
ILScopeRef.Local,
+ SyntaxAccess.Unknown,
injectedNamespace
|> List.rev
|> List.map (fun n -> (n, ModuleOrNamespaceKind.Namespace true))
@@ -2522,7 +2523,8 @@ and [] TcImports
tcConfig.emitDebugInfoInQuotations,
tcConfig.noDebugAttributes,
tcConfig.pathMap,
- tcConfig.langVersion
+ tcConfig.langVersion,
+ tcConfig.realsig
)
#if DEBUG
diff --git a/src/Compiler/Driver/CompilerOptions.fs b/src/Compiler/Driver/CompilerOptions.fs
index d1618dd19d6..e742a20e139 100644
--- a/src/Compiler/Driver/CompilerOptions.fs
+++ b/src/Compiler/Driver/CompilerOptions.fs
@@ -568,6 +568,9 @@ let SetTailcallSwitch (tcConfigB: TcConfigBuilder) switch =
let SetDeterministicSwitch (tcConfigB: TcConfigBuilder) switch =
tcConfigB.deterministic <- (switch = OptionSwitch.On)
+let SetRealsig (tcConfigB: TcConfigBuilder) switch =
+ tcConfigB.realsig <- (switch = OptionSwitch.On)
+
let SetReferenceAssemblyOnlySwitch (tcConfigB: TcConfigBuilder) switch =
match tcConfigB.emitMetadataAssembly with
| MetadataAssemblyGeneration.None when (not tcConfigB.standalone) && tcConfigB.extraStaticLinkRoots.IsEmpty ->
@@ -1026,6 +1029,8 @@ let codeGenerationFlags isFsi (tcConfigB: TcConfigBuilder) =
Some(FSComp.SR.optsDeterministic ())
)
+ CompilerOption("realsig", tagNone, OptionSwitch(SetRealsig tcConfigB), None, Some(FSComp.SR.optsRealsig ()))
+
CompilerOption("pathmap", tagPathMap, OptionStringList(AddPathMapping tcConfigB), None, Some(FSComp.SR.optsPathMap ()))
CompilerOption(
diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt
index a1086629fbe..52a5a184823 100644
--- a/src/Compiler/FSComp.txt
+++ b/src/Compiler/FSComp.txt
@@ -879,6 +879,7 @@ optsDebug,"Specify debugging type: full, portable, embedded, pdbonly. ('%s' is t
optsOptimize,"Enable optimizations (Short form: -O)"
optsTailcalls,"Enable or disable tailcalls"
optsDeterministic,"Produce a deterministic assembly (including module version GUID and timestamp)"
+optsRealsig,"Generate assembly with IL visibility that matches the source code visibility"
optsRefOnly,"Produce a reference assembly, instead of a full assembly, as the primary output"
optsRefOut,"Produce a reference assembly with the specified file path."
optsPathMap,"Maps physical paths to source path names output by the compiler"
@@ -993,7 +994,6 @@ lexhlpIdentifierReserved,"The identifier '%s' is reserved for future use by F#"
1112,impImportedAssemblyUsesNotPublicType,"An imported assembly uses the type '%s' but that type is not public"
1113,optValueMarkedInlineButIncomplete,"The value '%s' was marked inline but its implementation makes use of an internal or private function which is not sufficiently accessible"
1114,optValueMarkedInlineButWasNotBoundInTheOptEnv,"The value '%s' was marked inline but was not bound in the optimization environment"
-1115,optLocalValueNotFoundDuringOptimization,"Local value %s not found during optimization"
1116,optValueMarkedInlineHasUnexpectedValue,"A value marked as 'inline' has an unexpected value"
1117,optValueMarkedInlineCouldNotBeInlined,"A value marked as 'inline' could not be inlined"
1118,optFailedToInlineValue,"Failed to inline the value '%s' marked 'inline', perhaps because a recursive value was marked 'inline'"
@@ -1595,6 +1595,7 @@ featureChkTailCallAttrOnNonRec,"Raises warnings if the 'TailCall' attribute is u
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"
featureLowerInterpolatedStringToConcat,"Optimizes interpolated strings in certain cases, by lowering to concatenation"
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/FSharp.Compiler.Service.fsproj b/src/Compiler/FSharp.Compiler.Service.fsproj
index 6a52de46022..e1fe24ea421 100644
--- a/src/Compiler/FSharp.Compiler.Service.fsproj
+++ b/src/Compiler/FSharp.Compiler.Service.fsproj
@@ -21,7 +21,6 @@
$(OtherFlags) --warnon:3218
$(OtherFlags) --warnon:3390
-
true
$(IntermediateOutputPath)$(TargetFramework)\
$(IntermediateOutputPath)$(TargetFramework)\
diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs
index 6e2d91bc6cd..dd7133224e8 100644
--- a/src/Compiler/Facilities/LanguageFeatures.fs
+++ b/src/Compiler/Facilities/LanguageFeatures.fs
@@ -86,6 +86,7 @@ type LanguageFeature =
| WarningWhenTailCallAttrOnNonRec
| BooleanReturningAndReturnTypeDirectedPartialActivePattern
| EnforceAttributeTargetsOnFunctions
+ | EnforceAttributeTargetsUnionCaseDeclarations
| LowerInterpolatedStringToConcat
/// LanguageVersion management
@@ -200,6 +201,7 @@ type LanguageVersion(versionText) =
LanguageFeature.UnionIsPropertiesVisible, previewVersion
LanguageFeature.BooleanReturningAndReturnTypeDirectedPartialActivePattern, previewVersion
LanguageFeature.EnforceAttributeTargetsOnFunctions, previewVersion
+ LanguageFeature.EnforceAttributeTargetsUnionCaseDeclarations, previewVersion
LanguageFeature.LowerInterpolatedStringToConcat, previewVersion
]
@@ -345,6 +347,7 @@ type LanguageVersion(versionText) =
| LanguageFeature.BooleanReturningAndReturnTypeDirectedPartialActivePattern ->
FSComp.SR.featureBooleanReturningAndReturnTypeDirectedPartialActivePattern ()
| LanguageFeature.EnforceAttributeTargetsOnFunctions -> FSComp.SR.featureEnforceAttributeTargetsOnFunctions ()
+ | LanguageFeature.EnforceAttributeTargetsUnionCaseDeclarations -> FSComp.SR.featureEnforceAttributeTargetsUnionCaseDeclarations ()
| LanguageFeature.LowerInterpolatedStringToConcat -> FSComp.SR.featureLowerInterpolatedStringToConcat ()
/// Get a version string associated with the given feature.
diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi
index 4888479d867..5be15a88284 100644
--- a/src/Compiler/Facilities/LanguageFeatures.fsi
+++ b/src/Compiler/Facilities/LanguageFeatures.fsi
@@ -77,6 +77,7 @@ type LanguageFeature =
| WarningWhenTailCallAttrOnNonRec
| BooleanReturningAndReturnTypeDirectedPartialActivePattern
| EnforceAttributeTargetsOnFunctions
+ | EnforceAttributeTargetsUnionCaseDeclarations
| LowerInterpolatedStringToConcat
/// LanguageVersion management
diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs
index e5ff5b6c754..a6ea4f1867e 100644
--- a/src/Compiler/Interactive/fsi.fs
+++ b/src/Compiler/Interactive/fsi.fs
@@ -1606,7 +1606,10 @@ let rec ConvReflectionTypeToILType (reflectionTy: Type) =
let internal mkBoundValueTypedImpl tcGlobals m moduleName name ty =
let vis = Accessibility.TAccess([])
- let compPath = (CompilationPath.CompPath(ILScopeRef.Local, []))
+
+ let compPath =
+ (CompilationPath.CompPath(ILScopeRef.Local, SyntaxAccess.Unknown, []))
+
let mutable mty = Unchecked.defaultof<_>
let entity =
diff --git a/src/Compiler/Optimize/InnerLambdasToTopLevelFuncs.fs b/src/Compiler/Optimize/InnerLambdasToTopLevelFuncs.fs
index 37b3f26c429..291e24fe6e9 100644
--- a/src/Compiler/Optimize/InnerLambdasToTopLevelFuncs.fs
+++ b/src/Compiler/Optimize/InnerLambdasToTopLevelFuncs.fs
@@ -129,10 +129,10 @@ let mkLocalNameTypeArity compgen m name ty valReprInfo =
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
-// pass1: GetValsBoundUnderMustInline (see comment further below)
+// pass1: GetValsBoundUnderShouldInline (see comment further below)
//-------------------------------------------------------------------------
-let GetValsBoundUnderMustInline xinfo =
+let GetValsBoundUnderShouldInline xinfo =
let accRejectFrom (v: Val) repr rejectS =
if v.InlineInfo = ValInline.Always then
Zset.union (GetValsBoundInExpr repr) rejectS
@@ -194,8 +194,14 @@ module Pass1_DetermineTLRAndArities =
let nFormals = vss.Length
let nMaxApplied = GetMaxNumArgsAtUses xinfo f
let arity = Operators.min nFormals nMaxApplied
- if atTopLevel || arity<>0 || not (isNil tps) then Some (f, arity)
- else None
+ if atTopLevel then
+ Some (f, arity)
+ elif g.realsig then
+ None
+ else if arity<>0 || not (isNil tps) then
+ Some (f, arity)
+ else
+ None
/// Check if f involves any value recursion (so can skip those).
/// ValRec considered: recursive && some f in mutual binding is not bound to a lambda
@@ -213,21 +219,21 @@ module Pass1_DetermineTLRAndArities =
let xinfo = GetUsageInfoOfImplFile g expr
let fArities = Zmap.chooseL (SelectTLRVals g xinfo) xinfo.Defns
let fArities = List.filter (fst >> IsValueRecursionFree xinfo) fArities
- // Do not TLR v if it is bound under a mustinline defn
+ // Do not TLR v if it is bound under a shouldinline defn
// There is simply no point - the original value will be duplicated and TLR'd anyway
- let rejectS = GetValsBoundUnderMustInline xinfo
+ let rejectS = GetValsBoundUnderShouldInline xinfo
let fArities = List.filter (fun (v, _) -> not (Zset.contains v rejectS)) fArities
(*-*)
let tlrS = Zset.ofList valOrder (List.map fst fArities)
- let topValS = xinfo.TopLevelBindings (* genuinely top level *)
- let topValS = Zset.filter (IsMandatoryNonTopLevel g >> not) topValS (* restrict *)
- (* REPORT MISSED CASES *)
+ let topValS = xinfo.TopLevelBindings (* genuinely top level *)
+ let topValS = Zset.filter (IsMandatoryNonTopLevel g >> not) topValS (* restrict *)
#if DEBUG
+ (* REPORT MISSED CASES *)
if verboseTLR then
let missed = Zset.diff xinfo.TopLevelBindings tlrS
missed |> Zset.iter (fun v -> dprintf "TopLevel but not TLR = %s\n" v.LogicalName)
-#endif
(* REPORT OVER *)
+#endif
let arityM = Zmap.ofList valOrder fArities
#if DEBUG
if verboseTLR then DumpArity arityM
@@ -885,24 +891,24 @@ module Pass4_RewriteAssembly =
/// Any TLR repr bindings under lambdas can be filtered out (and collected),
/// giving pre-declarations to insert before the outermost lambda expr.
type RewriteState =
- { rws_mustinline: bool
+ { rws_shouldinline: bool
/// counts level of enclosing "lambdas"
rws_innerLevel: int
/// collected preDecs (fringe is in-order)
rws_preDecs: Tree
}
- let rewriteState0 = {rws_mustinline=false;rws_innerLevel=0;rws_preDecs=emptyTR}
+ let rewriteState0 = {rws_shouldinline=false;rws_innerLevel=0;rws_preDecs=emptyTR}
// move in/out of lambdas (or lambda containing construct)
let EnterInner z = {z with rws_innerLevel = z.rws_innerLevel + 1}
let ExitInner z = {z with rws_innerLevel = z.rws_innerLevel - 1}
- let EnterMustInline b z f =
- let orig = z.rws_mustinline
- let x, z' = f (if b then {z with rws_mustinline = true } else z)
- {z' with rws_mustinline = orig }, x
+ let EnterShouldInline b z f =
+ let orig = z.rws_shouldinline
+ let x, z' = f (if b then {z with rws_shouldinline = true } else z)
+ {z' with rws_shouldinline = orig }, x
/// extract PreDecs (iff at top-level)
let ExtractPreDecs z =
@@ -1263,8 +1269,8 @@ module Pass4_RewriteAssembly =
TObjExprMethod(slotsig, attribs, tps, vs, e, m), z
and TransBindingRhs penv z (TBind(v, e, letSeqPtOpt)) : Binding * RewriteState =
- let mustInline = v.MustInline
- let z, e = EnterMustInline mustInline z (fun z -> TransExpr penv z e)
+ let shouldInline = v.ShouldInline
+ let z, e = EnterShouldInline shouldInline z (fun z -> TransExpr penv z e)
TBind (v, e, letSeqPtOpt), z
and TransDecisionTree penv z x: DecisionTree * RewriteState =
diff --git a/src/Compiler/Optimize/Optimizer.fs b/src/Compiler/Optimize/Optimizer.fs
index afdc0616505..fafb8184600 100644
--- a/src/Compiler/Optimize/Optimizer.fs
+++ b/src/Compiler/Optimize/Optimizer.fs
@@ -435,6 +435,7 @@ type cenv =
stackGuard: StackGuard
+ realsig: bool
}
override x.ToString() = ""
@@ -499,7 +500,7 @@ let rec IsPartialExprVal x =
| SizeValue (_, a) -> IsPartialExprVal a
let CheckInlineValueIsComplete (v: Val) res =
- if v.MustInline && IsPartialExprVal res then
+ if v.ShouldInline && IsPartialExprVal res then
errorR(Error(FSComp.SR.optValueMarkedInlineButIncomplete(v.DisplayName), v.Range))
//System.Diagnostics.Debug.Assert(false, sprintf "Break for incomplete inline value %s" v.DisplayName)
@@ -557,7 +558,7 @@ let UnknownValInfo = { ValExprInfo=UnknownValue; ValMakesNoCriticalTailcalls=fal
let mkValInfo info (v: Val) = { ValExprInfo=info.Info; ValMakesNoCriticalTailcalls= v.MakesNoCriticalTailcalls }
(* Bind a value *)
-let BindInternalLocalVal cenv (v: Val) vval env =
+let BindInternalLocalVal cenv (v: Val) vval env =
let vval = if v.IsMutable then UnknownValInfo else vval
match vval.ValExprInfo with
@@ -565,7 +566,7 @@ let BindInternalLocalVal cenv (v: Val) vval env =
| _ ->
cenv.localInternalVals[v.Stamp] <- vval
env
-
+
let BindExternalLocalVal cenv (v: Val) vval env =
let g = cenv.g
@@ -635,7 +636,7 @@ let GetInfoForLocalValue cenv env (v: Val) m =
match env.localExternalVals.TryFind v.Stamp with
| Some vval -> vval
| None ->
- if v.MustInline then
+ if v.ShouldInline then
errorR(Error(FSComp.SR.optValueMarkedInlineButWasNotBoundInTheOptEnv(fullDisplayTextOfValRef (mkLocalValRef v)), m))
UnknownValInfo
@@ -663,7 +664,7 @@ let GetInfoForNonLocalVal cenv env (vref: ValRef) =
if vref.IsDispatchSlot then
UnknownValInfo
// REVIEW: optionally turn x-module on/off on per-module basis or
- elif cenv.settings.crossAssemblyOpt () || vref.MustInline then
+ elif cenv.settings.crossAssemblyOpt () || vref.ShouldInline then
match TryGetInfoForNonLocalEntityRef env vref.nlr.EnclosingEntity.nlr with
| Some structInfo ->
match structInfo.ValInfos.TryFind vref with
@@ -1415,7 +1416,7 @@ let AbstractOptimizationInfoToEssentials =
let rec abstractModulInfo (ss: ModuleInfo) =
{ ModuleOrNamespaceInfos = NameMap.map (InterruptibleLazy.force >> abstractModulInfo >> notlazy) ss.ModuleOrNamespaceInfos
- ValInfos = ss.ValInfos.Filter (fun (v, _) -> v.MustInline) }
+ ValInfos = ss.ValInfos.Filter (fun (v, _) -> v.ShouldInline) }
and abstractLazyModulInfo ss = ss |> InterruptibleLazy.force |> abstractModulInfo |> notlazy
@@ -2354,8 +2355,17 @@ let rec OptimizeExpr cenv (env: IncrementalOptimizationEnv) expr =
| Expr.Const (c, m, ty) ->
OptimizeConst cenv env expr (c, m, ty)
- | Expr.Val (v, _vFlags, m) ->
- OptimizeVal cenv env expr (v, m)
+ | Expr.Val (v, _vFlags, m) ->
+ if not (v.Accessibility.IsPrivate) then
+ OptimizeVal cenv env expr (v, m)
+ else
+ expr,
+ { TotalSize = 10
+ FunctionSize = 1
+ HasEffect = false
+ MightMakeCriticalTailcall=false
+ Info=UnknownValue }
+
| Expr.Quote (ast, splices, isFromQueryExpression, m, ty) ->
let doData data = map3Of4 (List.map (OptimizeExpr cenv env >> fst)) data
@@ -3035,8 +3045,7 @@ and CopyExprForInlining cenv isInlineIfLambda expr (m: range) =
/// Make optimization decisions once we know the optimization information
/// for a value
-and TryOptimizeVal cenv env (vOpt: ValRef option, mustInline, inlineIfLambda, valInfoForVal, m) =
-
+and TryOptimizeVal cenv env (vOpt: ValRef option, shouldInline, inlineIfLambda, valInfoForVal, m) =
let g = cenv.g
match valInfoForVal with
@@ -3045,13 +3054,13 @@ and TryOptimizeVal cenv env (vOpt: ValRef option, mustInline, inlineIfLambda, va
Some (Expr.Const (c, m, ty))
| SizeValue (_, detail) ->
- TryOptimizeVal cenv env (vOpt, mustInline, inlineIfLambda, detail, m)
+ TryOptimizeVal cenv env (vOpt, shouldInline, inlineIfLambda, detail, m)
| ValValue (vR, detail) ->
// Inline values bound to other values immediately
// Prefer to inline using the more specific info if possible
// If the more specific info didn't reveal an inline then use the value
- match TryOptimizeVal cenv env (vOpt, mustInline, inlineIfLambda, detail, m) with
+ match TryOptimizeVal cenv env (vOpt, shouldInline, inlineIfLambda, detail, m) with
| Some e -> Some e
| None ->
// If we have proven 'v = compilerGeneratedValue'
@@ -3069,22 +3078,30 @@ and TryOptimizeVal cenv env (vOpt: ValRef option, mustInline, inlineIfLambda, va
| ConstExprValue(_size, expr) ->
Some (remarkExpr m (copyExpr g CloneAllAndMarkExprValsAsCompilerGenerated expr))
- | CurriedLambdaValue (_, _, _, expr, _) when mustInline || inlineIfLambda ->
- let exprCopy = CopyExprForInlining cenv inlineIfLambda expr m
- Some exprCopy
+ | CurriedLambdaValue (_, _, _, expr, _) when shouldInline || inlineIfLambda ->
+ let fvs = freeInExpr CollectLocals expr
+ if fvs.UsesMethodLocalConstructs then
+ // Discarding lambda for binding because uses protected members --- TBD: Should we warn or error here
+ None
+ elif fvs.FreeLocals |> Seq.exists(fun v -> v.Accessibility.IsPrivate ) then
+ // Discarding lambda for binding because uses private members --- TBD: Should we warn or error here
+ None
+ else
+ let exprCopy = CopyExprForInlining cenv inlineIfLambda expr m
+ Some exprCopy
- | TupleValue _ | UnionCaseValue _ | RecdValue _ when mustInline ->
+ | TupleValue _ | UnionCaseValue _ | RecdValue _ when shouldInline ->
failwith "tuple, union and record values cannot be marked 'inline'"
- | UnknownValue when mustInline ->
+ | UnknownValue when shouldInline ->
warning(Error(FSComp.SR.optValueMarkedInlineHasUnexpectedValue(), m))
None
- | _ when mustInline ->
+ | _ when shouldInline ->
warning(Error(FSComp.SR.optValueMarkedInlineCouldNotBeInlined(), m))
None
- | _ -> None
+ | _ -> None
and TryOptimizeValInfo cenv env m vinfo =
if vinfo.HasEffect then None else TryOptimizeVal cenv env (None, false, false, vinfo.Info, m)
@@ -3109,7 +3126,7 @@ and OptimizeVal cenv env expr (v: ValRef, m) =
let valInfoForVal = GetInfoForValWithCheck cenv env m v
- match TryOptimizeVal cenv env (Some v, v.MustInline, v.InlineIfLambda, valInfoForVal.ValExprInfo, m) with
+ match TryOptimizeVal cenv env (Some v, v.ShouldInline, v.InlineIfLambda, valInfoForVal.ValExprInfo, m) with
| Some e ->
// don't reoptimize inlined lambdas until they get applied to something
match e with
@@ -3125,9 +3142,9 @@ and OptimizeVal cenv env expr (v: ValRef, m) =
let e, einfo = OptimizeExpr cenv env e
e, AddValEqualityInfo g m v einfo
- | None ->
- if v.MustInline then
- error(Error(FSComp.SR.optFailedToInlineValue(v.DisplayName), m))
+ | None ->
+ if v.ShouldInline then
+ warning(Error(FSComp.SR.optFailedToInlineValue(v.DisplayName), m))
if v.InlineIfLambda then
warning(Error(FSComp.SR.optFailedToInlineSuggestedValue(v.DisplayName), m))
expr, (AddValEqualityInfo g m v
@@ -3578,45 +3595,46 @@ and OptimizeApplication cenv env (f0, f0ty, tyargs, args, m) =
| Choice2Of2 (newf0, remake) ->
match TryInlineApplication cenv env finfo (tyargs, args, m) with
- | Some (res, info) ->
+ | Some (res, info) ->
// inlined
(res |> remake), info
- | None ->
- let shapes =
- match newf0 with
- | Expr.Val (vref, _, _) ->
- match vref.ValReprInfo with
- | Some(ValReprInfo(_, detupArgsL, _)) ->
- let nargs = args.Length
- let nDetupArgsL = detupArgsL.Length
- let nShapes = min nargs nDetupArgsL
- let detupArgsShapesL =
- List.truncate nShapes detupArgsL
- |> List.map (fun detupArgs ->
- match detupArgs with
- | [] | [_] -> UnknownValue
- | _ -> TupleValue(Array.ofList (List.map (fun _ -> UnknownValue) detupArgs)))
- List.zip (detupArgsShapesL @ List.replicate (nargs - nShapes) UnknownValue) args
- | _ -> args |> List.map (fun arg -> UnknownValue, arg)
- | _ -> args |> List.map (fun arg -> UnknownValue, arg)
-
- let newArgs, arginfos = OptimizeExprsThenReshapeAndConsiderSplits cenv env shapes
- // beta reducing
- let reducedExpr = MakeApplicationAndBetaReduce g (newf0, f0ty, [tyargs], newArgs, m)
- let newExpr = reducedExpr |> remake
-
- match newf0, reducedExpr with
- | (Expr.Lambda _ | Expr.TyLambda _), Expr.Let _ ->
- // we beta-reduced, hence reoptimize
- OptimizeExpr cenv env newExpr
| _ ->
- // regular
- // Determine if this application is a critical tailcall
- let mayBeCriticalTailcall =
+ let shapes =
match newf0 with
- | KnownValApp(vref, _typeArgs, otherArgs) ->
+ | Expr.Val (vref, _, _) ->
+ match vref.ValReprInfo with
+ | Some(ValReprInfo(_, detupArgsL, _)) ->
+ let nargs = args.Length
+ let nDetupArgsL = detupArgsL.Length
+ let nShapes = min nargs nDetupArgsL
+ let detupArgsShapesL =
+ List.truncate nShapes detupArgsL
+ |> List.map (fun detupArgs ->
+ match detupArgs with
+ | [] | [_] -> UnknownValue
+ | _ -> TupleValue(Array.ofList (List.map (fun _ -> UnknownValue) detupArgs)))
+ List.zip (detupArgsShapesL @ List.replicate (nargs - nShapes) UnknownValue) args
+ | _ -> args |> List.map (fun arg -> UnknownValue, arg)
+ | _ -> args |> List.map (fun arg -> UnknownValue, arg)
+
+ let newArgs, arginfos = OptimizeExprsThenReshapeAndConsiderSplits cenv env shapes
+ // beta reducing
+ let reducedExpr = MakeApplicationAndBetaReduce g (newf0, f0ty, [tyargs], newArgs, m)
+ let newExpr = reducedExpr |> remake
+
+ match newf0, reducedExpr with
+ | (Expr.Lambda _ | Expr.TyLambda _), Expr.Let _ ->
+ // we beta-reduced, hence reoptimize
+ OptimizeExpr cenv env newExpr
+ | _ ->
+ // regular
+
+ // Determine if this application is a critical tailcall
+ let mayBeCriticalTailcall =
+ match newf0 with
+ | KnownValApp(vref, _typeArgs, otherArgs) ->
// Check if this is a call to a function of known arity that has been inferred to not be a critical tailcall when used as a direct call
// This includes recursive calls to the function being defined (in which case we get a non-critical, closed-world tailcall).
@@ -3635,16 +3653,16 @@ and OptimizeApplication cenv env (f0, f0ty, tyargs, args, m) =
| None -> true // over-application of a known function, which presumably returns a function. This counts as an indirect call
else
true // application of a function that may make a critical tailcall
-
- | _ ->
- // All indirect calls (calls to unknown functions) are assumed to be critical tailcalls
- true
- newExpr, { TotalSize=finfo.TotalSize + AddTotalSizes arginfos
- FunctionSize=finfo.FunctionSize + AddFunctionSizes arginfos
- HasEffect=true
- MightMakeCriticalTailcall = mayBeCriticalTailcall
- Info=ValueOfExpr newExpr }
+ | _ ->
+ // All indirect calls (calls to unknown functions) are assumed to be critical tailcalls
+ true
+
+ newExpr, { TotalSize=finfo.TotalSize + AddTotalSizes arginfos
+ FunctionSize=finfo.FunctionSize + AddFunctionSizes arginfos
+ HasEffect=true
+ MightMakeCriticalTailcall = mayBeCriticalTailcall
+ Info=ValueOfExpr newExpr }
/// Extract a sequence of pipe-right operations (note the pipe-right operator is left-associative
/// so we start with the full thing and descend down taking apps off the end first)
@@ -4087,7 +4105,7 @@ and OptimizeBinding cenv isRec env (TBind(vref, expr, spBind)) =
let exprOptimized, einfo =
let env = if vref.IsCompilerGenerated && Option.isSome env.latestBoundId then env else {env with latestBoundId=Some vref.Id}
- let cenv = if vref.InlineInfo.MustInline then { cenv with optimizing=false} else cenv
+ let cenv = if vref.InlineInfo.ShouldInline then { cenv with optimizing=false} else cenv
let arityInfo = InferValReprInfoOfBinding g AllowTypeDirectedDetupling.No vref expr
let exprOptimized, einfo = OptimizeLambdas (Some vref) cenv env arityInfo expr vref.Type
let size = localVarSize
@@ -4106,6 +4124,9 @@ and OptimizeBinding cenv isRec env (TBind(vref, expr, spBind)) =
if fvs.UsesMethodLocalConstructs then
// Discarding lambda for binding because uses protected members
UnknownValue
+ elif fvs.FreeLocals.ToArray() |> Seq.fold(fun acc v -> if not acc then v.Accessibility.IsPrivate else acc) false then
+ // Discarding lambda for binding because uses private members
+ UnknownValue
else
ivalue
@@ -4116,10 +4137,10 @@ and OptimizeBinding cenv isRec env (TBind(vref, expr, spBind)) =
| UnknownValue | ConstValue _ | ConstExprValue _ -> ivalue
| SizeValue(_, a) -> MakeSizedValueInfo (cut a)
- let einfo = if vref.MustInline || vref.InlineIfLambda then einfo else {einfo with Info = cut einfo.Info }
+ let einfo = if vref.ShouldInline || vref.InlineIfLambda then einfo else {einfo with Info = cut einfo.Info }
let einfo =
- if (not vref.MustInline && not vref.InlineIfLambda && not cenv.settings.KeepOptimizationValues) ||
+ if (not vref.ShouldInline && not vref.InlineIfLambda && not cenv.settings.KeepOptimizationValues) ||
// Bug 4916: do not record inline data for initialization trigger expressions
// Note: we can't eliminate these value infos at the file boundaries because that would change initialization
@@ -4166,8 +4187,8 @@ and OptimizeBinding cenv isRec env (TBind(vref, expr, spBind)) =
valRefEq g nvref g.generic_hash_inner_vref))
then {einfo with Info=UnknownValue}
else einfo
- if vref.MustInline && IsPartialExprVal einfo.Info then
- errorR(InternalError("the mustinline value '"+vref.LogicalName+"' was not inferred to have a known value", vref.Range))
+ if vref.ShouldInline && IsPartialExprVal einfo.Info then
+ errorR(InternalError("the inline value '"+vref.LogicalName+"' was not inferred to have a known value", vref.Range))
let env = BindInternalLocalVal cenv vref (mkValInfo einfo vref) env
(TBind(vref, exprOptimized, spBind), einfo), env
@@ -4366,7 +4387,8 @@ let OptimizeImplFile (settings, ccu, tcGlobals, tcVal, importMap, optEnv, isIncr
localInternalVals=Dictionary(10000)
emitTailcalls=emitTailcalls
casApplied=Dictionary()
- stackGuard = StackGuard(OptimizerStackGuardDepth, "OptimizerStackGuardDepth")
+ stackGuard = StackGuard(OptimizerStackGuardDepth, "OptimizerStackGuardDepth")
+ realsig = tcGlobals.realsig
}
let env, _, _, _ as results = OptimizeImplFileInternal cenv optEnv isIncrementalFragment fsiMultiAssemblyEmit hidden mimpls
diff --git a/src/Compiler/Service/FSharpProjectSnapshot.fs b/src/Compiler/Service/FSharpProjectSnapshot.fs
index 76d9705890e..6efd49f11c1 100644
--- a/src/Compiler/Service/FSharpProjectSnapshot.fs
+++ b/src/Compiler/Service/FSharpProjectSnapshot.fs
@@ -149,13 +149,13 @@ type internal FSharpParsedFile
SyntaxTreeHash: byte array,
SourceText: ISourceText,
ParsedInput: ParsedInput,
- ParseErrors: (PhasedDiagnostic * FSharpDiagnosticSeverity)[]
+ ParseDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity)[]
) =
member _.FileName = FileName
member _.SourceText = SourceText
member _.ParsedInput = ParsedInput
- member _.ParseErrors = ParseErrors
+ member _.ParseDiagnostics = ParseDiagnostics
member val IsSignatureFile = FileName |> isSignatureFile
diff --git a/src/Compiler/Service/ServiceLexing.fs b/src/Compiler/Service/ServiceLexing.fs
index bc967f30dbe..9abe2199dc0 100644
--- a/src/Compiler/Service/ServiceLexing.fs
+++ b/src/Compiler/Service/ServiceLexing.fs
@@ -36,7 +36,7 @@ module FSharpTokenTag =
tagOfToken (INTERP_STRING_BEGIN_PART("a", SynStringKind.Regular, LexCont.Default))
let INTERP_STRING_PART = tagOfToken (INTERP_STRING_PART("a", LexCont.Default))
- let INTERP_STRING_END = tagOfToken (INTERP_STRING_END("a", None, LexCont.Default))
+ let INTERP_STRING_END = tagOfToken (INTERP_STRING_END("a", LexCont.Default))
let LPAREN = tagOfToken LPAREN
let RPAREN = tagOfToken RPAREN
let LBRACK = tagOfToken LBRACK
@@ -493,7 +493,7 @@ module internal LexerStateEncoding =
| INTERP_STRING_BEGIN_PART(_, _, cont)
| INTERP_STRING_PART(_, cont)
| INTERP_STRING_BEGIN_END(_, _, cont)
- | INTERP_STRING_END(_, _, cont)
+ | INTERP_STRING_END(_, cont)
| LBRACE cont
| RBRACE cont
| BYTEARRAY(_, _, cont)
diff --git a/src/Compiler/Service/TransparentCompiler.fs b/src/Compiler/Service/TransparentCompiler.fs
index c5ecfba812f..f13b7be6d69 100644
--- a/src/Compiler/Service/TransparentCompiler.fs
+++ b/src/Compiler/Service/TransparentCompiler.fs
@@ -1251,7 +1251,9 @@ type internal TransparentCompiler
let sink = TcResultsSinkImpl(tcGlobals, file.SourceText)
- let hadParseErrors = not (Array.isEmpty file.ParseErrors)
+ let hadParseErrors =
+ file.ParseDiagnostics
+ |> Array.exists (snd >> (=) FSharpDiagnosticSeverity.Error)
let input, moduleNamesDict =
DeduplicateParsedInputModuleName prevTcInfo.moduleNamesDict input
@@ -1448,7 +1450,7 @@ type internal TransparentCompiler
tcConfig.diagnosticsOptions,
false,
file.FileName,
- parsedFile.ParseErrors,
+ parsedFile.ParseDiagnostics,
suggestNamesForErrors,
tcConfig.flatErrors,
None
diff --git a/src/Compiler/Symbols/Symbols.fs b/src/Compiler/Symbols/Symbols.fs
index b5b244a6e5c..19fbfe9306b 100644
--- a/src/Compiler/Symbols/Symbols.fs
+++ b/src/Compiler/Symbols/Symbols.fs
@@ -32,9 +32,9 @@ type FSharpAccessibility(a:Accessibility, ?isProtected) =
let isInternalCompPath x =
match x with
- | CompPath(ILScopeRef.Local, []) -> true
+ | CompPath(ILScopeRef.Local, _, []) -> true
| _ -> false
-
+
let (|Public|Internal|Private|) (TAccess p) =
match p with
| [] -> Public
@@ -53,7 +53,7 @@ type FSharpAccessibility(a:Accessibility, ?isProtected) =
override _.ToString() =
let (TAccess paths) = a
- let mangledTextOfCompPath (CompPath(scoref, path)) = getNameOfScopeRef scoref + "/" + textOfPath (List.map fst path)
+ let mangledTextOfCompPath (CompPath(scoref, _, path)) = getNameOfScopeRef scoref + "/" + textOfPath (List.map fst path)
String.concat ";" (List.map mangledTextOfCompPath paths)
type SymbolEnv(g: TcGlobals, thisCcu: CcuThunk, thisCcuTyp: ModuleOrNamespaceType option, tcImports: TcImports, amap: Import.ImportMap, infoReader: InfoReader) =
@@ -122,7 +122,7 @@ module Impl =
| ILScopeRef.Assembly aref -> aref.Name
| ILScopeRef.Module mref -> mref.Name
| ILScopeRef.PrimaryAssembly -> ilg.primaryAssemblyName
- let canAccessCompPathFromCrossProject (CompPath(scoref1, cpath1)) (CompPath(scoref2, cpath2)) =
+ let canAccessCompPathFromCrossProject (CompPath(scoref1, _, cpath1)) (CompPath(scoref2, _, cpath2)) =
let rec loop p1 p2 =
match p1, p2 with
| (a1, k1) :: rest1, (a2, k2) :: rest2 -> (a1=a2) && (k1=k2) && loop rest1 rest2
@@ -141,7 +141,7 @@ module Impl =
| ILMemberAccess.CompilerControlled
| ILMemberAccess.FamilyAndAssembly
| ILMemberAccess.Assembly ->
- taccessPrivate (CompPath(declaringEntity.CompilationPath.ILScopeRef, []))
+ taccessPrivate (CompPath(declaringEntity.CompilationPath.ILScopeRef, SyntaxAccess.Unknown, []))
| ILMemberAccess.Private ->
taccessPrivate declaringEntity.CompilationPath
@@ -166,7 +166,7 @@ module Impl =
match td.Access with
| ILTypeDefAccess.Public
| ILTypeDefAccess.Nested ILMemberAccess.Public -> taccessPublic
- | ILTypeDefAccess.Private -> taccessPrivate (CompPath(entity.CompilationPath.ILScopeRef, []))
+ | ILTypeDefAccess.Private -> taccessPrivate (CompPath(entity.CompilationPath.ILScopeRef, SyntaxAccess.Unknown, []))
| ILTypeDefAccess.Nested nested -> getApproxFSharpAccessibilityOfMember entity nested
| FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata ->
@@ -409,13 +409,13 @@ type FSharpEntity(cenv: SymbolEnv, entity: EntityRef, tyargs: TType list) =
checkIsResolved()
match entity.CompilationPathOpt with
| None -> "global"
- | Some (CompPath(_, [])) -> "global"
+ | Some (CompPath(_, _, [])) -> "global"
| Some cp -> buildAccessPath (Some cp)
member x.DeclaringEntity =
match entity.CompilationPathOpt with
| None -> None
- | Some (CompPath(_, [])) -> None
+ | Some (CompPath(_, _, [])) -> None
| Some cp ->
match x.Assembly.Contents.FindEntityByPath cp.MangledPath with
| Some res -> Some res
@@ -431,7 +431,7 @@ type FSharpEntity(cenv: SymbolEnv, entity: EntityRef, tyargs: TType list) =
checkIsResolved()
match entity.CompilationPathOpt with
| None -> None
- | Some (CompPath(_, [])) -> None
+ | Some (CompPath(_, _, [])) -> None
| Some cp when cp.AccessPath |> List.forall (function _, ModuleOrNamespaceKind.Namespace _ -> true | _ -> false) ->
Some (buildAccessPath (Some cp))
| Some _ -> None
@@ -774,7 +774,7 @@ type FSharpEntity(cenv: SymbolEnv, entity: EntityRef, tyargs: TType list) =
member _.AllCompilationPaths =
checkIsResolved()
- let (CompPath(_, parts)) = entity.CompilationPath
+ let (CompPath(_, _, parts)) = entity.CompilationPath
let partsList =
[ yield parts
match parts with
diff --git a/src/Compiler/SyntaxTree/LexHelpers.fs b/src/Compiler/SyntaxTree/LexHelpers.fs
index 5ee9a16c90b..02d4da364d4 100644
--- a/src/Compiler/SyntaxTree/LexHelpers.fs
+++ b/src/Compiler/SyntaxTree/LexHelpers.fs
@@ -190,7 +190,7 @@ type LexerStringFinisher =
else if isPart then
INTERP_STRING_PART(s, cont)
else
- INTERP_STRING_END(s, None, cont)
+ INTERP_STRING_END(s, cont)
elif kind.IsByteString then
let synByteStringKind =
if isVerbatim then
diff --git a/src/Compiler/TypedTree/TcGlobals.fs b/src/Compiler/TypedTree/TcGlobals.fs
index 3830dd008e5..4f713fb4d5d 100644
--- a/src/Compiler/TypedTree/TcGlobals.fs
+++ b/src/Compiler/TypedTree/TcGlobals.fs
@@ -193,7 +193,8 @@ type TcGlobals(
emitDebugInfoInQuotations: bool,
noDebugAttributes: bool,
pathMap: PathMap,
- langVersion: LanguageVersion) =
+ langVersion: LanguageVersion,
+ realsig: bool) =
// empty flags
let v_knownWithoutNull = 0uy
@@ -354,7 +355,7 @@ type TcGlobals(
let attrRef = ILTypeRef.Create(ILScopeRef.Local, [], nm)
let attrTycon =
Construct.NewTycon(
- Some (CompPath(ILScopeRef.Local, [])),
+ Some (CompPath(ILScopeRef.Local, SyntaxAccess.Internal, [])),
attrRef.Name,
range0,
taccessInternal,
@@ -1104,6 +1105,8 @@ type TcGlobals(
member _.langVersion = langVersion
+ member _.realsig = realsig
+
member _.unionCaseRefEq x y = primUnionCaseRefEq compilingFSharpCore fslibCcu x y
member _.valRefEq x y = primValRefEq compilingFSharpCore fslibCcu x y
diff --git a/src/Compiler/TypedTree/TypedTree.fs b/src/Compiler/TypedTree/TypedTree.fs
index da8e43bfba5..7c2a454ae36 100644
--- a/src/Compiler/TypedTree/TypedTree.fs
+++ b/src/Compiler/TypedTree/TypedTree.fs
@@ -48,8 +48,8 @@ type ValInline =
/// Indicates the value must never be inlined by the optimizer
| Never
- /// Returns true if the implementation of a value must always be inlined
- member x.MustInline =
+ /// Returns true if the implementation of a value should be inlined
+ member x.ShouldInline =
match x with
| ValInline.Always -> true
| ValInline.Optional | ValInline.Never -> false
@@ -519,14 +519,21 @@ type PublicPath =
assert (pp.Length >= 1)
pp[0..pp.Length-2]
+/// Represents the specified visibility of the accessibility -- used to ensure IL visibility
+[]
+type SyntaxAccess =
+ | Public
+ | Internal
+ | Private
+ | Unknown
/// The information ILXGEN needs about the location of an item
-type CompilationPath =
- | CompPath of ILScopeRef * (string * ModuleOrNamespaceKind) list
+type CompilationPath =
+ | CompPath of ILScopeRef * SyntaxAccess * (string * ModuleOrNamespaceKind) list
- member x.ILScopeRef = let (CompPath(scoref, _)) = x in scoref
+ member x.ILScopeRef = let (CompPath(scoref, _, _)) = x in scoref
- member x.AccessPath = let (CompPath(_, p)) = x in p
+ member x.AccessPath = let (CompPath(_, _, p)) = x in p
member x.MangledPath = List.map fst x.AccessPath
@@ -534,10 +541,10 @@ type CompilationPath =
member x.ParentCompPath =
let a, _ = List.frontAndBack x.AccessPath
- CompPath(x.ILScopeRef, a)
+ CompPath(x.ILScopeRef, x.SyntaxAccess, a)
member x.NestedCompPath n moduleKind =
- CompPath(x.ILScopeRef, x.AccessPath@[(n, moduleKind)])
+ CompPath(x.ILScopeRef, x.SyntaxAccess, x.AccessPath@[(n, moduleKind)])
member x.DemangledPath =
x.AccessPath |> List.map (fun (nm, k) -> CompilationPath.DemangleEntityName nm k)
@@ -548,6 +555,8 @@ type CompilationPath =
| FSharpModuleWithSuffix -> String.dropSuffix nm FSharpModuleSuffix
| _ -> nm
+ member x.SyntaxAccess = let (CompPath(_, access, _)) = x in access
+
[]
type EntityOptionalData =
{
@@ -1271,7 +1280,7 @@ type Entity =
| TProvidedNamespaceRepr _ -> failwith "No compiled representation for provided namespace"
| _ ->
#endif
- let ilTypeRefForCompilationPath (CompPath(sref, p)) item =
+ let ilTypeRefForCompilationPath (CompPath(sref, _, p)) item =
let rec top racc p =
match p with
| [] -> ILTypeRef.Create(sref, [], textOfPath (List.rev (item :: racc)))
@@ -2138,19 +2147,78 @@ type ModuleOrNamespaceType(kind: ModuleOrNamespaceKind, vals: QueueList, en
type ModuleOrNamespace = Entity
/// Represents a type or exception definition in the typed AST
-type Tycon = Entity
+type Tycon = Entity
+
+let getNameOfScopeRef sref =
+ match sref with
+ | ILScopeRef.Local -> ""
+ | ILScopeRef.Module mref -> mref.Name
+ | ILScopeRef.Assembly aref -> aref.Name
+ | ILScopeRef.PrimaryAssembly -> ""
+
+let private isInternalCompPath x =
+ match x with
+ | CompPath(ILScopeRef.Local, _, []) -> true
+ | _ -> false
+
+let private (|Public|Internal|Private|) (TAccess p) =
+ match p with
+ | [] -> Public
+ | _ when List.forall isInternalCompPath p -> Internal
+ | _ -> Private
+
+let getSyntaxAccessForCompPath (TAccess a) = match a with | CompPath(_, sa, _) :: _ -> sa | _ -> TypedTree.SyntaxAccess.Unknown
+
+let updateSyntaxAccessForCompPath access syntaxAccess =
+ match access with
+ | CompPath(sc, sa, p) :: rest when sa <> syntaxAccess -> ([CompPath(sc, syntaxAccess, p)]@rest)
+ | _ -> access
/// Represents the constraint on access for a construct
[]
-type Accessibility =
-
+type Accessibility =
/// Indicates the construct can only be accessed from any code in the given type constructor, module or assembly. [] indicates global scope.
| TAccess of compilationPaths: CompilationPath list
-
+
+ member public x.IsPublic = match x with Public -> true | _ -> false
+
+ member public x.IsInternal = match x with Internal -> true | _ -> false
+
+ member public x.IsPrivate = match x with Private -> true | _ -> false
+
[]
member x.DebugText = x.ToString()
- override x.ToString() = "Accessibility(...)"
+ member x.AsILMemberAccess () =
+ match getSyntaxAccessForCompPath x with
+ | TypedTree.SyntaxAccess.Public -> ILMemberAccess.Public
+ | TypedTree.SyntaxAccess.Internal -> ILMemberAccess.Assembly
+ | TypedTree.SyntaxAccess.Private -> ILMemberAccess.Private
+ | _ ->
+ if x.IsPublic then ILMemberAccess.Public
+ elif x.IsInternal then ILMemberAccess.Assembly
+ else ILMemberAccess.Private
+
+ member x.AsILTypeDefAccess () =
+ if x.IsPublic then ILTypeDefAccess.Public
+ else ILTypeDefAccess.Private
+
+ member x.CompilationPaths = match x with | TAccess compilationPaths -> compilationPaths
+
+ override x.ToString() =
+ match x with
+ | TAccess (paths) ->
+ let mangledTextOfCompPath (CompPath(scoref, _, path)) = getNameOfScopeRef scoref + "/" + textOfPath (List.map fst path)
+ let scopename =
+ if x.IsPublic then "public"
+ elif x.IsInternal then "internal"
+ else "private"
+ let paths = String.concat ";" (List.map mangledTextOfCompPath paths)
+ if paths = "" then
+ scopename
+ else
+ $"{scopename} {paths}"
+
/// Represents less-frequently-required data about a type parameter of type inference variable
[]
@@ -2906,8 +2974,8 @@ type Val =
/// Determines if the values is implied by another construct, e.g. a `IsA` property is implied by the union case for A
member x.IsImplied = x.val_flags.IsImplied
- /// Indicates whether the inline declaration for the value indicate that the value must be inlined?
- member x.MustInline = x.InlineInfo.MustInline
+ /// Indicates whether the inline declaration for the value indicate that the value should be inlined?
+ member x.ShouldInline = x.InlineInfo.ShouldInline
/// Indicates whether this value was generated by the compiler.
///
@@ -4065,7 +4133,7 @@ type ValRef =
member x.InlineIfLambda = x.Deref.InlineIfLambda
/// Indicates whether the inline declaration for the value indicate that the value must be inlined?
- member x.MustInline = x.Deref.MustInline
+ member x.ShouldInline = x.Deref.ShouldInline
/// Indicates whether this value was generated by the compiler.
///
@@ -5898,7 +5966,7 @@ type Construct() =
| None ->
let ilScopeRef = st.TypeProviderAssemblyRef
let enclosingName = GetFSharpPathToProvidedType(st, m)
- CompPath(ilScopeRef, enclosingName |> List.map(fun id->id, ModuleOrNamespaceKind.Namespace true))
+ CompPath(ilScopeRef, SyntaxAccess.Unknown, enclosingName |> List.map(fun id->id, ModuleOrNamespaceKind.Namespace true))
| Some p -> p
let pubpath = cpath.NestedPublicPath id
@@ -6127,7 +6195,7 @@ type Construct() =
/// Create the new contents of an overall assembly
static member NewCcuContents sref m nm mty =
- Construct.NewModuleOrNamespace (Some(CompPath(sref, []))) taccessPublic (ident(nm, m)) XmlDoc.Empty [] (MaybeLazy.Strict mty)
+ Construct.NewModuleOrNamespace (Some(CompPath(sref, SyntaxAccess.Unknown, []))) taccessPublic (ident(nm, m)) XmlDoc.Empty [] (MaybeLazy.Strict mty)
/// Create a tycon based on an existing one using the function 'f'.
/// We require that we be given the new parent for the new tycon.
diff --git a/src/Compiler/TypedTree/TypedTree.fsi b/src/Compiler/TypedTree/TypedTree.fsi
index 7f0a0ef4ed3..00aee7a92ef 100644
--- a/src/Compiler/TypedTree/TypedTree.fsi
+++ b/src/Compiler/TypedTree/TypedTree.fsi
@@ -17,6 +17,8 @@ open FSharp.Compiler.TypeProviders
open FSharp.Compiler.Xml
open FSharp.Core.CompilerServices
+val getNameOfScopeRef: sref: ILScopeRef -> string
+
type Stamp = int64
type StampMap<'T> = Map
@@ -34,7 +36,7 @@ type ValInline =
| Never
/// Returns true if the implementation of a value must always be inlined
- member MustInline: bool
+ member ShouldInline: bool
/// A flag associated with values that indicates whether the recursive scope of the value is currently being processed, type
/// if the value has been generalized or not as yet.
@@ -320,9 +322,17 @@ type PublicPath =
member EnclosingPath: string[]
+/// Represents the specified visibility of the accessibility -- used to ensure IL visibility
+[]
+type SyntaxAccess =
+ | Public
+ | Internal
+ | Private
+ | Unknown
+
/// The information ILXGEN needs about the location of an item
type CompilationPath =
- | CompPath of ILScopeRef * (string * ModuleOrNamespaceKind) list
+ | CompPath of ILScopeRef * SyntaxAccess * (string * ModuleOrNamespaceKind) list
/// String 'Module' off an F# module name, if FSharpModuleWithSuffix is used
static member DemangleEntityName: nm: string -> k: ModuleOrNamespaceKind -> string
@@ -341,6 +351,8 @@ type CompilationPath =
member ParentCompPath: CompilationPath
+ member SyntaxAccess: SyntaxAccess
+
[]
type EntityOptionalData =
{
@@ -1424,6 +1436,8 @@ type ModuleOrNamespace = Entity
/// Represents a type or exception definition in the typed AST
type Tycon = Entity
+val updateSyntaxAccessForCompPath: CompilationPath list -> TypedTree.SyntaxAccess -> CompilationPath list
+
/// Represents the constraint on access for a construct
[]
type Accessibility =
@@ -1431,6 +1445,19 @@ type Accessibility =
/// Indicates the construct can only be accessed from any code in the given type constructor, module or assembly. [] indicates global scope.
| TAccess of compilationPaths: CompilationPath list
+ member AsILMemberAccess: unit -> ILMemberAccess
+
+ member AsILTypeDefAccess: unit -> ILTypeDefAccess
+
+ member CompilationPaths: CompilationPath list
+
+ member IsPublic: bool
+
+ member IsInternal: bool
+
+ member IsPrivate: bool
+
+ /// Readable rendering of Accessibility
override ToString: unit -> string
[]
@@ -2155,8 +2182,8 @@ type Val =
/// a true body. These cases are often causes of bugs in the compiler.
member MemberInfo: ValMemberInfo option
- /// Indicates whether the inline declaration for the value indicate that the value must be inlined?
- member MustInline: bool
+ /// Indicates whether the inline declaration for the value indicates that the value should be inlined.
+ member ShouldInline: bool
/// Get the number of 'this'/'self' object arguments for the member. Instance extension members return '1'.
member NumObjArgs: int
@@ -2870,8 +2897,8 @@ type ValRef =
/// Is this a member, if so some more data about the member.
member MemberInfo: ValMemberInfo option
- /// Indicates whether the inline declaration for the value indicate that the value must be inlined?
- member MustInline: bool
+ /// Indicates whether the inline declaration for the value indicate that the value should be inlined?
+ member ShouldInline: bool
/// Get the number of 'this'/'self' object arguments for the member. Instance extension members return '1'.
member NumObjArgs: int
diff --git a/src/Compiler/TypedTree/TypedTreeBasics.fs b/src/Compiler/TypedTree/TypedTreeBasics.fs
index c71994685d3..1fca2981579 100644
--- a/src/Compiler/TypedTree/TypedTreeBasics.fs
+++ b/src/Compiler/TypedTree/TypedTreeBasics.fs
@@ -19,13 +19,6 @@ assert (sizeof = 8)
assert (sizeof = 4)
#endif
-let getNameOfScopeRef sref =
- match sref with
- | ILScopeRef.Local -> ""
- | ILScopeRef.Module mref -> mref.Name
- | ILScopeRef.Assembly aref -> aref.Name
- | ILScopeRef.PrimaryAssembly -> ""
-
/// Metadata on values (names of arguments etc.)
module ValReprInfo =
@@ -436,11 +429,11 @@ let primValRefEq compilingFSharpCore fslibCcu (x: ValRef) (y: ValRef) =
//---------------------------------------------------------------------------
let fullCompPathOfModuleOrNamespace (m: ModuleOrNamespace) =
- let (CompPath(scoref, cpath)) = m.CompilationPath
- CompPath(scoref, cpath@[(m.LogicalName, m.ModuleOrNamespaceType.ModuleOrNamespaceKind)])
+ let (CompPath(scoref, sa, cpath)) = m.CompilationPath
+ CompPath(scoref, sa, cpath@[(m.LogicalName, m.ModuleOrNamespaceType.ModuleOrNamespaceKind)])
// Can cpath2 be accessed given a right to access cpath1. That is, is cpath2 a nested type or namespace of cpath1. Note order of arguments.
-let inline canAccessCompPathFrom (CompPath(scoref1, cpath1)) (CompPath(scoref2, cpath2)) =
+let inline canAccessCompPathFrom (CompPath(scoref1, _, cpath1)) (CompPath(scoref2, _, cpath2)) =
let rec loop p1 p2 =
match p1, p2 with
| (a1, k1) :: rest1, (a2, k2) :: rest2 -> (a1=a2) && (k1=k2) && loop rest1 rest2
@@ -465,12 +458,20 @@ let accessSubstPaths (newPath, oldPath) (TAccess paths) =
let subst cpath = if cpath=oldPath then newPath else cpath
TAccess (List.map subst paths)
-let compPathOfCcu (ccu: CcuThunk) = CompPath(ccu.ILScopeRef, [])
+let compPathOfCcu (ccu: CcuThunk) = CompPath(ccu.ILScopeRef, SyntaxAccess.Unknown, [])
let taccessPublic = TAccess []
-let taccessPrivate accessPath = TAccess [accessPath]
-let compPathInternal = CompPath(ILScopeRef.Local, [])
+let compPathInternal = CompPath(ILScopeRef.Local, SyntaxAccess.Internal, [])
let taccessInternal = TAccess [compPathInternal]
-let combineAccess (TAccess a1) (TAccess a2) = TAccess(a1@a2)
+let taccessPrivate accessPath = let (CompPath(sc,_, paths)) = accessPath in TAccess [CompPath(sc, TypedTree.SyntaxAccess.Private, paths)]
+
+let combineAccess access1 access2 =
+ let (TAccess a1) = access1
+ let (TAccess a2) = access2
+ let combined =
+ if access1 = taccessPublic then updateSyntaxAccessForCompPath (a1@a2) TypedTree.SyntaxAccess.Public
+ elif access1 = taccessInternal then updateSyntaxAccessForCompPath (a1@a2) TypedTree.SyntaxAccess.Internal
+ else (a1@a2)
+ TAccess combined
exception Duplicate of string * string * range
exception NameClash of string * string * string * range * string * string * range
diff --git a/src/Compiler/TypedTree/TypedTreeBasics.fsi b/src/Compiler/TypedTree/TypedTreeBasics.fsi
index ea1f5979262..c3edc900871 100644
--- a/src/Compiler/TypedTree/TypedTreeBasics.fsi
+++ b/src/Compiler/TypedTree/TypedTreeBasics.fsi
@@ -12,8 +12,6 @@ open FSharp.Compiler.Syntax
open FSharp.Compiler.Text
open FSharp.Compiler.TypedTree
-val getNameOfScopeRef: sref: ILScopeRef -> string
-
/// Metadata on values (names of arguments etc.
module ValReprInfo =
diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs
index 8ef6ce62182..68b924df6a2 100644
--- a/src/Compiler/TypedTree/TypedTreeOps.fs
+++ b/src/Compiler/TypedTree/TypedTreeOps.fs
@@ -1198,7 +1198,7 @@ let mkMultiLambdaTy g m vs bodyTy = mkFunTy g (typeOfLambdaArg m vs) bodyTy
/// the library arising from env.fs. Part of this means that we have to be able to resolve these
/// references. This function artificially forces the existence of a module or namespace at a
/// particular point in order to do this.
-let ensureCcuHasModuleOrNamespaceAtPath (ccu: CcuThunk) path (CompPath(_, cpath)) xml =
+let ensureCcuHasModuleOrNamespaceAtPath (ccu: CcuThunk) path (CompPath(_, sa, cpath)) xml =
let scoref = ccu.ILScopeRef
let rec loop prior_cpath (path: Ident list) cpath (modul: ModuleOrNamespace) =
let mtype = modul.ModuleOrNamespaceType
@@ -1207,7 +1207,7 @@ let ensureCcuHasModuleOrNamespaceAtPath (ccu: CcuThunk) path (CompPath(_, cpath)
let modName = hpath.idText
if not (Map.containsKey modName mtype.AllEntitiesByCompiledAndLogicalMangledNames) then
let mty = Construct.NewEmptyModuleOrNamespaceType mkind
- let cpath = CompPath(scoref, prior_cpath)
+ let cpath = CompPath(scoref, sa, prior_cpath)
let smodul = Construct.NewModuleOrNamespace (Some cpath) taccessPublic hpath xml [] (MaybeLazy.Strict mty)
mtype.AddModuleOrNamespaceByMutation smodul
let modul = Map.find modName mtype.AllEntitiesByCompiledAndLogicalMangledNames
@@ -4150,7 +4150,7 @@ module DebugPrint =
let typeOfValL (v: Val) =
valL v
- ^^ (if v.MustInline then wordL (tagText "inline ") else emptyL)
+ ^^ (if v.ShouldInline then wordL (tagText "inline ") else emptyL)
^^ (if v.IsMutable then wordL(tagText "mutable ") else emptyL)
^^ (if layoutTypes then wordL (tagText ":") ^^ typeL v.Type else emptyL)
@@ -4940,20 +4940,36 @@ let rec accImplHidingInfoAtAssemblyBoundary mdef acc =
let ComputeImplementationHidingInfoAtAssemblyBoundary mty acc =
accImplHidingInfoAtAssemblyBoundary mty acc
+let DoRemap setF remapF =
+ let rec remap mrmi x =
+
+ match mrmi with
+ | [] -> x
+ | (rpi, mhi) :: rest ->
+ // Explicitly hidden?
+ if Zset.contains x (setF mhi) then
+ x
+ else
+ remap rest (remapF rpi x)
+ fun mrmi x -> remap mrmi x
+
+let DoRemapTycon mrmi x = DoRemap (fun mhi -> mhi.HiddenTycons) (fun rpi x -> (remapTyconRef rpi.tyconRefRemap (mkLocalTyconRef x)).Deref) mrmi x
+
+let DoRemapVal mrmi x = DoRemap (fun mhi -> mhi.HiddenVals) (fun rpi x -> (remapValRef rpi (mkLocalValRef x)).Deref) mrmi x
+
//--------------------------------------------------------------------------
// Compute instances of the above for mexpr -> mty
//--------------------------------------------------------------------------
-
let IsHidden setF accessF remapF =
- let rec check mrmi x =
- // Internal/private?
- not (canAccessFromEverywhere (accessF x)) ||
- (match mrmi with
- | [] -> false // Ah! we escaped to freedom!
- | (rpi, mhi) :: rest ->
- // Explicitly hidden?
- Zset.contains x (setF mhi) ||
- // Recurse...
+ let rec check mrmi x =
+ // Internal/private?
+ not (canAccessFromEverywhere (accessF x)) ||
+ (match mrmi with
+ | [] -> false // Ah! we escaped to freedom!
+ | (rpi, mhi) :: rest ->
+ // Explicitly hidden?
+ Zset.contains x (setF mhi) ||
+ // Recurse...
check rest (remapF rpi x))
check
@@ -5752,7 +5768,7 @@ and mapImmediateValsAndTycons ft fv (x: ModuleOrNamespaceType) =
let vals = x.AllValsAndMembers |> QueueList.map fv
let tycons = x.AllEntities |> QueueList.map ft
ModuleOrNamespaceType(x.ModuleOrNamespaceKind, vals, tycons)
-
+
and copyVal compgen (v: Val) =
match compgen with
| OnlyCloneExprVals when v.IsMemberOrModuleBinding -> v
@@ -6129,10 +6145,7 @@ and copyAndRemapAndBindModTy ctxt compgen tmenv mty =
let tycons = allEntitiesOfModuleOrNamespaceTy mty
let vs = allValsOfModuleOrNamespaceTy mty
let _, _, tmenvinner = copyAndRemapAndBindTyconsAndVals ctxt compgen tmenv tycons vs
- remapModTy compgen tmenvinner mty, tmenvinner
-
-and remapModTy _compgen tmenv mty =
- mapImmediateValsAndTycons (renameTycon tmenv) (renameVal tmenv) mty
+ (mapImmediateValsAndTycons (renameTycon tmenvinner) (renameVal tmenvinner) mty), tmenvinner
and renameTycon tyenv x =
let tcref =
diff --git a/src/Compiler/TypedTree/TypedTreeOps.fsi b/src/Compiler/TypedTree/TypedTreeOps.fsi
index bec1e031185..534eefc7762 100755
--- a/src/Compiler/TypedTree/TypedTreeOps.fsi
+++ b/src/Compiler/TypedTree/TypedTreeOps.fsi
@@ -1331,6 +1331,12 @@ val MakeExportRemapping: CcuThunk -> ModuleOrNamespace -> Remap
/// Make a remapping table for viewing a module or namespace 'from the outside'
val ApplyExportRemappingToEntity: TcGlobals -> Remap -> ModuleOrNamespace -> ModuleOrNamespace
+/// Get the value including fsi remapping
+val DoRemapTycon: (Remap * SignatureHidingInfo) list -> Tycon -> Tycon
+
+/// Get the value including fsi remapping
+val DoRemapVal: (Remap * SignatureHidingInfo) list -> Val -> Val
+
/// Determine if a type definition is hidden by a signature
val IsHiddenTycon: (Remap * SignatureHidingInfo) list -> Tycon -> bool
diff --git a/src/Compiler/TypedTree/TypedTreePickle.fs b/src/Compiler/TypedTree/TypedTreePickle.fs
index f2fd9887772..fe71dc1429f 100644
--- a/src/Compiler/TypedTree/TypedTreePickle.fs
+++ b/src/Compiler/TypedTree/TypedTreePickle.fs
@@ -1777,7 +1777,7 @@ let p_istype x st =
| ModuleOrType -> p_byte 1 st
| Namespace _ -> p_byte 2 st
-let p_cpath (CompPath(a, b)) st =
+let p_cpath (CompPath(a, _, b)) st =
p_tup2 p_ILScopeRef (p_list (p_tup2 p_string p_istype)) (a, b) st
let u_ranges st = u_option (u_tup2 u_range u_range) st
@@ -1792,7 +1792,7 @@ let u_istype st =
let u_cpath st =
let a, b = u_tup2 u_ILScopeRef (u_list (u_tup2 u_string u_istype)) st
- CompPath(a, b)
+ CompPath(a, SyntaxAccess.Unknown, b)
let rec p_tycon_repr x st =
// The leading "p_byte 1" and "p_byte 0" come from the F# 2.0 format, which used an option value at this point.
diff --git a/src/Compiler/lex.fsl b/src/Compiler/lex.fsl
index 958c2fa51ea..1e48cc8d0a2 100644
--- a/src/Compiler/lex.fsl
+++ b/src/Compiler/lex.fsl
@@ -120,7 +120,7 @@ let checkExprGreaterColonOp (lexbuf:UnicodeLexing.Lexbuf) =
let unexpectedChar lexbuf =
LEX_FAILURE (FSComp.SR.lexUnexpectedChar(lexeme lexbuf))
-let startString args (lexbuf: UnicodeLexing.Lexbuf) altStartForStringEnd =
+let startString args (lexbuf: UnicodeLexing.Lexbuf) =
let buf = ByteBuffer.Create StringCapacity
let m = lexbuf.LexemeRange
let startp = lexbuf.StartPos
@@ -160,7 +160,7 @@ let startString args (lexbuf: UnicodeLexing.Lexbuf) altStartForStringEnd =
if isPart then
INTERP_STRING_PART (s, cont)
else
- INTERP_STRING_END (s, altStartForStringEnd, cont)
+ INTERP_STRING_END (s, cont)
else
let s = Lexhelp.stringBufferAsString buf
let synStringKind =
@@ -587,7 +587,7 @@ rule token (args: LexArgs) (skip: bool) = parse
else mlOnly m args skip lexbuf }
| '"'
- { let buf, fin, m = startString args lexbuf None
+ { let buf, fin, m = startString args lexbuf
// Single quote in triple quote ok, others disallowed
match args.stringNest with
@@ -600,7 +600,7 @@ rule token (args: LexArgs) (skip: bool) = parse
else singleQuoteString (buf, fin, m, LexerStringKind.String, args) skip lexbuf }
| '$' '"' '"' '"'
- { let buf, fin, m = startString args lexbuf None
+ { let buf, fin, m = startString args lexbuf
// Single quote in triple quote ok, others disallowed
match args.stringNest with
@@ -612,7 +612,7 @@ rule token (args: LexArgs) (skip: bool) = parse
else tripleQuoteString (buf, fin, m, LexerStringKind.InterpolatedStringFirst, args) skip lexbuf }
| ('$'+) '"' '"' '"'
- { let buf, fin, m = startString args lexbuf None
+ { let buf, fin, m = startString args lexbuf
if lexbuf.SupportsFeature LanguageFeature.ExtendedStringInterpolation then
// Single quote in triple quote ok, others disallowed
@@ -635,7 +635,7 @@ rule token (args: LexArgs) (skip: bool) = parse
}
| '$' '"'
- { let buf,fin,m = startString args lexbuf None
+ { let buf,fin,m = startString args lexbuf
// Single quote in triple quote ok, others disallowed
match args.stringNest with
@@ -649,7 +649,7 @@ rule token (args: LexArgs) (skip: bool) = parse
singleQuoteString (buf, fin, m, LexerStringKind.InterpolatedStringFirst, args) skip lexbuf }
| '"' '"' '"'
- { let buf, fin, m = startString args lexbuf None
+ { let buf, fin, m = startString args lexbuf
args.interpolationDelimiterLength <- 0
@@ -664,7 +664,7 @@ rule token (args: LexArgs) (skip: bool) = parse
tripleQuoteString (buf, fin, m, LexerStringKind.String, args) skip lexbuf }
| '@' '"'
- { let buf, fin, m = startString args lexbuf None
+ { let buf, fin, m = startString args lexbuf
// Single quote in triple quote ok, others disallowed
match args.stringNest with
@@ -679,7 +679,7 @@ rule token (args: LexArgs) (skip: bool) = parse
verbatimString (buf, fin, m, LexerStringKind.String, args) skip lexbuf }
| ("$@" | "@$") '"'
- { let buf, fin, m = startString args lexbuf None
+ { let buf, fin, m = startString args lexbuf
// Single quote in triple quote ok, others disallowed
match args.stringNest with
@@ -914,7 +914,11 @@ rule token (args: LexArgs) (skip: bool) = parse
token args skip lexbuf
| (1, style, _, altR, _r) :: rest ->
args.stringNest <- rest
- let buf, fin, m = startString args lexbuf altR
+ altR
+ |> Option.iter (fun r ->
+ let n = r.StartColumn - lexbuf.StartPos.Column
+ lexbuf.StartPos <- lexbuf.StartPos.ShiftColumnBy(n))
+ let buf, fin, m = startString args lexbuf
if not skip then
STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, style, LexerStringKind.InterpolatedStringPart, args.interpolationDelimiterLength, m))
else
diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy
index 36e8d0838c8..4080fc7ec8b 100644
--- a/src/Compiler/pars.fsy
+++ b/src/Compiler/pars.fsy
@@ -38,7 +38,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) ->
%token INTERP_STRING_BEGIN_END
%token INTERP_STRING_BEGIN_PART
%token INTERP_STRING_PART
-%token INTERP_STRING_END
+%token INTERP_STRING_END
%token LBRACE RBRACE
%token KEYWORD_STRING // Like __SOURCE_DIRECTORY__
@@ -6774,14 +6774,7 @@ interpolatedStringFill:
interpolatedStringParts:
| INTERP_STRING_END
- {
- let (s, altStart, _) = $1
- let mOrig = rhs parseState 1
- let m =
- match altStart with
- | Some r -> unionRanges r mOrig
- | None -> mOrig
- [ SynInterpolatedStringPart.String(s, m) ] }
+ { [ SynInterpolatedStringPart.String(fst $1, rhs parseState 1) ] }
| INTERP_STRING_PART interpolatedStringFill interpolatedStringParts
{ SynInterpolatedStringPart.String(fst $1, rhs parseState 1) :: SynInterpolatedStringPart.FillExpr $2 :: $3 }
diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf
index d4142d783fa..c46e652979d 100644
--- a/src/Compiler/xlf/FSComp.txt.cs.xlf
+++ b/src/Compiler/xlf/FSComp.txt.cs.xlf
@@ -297,6 +297,11 @@
Enforce AttributeTargets on functions
+
+ Enforce AttributeTargets on union case declarations
+ Enforce AttributeTargets on union case declarations
+
+
Raises errors for non-virtual members overrides
Vyvolá chyby pro přepsání jiných než virtuálních členů
@@ -827,6 +832,11 @@
Název výstupního souboru pdb se nemůže shodovat s výstupním názvem souboru sestavení pomocí --pdb:filename.pdb.
+
+ Generate assembly with IL visibility that matches the source code visibility
+ Generate assembly with IL visibility that matches the source code visibility
+
+
Produce a reference assembly, instead of a full assembly, as the primary output
Vytvoří referenční sestavení místo úplného sestavení jako primární výstup.
@@ -6217,11 +6227,6 @@
Hodnota {0} má označení inline, ale není svázaná s prostředím optimalizace.
-
- Local value {0} not found during optimization
- Lokální hodnota {0} se během optimalizace nenašla.
-
-
A value marked as 'inline' has an unexpected value
Hodnota s označením inline má neočekávanou hodnotu.
diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf
index fa0904ef50f..56f7493d1d1 100644
--- a/src/Compiler/xlf/FSComp.txt.de.xlf
+++ b/src/Compiler/xlf/FSComp.txt.de.xlf
@@ -297,6 +297,11 @@
Enforce AttributeTargets on functions
+
+ Enforce AttributeTargets on union case declarations
+ Enforce AttributeTargets on union case declarations
+
+
Raises errors for non-virtual members overrides
Löst Fehler für Außerkraftsetzungen nicht virtueller Member aus.
@@ -827,6 +832,11 @@
Der Name der PDB-Ausgabedatei kann nicht mit dem Ausgabedateinamen für den Build übereinstimmen, verwenden Sie --pdb:filename.pdb
+
+ Generate assembly with IL visibility that matches the source code visibility
+ Generate assembly with IL visibility that matches the source code visibility
+
+
Produce a reference assembly, instead of a full assembly, as the primary output
Erstellen einer Referenzassembly anstelle einer vollständigen Assembly als primäre Ausgabe
@@ -6217,11 +6227,6 @@
Der Wert "{0}" war als inline markiert, aber nicht in der Optimierungsumgebung gebunden.
-
- Local value {0} not found during optimization
- Der lokale Wert "{0}" wurde während der Optimierung nicht gefunden.
-
-
A value marked as 'inline' has an unexpected value
Ein als "inline" markierter Wert hat einen unerwarteten Wert.
diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf
index 2d5ada63574..a35a6bce598 100644
--- a/src/Compiler/xlf/FSComp.txt.es.xlf
+++ b/src/Compiler/xlf/FSComp.txt.es.xlf
@@ -297,6 +297,11 @@
Enforce AttributeTargets on functions
+
+ Enforce AttributeTargets on union case declarations
+ Enforce AttributeTargets on union case declarations
+
+
Raises errors for non-virtual members overrides
Genera errores para invalidaciones de miembros no virtuales
@@ -827,6 +832,11 @@
El nombre del archivo de salida pdb no puede coincidir con el nombre de archivo de salida de compilación. Use --pdb:filename.pdb
+
+ Generate assembly with IL visibility that matches the source code visibility
+ Generate assembly with IL visibility that matches the source code visibility
+
+
Produce a reference assembly, instead of a full assembly, as the primary output
Generar un ensamblado de referencia, en lugar de un ensamblado completo, como salida principal
@@ -6217,11 +6227,6 @@
El valor '{0}' estaba marcado como inline pero no estaba enlazado en el entorno de optimización.
-
- Local value {0} not found during optimization
- No se encontró el valor local {0} durante la optimización.
-
-
A value marked as 'inline' has an unexpected value
Un valor marcado como 'inline' tiene un valor inesperado.
diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf
index da3c6f4b9b6..aeeb53ac93d 100644
--- a/src/Compiler/xlf/FSComp.txt.fr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.fr.xlf
@@ -297,6 +297,11 @@
Enforce AttributeTargets on functions
+
+ Enforce AttributeTargets on union case declarations
+ Enforce AttributeTargets on union case declarations
+
+
Raises errors for non-virtual members overrides
Déclenche des erreurs pour les remplacements de membres non virtuels
@@ -827,6 +832,11 @@
Le nom du fichier de sortie pdb ne peut pas correspondre au nom de fichier de sortie de build utilisé --pdb:filename.pdb.
+
+ Generate assembly with IL visibility that matches the source code visibility
+ Generate assembly with IL visibility that matches the source code visibility
+
+
Produce a reference assembly, instead of a full assembly, as the primary output
Produire un assembly de référence, au lieu d’un assembly complet, en tant que sortie principale
@@ -6217,11 +6227,6 @@
La valeur '{0}' a été marquée comme inline mais n'a pas été liée dans l'environnement d'optimisation
-
- Local value {0} not found during optimization
- Valeur locale {0} introuvable durant l'optimisation
-
-
A value marked as 'inline' has an unexpected value
Une valeur marquée comme 'inline' a une valeur inattendue
diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf
index 010e34a81a2..390160ee95e 100644
--- a/src/Compiler/xlf/FSComp.txt.it.xlf
+++ b/src/Compiler/xlf/FSComp.txt.it.xlf
@@ -297,6 +297,11 @@
Enforce AttributeTargets on functions
+
+ Enforce AttributeTargets on union case declarations
+ Enforce AttributeTargets on union case declarations
+
+
Raises errors for non-virtual members overrides
Genera errori per gli override dei membri non virtuali
@@ -827,6 +832,11 @@
Il nome del file di output pdb non può corrispondere all’uso del nome file di output della compilazione --pdb:filename.pdb
+
+ Generate assembly with IL visibility that matches the source code visibility
+ Generate assembly with IL visibility that matches the source code visibility
+
+
Produce a reference assembly, instead of a full assembly, as the primary output
Produce un assembly di riferimento, anziché un assembly completo, come output primario
@@ -6217,11 +6227,6 @@
Il valore '{0}' è stato contrassegnato come inline, tuttavia non è stato associato nell'ambiente di ottimizzazione
-
- Local value {0} not found during optimization
- Valore locale {0} non trovato durante l'ottimizzazione
-
-
A value marked as 'inline' has an unexpected value
Valore imprevisto contrassegnato come 'inline'
diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf
index 8a92ac2ea9e..e57dac6f312 100644
--- a/src/Compiler/xlf/FSComp.txt.ja.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ja.xlf
@@ -297,6 +297,11 @@
Enforce AttributeTargets on functions
+
+ Enforce AttributeTargets on union case declarations
+ Enforce AttributeTargets on union case declarations
+
+
Raises errors for non-virtual members overrides
仮想メンバー以外のオーバーライドに対してエラーを発生させます
@@ -827,6 +832,11 @@
PDB 出力ファイル名がビルド出力ファイル名と一致しません - --pdb:filename.pdb を使用してください
+
+ Generate assembly with IL visibility that matches the source code visibility
+ Generate assembly with IL visibility that matches the source code visibility
+
+
Produce a reference assembly, instead of a full assembly, as the primary output
完全なアセンブリではなく、参照アセンブリをプライマリ出力として生成します
@@ -6217,11 +6227,6 @@
値 '{0}' は 'inline' とマークされましたが、最適化環境ではバインドされません
-
- Local value {0} not found during optimization
- 最適化中にローカルの値 {0} が見つかりませんでした
-
-
A value marked as 'inline' has an unexpected value
'inline' とマークされた値に予期しない値が含まれます
diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf
index 51778bd4145..2d6a4e5e22b 100644
--- a/src/Compiler/xlf/FSComp.txt.ko.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ko.xlf
@@ -297,6 +297,11 @@
Enforce AttributeTargets on functions
+
+ Enforce AttributeTargets on union case declarations
+ Enforce AttributeTargets on union case declarations
+
+
Raises errors for non-virtual members overrides
비가상 멤버 재정의에 대한 오류 발생
@@ -827,6 +832,11 @@
pdb 출력 파일 이름은 빌드 출력 파일 이름 사용 --pdb:filename.pdb와 일치할 수 없습니다.
+
+ Generate assembly with IL visibility that matches the source code visibility
+ Generate assembly with IL visibility that matches the source code visibility
+
+
Produce a reference assembly, instead of a full assembly, as the primary output
주 출력으로 전체 어셈블리 대신 참조 어셈블리를 생성합니다.
@@ -6217,11 +6227,6 @@
값 '{0}'이(가) inline으로 표시되었지만 최적화 환경에 바인딩되지 않았습니다.
-
- Local value {0} not found during optimization
- 최적화하는 동안 로컬 값 {0}을(를) 찾을 수 없습니다.
-
-
A value marked as 'inline' has an unexpected value
'inline'으로 표시된 값에 예기치 않은 값이 있습니다.
diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf
index a8a3f05ba9a..db56cd3ba49 100644
--- a/src/Compiler/xlf/FSComp.txt.pl.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pl.xlf
@@ -297,6 +297,11 @@
Enforce AttributeTargets on functions
+
+ Enforce AttributeTargets on union case declarations
+ Enforce AttributeTargets on union case declarations
+
+
Raises errors for non-virtual members overrides
Zgłasza błędy w przypadku przesłonięć elementów innych niż wirtualne
@@ -827,6 +832,11 @@
Nazwa pliku wyjściowego pdb nie może być zgodna z nazwą pliku wyjściowego kompilacji, użyj parametru --pdb:filename.pdb
+
+ Generate assembly with IL visibility that matches the source code visibility
+ Generate assembly with IL visibility that matches the source code visibility
+
+
Produce a reference assembly, instead of a full assembly, as the primary output
Utwórz zestaw odwołania zamiast pełnego zestawu jako podstawowe dane wyjściowe
@@ -6217,11 +6227,6 @@
Wartość „{0}” została oznaczona jako śródwierszowa, ale nie powiązano jej w środowisku optymalizacji
-
- Local value {0} not found during optimization
- Nie znaleziono wartości lokalnej {0} podczas optymalizacji
-
-
A value marked as 'inline' has an unexpected value
Wartość oznaczona jako „inline” ma nieoczekiwaną wartość
diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
index 1f62f9a3d04..7566fb49ae1 100644
--- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
@@ -297,6 +297,11 @@
Enforce AttributeTargets on functions
+
+ Enforce AttributeTargets on union case declarations
+ Enforce AttributeTargets on union case declarations
+
+
Raises errors for non-virtual members overrides
Gera erros para substituições de membros não virtuais
@@ -827,6 +832,11 @@
O nome do arquivo de saída pdb não pode corresponder ao nome do arquivo de saída do build. Use --pdb:filename.pdb
+
+ Generate assembly with IL visibility that matches the source code visibility
+ Generate assembly with IL visibility that matches the source code visibility
+
+
Produce a reference assembly, instead of a full assembly, as the primary output
Produzir um assembly de referência, em vez de um assembly completo, como a saída primária
@@ -6217,11 +6227,6 @@
O valor '{0}' foi marcado como embutido, mas não está associado no ambiente de otimização
-
- Local value {0} not found during optimization
- O valor local {0} não foi encontrado durante a otimização
-
-
A value marked as 'inline' has an unexpected value
Um valor marcado como 'embutido' possui um valor inesperado
diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf
index 64ce92b6125..90c39f565ee 100644
--- a/src/Compiler/xlf/FSComp.txt.ru.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ru.xlf
@@ -297,6 +297,11 @@
Enforce AttributeTargets on functions
+
+ Enforce AttributeTargets on union case declarations
+ Enforce AttributeTargets on union case declarations
+
+
Raises errors for non-virtual members overrides
Вызывает ошибки при переопределениях невиртуальных элементов
@@ -827,6 +832,11 @@
Имя выходного файла pdb не может совпадать с именем выходного файла сборки. Используйте --pdb:filename.pdb
+
+ Generate assembly with IL visibility that matches the source code visibility
+ Generate assembly with IL visibility that matches the source code visibility
+
+
Produce a reference assembly, instead of a full assembly, as the primary output
Создайте базовую сборку вместо полной сборки в качестве основных выходных данных
@@ -6217,11 +6227,6 @@
Значение "{0}" отмечено как "inline", однако не было привязано в среде оптимизации
-
- Local value {0} not found during optimization
- В процессе оптимизации не найдено локальное значение {0}
-
-
A value marked as 'inline' has an unexpected value
Недопустимое значение для значения, отмеченного как "inline"
diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf
index d77dfd672ec..496bc35ef95 100644
--- a/src/Compiler/xlf/FSComp.txt.tr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.tr.xlf
@@ -297,6 +297,11 @@
Enforce AttributeTargets on functions
+
+ Enforce AttributeTargets on union case declarations
+ Enforce AttributeTargets on union case declarations
+
+
Raises errors for non-virtual members overrides
Sanal olmayan üyelerde geçersiz kılmalar için hatalar oluştur
@@ -827,6 +832,11 @@
pdb çıkış dosyası adı, derleme çıkış dosya adı kullanımı --pdb:filename.pdb ile eşleşmiyor
+
+ Generate assembly with IL visibility that matches the source code visibility
+ Generate assembly with IL visibility that matches the source code visibility
+
+
Produce a reference assembly, instead of a full assembly, as the primary output
Birincil çıktı olarak, tam bir derleme yerine, başvuru bütünleştirilmiş kodu üretin
@@ -6217,11 +6227,6 @@
'{0}' değeri satır içi olarak işaretlenmiş ancak iyileştirme ortamında bağlanmamış
-
- Local value {0} not found during optimization
- İyileştirme sırasında {0} yerel değeri bulunamadı
-
-
A value marked as 'inline' has an unexpected value
'inline' olarak işaretlenmiş değerde beklenmeyen bir değer var
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
index 5393d25202a..94bd2ea062c 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
@@ -297,6 +297,11 @@
Enforce AttributeTargets on functions
+
+ Enforce AttributeTargets on union case declarations
+ Enforce AttributeTargets on union case declarations
+
+
Raises errors for non-virtual members overrides
引发非虚拟成员替代的错误
@@ -827,6 +832,11 @@
pdb 输出文件名不能与生成输出文件名 use --pdb: filename.pdb 匹配
+
+ Generate assembly with IL visibility that matches the source code visibility
+ Generate assembly with IL visibility that matches the source code visibility
+
+
Produce a reference assembly, instead of a full assembly, as the primary output
生成引用程序集而不是完整程序集作为主输出
@@ -6217,11 +6227,6 @@
值“{0}”已标记为“inline”,但其未在优化环境中绑定
-
- Local value {0} not found during optimization
- 优化过程中未找到本地值 {0}
-
-
A value marked as 'inline' has an unexpected value
标记为“inline”的值具有意外的值
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
index f75fc155fde..9334199ba0f 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
@@ -297,6 +297,11 @@
Enforce AttributeTargets on functions
+
+ Enforce AttributeTargets on union case declarations
+ Enforce AttributeTargets on union case declarations
+
+
Raises errors for non-virtual members overrides
引發非虛擬成員覆寫的錯誤
@@ -827,6 +832,11 @@
pdb 輸出檔案名與使用 --pdb:filename.pdb 的建置輸出檔案名不相符
+
+ Generate assembly with IL visibility that matches the source code visibility
+ Generate assembly with IL visibility that matches the source code visibility
+
+
Produce a reference assembly, instead of a full assembly, as the primary output
產生參考組件,而非完整組件作為主要輸出
@@ -6217,11 +6227,6 @@
值 '{0}' 已標記為內嵌,但是未在最佳化環境中繫結
-
- Local value {0} not found during optimization
- 最佳化期間找不到區域數值 {0}
-
-
A value marked as 'inline' has an unexpected value
標記為 'inline' 的值有未預期的值
diff --git a/src/FSharp.Core/FSharp.Core.fsproj b/src/FSharp.Core/FSharp.Core.fsproj
index cf267f6f914..c2ad1d456a3 100644
--- a/src/FSharp.Core/FSharp.Core.fsproj
+++ b/src/FSharp.Core/FSharp.Core.fsproj
@@ -25,10 +25,11 @@
$(OtherFlags) --nowarn:3513
$(OtherFlags) --compiling-fslib --compiling-fslib-40 --maxerrors:100 --extraoptimizationloops:1
+
+ $(OtherFlags) --realsig-
true
true
-
true
FSharp.Core
$(FSCorePackageVersion)
diff --git a/src/FSharp.Core/array.fs b/src/FSharp.Core/array.fs
index a2797467b7c..344d7e3e7cf 100644
--- a/src/FSharp.Core/array.fs
+++ b/src/FSharp.Core/array.fs
@@ -2,6 +2,8 @@
namespace Microsoft.FSharp.Collections
+//#nowarn "1118" // 'Make' marked 'inline', perhaps because a recursive value was marked 'inline'
+
open System
open System.Diagnostics
open System.Collections.Generic
@@ -2081,10 +2083,10 @@ module Array =
// The following two parameters were benchmarked and found to be optimal.
// Benchmark was run using: 11th Gen Intel Core i9-11950H 2.60GHz, 1 CPU, 16 logical and 8 physical cores
- let private maxPartitions = Environment.ProcessorCount // The maximum number of partitions to use
- let private minChunkSize = 256 // The minimum size of a chunk to be sorted in parallel
+ let maxPartitions = Environment.ProcessorCount // The maximum number of partitions to use
+ let minChunkSize = 256 // The minimum size of a chunk to be sorted in parallel
- let private createPartitionsUpToWithMinChunkSize maxIdxExclusive minChunkSize (array: 'T array) =
+ let createPartitionsUpToWithMinChunkSize maxIdxExclusive minChunkSize (array: 'T array) =
[|
let chunkSize =
match maxIdxExclusive with
@@ -2101,7 +2103,7 @@ module Array =
yield new ArraySegment<'T>(array, offset, maxIdxExclusive - offset)
|]
- let private createPartitionsUpTo maxIdxExclusive (array: 'T array) =
+ let createPartitionsUpTo maxIdxExclusive (array: 'T array) =
createPartitionsUpToWithMinChunkSize maxIdxExclusive minChunkSize array
(* This function is there also as a support vehicle for other aggregations.
diff --git a/src/FSharp.Core/fslib-extra-pervasives.fs b/src/FSharp.Core/fslib-extra-pervasives.fs
index def5d42c2e5..b62d5b16eb8 100644
--- a/src/FSharp.Core/fslib-extra-pervasives.fs
+++ b/src/FSharp.Core/fslib-extra-pervasives.fs
@@ -13,6 +13,7 @@ module ExtraTopLevelOperators =
open Microsoft.FSharp.Core.Operators
open Microsoft.FSharp.Collections
open Microsoft.FSharp.Control
+ open Microsoft.FSharp.Linq
open Microsoft.FSharp.Primitives.Basics
open Microsoft.FSharp.Core.CompilerServices
@@ -334,7 +335,7 @@ module ExtraTopLevelOperators =
let (|Lazy|) (input: Lazy<_>) =
input.Force()
- let query = Microsoft.FSharp.Linq.QueryBuilder()
+ let query = QueryBuilder()
namespace Microsoft.FSharp.Core.CompilerServices
diff --git a/src/FSharp.Core/fslib-extra-pervasives.fsi b/src/FSharp.Core/fslib-extra-pervasives.fsi
index bd4bf0ee8b5..ffd6f6f6a00 100644
--- a/src/FSharp.Core/fslib-extra-pervasives.fsi
+++ b/src/FSharp.Core/fslib-extra-pervasives.fsi
@@ -13,6 +13,8 @@ module ExtraTopLevelOperators =
open Microsoft.FSharp.Core
open Microsoft.FSharp.Control
open Microsoft.FSharp.Collections
+ open Microsoft.FSharp.Control
+ open Microsoft.FSharp.Linq
open Microsoft.FSharp.Quotations
/// Print to stdout using the given format.
@@ -129,7 +131,7 @@ module ExtraTopLevelOperators =
///
///
[]
- val async: Microsoft.FSharp.Control.AsyncBuilder
+ val async: AsyncBuilder
/// Converts the argument to 32-bit float.
///
@@ -358,7 +360,7 @@ module ExtraTopLevelOperators =
///
/// Evaluates to [4; 4; 12; 12].
///
- val query: Microsoft.FSharp.Linq.QueryBuilder
+ val query: QueryBuilder
namespace Microsoft.FSharp.Core.CompilerServices
diff --git a/src/FSharp.Core/prim-types.fs b/src/FSharp.Core/prim-types.fs
index a6d5bcc6ac0..346c1a64e0e 100644
--- a/src/FSharp.Core/prim-types.fs
+++ b/src/FSharp.Core/prim-types.fs
@@ -1549,8 +1549,8 @@ namespace Microsoft.FSharp.Core
// Run in either PER or ER mode. In PER mode, equality involving a NaN returns "false".
// In ER mode, equality on two NaNs returns "true".
//
- // If "er" is true the "iec" is fsEqualityComparerNoHashingER
- // If "er" is false the "iec" is fsEqualityComparerNoHashingPER
+ // If "er" is true the "iec" is fsEqualityComparerUnlimitedHashingER
+ // If "er" is false the "iec" is fsEqualityComparerUnlimitedHashingPER
let rec GenericEqualityObj (er:bool) (iec:IEqualityComparer) ((xobj:obj),(yobj:obj)) : bool =
(*if objEq xobj yobj then true else *)
match xobj,yobj with
@@ -1654,28 +1654,186 @@ namespace Microsoft.FSharp.Core
else i <- i + 1
res
+ let isStructuralEquatable (ty: Type) = typeof.IsAssignableFrom ty
+ let isArray (ty: Type) = ty.IsArray || (typeof.IsAssignableFrom ty)
+ let isFloat (ty: Type) = Type.op_Equality(ty, typeof) || Type.op_Equality(ty, typeof)
+
+ let isValueTuple (ty: Type) =
+ if ty.IsGenericType
+ then
+ let typeDef = ty.GetGenericTypeDefinition().FullName
+ typeDef.Equals "System.ValueTuple`1" ||
+ typeDef.Equals "System.ValueTuple`2" ||
+ typeDef.Equals "System.ValueTuple`3" ||
+ typeDef.Equals "System.ValueTuple`4" ||
+ typeDef.Equals "System.ValueTuple`5" ||
+ typeDef.Equals "System.ValueTuple`6" ||
+ typeDef.Equals "System.ValueTuple`7" ||
+ typeDef.Equals "System.ValueTuple`8"
+ else false
+
+ let isOptionOrResult (ty: Type) =
+ if ty.IsGenericType
+ then
+ let typeDef = ty.GetGenericTypeDefinition().FullName
+ typeDef.Equals "Microsoft.FSharp.Core.FSharpOption`1" ||
+ typeDef.Equals "Microsoft.FSharp.Core.FSharpValueOption`1" ||
+ typeDef.Equals "Microsoft.FSharp.Core.FSharpResult`2"
+ else false
+
+ let isNullable (ty: Type) =
+ ty.IsGenericType &&
+ ty.GetGenericTypeDefinition().FullName.Equals "System.Nullable`1"
+
+ // A bit hard to grasp right away but think of this as if it was:
+ //
+ // let canUseDefaultEqualityComparer rootType =
+ // let processed = HashSet()
+ //
+ // let rec checkTypes types =
+ // match types with
+ // | [] -> true
+ // | ty :: rest ->
+ // if (processed.Add ty) then
+ // ... do all the checks
+ // checkTypes rest
+ // else
+ // checkTypes rest
+ //
+ // checkTypes [ rootType ]
+ //
+ // ... it's just that here in prim types, not much stuff is available yet
+ // so we have to resort to very basic techniques
+ let canUseDefaultEqualityComparer er rootType =
+ let processed = HashSet()
- /// One of the two unique instances of System.Collections.IEqualityComparer. Implements PER semantics
- /// where equality on NaN returns "false".
- let fsEqualityComparerNoHashingPER =
- { new IEqualityComparer with
- override iec.Equals(x:obj,y:obj) = GenericEqualityObj false iec (x,y) // PER Semantics
- override iec.GetHashCode(x:obj) = raise (InvalidOperationException (SR.GetString(SR.notUsedForHashing))) }
-
- /// One of the two unique instances of IEqualityComparer. Implements ER semantics
- /// where equality on NaN returns "true".
- let fsEqualityComparerNoHashingER =
- { new IEqualityComparer with
- override iec.Equals(x:obj,y:obj) = GenericEqualityObj true iec (x,y) // ER Semantics
- override iec.GetHashCode(x:obj) = raise (InvalidOperationException (SR.GetString(SR.notUsedForHashing))) }
+ let rec checkType index (types: Type array) =
+ if types.Length = index then true
+ else
+ let ty = get types index
+
+ if processed.Add ty
+ then
+ // avoid any types that need special handling in GenericEqualityObj
+ // GenericEqualityObj handles string as a special case, but internally routes to same equality
+
+ // covers enum and value types
+ // reference types need to be sealed as derived class might implement IStructuralEquatable
+ ty.IsSealed
+
+ // handled elsewhere in a specialized fashion
+ && not (isArray ty)
+ && (er || not (isFloat ty))
+
+ // analyze generic types
+ && (match ty with
+ | ty when isNullable ty ||
+ isStructuralEquatable ty && isValueTuple ty ||
+ isStructuralEquatable ty && isOptionOrResult ty -> checkType 0 (ty.GetGenericArguments())
+
+ | ty when isStructuralEquatable ty -> false
+
+ | _ -> true)
+
+ && checkType (index + 1) types
+
+ else
+ checkType (index + 1) types
+
+ checkType 0 [| rootType |]
+
+ let arrayEqualityComparer<'T> er comparer =
+ let arrayEquals (er: bool) (iec: IEqualityComparer) (xobj: obj) (yobj: obj) : bool =
+ match xobj, yobj with
+ | null, null -> true
+ | null, _ -> false
+ | _, null -> false
+ | (:? (obj array) as arr1), (:? (obj array) as arr2) -> GenericEqualityObjArray er iec arr1 arr2
+ | (:? (byte array) as arr1), (:? (byte array) as arr2) -> GenericEqualityByteArray arr1 arr2
+ | (:? (int32 array) as arr1), (:? (int32 array) as arr2) -> GenericEqualityInt32Array arr1 arr2
+ | (:? (int64 array) as arr1), (:? (int64 array) as arr2) -> GenericEqualityInt64Array arr1 arr2
+ | (:? (char array) as arr1), (:? (char array) as arr2) -> GenericEqualityCharArray arr1 arr2
+ | (:? (float32 array) as arr1), (:? (float32 array) as arr2) -> GenericEqualitySingleArray er arr1 arr2
+ | (:? (float array) as arr1), (:? (float array) as arr2) -> GenericEqualityDoubleArray er arr1 arr2
+ | (:? Array as arr1), (:? Array as arr2) -> GenericEqualityArbArray er iec arr1 arr2
+ | _ -> raise (Exception "invalid logic - expected array")
+
+ let getHashCode (iec, xobj: obj) =
+ match xobj with
+ | null -> 0
+ | :? (obj array) as oa -> GenericHashObjArray iec oa
+ | :? (byte array) as ba -> GenericHashByteArray ba
+ | :? (int array) as ia -> GenericHashInt32Array ia
+ | :? (int64 array) as ia -> GenericHashInt64Array ia
+ | :? Array as a -> GenericHashArbArray iec a
+ | _ -> raise (Exception "invalid logic - expected array")
+
+ { new EqualityComparer<'T>() with
+ member _.Equals (x, y) = arrayEquals er comparer (box x) (box y)
+ member _.GetHashCode x = getHashCode (fsEqualityComparerUnlimitedHashingPER, box x) }
+
+ let structuralEqualityComparer<'T> comparer =
+ { new EqualityComparer<'T>() with
+ member _.Equals (x,y) =
+ match box x, box y with
+ | null, null -> true
+ | null, _ -> false
+ | _, null -> false
+ | (:? IStructuralEquatable as x1), yobj -> x1.Equals (yobj, comparer)
+ | _ -> raise (Exception "invalid logic - expected IStructuralEquatable")
+
+ member _.GetHashCode x =
+ match box x with
+ | null -> 0
+ | :? IStructuralEquatable as a -> a.GetHashCode fsEqualityComparerUnlimitedHashingPER
+ | _ -> raise (Exception "invalid logic - expected IStructuralEquatable") }
+
+ let getEqualityComparer<'T> er =
+ let ty = typeof<'T>
+
+ match er with
+ | _ when canUseDefaultEqualityComparer er ty -> EqualityComparer<'T>.Default
+
+ | true when isArray ty -> arrayEqualityComparer true fsEqualityComparerUnlimitedHashingER
+ | false when isArray ty -> arrayEqualityComparer false fsEqualityComparerUnlimitedHashingPER
+ | true when isStructuralEquatable ty -> structuralEqualityComparer fsEqualityComparerUnlimitedHashingER
+ | false when isStructuralEquatable ty -> structuralEqualityComparer fsEqualityComparerUnlimitedHashingPER
+
+ | false when Type.op_Equality(ty, typeof) -> unboxPrim (box {
+ new EqualityComparer() with
+ member _.Equals (x,y) = (# "ceq" x y : bool #)
+ member _.GetHashCode x = x.GetHashCode () })
+
+ | false when Type.op_Equality(ty, typeof) -> unboxPrim (box {
+ new EqualityComparer() with
+ member _.Equals (x,y) = (# "ceq" x y : bool #)
+ member _.GetHashCode x = x.GetHashCode () })
+
+ | false -> {
+ new EqualityComparer<'T>() with
+ member _.Equals (x,y) = GenericEqualityObj false fsEqualityComparerUnlimitedHashingPER (box x, box y)
+ member _.GetHashCode x = GenericHashParamObj fsEqualityComparerUnlimitedHashingPER (box x) }
+
+ | true -> {
+ new EqualityComparer<'T>() with
+ member _.Equals (x,y) = GenericEqualityObj true fsEqualityComparerUnlimitedHashingER (box x, box y)
+ member _.GetHashCode x = GenericHashParamObj fsEqualityComparerUnlimitedHashingER (box x) }
+
+ type EqualityComparerER<'T> () =
+
+ static member val Comparer = getEqualityComparer<'T> true
+
+ type EqualityComparerPER<'T> () =
+
+ static member val Comparer = getEqualityComparer<'T> false
/// Implements generic equality between two values, with PER semantics for NaN (so equality on two NaN values returns false)
//
// The compiler optimizer is aware of this function (see use of generic_equality_per_inner_vref in opt.fs)
// and devirtualizes calls to it based on "T".
let GenericEqualityIntrinsic (x : 'T) (y : 'T) : bool =
- GenericEqualityObj false fsEqualityComparerNoHashingPER ((box x), (box y))
-
+ EqualityComparerPER<'T>.Comparer.Equals (x, y)
+
/// Implements generic equality between two values, with ER semantics for NaN (so equality on two NaN values returns true)
//
// ER semantics is used for recursive calls when implementing .Equals(that) for structural data, see the code generated for record and union types in augment.fs
@@ -1683,15 +1841,20 @@ namespace Microsoft.FSharp.Core
// The compiler optimizer is aware of this function (see use of generic_equality_er_inner_vref in opt.fs)
// and devirtualizes calls to it based on "T".
let GenericEqualityERIntrinsic (x : 'T) (y : 'T) : bool =
- GenericEqualityObj true fsEqualityComparerNoHashingER ((box x), (box y))
+ EqualityComparerER<'T>.Comparer.Equals (x, y)
/// Implements generic equality between two values using "comp" for recursive calls.
//
// The compiler optimizer is aware of this function (see use of generic_equality_withc_inner_vref in opt.fs)
// and devirtualizes calls to it based on "T", and under the assumption that "comp"
- // is either fsEqualityComparerNoHashingER or fsEqualityComparerNoHashingPER.
+ // is either fsEqualityComparerUnlimitedHashingER or fsEqualityComparerUnlimitedHashingPER.
let GenericEqualityWithComparerIntrinsic (comp : IEqualityComparer) (x : 'T) (y : 'T) : bool =
- comp.Equals((box x),(box y))
+ if obj.ReferenceEquals (comp, fsEqualityComparerUnlimitedHashingPER) then
+ EqualityComparerPER<'T>.Comparer.Equals (x, y)
+ elif obj.ReferenceEquals (comp, fsEqualityComparerUnlimitedHashingER) then
+ EqualityComparerER<'T>.Comparer.Equals (x, y)
+ else
+ comp.Equals ((box x), (box y))
/// Implements generic equality between two values, with ER semantics for NaN (so equality on two NaN values returns true)
@@ -1810,7 +1973,7 @@ namespace Microsoft.FSharp.Core
//
// NOTE: The compiler optimizer is aware of this function (see uses of generic_hash_inner_vref in opt.fs)
// and devirtualizes calls to it based on type "T".
- let GenericHashIntrinsic input = GenericHashParamObj fsEqualityComparerUnlimitedHashingPER (box input)
+ let GenericHashIntrinsic input = EqualityComparerPER<'T>.Comparer.GetHashCode input
/// Intrinsic for calls to depth-limited structural hashing that were not optimized by static conditionals.
let LimitedGenericHashIntrinsic limit input = GenericHashParamObj (CountLimitedHasherPER(limit)) (box input)
@@ -1823,7 +1986,10 @@ namespace Microsoft.FSharp.Core
// NOTE: The compiler optimizer is aware of this function (see uses of generic_hash_withc_inner_vref in opt.fs)
// and devirtualizes calls to it based on type "T".
let GenericHashWithComparerIntrinsic<'T> (comp : IEqualityComparer) (input : 'T) : int =
- GenericHashParamObj comp (box input)
+ if obj.ReferenceEquals (comp, fsEqualityComparerUnlimitedHashingPER) then
+ EqualityComparerPER<'T>.Comparer.GetHashCode input
+ else
+ GenericHashParamObj comp (box input)
let inline HashString (s:string) =
match s with
@@ -2136,46 +2302,8 @@ namespace Microsoft.FSharp.Core
member _.GetHashCode(x) = GenericLimitedHash limit x
member _.Equals(x,y) = GenericEquality x y }
- let BoolIEquality = MakeGenericEqualityComparer()
- let CharIEquality = MakeGenericEqualityComparer()
- let StringIEquality = MakeGenericEqualityComparer()
- let SByteIEquality = MakeGenericEqualityComparer()
- let Int16IEquality = MakeGenericEqualityComparer()
- let Int32IEquality = MakeGenericEqualityComparer()
- let Int64IEquality = MakeGenericEqualityComparer()
- let IntPtrIEquality = MakeGenericEqualityComparer()
- let ByteIEquality = MakeGenericEqualityComparer()
- let UInt16IEquality = MakeGenericEqualityComparer()
- let UInt32IEquality = MakeGenericEqualityComparer()
- let UInt64IEquality = MakeGenericEqualityComparer()
- let UIntPtrIEquality = MakeGenericEqualityComparer()
- let FloatIEquality = MakeGenericEqualityComparer()
- let Float32IEquality = MakeGenericEqualityComparer()
- let DecimalIEquality = MakeGenericEqualityComparer()
-
- type FastGenericEqualityComparerTable<'T>() =
- static let f : IEqualityComparer<'T> =
- match typeof<'T> with
- | ty when Type.op_Equality(ty, typeof) -> unboxPrim (box BoolIEquality)
- | ty when Type.op_Equality(ty, typeof) -> unboxPrim (box ByteIEquality)
- | ty when Type.op_Equality(ty, typeof) -> unboxPrim (box Int32IEquality)
- | ty when Type.op_Equality(ty, typeof) -> unboxPrim (box UInt32IEquality)
- | ty when Type.op_Equality(ty, typeof) -> unboxPrim (box CharIEquality)
- | ty when Type.op_Equality(ty, typeof) -> unboxPrim (box SByteIEquality)
- | ty when Type.op_Equality(ty, typeof) -> unboxPrim (box Int16IEquality)
- | ty when Type.op_Equality(ty, typeof) -> unboxPrim (box Int64IEquality)
- | ty when Type.op_Equality(ty, typeof) -> unboxPrim (box IntPtrIEquality)
- | ty when Type.op_Equality(ty, typeof) -> unboxPrim (box UInt16IEquality)
- | ty when Type.op_Equality(ty, typeof) -> unboxPrim (box UInt64IEquality)
- | ty when Type.op_Equality(ty, typeof) -> unboxPrim (box UIntPtrIEquality)
- | ty when Type.op_Equality(ty, typeof) -> unboxPrim (box FloatIEquality)
- | ty when Type.op_Equality(ty, typeof) -> unboxPrim (box Float32IEquality)
- | ty when Type.op_Equality(ty, typeof) -> unboxPrim (box DecimalIEquality)
- | ty when Type.op_Equality(ty, typeof) -> unboxPrim (box StringIEquality)
- | _ -> MakeGenericEqualityComparer<'T>()
- static member Function : IEqualityComparer<'T> = f
-
- let FastGenericEqualityComparerFromTable<'T> = FastGenericEqualityComparerTable<'T>.Function
+ let FastGenericEqualityComparerFromTable<'T> =
+ HashCompare.EqualityComparerPER<'T>.Comparer : IEqualityComparer<'T>
// This is the implementation of HashIdentity.Structural. In most cases this just becomes
// FastGenericEqualityComparerFromTable.
diff --git a/src/FSharp.Core/printf.fs b/src/FSharp.Core/printf.fs
index 7afcce1e66b..a326492c672 100644
--- a/src/FSharp.Core/printf.fs
+++ b/src/FSharp.Core/printf.fs
@@ -546,7 +546,7 @@ module internal PrintfImpl =
/// A wrapper struct used to slightly strengthen the types of "ValueConverter" objects produced during composition of
/// the dynamic implementation. These are always functions but sometimes they take one argument, sometimes two.
[]
- type ValueConverter private (f: obj) =
+ type ValueConverter internal (f: obj) =
member x.FuncObj = f
static member inline Make (f: obj -> string) = ValueConverter(box f)
@@ -981,9 +981,9 @@ module internal PrintfImpl =
let defaultFormat = getFormatForFloat spec.TypeChar DefaultPrecision
FloatAndDecimal.withPadding spec (getFormatForFloat spec.TypeChar) defaultFormat
- let private NonPublicStatics = BindingFlags.NonPublic ||| BindingFlags.Static
+ let private AllStatics = BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Static
- let mi_GenericToString = typeof.GetMethod("GenericToString", NonPublicStatics)
+ let mi_GenericToString = typeof.GetMethod("GenericToString", AllStatics)
let private getValueConverter (ty: Type) (spec: FormatSpecifier) : ValueConverter =
match spec.TypeChar with
@@ -1103,7 +1103,7 @@ module internal PrintfImpl =
// %a has an existential type which must be converted to obj
assert (argTys.Length = 2)
let captureMethName = "CaptureLittleA"
- let mi = typeof>.GetMethod(captureMethName, NonPublicStatics)
+ let mi = typeof>.GetMethod(captureMethName, AllStatics)
let mi = mi.MakeGenericMethod([| argTys.[1]; retTy |])
let factoryObj = mi.Invoke(null, [| next |])
factoryObj, false, argTys, retTy, None
@@ -1115,20 +1115,20 @@ module internal PrintfImpl =
match nextNextOpt with
| None ->
let captureMethName = "CaptureFinal" + string captureCount
- let mi = typeof>.GetMethod(captureMethName, NonPublicStatics)
+ let mi = typeof>.GetMethod(captureMethName, AllStatics)
let mi = mi.MakeGenericMethod(combinedArgTys)
let factoryObj = mi.Invoke(null, [| allSteps |])
factoryObj, true, combinedArgTys, nextRetTy, None
| Some nextNext ->
let captureMethName = "Capture" + string captureCount
- let mi = typeof>.GetMethod(captureMethName, NonPublicStatics)
+ let mi = typeof>.GetMethod(captureMethName, AllStatics)
let mi = mi.MakeGenericMethod(Array.append combinedArgTys [| nextRetTy |])
let factoryObj = mi.Invoke(null, [| nextNext |])
factoryObj, true, combinedArgTys, nextRetTy, nextNextOpt
| captureCount, _ ->
let captureMethName = "Capture" + string captureCount
- let mi = typeof>.GetMethod(captureMethName, NonPublicStatics)
+ let mi = typeof>.GetMethod(captureMethName, AllStatics)
let mi = mi.MakeGenericMethod(Array.append argTys [| retTy |])
let factoryObj = mi.Invoke(null, [| next |])
factoryObj, true, argTys, retTy, Some next
@@ -1277,7 +1277,7 @@ module internal PrintfImpl =
// If there is one simple format specifier then we can create an even better factory function
| [| StepWithArg (prefix1, conv1); StepString prefix2 |] ->
let captureMethName = "OneStepWithArg"
- let mi = typeof>.GetMethod(captureMethName, NonPublicStatics)
+ let mi = typeof>.GetMethod(captureMethName, AllStatics)
let mi = mi.MakeGenericMethod(combinedArgTys)
let factoryObj = mi.Invoke(null, [| box prefix1; box conv1; box prefix2 |])
factoryObj
@@ -1285,7 +1285,7 @@ module internal PrintfImpl =
// If there are two simple format specifiers then we can create an even better factory function
| [| StepWithArg (prefix1, conv1); StepWithArg (prefix2, conv2); StepString prefix3 |] ->
let captureMethName = "TwoStepWithArg"
- let mi = typeof>.GetMethod(captureMethName, NonPublicStatics)
+ let mi = typeof>.GetMethod(captureMethName, AllStatics)
let mi = mi.MakeGenericMethod(combinedArgTys)
let factoryObj = mi.Invoke(null, [| box prefix1; box conv1; box prefix2; box conv2; box prefix3 |])
factoryObj
diff --git a/tests/AheadOfTime/Equality/Equality.fsproj b/tests/AheadOfTime/Equality/Equality.fsproj
new file mode 100644
index 00000000000..f5a243c65b9
--- /dev/null
+++ b/tests/AheadOfTime/Equality/Equality.fsproj
@@ -0,0 +1,35 @@
+
+
+
+ Exe
+ net8.0
+ preview
+ true
+
+
+
+ true
+ true
+ true
+ true
+ win-x64
+
+
+
+ $(MSBuildThisFileDirectory)../../../artifacts/bin/fsc/Release/net8.0/fsc.dll
+ $(MSBuildThisFileDirectory)../../../artifacts/bin/fsc/Release/net8.0/fsc.dll
+ False
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/AheadOfTime/Equality/Program.fs b/tests/AheadOfTime/Equality/Program.fs
new file mode 100644
index 00000000000..052d2875da3
--- /dev/null
+++ b/tests/AheadOfTime/Equality/Program.fs
@@ -0,0 +1,77 @@
+open System.Collections.Generic
+open NonStructuralComparison
+
+let failures = HashSet()
+
+let reportFailure (s: string) =
+ stderr.Write " NO: "
+ stderr.WriteLine s
+ failures.Add s |> ignore
+
+let test testName x y =
+ let result = HashIdentity.Structural.Equals(x, y)
+ if result = false
+ then
+ stderr.WriteLine($"\n***** {testName}: Expected: 'true' Result: '{result}' = FAIL\n");
+ reportFailure testName
+
+module BasicTypes =
+ test "test000" true true
+ test "test001" 1y 1y
+ test "test002" 1uy 1uy
+ test "test003" 1s 1s
+ test "test004" 1us 1us
+ test "test005" 1 1
+ test "test006" 1u 1u
+ test "test007" 1L 1L
+ test "test008" 1UL 1UL
+ test "test009" (nativeint 1) (nativeint 1)
+ test "test010" (unativeint 1) (unativeint 1)
+ test "test011" 'a' 'a'
+ test "test012" "a" "a"
+ test "test013" 1m 1m
+ test "test014" 1.0 1.0
+ test "test015" 1.0f 1.0f
+
+module Arrays =
+ test "test100" [|1|] [|1|]
+ test "test101" [|1L|] [|1L|]
+ test "test102" [|1uy|] [|1uy|]
+ test "test103" [|box 1|] [|box 1|]
+
+module Structs =
+ test "test200" struct (1, 1) struct (1, 1)
+ test "test201" struct (1, 1, 1) struct (1, 1, 1)
+ test "test202" struct (1, 1, 1, 1) struct (1, 1, 1, 1)
+ test "test203" struct (1, 1, 1, 1, 1) struct (1, 1, 1, 1, 1)
+ test "test204" struct (1, 1, 1, 1, 1, 1) struct (1, 1, 1, 1, 1, 1)
+ test "test205" struct (1, 1, 1, 1, 1, 1, 1) struct (1, 1, 1, 1, 1, 1, 1)
+ test "test206" struct (1, 1, 1, 1, 1, 1, 1, 1) struct (1, 1, 1, 1, 1, 1, 1, 1)
+
+module OptionsAndCo =
+ open System
+
+ test "test301" (Some 1) (Some 1)
+ test "test302" (ValueSome 1) (ValueSome 1)
+ test "test303" (Ok 1) (Ok 1)
+ test "test304" (Nullable 1) (Nullable 1)
+
+module Enums =
+ open System
+
+ type SomeEnum =
+ | Case0 = 0
+ | Case1 = 1
+
+ test "test401" (enum(1)) (enum(1))
+ test "test402" (enum(1)) (enum(1))
+
+[]
+let main _ =
+ match failures with
+ | set when set.Count = 0 ->
+ stdout.WriteLine "All tests passed"
+ exit 0
+ | _ ->
+ stdout.WriteLine "Some tests failed"
+ exit 1
diff --git a/tests/AheadOfTime/Equality/check.ps1 b/tests/AheadOfTime/Equality/check.ps1
new file mode 100644
index 00000000000..7913d24599c
--- /dev/null
+++ b/tests/AheadOfTime/Equality/check.ps1
@@ -0,0 +1,32 @@
+Write-Host "Publish and Execute: net8.0 - Equality"
+
+$build_output = dotnet publish -restore -c release -f:net8.0 $(Join-Path $PSScriptRoot Equality.fsproj)
+
+# Checking that the build succeeded
+if ($LASTEXITCODE -ne 0)
+{
+ Write-Error "Build failed with exit code ${LASTEXITCODE}"
+ Write-Error "${build_output}" -ErrorAction Stop
+}
+
+$process = Start-Process `
+ -FilePath $(Join-Path $PSScriptRoot bin\release\net8.0\win-x64\publish\Equality.exe) `
+ -Wait `
+ -NoNewWindow `
+ -PassThru `
+ -RedirectStandardOutput $(Join-Path $PSScriptRoot output.txt)
+
+$output = Get-Content $(Join-Path $PSScriptRoot output.txt)
+
+# Checking that it is actually running.
+if ($LASTEXITCODE -ne 0)
+{
+ Write-Error "Test failed with exit code ${LASTEXITCODE}" -ErrorAction Stop
+}
+
+# Checking that the output is as expected.
+$expected = "All tests passed"
+if ($output -ne $expected)
+{
+ Write-Error "Test failed with unexpected output:`nExpected:`n`t${expected}`nActual`n`t${output}" -ErrorAction Stop
+}
diff --git a/tests/AheadOfTime/Trimming/check.cmd b/tests/AheadOfTime/Trimming/check.cmd
deleted file mode 100644
index 4eefff011c5..00000000000
--- a/tests/AheadOfTime/Trimming/check.cmd
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0check.ps1""""
diff --git a/tests/AheadOfTime/Trimming/check.ps1 b/tests/AheadOfTime/Trimming/check.ps1
index 8528710b76f..7412b21232c 100644
--- a/tests/AheadOfTime/Trimming/check.ps1
+++ b/tests/AheadOfTime/Trimming/check.ps1
@@ -39,7 +39,7 @@ function CheckTrim($root, $tfm, $outputfile, $expected_len) {
# error NETSDK1124: Trimming assemblies requires .NET Core 3.0 or higher.
# Check net7.0 trimmed assemblies
-CheckTrim -root "SelfContained_Trimming_Test" -tfm "net8.0" -outputfile "FSharp.Core.dll" -expected_len 287232
+CheckTrim -root "SelfContained_Trimming_Test" -tfm "net8.0" -outputfile "FSharp.Core.dll" -expected_len 284160
-# Check net7.0 trimmed assemblies
-CheckTrim -root "StaticLinkedFSharpCore_Trimming_Test" -tfm "net8.0" -outputfile "StaticLinkedFSharpCore_Trimming_Test.dll" -expected_len 8820736
+# Check net8.0 trimmed assemblies
+CheckTrim -root "StaticLinkedFSharpCore_Trimming_Test" -tfm "net8.0" -outputfile "StaticLinkedFSharpCore_Trimming_Test.dll" -expected_len 8817152
diff --git a/tests/AheadOfTime/check.cmd b/tests/AheadOfTime/check.cmd
new file mode 100644
index 00000000000..a52368e2c6f
--- /dev/null
+++ b/tests/AheadOfTime/check.cmd
@@ -0,0 +1,3 @@
+@echo off
+powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0Trimming\check.ps1""""
+powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0Equality\check.ps1""""
diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/misc/compiler_help_output.bsl b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/misc/compiler_help_output.bsl
index 2e064aacf82..8e207799112 100644
--- a/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/misc/compiler_help_output.bsl
+++ b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/misc/compiler_help_output.bsl
@@ -59,6 +59,7 @@ Copyright (c) Microsoft Corporation. All Rights Reserved.
--tailcalls[+|-] Enable or disable tailcalls
--deterministic[+|-] Produce a deterministic assembly (including module version GUID and
timestamp)
+--realsig[+|-] Generate assembly with IL visibility that matches the source code visibility
--pathmap: Maps physical paths to source path names output by the compiler
--crossoptimize[+|-] Enable or disable cross-module optimizations
--reflectionfree Disable implicit generation of constructs using reflection
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod01.fs
index b8de3b3349a..4018ae74be8 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod01.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsMethod01.fs
@@ -48,3 +48,10 @@ let test1 =
|> (=) 6
if not test1 then failwith "Failed: 1"
+
+[]
+type MethodLevelAttribute() =
+ inherit Attribute()
+
+type SomeUnion =
+| [] Case1 of 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 c7861ee3e56..5d930ea1e14 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs
@@ -34,7 +34,7 @@ module CustomAttributes_AttributeUsage =
|> verifyCompileAndRun
|> shouldSucceed
- // SOURCE=AssemblyVersion03.fs # AssemblyVersion03.fs
+ // SOURCE=AssemblyVersion03.fs # AssemblyVersion03.fs
[]
let ``AssemblyVersion03_fs`` compilation =
compilation
@@ -64,6 +64,14 @@ module CustomAttributes_AttributeUsage =
|> verifyCompileAndRun
|> shouldSucceed
+ // SOURCE=AttributeTargetsIsMethod01.fs # AttributeTargetsIsMethod01.fs
+ []
+ let ``AttributeTargetsIsMethod01_fs preview`` compilation =
+ compilation
+ |> withLangVersionPreview
+ |> verifyCompileAndRun
+ |> shouldSucceed
+
// SOURCE=ConditionalAttribute.fs # ConditionalAttribute.fs
[]
let ``ConditionalAttribute_fs`` compilation =
@@ -352,5 +360,45 @@ module CustomAttributes_AttributeUsage =
|> withDiagnostics [
(Warning 2003, Line 5, Col 59, Line 5, Col 68, "The attribute System.Reflection.AssemblyFileVersionAttribute specified version '9.8.*.6', but this value is invalid and has been ignored")
]
-
-
+
+ // SOURCE=E_AttributeTargetIsField03.fs # E_AttributeTargetIsField03.fs
+ []
+ let ``E_AttributeTargetIsField03_fs`` compilation =
+ compilation
+ |> verifyCompile
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 842, Line 14, Col 5, Line 14, Col 15, "This attribute is not valid for use on this language element")
+ ]
+
+ // SOURCE=E_AttributeTargetIsField03.fs # E_AttributeTargetIsField03.fs
+ []
+ let ``E_AttributeTargetIsField03_fs preview`` compilation =
+ compilation
+ |> withLangVersionPreview
+ |> verifyCompile
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 842, Line 14, Col 5, Line 14, Col 15, "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_AttributeTargetIsProperty01.fs # E_AttributeTargetIsField03.fs
+ []
+ let ``E_AttributeTargetIsProperty01_fs`` compilation =
+ compilation
+ |> verifyCompile
+ |> shouldSucceed
+
+ // SOURCE=E_AttributeTargetIsProperty01.fs # E_AttributeTargetIsField03.fs
+ []
+ let ``E_AttributeTargetIsProperty01_fs preview`` compilation =
+ compilation
+ |> withLangVersionPreview
+ |> verifyCompile
+ |> shouldFail
+ |> 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")
+ ]
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsField03.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsField03.fs
new file mode 100644
index 00000000000..cc5fb20b495
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsField03.fs
@@ -0,0 +1,16 @@
+// This tests that AttributeTargets.Field is not allowed in union-case declaration
+
+open System
+
+[]
+type FieldLevelAttribute() =
+ inherit Attribute()
+
+[]
+type PropertyOrFieldLevelAttribute() =
+ inherit Attribute()
+
+type SomeUnion =
+| [] Case1 of int // Should fail
+| [] Case2 of int // Should fail
+
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsProperty01.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsProperty01.fs
new file mode 100644
index 00000000000..4627c3680dd
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsProperty01.fs
@@ -0,0 +1,15 @@
+// This tests that AttributeTargets.Property is not allowed in union-case declaration
+
+open System
+
+[]
+type PropertyLevelAttribute() =
+ inherit Attribute()
+
+[]
+type PropertyOrFieldLevelAttribute() =
+ inherit Attribute()
+
+type SomeUnion =
+| [] Case1 of int // Should fail
+| [] Case2 of int // Should fail
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MethodResolution.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MethodResolution.fs
index 3ac3d49ce4b..f6145c01abc 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MethodResolution.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MethodResolution.fs
@@ -34,7 +34,7 @@ if returnvalue2<> true && value2 <> 7 then
|> ignore
[]
- let ``Method with optional and out parameters resolves correctly (verify IL)`` () =
+ let ``Method with optional and out parameters resolves correctly withRealInternalSignatureOff (verify IL)`` () =
FSharp """
module OutOptionalTests
open System.Runtime.InteropServices
@@ -47,6 +47,7 @@ let (_:bool), (_:int) = Thing.Do(i = 42)
let (_:bool), (_:int) = Thing.Do()
"""
|> ignoreWarnings
+ |> withRealInternalSignatureOff
|> compile
|> shouldSucceed
|> verifyIL [
@@ -203,6 +204,195 @@ extends [runtime]System.Object
}
"""]
+ []
+ let ``Method with optional and out parameters resolves correctly withRealInternalSignatureOn (verify IL)`` () =
+ FSharp """
+module OutOptionalTests
+open System.Runtime.InteropServices
+
+type Thing =
+ static member Do(o: outref, []i: int) =
+ o <- i
+ i = 7
+let (_:bool), (_:int) = Thing.Do(i = 42)
+let (_:bool), (_:int) = Thing.Do()
+ """
+ |> ignoreWarnings
+ |> withRealInternalSignatureOn
+ |> compile
+ |> shouldSucceed
+ |> verifyIL [
+ """
+.class public abstract auto ansi sealed OutOptionalTests
+ 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 )
+ .class auto ansi serializable nested public Thing
+ extends [runtime]System.Object
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 )
+ .method public static bool Do([out] int32& o,
+ [opt] int32 i) cil managed
+ {
+ .param [2] = int32(0x00000001)
+
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldarg.1
+ IL_0002: stobj [runtime]System.Int32
+ IL_0007: ldarg.1
+ IL_0008: ldc.i4.7
+ IL_0009: ceq
+ IL_000b: ret
+ }
+
+ }
+
+ .field static assembly class [runtime]System.Tuple`2 patternInput@9
+ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .field static assembly int32 outArg@9
+ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .field static assembly class [runtime]System.Tuple`2 'patternInput@10-1'
+ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .field static assembly int32 'outArg@10-1'
+ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .method assembly specialname static class [runtime]System.Tuple`2 get_patternInput@9() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldsfld class [runtime]System.Tuple`2 OutOptionalTests::patternInput@9
+ IL_0005: ret
+ }
+
+ .method assembly specialname static int32 get_outArg@9() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldsfld int32 OutOptionalTests::outArg@9
+ IL_0005: ret
+ }
+
+ .method assembly specialname static void set_outArg@9(int32 'value') cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: stsfld int32 OutOptionalTests::outArg@9
+ IL_0006: ret
+ }
+
+ .method assembly specialname static class [runtime]System.Tuple`2 'get_patternInput@10-1'() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldsfld class [runtime]System.Tuple`2 OutOptionalTests::'patternInput@10-1'
+ IL_0005: ret
+ }
+
+ .method assembly specialname static int32 'get_outArg@10-1'() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldsfld int32 OutOptionalTests::'outArg@10-1'
+ IL_0005: ret
+ }
+
+ .method assembly specialname static void 'set_outArg@10-1'(int32 'value') cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: stsfld int32 OutOptionalTests::'outArg@10-1'
+ IL_0006: ret
+ }
+
+ .method private specialname rtspecialname static void .cctor() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldc.i4.0
+ IL_0001: stsfld int32 ''.$OutOptionalTests::init@
+ IL_0006: ldsfld int32 ''.$OutOptionalTests::init@
+ IL_000b: pop
+ IL_000c: ret
+ }
+
+ .method assembly specialname static void staticInitialization@() cil managed
+ {
+
+ .maxstack 4
+ .locals init (int32& V_0)
+ IL_0000: ldc.i4.0
+ IL_0001: stsfld int32 OutOptionalTests::outArg@9
+ IL_0006: ldsflda int32 OutOptionalTests::outArg@9
+ IL_000b: stloc.0
+ IL_000c: ldloc.0
+ IL_000d: ldc.i4.s 42
+ IL_000f: stobj [runtime]System.Int32
+ IL_0014: ldc.i4.0
+ IL_0015: call int32 OutOptionalTests::get_outArg@9()
+ IL_001a: newobj instance void class [runtime]System.Tuple`2::.ctor(!0,
+ !1)
+ IL_001f: stsfld class [runtime]System.Tuple`2 OutOptionalTests::patternInput@9
+ IL_0024: ldc.i4.0
+ IL_0025: stsfld int32 OutOptionalTests::'outArg@10-1'
+ IL_002a: ldsflda int32 OutOptionalTests::'outArg@10-1'
+ IL_002f: stloc.0
+ IL_0030: ldloc.0
+ IL_0031: ldc.i4.1
+ IL_0032: stobj [runtime]System.Int32
+ IL_0037: ldc.i4.0
+ IL_0038: call int32 OutOptionalTests::'get_outArg@10-1'()
+ IL_003d: newobj instance void class [runtime]System.Tuple`2::.ctor(!0,
+ !1)
+ IL_0042: stsfld class [runtime]System.Tuple`2 OutOptionalTests::'patternInput@10-1'
+ IL_0047: ret
+ }
+
+ .property class [runtime]System.Tuple`2
+ patternInput@9()
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 09 00 00 00 00 00 )
+ .get class [runtime]System.Tuple`2 OutOptionalTests::get_patternInput@9()
+ }
+ .property int32 outArg@9()
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 09 00 00 00 00 00 )
+ .set void OutOptionalTests::set_outArg@9(int32)
+ .get int32 OutOptionalTests::get_outArg@9()
+ }
+ .property class [runtime]System.Tuple`2
+ 'patternInput@10-1'()
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 09 00 00 00 00 00 )
+ .get class [runtime]System.Tuple`2 OutOptionalTests::'get_patternInput@10-1'()
+ }
+ .property int32 'outArg@10-1'()
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 09 00 00 00 00 00 )
+ .set void OutOptionalTests::'set_outArg@10-1'(int32)
+ .get int32 OutOptionalTests::'get_outArg@10-1'()
+ }
+}
+
+.class private abstract auto ansi sealed ''.$OutOptionalTests
+ extends [runtime]System.Object
+{
+ .field static assembly int32 init@
+ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+ .method private specialname rtspecialname static void .cctor() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: call void OutOptionalTests::staticInitialization@()
+ IL_0005: ret
+ }
+
+}
+ """]
+
[]
let ``Method with optional and out parameters resolves correctly (examples from original issue: https://github.com/dotnet/fsharp/issues/12515)`` () =
Fsx """
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/StaticLet/StaticLetInGenericRecords.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/StaticLet/StaticLetInGenericRecords.fs
index 32e090ebdbf..4facec5630e 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/StaticLet/StaticLetInGenericRecords.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/StaticLet/StaticLetInGenericRecords.fs
@@ -7,7 +7,7 @@ type MyRecord<'T> =
}
static let sizeOfT = sizeof<'T>
- static let cachedVal =
+ static let cachedVal =
printfn "Creating cached val for %s" (typeof<'T>.Name)
{ X = Unchecked.defaultof<'T> ; Y = 15}
static let mutable perTyparInstMutableCounter = 0
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/StaticLet/StaticLetInGenericRecordsILtest.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/StaticLet/StaticLetInGenericRecordsILtest.fs
index 738bd09f0fd..ef2414db2ed 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/StaticLet/StaticLetInGenericRecordsILtest.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/StaticLet/StaticLetInGenericRecordsILtest.fs
@@ -9,7 +9,7 @@ type MyRecord<'T> =
X: 'T
}
// Init per typar
- static let cachedVal =
+ static let cachedVal =
Console.WriteLine(typeof<'T>.Name)
typeof<'T>.Name
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/StaticLet/StaticLetInUnionsAndRecords.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/StaticLet/StaticLetInUnionsAndRecords.fs
index 257fb1eeab3..17c7c03c808 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/StaticLet/StaticLetInUnionsAndRecords.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/StaticLet/StaticLetInUnionsAndRecords.fs
@@ -396,7 +396,7 @@ Case2 1"""
[]
-let ``Static let IL init single file test`` () =
+let ``Static let IL init single file test withRealInternalSignatureOff`` () =
FSharp """
module Test
open System
@@ -408,6 +408,7 @@ type X =
do Console.WriteLine("module after type")
"""
|> withLangVersion80
+ |> withRealInternalSignatureOff
|> compile
|> shouldSucceed
|> verifyIL ["""
@@ -461,7 +462,99 @@ do Console.WriteLine("module after type")
}"""]
[]
-let ``Static let in penultimate file IL test`` () =
+let ``Static let IL init single file test withRealInternalSignatureOn`` () =
+ FSharp """
+module Test
+open System
+
+do Console.WriteLine("module before type")
+[]
+type X =
+ static do Console.WriteLine("from type")
+do Console.WriteLine("module after type")
+"""
+ |> withLangVersion80
+ |> withRealInternalSignatureOn
+ |> compile
+ |> shouldSucceed
+ |> verifyIL ["""
+.class public abstract auto ansi sealed Test
+ 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 )
+ .class auto ansi serializable nested public X
+ extends [runtime]System.Object
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoEqualityAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoComparisonAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 )
+ .method private specialname rtspecialname static void .cctor() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldc.i4.0
+ IL_0001: stsfld int32 ''.$Test::init@
+ IL_0006: ldsfld int32 ''.$Test::init@
+ IL_000b: pop
+ IL_000c: ret
+ }
+
+ .method assembly specialname static void staticInitialization@() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldstr "from type"
+ IL_0005: call void [runtime]System.Console::WriteLine(string)
+ IL_000a: ret
+ }
+
+ }
+
+ .method private specialname rtspecialname static void .cctor() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldc.i4.0
+ IL_0001: stsfld int32 ''.$Test::init@
+ IL_0006: ldsfld int32 ''.$Test::init@
+ IL_000b: pop
+ IL_000c: ret
+ }
+
+ .method assembly specialname static void staticInitialization@() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldstr "module before type"
+ IL_0005: call void [runtime]System.Console::WriteLine(string)
+ IL_000a: call void Test/X::staticInitialization@()
+ IL_000f: ldstr "module after type"
+ IL_0014: call void [runtime]System.Console::WriteLine(string)
+ IL_0019: ret
+ }
+
+}
+
+.class private abstract auto ansi sealed ''.$Test
+ extends [runtime]System.Object
+{
+ .field static assembly int32 init@
+ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+ .method private specialname rtspecialname static void .cctor() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: call void Test::staticInitialization@()
+ IL_0005: ret
+ }
+
+}
+"""]
+
+[]
+let ``Static let in penultimate file IL test withRealInternalSignatureOff`` () =
let types = """
namespace MyTypes
open System
@@ -483,6 +576,7 @@ Console.Write(MyTypes.X.GetX)
FSharp types
|> withAdditionalSourceFiles [SourceCodeFileKind.Create("program.fs", program)]
|> withLangVersion80
+ |> withRealInternalSignatureOff
|> compile
|> shouldSucceed
|> verifyIL ["""
@@ -578,6 +672,148 @@ Console.Write(MyTypes.X.GetX)
}"""]
+[]
+let ``Static let in penultimate file IL test withRealInternalSignatureOn`` () =
+ let types = """
+namespace MyTypes
+open System
+
+[]
+type X =
+ static do Console.WriteLine("from type")
+ static let mutable x_value = 42
+ static member GetX = x_value
+
+"""
+
+ let program = """
+module ProgramMain
+open System
+Console.Write(MyTypes.X.GetX)
+"""
+
+ FSharp types
+ |> withAdditionalSourceFiles [SourceCodeFileKind.Create("program.fs", program)]
+ |> withLangVersion80
+ |> withRealInternalSignatureOn
+ |> compile
+ |> shouldSucceed
+ |> verifyIL ["""
+.class public auto ansi serializable MyTypes.X
+ extends [runtime]System.Object
+{
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoEqualityAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoComparisonAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 )
+ .field static assembly int32 x_value
+ .field static assembly int32 init@6
+ .method public specialname static int32 get_GetX() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: volatile.
+ IL_0002: ldsfld int32 MyTypes.X::init@6
+ IL_0007: ldc.i4.0
+ IL_0008: bge.s IL_0011
+
+ IL_000a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::FailStaticInit()
+ IL_000f: br.s IL_0011
+
+ IL_0011: ldsfld int32 MyTypes.X::x_value
+ IL_0016: ret
+ }
+
+ .method private specialname rtspecialname static void .cctor() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldc.i4.0
+ IL_0001: stsfld int32 ''.$Test::init@
+ IL_0006: ldsfld int32 ''.$Test::init@
+ IL_000b: pop
+ IL_000c: ret
+ }
+
+ .method assembly specialname static void staticInitialization@() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldstr "from type"
+ IL_0005: call void [runtime]System.Console::WriteLine(string)
+ IL_000a: ldc.i4.s 42
+ IL_000c: stsfld int32 MyTypes.X::x_value
+ IL_0011: ldc.i4.0
+ IL_0012: volatile.
+ IL_0014: stsfld int32 MyTypes.X::init@6
+ IL_0019: ret
+ }
+
+ .property int32 GetX()
+ {
+ .get int32 MyTypes.X::get_GetX()
+ }
+}
+
+.class public abstract auto ansi sealed ProgramMain
+ 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 private specialname rtspecialname static void .cctor() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldc.i4.0
+ IL_0001: stsfld int32 ''.$ProgramMain::init@
+ IL_0006: ldsfld int32 ''.$ProgramMain::init@
+ IL_000b: pop
+ IL_000c: ret
+ }
+
+ .method assembly specialname static void staticInitialization@() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: call int32 MyTypes.X::get_GetX()
+ IL_0005: call void [runtime]System.Console::Write(int32)
+ IL_000a: ret
+ }
+
+}
+
+.class private abstract auto ansi sealed ''.$ProgramMain
+ extends [runtime]System.Object
+{
+ .field static assembly int32 init@
+ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+ .method private specialname rtspecialname static void .cctor() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: call void ProgramMain::staticInitialization@()
+ IL_0005: ret
+ }
+
+}
+
+.class private abstract auto ansi sealed ''.$Test
+ extends [runtime]System.Object
+{
+ .field static assembly int32 init@
+ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+ .method private specialname rtspecialname static void .cctor() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: call void MyTypes.X::staticInitialization@()
+ IL_0005: ret
+ }
+"""]
+
+
[]
[]
let ``Regression 16009 - module rec does not initialize let bindings`` langVersion =
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/RecursiveSafetyAnalysis.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/RecursiveSafetyAnalysis.fs
index 52bf8601869..9b9beecfdb0 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/RecursiveSafetyAnalysis.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/RecursiveSafetyAnalysis.fs
@@ -49,7 +49,7 @@ module RecursiveSafetyAnalysis =
(Error 1114, Line 8, Col 15, Line 8, Col 25, "The value 'E_RecursiveInline.test' was marked inline but was not bound in the optimization environment")
(Error 1113, Line 7, Col 16, Line 7, Col 20, "The value 'test' was marked inline but its implementation makes use of an internal or private function which is not sufficiently accessible")
(Warning 1116, Line 8, Col 15, Line 8, Col 25, "A value marked as 'inline' has an unexpected value")
- (Error 1118, Line 8, Col 15, Line 8, Col 25, "Failed to inline the value 'test' marked 'inline', perhaps because a recursive value was marked 'inline'")
+ (Warning 1118, Line 8, Col 15, Line 8, Col 25, "Failed to inline the value 'test' marked 'inline', perhaps because a recursive value was marked 'inline'")
]
// SOURCE=E_TypeDeclaration01.fs SCFLAGS="--langversion:5.0 --test:ErrorRanges" COMPILE_ONLY=1 # E_TypeDeclaration01.fs
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionStepping.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionStepping.fs
index 9f5b523b944..89c1c62c7c0 100644
--- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionStepping.fs
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionStepping.fs
@@ -1,4 +1,4 @@
-namespace EmittedIL
+namespace EmittedIL.RealInternalSignature
open Xunit
open FSharp.Test
@@ -17,28 +17,74 @@ module AsyncExpressionStepping =
|> verifyBaseline
|> verifyILBaseline
- []
- let ``AsyncExpressionSteppingTest1_fs`` compilation =
- verifyCompilation compilation
+ []
+ let ``AsyncExpressionSteppingTest1_RealInternalSignatureOn_fs`` compilation =
+ compilation
+ |> withRealInternalSignatureOn
+ |> verifyCompilation
+
+ []
+ let ``AsyncExpressionSteppingTest1_RealInternalSignatureOff_fs`` compilation =
+ compilation
+ |> withRealInternalSignatureOff
+ |> verifyCompilation
+
+ []
+ let ``AsyncExpressionSteppingTest2_RealInternalSignatureOnfs`` compilation =
+ compilation
+ |> withRealInternalSignatureOn
+ |> verifyCompilation
+
+ []
+ let ``AsyncExpressionSteppingTest2_RealInternalSignatureOff_fs`` compilation =
+ compilation
+ |> withRealInternalSignatureOff
+ |> verifyCompilation
+
+ []
+ let ``AsyncExpressionSteppingTest3_RealInternalSignatureOn_fs`` compilation =
+ compilation
+ |> withRealInternalSignatureOn
+ |> verifyCompilation
- []
- let ``AsyncExpressionSteppingTest2_fs`` compilation =
- verifyCompilation compilation
+ []
+ let ``AsyncExpressionSteppingTest3_RealInternalSignatureOff_fs`` compilation =
+ compilation
+ |> withRealInternalSignatureOff
+ |> verifyCompilation
- []
- let ``AsyncExpressionSteppingTest3_fs`` compilation =
- verifyCompilation compilation
+ []
+ let ``AsyncExpressionSteppingTest4_RealInternalSignatureOn_fs`` compilation =
+ compilation
+ |> withRealInternalSignatureOn
+ |> verifyCompilation
- []
- let ``AsyncExpressionSteppingTest4_fs`` compilation =
- verifyCompilation compilation
+ []
+ let ``AsyncExpressionSteppingTest4_RealInternalSignatureOff_fs`` compilation =
+ compilation
+ |> withRealInternalSignatureOff
+ |> verifyCompilation
- []
- let ``AsyncExpressionSteppingTest5_fs`` compilation =
- verifyCompilation compilation
+ []
+ let ``AsyncExpressionSteppingTest5_RealInternalSignatureOn_fs`` compilation =
+ compilation
+ |> withRealInternalSignatureOn
+ |> verifyCompilation
- []
- let ``AsyncExpressionSteppingTest6_fs`` compilation =
- verifyCompilation compilation
+ []
+ let ``AsyncExpressionSteppingTest5_RealInternalSignatureOff_fs`` compilation =
+ compilation
+ |> withRealInternalSignatureOff
+ |> verifyCompilation
+ []
+ let ``AsyncExpressionSteppingTest6_RealInternalSignatureOn_fs`` compilation =
+ compilation
+ |> withRealInternalSignatureOn
+ |> verifyCompilation
+ []
+ let ``AsyncExpressionSteppingTest6_RealInternalSignatureOff_fs`` compilation =
+ compilation
+ |> withRealInternalSignatureOff
+ |> verifyCompilation
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.fs.il.debug.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.fs.RealInternalSignatureOff.il.debug.bsl
similarity index 100%
rename from tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.fs.il.debug.bsl
rename to tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.fs.RealInternalSignatureOff.il.debug.bsl
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.fs.il.release.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.fs.RealInternalSignatureOff.il.release.bsl
similarity index 100%
rename from tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.fs.il.release.bsl
rename to tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.fs.RealInternalSignatureOff.il.release.bsl
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.fs.RealInternalSignatureOn.il.debug.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.fs.RealInternalSignatureOn.il.debug.bsl
new file mode 100644
index 00000000000..b8ab856f75a
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.fs.RealInternalSignatureOn.il.debug.bsl
@@ -0,0 +1,186 @@
+
+
+
+
+
+.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.dll
+
+.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 )
+ .class abstract auto ansi sealed nested public 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 )
+ .class auto ansi serializable sealed nested assembly beforefieldinit f1@6
+ extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>
+ {
+ .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder builder@
+ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+ .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder builder@) cil managed
+ {
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor()
+ IL_0006: ldarg.0
+ IL_0007: ldarg.1
+ IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f1@6::builder@
+ IL_000d: ret
+ }
+
+ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldstr "hello"
+ IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string)
+ IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4)
+ IL_000f: pop
+ IL_0010: ldstr "stuck in the middle"
+ IL_0015: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string)
+ IL_001a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4)
+ IL_001f: pop
+ IL_0020: ldstr "goodbye"
+ IL_0025: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string)
+ IL_002a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4)
+ IL_002f: pop
+ IL_0030: ldarg.0
+ IL_0031: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f1@6::builder@
+ IL_0036: tail.
+ IL_0038: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Zero()
+ IL_003d: ret
+ }
+
+ }
+
+ .method public static class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 f1() cil managed
+ {
+
+ .maxstack 4
+ .locals init (class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_0)
+ IL_0000: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_DefaultAsyncBuilder()
+ IL_0005: stloc.0
+ IL_0006: ldloc.0
+ IL_0007: ldloc.0
+ IL_0008: newobj instance void assembly/assembly/f1@6::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder)
+ IL_000d: tail.
+ IL_000f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>)
+ IL_0014: ret
+ }
+
+ .method private specialname rtspecialname static void .cctor() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldc.i4.0
+ IL_0001: stsfld int32 ''.$assembly::init@
+ IL_0006: ldsfld int32 ''.$assembly::init@
+ IL_000b: pop
+ IL_000c: ret
+ }
+
+ .method assembly specialname static void staticInitialization@() cil managed
+ {
+
+ .maxstack 5
+ .locals init (class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_0,
+ class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_1)
+ IL_0000: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly::f1()
+ IL_0005: stloc.0
+ IL_0006: ldloc.0
+ IL_0007: stloc.1
+ IL_0008: ldloc.1
+ IL_0009: ldnull
+ IL_000a: ldnull
+ IL_000b: call !!0 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync::RunSynchronously(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1,
+ class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1,
+ class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1)
+ IL_0010: pop
+ IL_0011: ret
+ }
+
+ }
+
+ .method private specialname rtspecialname static void .cctor() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldc.i4.0
+ IL_0001: stsfld int32 ''.$assembly::init@
+ IL_0006: ldsfld int32 ''.$assembly::init@
+ IL_000b: pop
+ IL_000c: ret
+ }
+
+ .method assembly specialname static void staticInitialization@() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: call void assembly/assembly::staticInitialization@()
+ IL_0005: ret
+ }
+
+}
+
+.class private abstract auto ansi sealed ''.$assembly
+ extends [runtime]System.Object
+{
+ .field static assembly int32 init@
+ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+ .method private specialname rtspecialname static void .cctor() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: call void assembly::staticInitialization@()
+ IL_0005: ret
+ }
+
+}
+
+
+
+
+
+
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.fs.RealInternalSignatureOn.il.release.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.fs.RealInternalSignatureOn.il.release.bsl
new file mode 100644
index 00000000000..b8ab856f75a
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.fs.RealInternalSignatureOn.il.release.bsl
@@ -0,0 +1,186 @@
+
+
+
+
+
+.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.dll
+
+.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 )
+ .class abstract auto ansi sealed nested public 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 )
+ .class auto ansi serializable sealed nested assembly beforefieldinit f1@6
+ extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>
+ {
+ .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder builder@
+ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+ .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder builder@) cil managed
+ {
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor()
+ IL_0006: ldarg.0
+ IL_0007: ldarg.1
+ IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f1@6::builder@
+ IL_000d: ret
+ }
+
+ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldstr "hello"
+ IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string)
+ IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4)
+ IL_000f: pop
+ IL_0010: ldstr "stuck in the middle"
+ IL_0015: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string)
+ IL_001a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4)
+ IL_001f: pop
+ IL_0020: ldstr "goodbye"
+ IL_0025: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string)
+ IL_002a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4)
+ IL_002f: pop
+ IL_0030: ldarg.0
+ IL_0031: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/f1@6::builder@
+ IL_0036: tail.
+ IL_0038: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Zero()
+ IL_003d: ret
+ }
+
+ }
+
+ .method public static class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 f1() cil managed
+ {
+
+ .maxstack 4
+ .locals init (class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_0)
+ IL_0000: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_DefaultAsyncBuilder()
+ IL_0005: stloc.0
+ IL_0006: ldloc.0
+ IL_0007: ldloc.0
+ IL_0008: newobj instance void assembly/assembly/f1@6::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder)
+ IL_000d: tail.
+ IL_000f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>)
+ IL_0014: ret
+ }
+
+ .method private specialname rtspecialname static void .cctor() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldc.i4.0
+ IL_0001: stsfld int32 ''.$assembly::init@
+ IL_0006: ldsfld int32 ''.$assembly::init@
+ IL_000b: pop
+ IL_000c: ret
+ }
+
+ .method assembly specialname static void staticInitialization@() cil managed
+ {
+
+ .maxstack 5
+ .locals init (class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_0,
+ class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_1)
+ IL_0000: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 assembly/assembly::f1()
+ IL_0005: stloc.0
+ IL_0006: ldloc.0
+ IL_0007: stloc.1
+ IL_0008: ldloc.1
+ IL_0009: ldnull
+ IL_000a: ldnull
+ IL_000b: call !!0 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync::RunSynchronously(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1,
+ class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1,
+ class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1)
+ IL_0010: pop
+ IL_0011: ret
+ }
+
+ }
+
+ .method private specialname rtspecialname static void .cctor() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldc.i4.0
+ IL_0001: stsfld int32 ''.$assembly::init@
+ IL_0006: ldsfld int32 ''.$assembly::init@
+ IL_000b: pop
+ IL_000c: ret
+ }
+
+ .method assembly specialname static void staticInitialization@() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: call void assembly/assembly::staticInitialization@()
+ IL_0005: ret
+ }
+
+}
+
+.class private abstract auto ansi sealed ''.$assembly
+ extends [runtime]System.Object
+{
+ .field static assembly int32 init@
+ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+ .method private specialname rtspecialname static void .cctor() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: call void assembly::staticInitialization@()
+ IL_0005: ret
+ }
+
+}
+
+
+
+
+
+
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest2.fs.il.debug.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest2.fs.RealInternalSignatureOff.il.debug.bsl
similarity index 100%
rename from tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest2.fs.il.debug.bsl
rename to tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest2.fs.RealInternalSignatureOff.il.debug.bsl
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest2.fs.il.release.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest2.fs.RealInternalSignatureOff.il.release.bsl
similarity index 100%
rename from tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest2.fs.il.release.bsl
rename to tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest2.fs.RealInternalSignatureOff.il.release.bsl
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest2.fs.RealInternalSignatureOn.il.debug.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest2.fs.RealInternalSignatureOn.il.debug.bsl
new file mode 100644
index 00000000000..39b879bc70a
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest2.fs.RealInternalSignatureOn.il.debug.bsl
@@ -0,0 +1,284 @@
+
+
+
+
+
+.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.dll
+
+.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 )
+ .class abstract auto ansi sealed nested public 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 )
+ .class auto ansi serializable sealed nested assembly beforefieldinit 'f2@6-1'
+ extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2
+ {
+ .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x
+ .method assembly specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x) cil managed
+ {
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor()
+ IL_0006: ldarg.0
+ IL_0007: ldarg.1
+ IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 assembly/assembly/'f2@6-1'::x
+ IL_000d: ret
+ }
+
+ .method public strict virtual instance bool Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 assembly/assembly/'f2@6-1'::x
+ IL_0006: callvirt instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1::get_Value()
+ IL_000b: ldc.i4.4
+ IL_000c: clt
+ IL_000e: ret
+ }
+
+ }
+
+ .class auto ansi serializable sealed nested assembly beforefieldinit 'f2@7-2'
+ extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>
+ {
+ .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x
+ .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder builder@
+ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+ .method assembly specialname rtspecialname
+ instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x,
+ class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder builder@) cil managed
+ {
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor()
+ IL_0006: ldarg.0
+ IL_0007: ldarg.1
+ IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 assembly/assembly/'f2@7-2'::x
+ IL_000d: ldarg.0
+ IL_000e: ldarg.2
+ IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder assembly/assembly/'f2@7-2'::builder@
+ IL_0014: ret
+ }
+
+ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 assembly/assembly/'f2@7-2'::x
+ IL_0006: ldarg.0
+ IL_0007: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 assembly/assembly/'f2@7-2'::x
+ IL_000c: callvirt instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1