From e31552c622de6360923f6628f89bca7b0f5853aa Mon Sep 17 00:00:00 2001 From: Petr Date: Thu, 19 Dec 2024 17:36:31 +0100 Subject: [PATCH 1/8] Reuse typechecking results - stage 1 --- .../.FSharp.Compiler.Service/9.0.200.md | 1 + src/Compiler/Driver/CompilerConfig.fs | 13 ++ src/Compiler/Driver/CompilerConfig.fsi | 13 ++ src/Compiler/Driver/CompilerOptions.fs | 8 + .../Driver/ReuseTcResults/CachingDriver.fs | 141 ++++++++++++++++ src/Compiler/Driver/fsc.fs | 9 ++ src/Compiler/FSComp.txt | 1 + src/Compiler/FSharp.Compiler.Service.fsproj | 1 + src/Compiler/SyntaxTree/PrettyNaming.fs | 2 + src/Compiler/SyntaxTree/PrettyNaming.fsi | 2 + src/Compiler/Utilities/Activity.fs | 6 + src/Compiler/Utilities/Activity.fsi | 5 + src/Compiler/xlf/FSComp.txt.cs.xlf | 5 + src/Compiler/xlf/FSComp.txt.de.xlf | 5 + src/Compiler/xlf/FSComp.txt.es.xlf | 5 + src/Compiler/xlf/FSComp.txt.fr.xlf | 5 + src/Compiler/xlf/FSComp.txt.it.xlf | 5 + src/Compiler/xlf/FSComp.txt.ja.xlf | 5 + src/Compiler/xlf/FSComp.txt.ko.xlf | 5 + src/Compiler/xlf/FSComp.txt.pl.xlf | 5 + src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 5 + src/Compiler/xlf/FSComp.txt.ru.xlf | 5 + src/Compiler/xlf/FSComp.txt.tr.xlf | 5 + src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 5 + src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 5 + src/FSharp.Build/Fsc.fs | 10 ++ src/FSharp.Build/Microsoft.FSharp.Targets | 1 + .../fsc/misc/compiler_help_output.bsl | 1 + .../FSharp.Compiler.ComponentTests.fsproj | 1 + .../TypeChecks/ReuseTcResults/Activities.fs | 153 ++++++++++++++++++ .../expected-help-output.bsl | 2 + tests/FSharp.Test.Utilities/Compiler.fs | 31 ++++ 32 files changed, 466 insertions(+) create mode 100644 src/Compiler/Driver/ReuseTcResults/CachingDriver.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Activities.fs diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md index 0a05f20bf45..b106b96a268 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md @@ -27,6 +27,7 @@ ### Added +* New flag `--reusetypecheckingresults`, for skipping recompilation in some cases * Let `dotnet fsi --help` print a link to the documentation website. ([PR #18006](https://github.com/dotnet/fsharp/pull/18006)) * Deprecate places where `seq` can be omitted. ([Language suggestion #1033](https://github.com/fsharp/fslang-suggestions/issues/1033), [PR #17772](https://github.com/dotnet/fsharp/pull/17772)) * Support literal attribute on decimals ([PR #17769](https://github.com/dotnet/fsharp/pull/17769)) diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index cf875be4959..1e06e938a04 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -445,6 +445,11 @@ type TypeCheckingMode = | Sequential | Graph +[] +type ReuseTcResults = + | On + | Off + [] type TypeCheckingConfig = { @@ -652,6 +657,8 @@ type TcConfigBuilder = mutable parallelReferenceResolution: ParallelReferenceResolution + mutable reuseTcResults: ReuseTcResults + mutable captureIdentifiersWhenParsing: bool mutable typeCheckingConfig: TypeCheckingConfig @@ -661,6 +668,8 @@ type TcConfigBuilder = mutable realsig: bool mutable compilationMode: TcGlobals.CompilationMode + + mutable cmdLineArgs: string array } // Directories to start probing in @@ -859,6 +868,7 @@ type TcConfigBuilder = xmlDocInfoLoader = None exiter = QuitProcessExiter parallelReferenceResolution = ParallelReferenceResolution.Off + reuseTcResults = ReuseTcResults.Off captureIdentifiersWhenParsing = false typeCheckingConfig = { @@ -873,6 +883,7 @@ type TcConfigBuilder = realsig = false strictIndentation = None compilationMode = TcGlobals.CompilationMode.Unset + cmdLineArgs = [||] } member tcConfigB.FxResolver = @@ -1413,11 +1424,13 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) = member _.xmlDocInfoLoader = data.xmlDocInfoLoader member _.exiter = data.exiter member _.parallelReferenceResolution = data.parallelReferenceResolution + member _.reuseTcResults = data.reuseTcResults member _.captureIdentifiersWhenParsing = data.captureIdentifiersWhenParsing member _.typeCheckingConfig = data.typeCheckingConfig member _.dumpSignatureData = data.dumpSignatureData member _.realsig = data.realsig member _.compilationMode = data.compilationMode + member _.cmdLineArgs = data.cmdLineArgs static member Create(builder, validate) = use _ = UseBuildPhase BuildPhase.Parameter diff --git a/src/Compiler/Driver/CompilerConfig.fsi b/src/Compiler/Driver/CompilerConfig.fsi index 0e6c25727f8..57814db287d 100644 --- a/src/Compiler/Driver/CompilerConfig.fsi +++ b/src/Compiler/Driver/CompilerConfig.fsi @@ -208,6 +208,11 @@ type ParallelReferenceResolution = | On | Off +[] +type ReuseTcResults = + | On + | Off + /// Determines the algorithm used for type-checking. [] type TypeCheckingMode = @@ -519,6 +524,8 @@ type TcConfigBuilder = mutable parallelReferenceResolution: ParallelReferenceResolution + mutable reuseTcResults: ReuseTcResults + mutable captureIdentifiersWhenParsing: bool mutable typeCheckingConfig: TypeCheckingConfig @@ -528,6 +535,8 @@ type TcConfigBuilder = mutable realsig: bool mutable compilationMode: TcGlobals.CompilationMode + + mutable cmdLineArgs: string array } static member CreateNew: @@ -899,6 +908,8 @@ type TcConfig = member parallelReferenceResolution: ParallelReferenceResolution + member reuseTcResults: ReuseTcResults + member captureIdentifiersWhenParsing: bool member typeCheckingConfig: TypeCheckingConfig @@ -909,6 +920,8 @@ type TcConfig = member compilationMode: TcGlobals.CompilationMode + member cmdLineArgs: string array + /// 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/CompilerOptions.fs b/src/Compiler/Driver/CompilerOptions.fs index 7c4c81efd40..ab0afa1e457 100644 --- a/src/Compiler/Driver/CompilerOptions.fs +++ b/src/Compiler/Driver/CompilerOptions.fs @@ -1388,6 +1388,14 @@ let advancedFlagsFsc tcConfigB = None, Some(FSComp.SR.optsEmitDebugInfoInQuotations (formatOptionSwitch tcConfigB.emitDebugInfoInQuotations)) ) + + CompilerOption( + "reusetypecheckingresults", + tagNone, + OptionUnit(fun () -> tcConfigB.reuseTcResults <- ReuseTcResults.On), + None, + Some(FSComp.SR.optsReuseTcResults ()) + ) ] // OptionBlock: Internal options (test use only) diff --git a/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs b/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs new file mode 100644 index 00000000000..9a4c4862de6 --- /dev/null +++ b/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs @@ -0,0 +1,141 @@ +module internal FSharp.Compiler.ReuseTcResults + +open System.Collections.Generic +open System.IO + +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.GraphChecking +open FSharp.Compiler.IO +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming + +type TcData = + { + CmdLine: string array + Graph: string array + References: string array + } + +[] +type CachingDriver(tcConfig: TcConfig) = + + let outputDir = tcConfig.outputDir |> Option.defaultValue "" + let tcDataFilePath = Path.Combine(outputDir, FSharpTcDataResourceName) + + [] + let CmdLineHeader = "CMDLINE" + + [] + let GraphHeader = "GRAPH" + + [] + let ReferencesHeader = "REFERENCES" + + let writeThisTcData (tcData: TcData) = + use tcDataFile = FileSystem.OpenFileForWriteShim tcDataFilePath + + let lines = ResizeArray() + lines.Add $"BEGIN {CmdLineHeader}" + lines.AddRange tcData.CmdLine + lines.Add $"BEGIN {GraphHeader}" + lines.AddRange tcData.Graph + lines.Add $"BEGIN {ReferencesHeader}" + lines.AddRange tcData.References + + tcDataFile.WriteAllLines lines + + let readPrevTcData () = + if FileSystem.FileExistsShim tcDataFilePath then + use tcDataFile = FileSystem.OpenFileForReadShim tcDataFilePath + + let cmdLine = ResizeArray() + let graph = ResizeArray() + let refs = ResizeArray() + + let mutable currentHeader = "" + + tcDataFile.ReadLines() + |> Seq.iter (fun line -> + match line with + | line when line.StartsWith "BEGIN" -> currentHeader <- line.Split ' ' |> Array.last + | line -> + match currentHeader with + | CmdLineHeader -> cmdLine.Add line + | GraphHeader -> graph.Add line + | ReferencesHeader -> refs.Add line + | _ -> invalidOp "broken tc cache") + + Some + { + CmdLine = cmdLine.ToArray() + Graph = graph.ToArray() + References = refs.ToArray() + } + + else + None + + let formatAssemblyReference (r: AssemblyReference) = + let fileName = r.Text + let lastWriteTime = FileSystem.GetLastWriteTimeShim fileName + sprintf "%s,%i" fileName lastWriteTime.Ticks + + let getThisCompilationCmdLine args = args + + // maybe split into two things? + let getThisCompilationGraph inputs = + let sourceFiles = + inputs + |> Seq.toArray + |> Array.mapi (fun idx (input: ParsedInput) -> + { + Idx = idx + FileName = input.FileName + ParsedInput = input + }) + + let filePairs = FilePairMap sourceFiles + let graph, _ = DependencyResolution.mkGraph filePairs sourceFiles + + let list = List() + + for KeyValue(idx, _) in graph do + let fileName = sourceFiles[idx].FileName + let lastWriteTime = FileSystem.GetLastWriteTimeShim fileName + list.Add(sprintf "%i,%s,%i" idx fileName lastWriteTime.Ticks) + + for KeyValue(idx, deps) in graph do + for depIdx in deps do + list.Add $"%i{idx} --> %i{depIdx}" + + list.ToArray() + + let getThisCompilationReferences = Seq.map formatAssemblyReference >> Seq.toArray + + member _.CanReuseTcResults inputs = + let prevTcDataOpt = readPrevTcData () + + let thisTcData = + { + CmdLine = getThisCompilationCmdLine tcConfig.cmdLineArgs + Graph = getThisCompilationGraph inputs + References = getThisCompilationReferences tcConfig.referencedDLLs + } + + match prevTcDataOpt with + | Some prevTcData -> + use _ = Activity.start Activity.Events.reuseTcResultsCachePresent [] + + if prevTcData = thisTcData then + use _ = Activity.start Activity.Events.reuseTcResultsCacheHit [] + true + else + use _ = Activity.start Activity.Events.reuseTcResultsCacheMissed [] + writeThisTcData thisTcData + false + + | None -> + use _ = Activity.start Activity.Events.reuseTcResultsCacheAbsent [] + writeThisTcData thisTcData + false diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs index 0e26f2db4ac..c119fa78076 100644 --- a/src/Compiler/Driver/fsc.fs +++ b/src/Compiler/Driver/fsc.fs @@ -54,6 +54,7 @@ open FSharp.Compiler.TypedTree open FSharp.Compiler.TypedTreeOps open FSharp.Compiler.XmlDocFileWriter open FSharp.Compiler.CheckExpressionsOps +open ReuseTcResults //---------------------------------------------------------------------------- // Reporting - warnings, errors @@ -162,6 +163,13 @@ let TypeCheck let eagerFormat (diag: PhasedDiagnostic) = diag.EagerlyFormatCore true + if tcConfig.reuseTcResults = ReuseTcResults.On then + let cachingDriver = CachingDriver(tcConfig) + + if cachingDriver.CanReuseTcResults(inputs) then + // do nothing, yet + () + CheckClosedInputSet( ctok, (fun () -> diagnosticsLogger.CheckForRealErrorsIgnoringWarnings), @@ -511,6 +519,7 @@ let main1 ) tcConfigB.exiter <- exiter + tcConfigB.cmdLineArgs <- argv // Preset: --optimize+ -g --tailcalls+ (see 4505) SetOptimizeSwitch tcConfigB OptionSwitch.On diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index eedaecbb9be..b0137486cba 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1796,3 +1796,4 @@ featureDontWarnOnUppercaseIdentifiersInBindingPatterns,"Don't warn on uppercase featureDeprecatePlacesWhereSeqCanBeOmitted,"Deprecate places where 'seq' can be omitted" featureSupportValueOptionsAsOptionalParameters,"Support ValueOption as valid type for optional member parameters" featureSupportWarnWhenUnitPassedToObjArg,"Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`." +optsReuseTcResults,"Reuse previous typechecking results for faster compilation" diff --git a/src/Compiler/FSharp.Compiler.Service.fsproj b/src/Compiler/FSharp.Compiler.Service.fsproj index 493248a11d3..b69652a811f 100644 --- a/src/Compiler/FSharp.Compiler.Service.fsproj +++ b/src/Compiler/FSharp.Compiler.Service.fsproj @@ -464,6 +464,7 @@ + diff --git a/src/Compiler/SyntaxTree/PrettyNaming.fs b/src/Compiler/SyntaxTree/PrettyNaming.fs index b0ef32edaf0..ec9303271e7 100755 --- a/src/Compiler/SyntaxTree/PrettyNaming.fs +++ b/src/Compiler/SyntaxTree/PrettyNaming.fs @@ -1132,6 +1132,8 @@ let FSharpSignatureCompressedDataResourceNameB = "FSharpSignatureCompressedDataB let FSharpOptimizationDataResourceName2 = "FSharpOptimizationInfo." let FSharpSignatureDataResourceName2 = "FSharpSignatureInfo." +let FSharpTcDataResourceName = "FSharpTypecheckingData" + [] let suffixForVariablesThatMayNotBeEliminated = "$cont" diff --git a/src/Compiler/SyntaxTree/PrettyNaming.fsi b/src/Compiler/SyntaxTree/PrettyNaming.fsi index 9843656e46f..59c33a664d5 100644 --- a/src/Compiler/SyntaxTree/PrettyNaming.fsi +++ b/src/Compiler/SyntaxTree/PrettyNaming.fsi @@ -284,6 +284,8 @@ val internal FSharpOptimizationDataResourceName2: string val internal FSharpSignatureDataResourceName2: string +val internal FSharpTcDataResourceName: string + val GetLongNameFromString: string -> string list val FormatAndOtherOverloadsString: int -> string diff --git a/src/Compiler/Utilities/Activity.fs b/src/Compiler/Utilities/Activity.fs index 2d204864f69..54cd1d936b4 100644 --- a/src/Compiler/Utilities/Activity.fs +++ b/src/Compiler/Utilities/Activity.fs @@ -70,6 +70,12 @@ module internal Activity = module Events = let cacheHit = "cacheHit" + let reuseTcResultsCachePrefix = "reuseTcResultsCache" + let reuseTcResultsCachePresent = $"{reuseTcResultsCachePrefix}Present" + let reuseTcResultsCacheAbsent = $"{reuseTcResultsCachePrefix}Absent" + let reuseTcResultsCacheHit = $"{reuseTcResultsCachePrefix}Hit" + let reuseTcResultsCacheMissed = $"{reuseTcResultsCachePrefix}Missed" + type Diagnostics.Activity with member this.RootId = diff --git a/src/Compiler/Utilities/Activity.fsi b/src/Compiler/Utilities/Activity.fsi index 041b2998765..8b72eaa2e39 100644 --- a/src/Compiler/Utilities/Activity.fsi +++ b/src/Compiler/Utilities/Activity.fsi @@ -39,6 +39,11 @@ module internal Activity = module Events = val cacheHit: string + val reuseTcResultsCachePrefix: string + val reuseTcResultsCachePresent: string + val reuseTcResultsCacheAbsent: string + val reuseTcResultsCacheHit: string + val reuseTcResultsCacheMissed: string val startNoTags: name: string -> IDisposable MaybeNull diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 74894da5d02..cca5ceb7c61 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -987,6 +987,11 @@ Zakázat implicitní generování konstruktorů pomocí reflexe + + Reuse previous typechecking results for faster compilation + Reuse previous typechecking results for faster compilation + + Specify language version such as 'latest' or 'preview'. Upřesněte verzi jazyka, například „latest“ nebo „preview“. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 77409615867..3edfdb8abc9 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -987,6 +987,11 @@ Deaktivieren der impliziten Generierung von Konstrukten mithilfe von Reflektion + + Reuse previous typechecking results for faster compilation + Reuse previous typechecking results for faster compilation + + Specify language version such as 'latest' or 'preview'. Geben Sie eine Sprachversion wie „latest“ oder „preview“ an. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 9f042384d39..b4e9b932a9d 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -987,6 +987,11 @@ Deshabilitar la generación implícita de construcciones mediante reflexión + + Reuse previous typechecking results for faster compilation + Reuse previous typechecking results for faster compilation + + Specify language version such as 'latest' or 'preview'. Especifique la versión de idioma, como "latest" o "preview". diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 621286a8e21..53e5b1d0acc 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -987,6 +987,11 @@ Désactiver la génération implicite de constructions à l’aide de la réflexion + + Reuse previous typechecking results for faster compilation + Reuse previous typechecking results for faster compilation + + Specify language version such as 'latest' or 'preview'. Spécifiez une version de langage telle que 'latest' ou 'preview'. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 1d7bdf56aa0..cf1a38248a5 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -987,6 +987,11 @@ Disabilitare la generazione implicita di costrutti usando reflection + + Reuse previous typechecking results for faster compilation + Reuse previous typechecking results for faster compilation + + Specify language version such as 'latest' or 'preview'. Specificare la versione della lingua, ad esempio 'latest' o 'preview'. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index c928a51da3e..f12b9e49e74 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -987,6 +987,11 @@ リフレクションを使用してコンストラクトの暗黙的な生成を無効にする + + Reuse previous typechecking results for faster compilation + Reuse previous typechecking results for faster compilation + + Specify language version such as 'latest' or 'preview'. 'latest' や 'preview' などの言語バージョンを指定します。 diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index aaff373fcda..11ac70a8312 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -987,6 +987,11 @@ 리플렉션을 사용하여 구문의 암시적 생성 사용 안 함 + + Reuse previous typechecking results for faster compilation + Reuse previous typechecking results for faster compilation + + Specify language version such as 'latest' or 'preview'. 'latest' 또는 'preview'와 같이 언어 버전을 지정합니다. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index f886e72e8f8..1c92ec23af4 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -987,6 +987,11 @@ Wyłącz niejawne generowanie konstrukcji przy użyciu odbicia + + Reuse previous typechecking results for faster compilation + Reuse previous typechecking results for faster compilation + + Specify language version such as 'latest' or 'preview'. Określ wersję językową, taką jak „najnowsza” lub „wersja zapoznawcza”. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 69082574676..e2f803840e5 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -987,6 +987,11 @@ Desabilitar a geração implícita de constructos usando reflexão + + Reuse previous typechecking results for faster compilation + Reuse previous typechecking results for faster compilation + + Specify language version such as 'latest' or 'preview'. Especifique a versão do idioma, como 'última versão' ou 'versão prévia'. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index df0d5f9770a..cbc4352d4f0 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -987,6 +987,11 @@ Отключить неявное создание конструкций с помощью отражения + + Reuse previous typechecking results for faster compilation + Reuse previous typechecking results for faster compilation + + Specify language version such as 'latest' or 'preview'. Укажите версию языка, например "новейшая" или "предварительная версия". diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 77568593137..35f20c3edfd 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -987,6 +987,11 @@ Yansıma kullanarak yapıların örtük oluşturulmasını devre dışı bırak + + Reuse previous typechecking results for faster compilation + Reuse previous typechecking results for faster compilation + + Specify language version such as 'latest' or 'preview'. 'latest' veya 'preview' gibi dil sürümünü belirtin. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 59532dc06d8..2a3d57f31d8 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -987,6 +987,11 @@ 使用反射禁用隐式构造生成 + + Reuse previous typechecking results for faster compilation + Reuse previous typechecking results for faster compilation + + Specify language version such as 'latest' or 'preview'. 指定语言版本,如 "latest" 或 "preview"。 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 2274eb373c8..c4585d45108 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -987,6 +987,11 @@ 停用使用反射的隱含產生建構 + + Reuse previous typechecking results for faster compilation + Reuse previous typechecking results for faster compilation + + Specify language version such as 'latest' or 'preview'. 指定語言版本,例如 'latest' 或 'preview'。 diff --git a/src/FSharp.Build/Fsc.fs b/src/FSharp.Build/Fsc.fs index ccbece545d5..9894db58699 100644 --- a/src/FSharp.Build/Fsc.fs +++ b/src/FSharp.Build/Fsc.fs @@ -45,6 +45,7 @@ type public Fsc() as this = let mutable noFramework = false let mutable noInterfaceData = false let mutable noOptimizationData = false + let mutable reuseTcResults = false let mutable optimize: bool = true let mutable otherFlags: string MaybeNull = null let mutable outputAssembly: string MaybeNull = null @@ -165,6 +166,10 @@ type public Fsc() as this = if noOptimizationData then builder.AppendSwitch("--nooptimizationdata") + // ReuseTypecheckingResults + if reuseTcResults then + builder.AppendSwitch("--reusetypecheckingresults") + // BaseAddress builder.AppendSwitchIfNotNull("--baseaddress:", baseAddress) @@ -483,6 +488,11 @@ type public Fsc() as this = with get () = noOptimizationData and set (b) = noOptimizationData <- b + // --reusetypecheckingresults + member _.ReuseTcResults + with get () = reuseTcResults + and set (b) = reuseTcResults <- b + // --optimize member _.Optimize with get () = optimize diff --git a/src/FSharp.Build/Microsoft.FSharp.Targets b/src/FSharp.Build/Microsoft.FSharp.Targets index a1385f6aff2..8cb32d5c7e1 100644 --- a/src/FSharp.Build/Microsoft.FSharp.Targets +++ b/src/FSharp.Build/Microsoft.FSharp.Targets @@ -375,6 +375,7 @@ this file. NoFramework="true" NoInterfaceData="$(NoInterfaceData)" NoOptimizationData="$(NoOptimizationData)" + ReuseTcResults="$(ReuseTypecheckingResults)" Optimize="$(Optimize)" ReflectionFree="$(ReflectionFree)" OtherFlags="$(FscOtherFlags)" 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 beafa217722..96734eebb96 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 @@ -116,3 +116,4 @@ Copyright (c) Microsoft Corporation. All Rights Reserved. --highentropyva[+|-] Enable high-entropy ASLR (off by default) --subsystemversion: Specify subsystem version of this assembly --quotations-debug[+|-] Emit debug information in quotations (off by default) +--reusetypecheckingresults Reuse previous typechecking results for faster compilation diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 60b867c7815..a83be01f432 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -264,6 +264,7 @@ + diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Activities.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Activities.fs new file mode 100644 index 00000000000..1054b4af2a9 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Activities.fs @@ -0,0 +1,153 @@ +namespace TypeChecks.ReuseTcResultsTests + +open System.Collections.Generic +open System.Diagnostics +open System.IO + +open FSharp.Compiler.Diagnostics +open FSharp.Test +open FSharp.Test.Compiler + +open Xunit + +open TestFramework + + +[] +type Activities() = + + let tempPath = $"{getTemporaryFileName()}.fsx" + + let actualActivities = List() + + let listener = new ActivityListener( + ShouldListenTo = (fun source -> source.Name = ActivityNames.FscSourceName), + Sample = (fun _ -> ActivitySamplingResult.AllData), + ActivityStarted = (fun activity -> + if activity.DisplayName.Contains Activity.Events.reuseTcResultsCachePrefix then + actualActivities.Add activity.DisplayName)) + + do + ActivitySource.AddActivityListener listener + + + [] + let ``Recompilation with changed sources``() = + let expectedActivities = List [ + Activity.Events.reuseTcResultsCacheAbsent + Activity.Events.reuseTcResultsCachePresent + Activity.Events.reuseTcResultsCacheMissed + ] + + File.WriteAllText(tempPath, "42") + + let cUnit = + FsxFromPath tempPath + |> withReuseTcResults + + cUnit + |> compileExisting + |> shouldSucceed + |> ignore + + File.WriteAllText(tempPath, "42") + + cUnit + |> compileExisting + |> shouldSucceed + |> ignore + + Assert.Equal>(expectedActivities, actualActivities) + + [] + let ``Recompilation with changed command line``() = + let expectedActivities = List [ + Activity.Events.reuseTcResultsCacheAbsent + Activity.Events.reuseTcResultsCachePresent + Activity.Events.reuseTcResultsCacheMissed + ] + + File.WriteAllText(tempPath, "42") + + let cUnit = + FsxFromPath tempPath + |> withReuseTcResults + + cUnit + |> compileExisting + |> shouldSucceed + |> ignore + + cUnit + |> withNoOptimizationData // random option + |> compileExisting + |> shouldSucceed + |> ignore + + Assert.Equal>(expectedActivities, actualActivities) + + [] + let ``Recompilation with changed references``() = + let updateFsharpCoreReference() = + let fsharpCoreRef = typeof<_ list>.Assembly.Location + let lastWriteTime = File.GetLastWriteTime fsharpCoreRef + let earlier = lastWriteTime.AddMinutes -1 + + // Have to do this via a copy as otherwise the file is locked on .NET framework. + let fsharpCoreRefTemp = $"{fsharpCoreRef}.temp" + File.Copy(fsharpCoreRef, fsharpCoreRefTemp) + File.SetLastWriteTime(fsharpCoreRefTemp, earlier) + File.Replace(fsharpCoreRefTemp, fsharpCoreRef, null) + + + let expectedActivities = List [ + Activity.Events.reuseTcResultsCacheAbsent + Activity.Events.reuseTcResultsCachePresent + Activity.Events.reuseTcResultsCacheMissed + ] + + File.WriteAllText(tempPath, "42") + + let cUnit = + FsxFromPath tempPath + |> withReuseTcResults + + cUnit + |> compileExisting + |> shouldSucceed + |> ignore + + updateFsharpCoreReference() + + cUnit + |> compileExisting + |> shouldSucceed + |> ignore + + Assert.Equal>(expectedActivities, actualActivities) + + [] + let ``Recompilation with everything same``() = + let expectedActivities = List [ + Activity.Events.reuseTcResultsCacheAbsent + Activity.Events.reuseTcResultsCachePresent + Activity.Events.reuseTcResultsCacheHit + ] + + File.WriteAllText(tempPath, "42") + + let cUnit = + FsxFromPath tempPath + |> withReuseTcResults + + cUnit + |> compileExisting + |> shouldSucceed + |> ignore + + cUnit + |> compileExisting + |> shouldSucceed + |> ignore + + Assert.Equal>(expectedActivities, actualActivities) diff --git a/tests/FSharp.Compiler.Service.Tests/expected-help-output.bsl b/tests/FSharp.Compiler.Service.Tests/expected-help-output.bsl index 318bb051e59..71344358be9 100644 --- a/tests/FSharp.Compiler.Service.Tests/expected-help-output.bsl +++ b/tests/FSharp.Compiler.Service.Tests/expected-help-output.bsl @@ -183,3 +183,5 @@ assembly --quotations-debug[+|-] Emit debug information in quotations (off by default) +--reusetypecheckingresults Reuse previous typechecking results + for faster compilation diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs index c6346cb30f2..e4e2fbeda23 100644 --- a/tests/FSharp.Test.Utilities/Compiler.fs +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -686,6 +686,9 @@ module rec Compiler = let withNoInterfaceData (cUnit: CompilationUnit) : CompilationUnit = withOptionsHelper [ "--nointerfacedata" ] "withNoInterfaceData is only supported for F#" cUnit + let withReuseTcResults (cUnit: CompilationUnit) : CompilationUnit = + withOptionsHelper [ "--reusetypecheckingresults" ] "reusetypecheckingresults is only supported for F#" cUnit + //--refonly[+|-] let withRefOnly (cUnit: CompilationUnit) : CompilationUnit = withOptionsHelper [ $"--refonly+" ] "withRefOnly is only supported for F#" cUnit @@ -936,6 +939,34 @@ module rec Compiler = | CS cs -> compileCSharp cs | _ -> failwith "TODO" + let compileExisting (cUnit: CompilationUnit) : CompilationResult = + match cUnit with + | FS fs -> + let sourceFilePath = fs.Source.GetSourceFileName + if (not <| File.Exists sourceFilePath) then + failwith "File doesn't exist. Create it to use this function." + + let outputFilePath = Path.ChangeExtension(sourceFilePath, ".dll") + let err, _, _ = rawCompile outputFilePath false fs.Options TargetFramework.Current [ fs.Source ] + let diagnostics = err |> fromFSharpDiagnostic + + let result = { + OutputPath = Some outputFilePath + Dependencies = [] + Adjust = 0 + PerFileErrors = diagnostics + Diagnostics = diagnostics |> List.map snd + Output = None + Compilation = cUnit + } + + if err.Length = 0 then + CompilationResult.Success result + else + CompilationResult.Failure result + + | _ -> failwith "TODO" + let private getAssemblyInBytes (result: CompilationResult) = match result with | CompilationResult.Success output -> From d9e621fce1292b4bb18647dd07b5b761f6311bda Mon Sep 17 00:00:00 2001 From: Petr Date: Fri, 14 Feb 2025 18:48:25 +0100 Subject: [PATCH 2/8] Serialization and deserialization of the typechecking data (#18162) --- src/Compiler/AbstractIL/il.fs | 2 + src/Compiler/AbstractIL/il.fsi | 6 + src/Compiler/Driver/CompilerImports.fs | 48 + src/Compiler/Driver/CompilerImports.fsi | 18 + .../Driver/ReuseTcResults/CachingDriver.fs | 62 + src/Compiler/Driver/fsc.fs | 48 +- src/Compiler/TypedTree/CompilerGlobalState.fs | 2 +- .../TypedTree/CompilerGlobalState.fsi | 2 + src/Compiler/TypedTree/TypedTree.fs | 9 + src/Compiler/TypedTree/TypedTree.fsi | 10 + src/Compiler/TypedTree/TypedTreePickle.fs | 1722 +++++++++++++++-- src/Compiler/TypedTree/TypedTreePickle.fsi | 6 + .../FSharp.Compiler.ComponentTests.fsproj | 1 + .../TypeChecks/ReuseTcResults/Activities.fs | 2 + .../ReuseTcResults/Recompilation.fs | 82 + ...ervice.SurfaceArea.netstandard20.debug.bsl | 21 +- ...vice.SurfaceArea.netstandard20.release.bsl | 22 +- tests/FSharp.Test.Utilities/ILChecker.fs | 4 +- 18 files changed, 1888 insertions(+), 179 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Recompilation.fs diff --git a/src/Compiler/AbstractIL/il.fs b/src/Compiler/AbstractIL/il.fs index 33a46ff0a23..2b80afae54c 100644 --- a/src/Compiler/AbstractIL/il.fs +++ b/src/Compiler/AbstractIL/il.fs @@ -2781,6 +2781,8 @@ type ILTypeDef member _.MetadataIndex = metadataIndex + member _.Flags = additionalFlags + member x.With ( ?name, diff --git a/src/Compiler/AbstractIL/il.fsi b/src/Compiler/AbstractIL/il.fsi index f80c64b0c59..3485ea3d091 100644 --- a/src/Compiler/AbstractIL/il.fsi +++ b/src/Compiler/AbstractIL/il.fsi @@ -949,6 +949,8 @@ type internal ILSecurityDecl = ILSecurityDecl of ILSecurityAction * byte[] /// below to construct/destruct these. [] type internal ILSecurityDecls = + new: array: ILSecurityDecl[] -> ILSecurityDecls + member AsList: unit -> ILSecurityDecl list /// Represents the efficiency-oriented storage of ILSecurityDecls in another item. @@ -1207,6 +1209,8 @@ type ILMethodDef = /// name and arity. [] type ILMethodDefs = + new: f: (unit -> ILMethodDef array) -> ILMethodDefs + inherit DelayInitArrayMap interface IEnumerable @@ -1311,6 +1315,7 @@ type ILFieldDef = /// a form to allow efficient looking up fields by name. [] type ILFieldDefs = + member internal AsList: unit -> ILFieldDef list member internal LookupByName: string -> ILFieldDef list @@ -1613,6 +1618,7 @@ type ILTypeDef = member Encoding: ILDefaultPInvokeEncoding member IsKnownToBeAttribute: bool member CanContainExtensionMethods: bool + member Flags: ILTypeDefAdditionalFlags member internal WithAccess: ILTypeDefAccess -> ILTypeDef member internal WithNestedAccess: ILMemberAccess -> ILTypeDef diff --git a/src/Compiler/Driver/CompilerImports.fs b/src/Compiler/Driver/CompilerImports.fs index ae14ee51157..170db2c6f17 100644 --- a/src/Compiler/Driver/CompilerImports.fs +++ b/src/Compiler/Driver/CompilerImports.fs @@ -337,6 +337,54 @@ let EncodeOptimizationData (tcGlobals, tcConfig: TcConfig, outfile, exportRemapp else [] +let GetTypecheckingData (file, ilScopeRef, ilModule, byteReaderA, byteReaderB) = + + let memA = byteReaderA () + + let memB = + match byteReaderB with + | None -> ByteMemory.Empty.AsReadOnly() + | Some br -> br () + + unpickleObjWithDanglingCcus file ilScopeRef ilModule unpickleTcInfo memA memB + +let WriteTypecheckingData (tcConfig: TcConfig, tcGlobals, fileName, inMem, ccu, tcInfo) = + + // need to understand the naming and if we even want two resources here... + let rName = "FSharpTypecheckingData" + let rNameB = "FSharpTypecheckingDataB" + + PickleToResource + inMem + fileName + tcGlobals + tcConfig.compressMetadata + ccu + (rName + ccu.AssemblyName) + (rNameB + ccu.AssemblyName) + pickleTcInfo + tcInfo + +let EncodeTypecheckingData (tcConfig: TcConfig, tcGlobals, generatedCcu, outfile, isIncrementalBuild, tcInfo) = + let r1, r2 = + WriteTypecheckingData( + tcConfig, + tcGlobals, + outfile, + isIncrementalBuild, + generatedCcu, + tcInfo) + + let resources = + [ + r1 + match r2 with + | None -> () + | Some r -> r + ] + + resources + exception AssemblyNotResolved of originalName: string * range: range exception MSBuildReferenceResolutionWarning of message: string * warningCode: string * range: range diff --git a/src/Compiler/Driver/CompilerImports.fsi b/src/Compiler/Driver/CompilerImports.fsi index 2a95347ecbf..aa885a7b705 100644 --- a/src/Compiler/Driver/CompilerImports.fsi +++ b/src/Compiler/Driver/CompilerImports.fsi @@ -19,6 +19,7 @@ open FSharp.Compiler.TcGlobals open FSharp.Compiler.BuildGraph open FSharp.Compiler.IO open FSharp.Compiler.Text +open FSharp.Compiler.TypedTreePickle open FSharp.Core.CompilerServices #if !NO_TYPEPROVIDERS @@ -71,6 +72,23 @@ val EncodeOptimizationData: isIncrementalBuild: bool -> ILResource list +val GetTypecheckingData: + file: string * + ilScopeRef: ILScopeRef * + ilModule: ILModuleDef option * + byteReaderA: (unit -> ReadOnlyByteMemory) * + byteReaderB: (unit -> ReadOnlyByteMemory) option -> + PickledDataWithReferences + +val EncodeTypecheckingData: + tcConfig: TcConfig * + tcGlobals: TcGlobals * + generatedCcu: CcuThunk * + outfile: string * + isIncrementalBuild: bool * + tcInfo: PickledTcInfo -> + ILResource list + [] type ResolveAssemblyReferenceMode = | Speculative diff --git a/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs b/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs index 9a4c4862de6..89b04537b1e 100644 --- a/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs +++ b/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs @@ -3,12 +3,17 @@ module internal FSharp.Compiler.ReuseTcResults open System.Collections.Generic open System.IO +open FSharp.Compiler.CheckDeclarations open FSharp.Compiler.CompilerConfig open FSharp.Compiler.Diagnostics open FSharp.Compiler.GraphChecking open FSharp.Compiler.IO +open FSharp.Compiler.ParseAndCheckInputs open FSharp.Compiler.Syntax open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.TypedTree +open CompilerImports +open FSharp.Compiler.AbstractIL.IL type TcData = { @@ -139,3 +144,60 @@ type CachingDriver(tcConfig: TcConfig) = use _ = Activity.start Activity.Events.reuseTcResultsCacheAbsent [] writeThisTcData thisTcData false + + member _.ReuseTcResults inputs (tcInitialState: TcState) = + + let bytes = File.ReadAllBytes("tc") + let memory = ByteMemory.FromArray(bytes) + let byteReaderA () = ReadOnlyByteMemory(memory) + + let byteReaderB = None + + let tcInfo = + GetTypecheckingData( + "", // assembly.FileName, + ILScopeRef.Local, // assembly.ILScopeRef, + None, //assembly.RawMetadata.TryGetILModuleDef(), + byteReaderA, + byteReaderB + ) + + let rawData = tcInfo.RawData + + let topAttrs: TopAttribs = + { + mainMethodAttrs = rawData.MainMethodAttrs + netModuleAttrs = rawData.NetModuleAttrs + assemblyAttrs = rawData.AssemblyAttrs + } + + // need to understand if anything can be used here, pickling state is hard + tcInitialState, + topAttrs, + rawData.DeclaredImpls, + // this is quite definitely wrong, need to figure out what to do with the environment + tcInitialState.TcEnvFromImpls + + member _.CacheTcResults(tcState: TcState, topAttrs: TopAttribs, declaredImpls, tcEnvAtEndOfLastFile, inputs, tcGlobals, outfile) = + let thisTcData = + { + CmdLine = getThisCompilationCmdLine tcConfig.cmdLineArgs + Graph = getThisCompilationGraph inputs + References = getThisCompilationReferences tcConfig.referencedDLLs + } + + writeThisTcData thisTcData + + let tcInfo = + { + MainMethodAttrs = topAttrs.mainMethodAttrs + NetModuleAttrs = topAttrs.netModuleAttrs + AssemblyAttrs = topAttrs.assemblyAttrs + DeclaredImpls = declaredImpls + } + + let encodedData = + EncodeTypecheckingData(tcConfig, tcGlobals, tcState.Ccu, outfile, false, tcInfo) + + let resource = encodedData[0].GetBytes().ToArray() + File.WriteAllBytes("tc", resource) diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs index c119fa78076..5b9bbb25be3 100644 --- a/src/Compiler/Driver/fsc.fs +++ b/src/Compiler/Driver/fsc.fs @@ -150,7 +150,8 @@ let TypeCheck tcEnv0, openDecls0, inputs, - exiter: Exiter + exiter: Exiter, + outfile ) = try if isNil inputs then @@ -167,20 +168,35 @@ let TypeCheck let cachingDriver = CachingDriver(tcConfig) if cachingDriver.CanReuseTcResults(inputs) then - // do nothing, yet - () + cachingDriver.ReuseTcResults inputs tcInitialState + else + let tcState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile = + CheckClosedInputSet( + ctok, + diagnosticsLogger.CheckForErrors, + tcConfig, + tcImports, + tcGlobals, + None, + tcInitialState, + eagerFormat, + inputs + ) - CheckClosedInputSet( - ctok, - (fun () -> diagnosticsLogger.CheckForRealErrorsIgnoringWarnings), - tcConfig, - tcImports, - tcGlobals, - None, - tcInitialState, - eagerFormat, - inputs - ) + cachingDriver.CacheTcResults(tcState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile, inputs, tcGlobals, outfile) + tcState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile + else + CheckClosedInputSet( + ctok, + (fun () -> diagnosticsLogger.CheckForRealErrorsIgnoringWarnings), + tcConfig, + tcImports, + tcGlobals, + None, + tcInitialState, + eagerFormat, + inputs + ) with exn -> errorRecovery exn rangeStartup exiter.Exit 1 @@ -481,6 +497,8 @@ let main1 disposables: DisposablesTracker ) = + CompilerGlobalState.stampCount <- 0L + // See Bug 735819 let lcidFromCodePage = let thread = Thread.CurrentThread @@ -701,7 +719,7 @@ let main1 let inputs = inputs |> List.map fst let tcState, topAttrs, typedAssembly, _tcEnvAtEnd = - TypeCheck(ctok, tcConfig, tcImports, tcGlobals, diagnosticsLogger, assemblyName, tcEnv0, openDecls0, inputs, exiter) + TypeCheck(ctok, tcConfig, tcImports, tcGlobals, diagnosticsLogger, assemblyName, tcEnv0, openDecls0, inputs, exiter, outfile) AbortOnError(diagnosticsLogger, exiter) ReportTime tcConfig "Typechecked" diff --git a/src/Compiler/TypedTree/CompilerGlobalState.fs b/src/Compiler/TypedTree/CompilerGlobalState.fs index 12dda2b08d8..7c93a7107d0 100644 --- a/src/Compiler/TypedTree/CompilerGlobalState.fs +++ b/src/Compiler/TypedTree/CompilerGlobalState.fs @@ -72,7 +72,7 @@ let newUnique() = System.Threading.Interlocked.Increment &uniqueCount /// Unique name generator for stamps attached to to val_specs, tycon_specs etc. //++GLOBAL MUTABLE STATE (concurrency-safe) -let mutable private stampCount = 0L +let mutable stampCount = 0L let newStamp() = let stamp = System.Threading.Interlocked.Increment &stampCount stamp \ No newline at end of file diff --git a/src/Compiler/TypedTree/CompilerGlobalState.fsi b/src/Compiler/TypedTree/CompilerGlobalState.fsi index 6f0dba79ddf..834825d671f 100644 --- a/src/Compiler/TypedTree/CompilerGlobalState.fsi +++ b/src/Compiler/TypedTree/CompilerGlobalState.fsi @@ -47,6 +47,8 @@ type Unique = int64 /// Concurrency-safe val newUnique: (unit -> int64) +val mutable stampCount: int64 + /// Unique name generator for stamps attached to to val_specs, tycon_specs etc. /// Concurrency-safe val newStamp: (unit -> int64) diff --git a/src/Compiler/TypedTree/TypedTree.fs b/src/Compiler/TypedTree/TypedTree.fs index 817730ec6ea..0797dee2d54 100644 --- a/src/Compiler/TypedTree/TypedTree.fs +++ b/src/Compiler/TypedTree/TypedTree.fs @@ -252,6 +252,8 @@ type ValFlags(flags: int64) = // Clear the IsGeneratedEventVal, since there's no use in propagating specialname information for generated add/remove event vals (flags &&& ~~~0b010011001100000000000L) + member x.Flags = flags + /// Represents the kind of a type parameter [] type TyparKind = @@ -490,6 +492,7 @@ type EntityFlags(flags: int64) = /// Get the flags as included in the F# binary metadata member x.PickledBits = (flags &&& ~~~0b000111111000100L) + member x.Flags = flags exception UndefinedName of @@ -5918,6 +5921,12 @@ type PickledCcuInfo = override _.ToString() = "PickledCcuInfo(...)" +type PickledTcInfo = { + MainMethodAttrs: Attribs + NetModuleAttrs: Attribs + AssemblyAttrs: Attribs + DeclaredImpls: CheckedImplFile list +} /// Represents a set of free local values. Computed and cached by later phases /// (never cached type checking). Cached in expressions. Not pickled. diff --git a/src/Compiler/TypedTree/TypedTree.fsi b/src/Compiler/TypedTree/TypedTree.fsi index 28ef5776e5a..761daa7105a 100644 --- a/src/Compiler/TypedTree/TypedTree.fsi +++ b/src/Compiler/TypedTree/TypedTree.fsi @@ -162,6 +162,8 @@ type ValFlags = member WithMakesNoCriticalTailcalls: ValFlags + member Flags: int64 + /// Represents the kind of a type parameter [] type TyparKind = @@ -292,6 +294,8 @@ type EntityFlags = /// Get the flags as included in the F# binary metadata member PickledBits: int64 + member Flags: int64 + member PreEstablishedHasDefaultConstructor: bool /// These two bits represents the on-demand analysis about whether the entity is assumed to be a readonly struct @@ -4297,6 +4301,12 @@ type PickledCcuInfo = [] member DebugText: string +type PickledTcInfo = + { MainMethodAttrs: Attribs + NetModuleAttrs: Attribs + AssemblyAttrs: Attribs + DeclaredImpls: CheckedImplFile list } + /// Represents a set of free local values. Computed type cached by later phases /// (never cached type checking). Cached in expressions. Not pickled. type FreeLocals = Zset diff --git a/src/Compiler/TypedTree/TypedTreePickle.fs b/src/Compiler/TypedTree/TypedTreePickle.fs index d2b3bd0ec79..c8fdf4127d7 100644 --- a/src/Compiler/TypedTree/TypedTreePickle.fs +++ b/src/Compiler/TypedTree/TypedTreePickle.fs @@ -284,6 +284,9 @@ let inline p_tup5 p1 p2 p3 p4 p5 (a, b, c, d, e) (st: WriterState) = let inline p_tup6 p1 p2 p3 p4 p5 p6 (a, b, c, d, e, f) (st: WriterState) = (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit); (p6 f st : unit) +let inline p_tup8 p1 p2 p3 p4 p5 p6 p7 p8 (a, b, c, d, e, f, g, h) (st: WriterState) = + (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit); (p6 f st : unit); (p7 g st : unit); (p8 h st : unit) + let inline p_tup9 p1 p2 p3 p4 p5 p6 p7 p8 p9 (a, b, c, d, e, f, x7, x8, x9) (st: WriterState) = (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit); (p6 f st : unit); (p7 x7 st : unit); (p8 x8 st : unit); (p9 x9 st : unit) @@ -420,6 +423,13 @@ let inline u_tup13 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 (st: ReaderState) let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12, x13) +let inline u_tup14 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 (st: ReaderState) = + let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in + let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in + let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in let x14 = p14 st in + (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12, x13, x14) + + let inline u_tup17 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 (st: ReaderState) = let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in @@ -427,6 +437,12 @@ let inline u_tup17 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 (s let x14 = p14 st in let x15 = p15 st in let x16 = p16 st in let x17 = p17 st in (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) +let inline u_tup18 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 (st: ReaderState) = + let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in + let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in + let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in + let x14 = p14 st in let x15 = p15 st in let x16 = p16 st in let x17 = p17 st in let x18 = p18 st in + (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) //--------------------------------------------------------------------------- // Pickle/unpickle operations for observably shared graph nodes @@ -517,6 +533,11 @@ let p_option f x st = | None -> p_byte 0 st | Some h -> p_byte 1 st; f h st +let p_non_null_slot f (x: 'a | null) st = + match x with + | null -> p_byte 0 st + | h -> p_byte 1 st; f h st + // Pickle lazy values in such a way that they can, in some future F# compiler version, be read back // lazily. However, a lazy reader is not used in this version because the value may contain the definitions of some // OSGN nodes. @@ -620,6 +641,13 @@ let u_option f st = | 1 -> Some (f st) | n -> ufailwith st ("u_option: found number " + string n) +let u_non_null_slot f st = + let tag = u_byte st + match tag with + | 0 -> Unchecked.defaultof<_> + | 1 -> f st + | n -> ufailwith st ("u_option: found number " + string n) + let u_lazy u st = // Read the number of bytes in the record @@ -802,7 +830,11 @@ let check (ilscope: ILScopeRef) (inMap: NodeInTable<_,_>) = for i = 0 to inMap.Count - 1 do let n = inMap.Get i if not (inMap.IsLinked n) then - warning(Error(FSComp.SR.pickleMissingDefinition (i, inMap.Name, ilscope.QualifiedName), range0)) + + // TODO: do not disable + // warning(Error(FSComp.SR.pickleMissingDefinition (i, inMap.Name, ilscope.QualifiedName), range0)) + () + // Note for compiler developers: to get information about which item this index relates to, // enable the conditional in Pickle.p_osgn_ref to refer to the given index number and recompile // an identical copy of the source for the DLL containing the data being unpickled. A message will @@ -973,6 +1005,27 @@ and p_ILCallSig x st = p_tup3 p_ILCallConv p_ILTypes p_ILType (x.CallingConv, x. and p_ILTypeRef (x: ILTypeRef) st = p_tup3 p_ILScopeRef p_strings p_string (x.Scope, x.Enclosing, x.Name) st +and p_ILTypeDefAdditionalFlags (x: ILTypeDefAdditionalFlags) st = + p_int32 (int x) st + +and p_ILTypeDef (x: ILTypeDef) st = + p_string x.Name st + //p_type_attributes x.Attributes + //p_il_type_def_layout x.Layout + //x.Implements + //x.Extends + //x.Methods + //x.NestedTypes + //x.Fields + //x.MethodImpls + //x.Events + //x.Properties + p_ILTypeDefAdditionalFlags x.Flags st + //x.SecurityDeclsStored + //x.CustomAttrsStored + //p_il + //p_int32 x.MetadataIndex st + and p_ILTypeSpec (a: ILTypeSpec) st = p_tup2 p_ILTypeRef p_ILTypes (a.TypeRef, a.GenericArgs) st let u_ILBasicCallConv st = @@ -994,6 +1047,44 @@ let u_ILHasThis st = let u_ILCallConv st = let a, b = u_tup2 u_ILHasThis u_ILBasicCallConv st in Callconv(a, b) let u_ILTypeRef st = let a, b, c = u_tup3 u_ILScopeRef u_strings u_string st in ILTypeRef.Create(a, b, c) + +let u_ILTypeDefAdditionalFlags st : ILTypeDefAdditionalFlags = + let i = u_int32 st + enum i + +let u_ILTypeDef st : ILTypeDef = + let name = u_string st + let attributes = System.Reflection.TypeAttributes.Public + let layout = ILTypeDefLayout.Auto + let implements = Unchecked.defaultof<_> + let genericParams = [] + let extends = Unchecked.defaultof<_> + let methods = ILMethodDefs(fun () -> [||]) + let nestedTypes = Unchecked.defaultof<_> + let fields = Unchecked.defaultof<_> + let methodImpls = Unchecked.defaultof<_> + let events = Unchecked.defaultof<_> + let properties = Unchecked.defaultof<_> + let additionalFlags = u_ILTypeDefAdditionalFlags st + let securityDeclsStored = ILSecurityDecls([||]) + let customAttrsStored = Unchecked.defaultof<_> + + ILTypeDef(name, + attributes, + layout, + implements, + genericParams, + extends, + methods, + nestedTypes, + fields, + methodImpls, + events, + properties, + additionalFlags, + securityDeclsStored, + customAttrsStored) + let u_ILArrayShape = u_wrap (ILArrayShape) (u_list (u_tup2 (u_option u_int32) (u_option u_int32))) @@ -1292,6 +1383,9 @@ let p_Map pk pv x st = let p_qlist pv = p_wrap QueueList.toList (p_list pv) let p_namemap p = p_Map p_string p +let p_stamp = p_int64 +let p_stamp_map pv = p_Map p_stamp pv + let u_Map_core uk uv n st = Map.ofSeq (seq { for _ in 1..n -> (uk st, uv st) }) @@ -1302,6 +1396,9 @@ let u_Map uk uv st = let u_qlist uv = u_wrap QueueList.ofList (u_list uv) let u_namemap u = u_Map u_string u +let u_stamp = u_int64 +let u_stamp_map uv = u_Map u_stamp uv + let p_pos (x: pos) st = p_tup2 p_int p_int (x.Line, x.Column) st let p_range (x: range) st = @@ -1670,13 +1767,31 @@ let p_tyar_spec_data (x: Typar) st = p_xmldoc (x.typar_id, x.Attribs, int64 x.typar_flags.PickledBits, x.Constraints, x.XmlDoc) st +let p_tyar_spec_data_new (x: Typar) st = + p_tup6 + p_ident + p_attribs + p_int64 + p_tyar_constraints + p_xmldoc + p_stamp + (x.typar_id, x.Attribs, int64 x.typar_flags.PickledBits, x.Constraints, x.XmlDoc, x.Stamp) st + let p_tyar_spec (x: Typar) st = //Disabled, workaround for bug 2721: if x.Rigidity <> TyparRigidity.Rigid then warning(Error(sprintf "p_tyar_spec: typar#%d is not rigid" x.Stamp, x.Range)) if x.IsFromError then warning(Error((0, "p_tyar_spec: from error"), x.Range)) p_osgn_decl st.otypars p_tyar_spec_data x st +let p_tyar_spec_new (x: Typar) st = + //Disabled, workaround for bug 2721: if x.Rigidity <> TyparRigidity.Rigid then warning(Error(sprintf "p_tyar_spec: typar#%d is not rigid" x.Stamp, x.Range)) + if x.IsFromError then warning(Error((0, "p_tyar_spec: from error"), x.Range)) + p_osgn_decl st.otypars p_tyar_spec_data_new x st + + let p_tyar_specs = (p_list p_tyar_spec) +let p_tyar_specs_new = (p_list p_tyar_spec_new) + let u_tyar_spec_data st = let a, c, d, e, g = u_tup5 u_ident u_attribs u_int64 u_tyar_constraints u_xmldoc st { typar_id=a @@ -1689,11 +1804,28 @@ let u_tyar_spec_data st = | doc, [], [] when doc.IsEmpty -> None | _ -> Some { typar_il_name = None; typar_xmldoc = g; typar_constraints = e; typar_attribs = c;typar_is_contravariant = false } } +let u_tyar_spec_data_new st = + let a, c, d, e, g, stamp = u_tup6 u_ident u_attribs u_int64 u_tyar_constraints u_xmldoc u_stamp st + { typar_id=a + typar_stamp=stamp + typar_flags=TyparFlags(int32 d) + typar_solution=None + typar_astype= Unchecked.defaultof<_> + typar_opt_data= + match g, e, c with + | doc, [], [] when doc.IsEmpty -> None + | _ -> Some { typar_il_name = None; typar_xmldoc = g; typar_constraints = e; typar_attribs = c;typar_is_contravariant = false } } + let u_tyar_spec st = u_osgn_decl st.itypars u_tyar_spec_data st +let u_tyar_spec_new st = + u_osgn_decl st.itypars u_tyar_spec_data_new st + let u_tyar_specs = (u_list u_tyar_spec) +let u_tyar_specs_new = (u_list u_tyar_spec_new) + let _ = fill_p_ty2 (fun isStructThisArgPos ty st -> let ty = stripTyparEqns ty @@ -1995,6 +2127,84 @@ let rec p_tycon_repr x st = | TILObjectRepr (TILObjectReprData (_, _, td)) -> error (Failure("Unexpected IL type definition"+td.Name)) +and p_tycon_repr_new (x: TyconRepresentation) 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. + + match x with + // Records + | TFSharpTyconRepr { fsobjmodel_rfields = fs; fsobjmodel_kind = TFSharpRecord } -> + p_byte 1 st + p_byte 0 st + p_rfield_table fs st + false + + // Unions without static fields + | TFSharpTyconRepr { fsobjmodel_cases = x; fsobjmodel_kind = TFSharpUnion; fsobjmodel_rfields = fs } when fs.FieldsByIndex.Length = 0 -> + p_byte 1 st + p_byte 1 st + p_array p_unioncase_spec x.CasesTable.CasesByIndex st + false + + // Unions with static fields, added to format + | TFSharpTyconRepr ({ fsobjmodel_cases = cases; fsobjmodel_kind = TFSharpUnion } as r) -> + if st.oglobals.compilingFSharpCore then + let fields = r.fsobjmodel_rfields.FieldsByIndex + let firstFieldRange = fields[0].DefinitionRange + let allFieldsText = fields |> Array.map (fun f -> f.LogicalName) |> String.concat System.Environment.NewLine + raise (Error(FSComp.SR.pickleFsharpCoreBackwardsCompatible("fields in union",allFieldsText), firstFieldRange)) + + p_byte 2 st + p_array p_unioncase_spec cases.CasesTable.CasesByIndex st + p_tycon_objmodel_data r st + false + + | TAsmRepr ilTy -> + p_byte 1 st + p_byte 2 st + p_ILType ilTy st + false + + | TFSharpTyconRepr r -> + p_byte 1 st + p_byte 3 st + p_tycon_objmodel_data r st + false + + | TMeasureableRepr ty -> + p_byte 1 st + p_byte 4 st + p_ty ty st + false + + | TNoRepr -> + p_byte 0 st + false + +#if !NO_TYPEPROVIDERS + | TProvidedTypeRepr info -> + if info.IsErased then + // Pickle erased type definitions as a NoRepr + p_byte 0 st + false + else + // Pickle generated type definitions as a TAsmRepr + p_byte 1 st + p_byte 2 st + p_ILType (mkILBoxedType(ILTypeSpec.Create(TypeProviders.GetILTypeRefOfProvidedType(info.ProvidedType, range0), []))) st + true + + | TProvidedNamespaceRepr _ -> + p_byte 0 st + false +#endif + + | TILObjectRepr (TILObjectReprData (scope, nesting, td)) -> + p_byte 5 st + p_ILScopeRef scope st + (p_list p_ILTypeDef) nesting st + p_ILTypeDef td st + false + and p_tycon_objmodel_data x st = p_tycon_objmodel_kind x.fsobjmodel_kind st p_vrefs "vslots" x.fsobjmodel_vslots st @@ -2062,6 +2272,29 @@ and p_entity_spec_data (x: Entity) st = else p_space 1 () st +and p_entity_spec_data_new (x: Entity) st = + p_tyar_specs_new (x.entity_typars.Force(x.entity_range)) st + p_string x.entity_logical_name st + p_option p_string x.EntityCompiledName st + p_range x.entity_range st + p_stamp x.entity_stamp st + p_option p_pubpath x.entity_pubpath st + p_access x.Accessibility st + p_access x.TypeReprAccessibility st + p_attribs x.entity_attribs st + let _ = p_tycon_repr_new x.entity_tycon_repr st + p_option p_ty_new x.TypeAbbrev st + p_tcaug_new x.entity_tycon_tcaug st + p_string System.String.Empty st + p_kind x.TypeOrMeasureKind st + p_int64 x.entity_flags.Flags st + p_option p_cpath x.entity_cpath st + p_maybe_lazy p_modul_typ_new x.entity_modul_type st + p_exnc_repr x.ExceptionInfo st + if st.oInMem then + p_used_space1 (p_xmldoc x.XmlDoc) st + else + p_space 1 () st and p_tcaug p st = p_tup9 @@ -2091,8 +2324,38 @@ and p_tcaug p st = p.tcaug_abstract, space) st +and p_tcaug_new (p: TyconAugmentation) st = + p_tup9 + (p_option (p_tup2 (p_vref "compare_obj") (p_vref "compare"))) + (p_option (p_vref "compare_withc")) + (p_option (p_tup3 (p_vref "hash_obj") (p_vref "hash_withc") (p_vref "equals_withc"))) + (p_option (p_tup2 (p_vref "hash") (p_vref "equals"))) + (p_list (p_tup2 p_string (p_vref "adhoc"))) + (p_list (p_tup3 p_ty_new p_bool p_dummy_range)) + (p_option p_ty_new) + p_bool + (p_space 1) + (p.tcaug_compare, + p.tcaug_compare_withc, + p.tcaug_hash_and_equals_withc |> Option.map (fun (v1, v2, v3, _) -> (v1, v2, v3)), + p.tcaug_equals, + (p.tcaug_adhoc_list + |> ResizeArray.toList + // Explicit impls of interfaces only get kept in the adhoc list + // in order to get check the well-formedness of an interface. + // Keeping them across assembly boundaries is not valid, because relinking their ValRefs + // does not work correctly (they may get incorrectly relinked to a default member) + |> List.filter (fun (isExplicitImpl, _) -> not isExplicitImpl) + |> List.map (fun (_, vref) -> vref.LogicalName, vref)), + p.tcaug_interfaces, + p.tcaug_super, + p.tcaug_abstract, + space) st + and p_entity_spec x st = p_osgn_decl st.oentities p_entity_spec_data x st +and p_entity_spec_new x st = p_osgn_decl st.oentities p_entity_spec_data_new x st + and p_parentref x st = match x with | ParentNone -> p_byte 0 st @@ -2162,9 +2425,34 @@ and p_ValData x st = else p_space 1 () st +and p_ValData_new x st = + p_string x.val_logical_name st + p_option p_string x.ValCompiledName st + // only keep range information on published values, not on optimization data + p_ranges (x.ValReprInfo |> Option.map (fun _ -> x.val_range, x.DefinitionRange)) st + + p_ty_new x.val_type st + p_stamp x.val_stamp st + + p_int64 x.val_flags.Flags st + p_option p_member_info x.MemberInfo st + p_attribs x.Attribs st + p_option p_ValReprInfo x.ValReprInfo st + p_string x.XmlDocSig st + p_access x.Accessibility st + p_parentref x.TryDeclaringEntity st + p_option p_const x.LiteralValue st + if st.oInMem then + p_used_space1 (p_xmldoc x.XmlDoc) st + else + p_space 1 () st + and p_Val x st = p_osgn_decl st.ovals p_ValData x st +and p_Val_new x st = + p_osgn_decl st.ovals p_ValData_new x st + and p_modul_typ (x: ModuleOrNamespaceType) st = p_tup3 p_istype @@ -2173,86 +2461,496 @@ and p_modul_typ (x: ModuleOrNamespaceType) st = (x.ModuleOrNamespaceKind, x.AllValsAndMembers, x.AllEntities) st -and u_tycon_repr st = - let tag1 = u_byte st - match tag1 with - | 0 -> (fun _flagBit -> TNoRepr) - | 1 -> - let tag2 = u_byte st - match tag2 with - // Records historically use a different format to other FSharpTyconRepr - | 0 -> - let v = u_rfield_table st - (fun _flagBit -> - TFSharpTyconRepr - { - fsobjmodel_cases = Construct.MakeUnionCases [] - fsobjmodel_kind=TFSharpRecord - fsobjmodel_vslots=[] - fsobjmodel_rfields=v - }) - - // Unions without static fields historically use a different format to other FSharpTyconRepr - | 1 -> - let v = u_list u_unioncase_spec st - (fun _flagBit -> Construct.MakeUnionRepr v) +and p_modul_typ_new (x: ModuleOrNamespaceType) st = + p_tup3 + p_istype + (p_qlist p_Val_new) + (p_qlist p_entity_spec_new) + (x.ModuleOrNamespaceKind, x.AllValsAndMembers, x.AllEntities) + st - | 2 -> - let v = u_ILType st - // This is the F# 3.0 extension to the format used for F# provider-generated types, which record an ILTypeRef in the format - // You can think of an F# 2.0 reader as always taking the path where 'flagBit' is false. Thus the F# 2.0 reader will - // interpret provider-generated types as TAsmRepr. - (fun flagBit -> - if flagBit then - let iltref = v.TypeRef - match st.iILModule with - | None -> TNoRepr - | Some iILModule -> - try - let rec find acc enclosingTypeNames (tdefs: ILTypeDefs) = - match enclosingTypeNames with - | [] -> List.rev acc, tdefs.FindByName iltref.Name - | h :: t -> - let nestedTypeDef = tdefs.FindByName h - find (nestedTypeDef :: acc) t nestedTypeDef.NestedTypes - let nestedILTypeDefs, ilTypeDef = find [] iltref.Enclosing iILModule.TypeDefs - TILObjectRepr(TILObjectReprData(st.iilscope, nestedILTypeDefs, ilTypeDef)) - with _ -> - System.Diagnostics.Debug.Assert(false, sprintf "failed to find IL backing metadata for cross-assembly generated type %s" iltref.FullName) - TNoRepr - else - TAsmRepr v) +and p_qualified_name_of_file qualifiedNameOfFile st = + let (QualifiedNameOfFile ident) = qualifiedNameOfFile + p_ident ident st - | 3 -> - let v = u_tycon_objmodel_data st - (fun _flagBit -> TFSharpTyconRepr v) +and p_pragma pragma st = + let (ScopedPragma.WarningOff (range, warningNumber)) = pragma + p_tup2 + p_range + p_int + (range, warningNumber) + st - | 4 -> - let v = u_ty st - (fun _flagBit -> TMeasureableRepr v) +and p_pragmas x st = + p_list p_pragma x st - | _ -> ufailwith st "u_tycon_repr" +and p_long_ident (x: LongIdent) st = + p_list p_ident x st - // Unions with static fields use a different format to other FSharpTyconRepr - | 2 -> - let cases = u_array u_unioncase_spec st - let data = u_tycon_objmodel_data st - fun _flagBit -> TFSharpTyconRepr { data with fsobjmodel_cases = Construct.MakeUnionCases (Array.toList cases) } - | _ -> ufailwith st "u_tycon_repr" +and p_trivia (x: SyntaxTrivia.IdentTrivia) st = + pfailwith st (nameof p_trivia) -and u_tycon_objmodel_data st = - let x1, x2, x3 = u_tup3 u_tycon_objmodel_kind u_vrefs u_rfield_table st - { - fsobjmodel_cases = Construct.MakeUnionCases [] - fsobjmodel_kind=x1 - fsobjmodel_vslots=x2 - fsobjmodel_rfields=x3 - } +and p_syn_long_ident (x: SynLongIdent) st = + let (SynLongIdent (id, dotRanges, trivia)) = x + p_tup3 + p_long_ident + (p_list p_range) + (p_list (p_option p_trivia)) + (id, dotRanges, trivia) + st -and u_attribs_ext extraf st = u_list_ext extraf u_attrib st -and u_unioncase_spec st = - let a = u_rfield_table st - let b = u_ty st +and p_syn_type (x: SynType) st = + pfailwith st (nameof p_syn_type) + +and p_syn_open_decl_target (x: SynOpenDeclTarget) st = + match x with + | SynOpenDeclTarget.ModuleOrNamespace (longId, range)-> + p_byte 0 st + p_tup2 + p_syn_long_ident + p_range + (longId, range) + st + | SynOpenDeclTarget.Type (typeName, range) -> + p_byte 1 st + p_tup2 + p_syn_type + p_range + (typeName, range) + st + +and p_ccu_data (x: CcuData) st = + p_option p_string x.FileName st + p_ILScopeRef x.ILScopeRef st + p_stamp x.Stamp st + p_option p_string x.QualifiedName st + p_string x.SourceCodeDirectory st + p_bool x.IsFSharp st +#if !NO_TYPEPROVIDERS + p_bool x.IsProviderGenerated st +#endif + p_bool x.UsesFSharp20PlusQuotations st + p_entity_spec_data_new x.Contents st + +and p_ccuref_new (x: CcuThunk) st = + p_tup2 + p_ccu_data + p_string + (x.target, x.name) + st + +and p_nleref_new (x: NonLocalEntityRef) st = + let (NonLocalEntityRef (ccu, strings)) = x + p_tup2 + p_ccuref_new + (p_array p_string) + (ccu, strings) + st + + +and p_tcref_new (x: EntityRef) st = + match x with + | ERefLocal x -> p_byte 0 st; p_local_item_ref "tcref" st.oentities x st + | ERefNonLocal x -> p_byte 1 st; p_nleref_new x st + +and p_nonlocal_val_ref_new (nlv: NonLocalValOrMemberRef) st = + let a = nlv.EnclosingEntity + let key = nlv.ItemKey + let pkey = key.PartialKey + p_tcref_new a st + p_option p_string pkey.MemberParentMangledName st + p_bool pkey.MemberIsOverride st + p_string pkey.LogicalName st + p_int pkey.TotalArgCount st + let isStructThisArgPos = + match key.TypeForLinkage with + | None -> false + | Some ty -> checkForInRefStructThisArg st ty + p_option p_ty_new key.TypeForLinkage st + + +and p_vref_new (x: ValRef) st = + match x with + | VRefLocal x -> p_byte 0 st; p_local_item_ref "valref" st.ovals x st + | VRefNonLocal x -> p_byte 1 st; p_nonlocal_val_ref_new x st + +and p_open_decl (x: OpenDeclaration) st = + p_tup6 + p_syn_open_decl_target + (p_option p_range) + (p_list p_tcref_new) + p_tys + p_range + p_bool + (x.Target, x.Range, x.Modules, x.Types, x.AppliedScope, x.IsOwnNamespace) + st + +and p_binding (x: ModuleOrNamespaceBinding) st = + match x with + | ModuleOrNamespaceBinding.Binding binding -> + p_byte 0 st + p_bind binding st + | ModuleOrNamespaceBinding.Module (moduleOrNamespace, moduleOrNamespaceContents) -> + p_byte 1 st + p_tup2 + p_entity_spec_new + p_module_or_namespace_contents + (moduleOrNamespace, moduleOrNamespaceContents) + st + +and p_tup_info (tupInfo: TupInfo) st = + let (TupInfo.Const c) = tupInfo + p_bool c st + +and p_nullness (nullness: Nullness) st = + match nullness.Evaluate() with + | NullnessInfo.WithNull -> p_byte 0 st + | NullnessInfo.WithoutNull -> p_byte 1 st + | NullnessInfo.AmbivalentToNull -> p_byte 2 st + +and p_typars = p_list p_tpref + +and p_ty_new (ty: TType) st : unit = + match ty with + | TType_tuple (tupInfo, l) -> + p_byte 0 st + p_tup2 + p_tup_info + p_tys_new + (tupInfo, l) + st + + | TType_app (tyconRef, typeInstantiation, nullness) -> + p_byte 1 st + p_tup4 + (p_tcref "app") + p_tys_new + p_nullness + (p_non_null_slot p_entity_spec_new) + (tyconRef, typeInstantiation, nullness, tyconRef.binding) + st + + | TType_fun (domainType, rangeType, nullness) -> + p_byte 2 st + p_ty_new domainType st + p_ty_new rangeType st + p_nullness nullness st + + | TType_var (typar, nullness) -> + p_byte 3 st + p_tup4 + p_tpref + p_nullness + (p_option p_ty_new) + p_stamp + (typar, nullness, typar.Solution, typar.Stamp) + st + + | TType_forall (tps, r) -> + p_byte 4 st + p_tup2 + p_typars + p_ty_new + (tps, r) + st + + | TType_measure unt -> + p_byte 5 st + p_measure_expr unt st + + | TType_ucase (uc, tinst) -> + p_byte 6 st + p_tup2 + p_ucref + p_tys_new + (uc, tinst) + st + + | TType_anon (anonInfo, l) -> + p_byte 7 st + p_tup2 + p_anonInfo + p_tys_new + (anonInfo, l) + st + +and p_tys_new l = + let _count = l.Length + p_list p_ty_new l + +and p_expr_new (expr: Expr) st = + match expr with + | Expr.Link e -> p_byte 0 st; p_expr_new e.Value st + | Expr.Const (x, m, ty) -> p_byte 1 st; p_tup3 p_const p_dummy_range p_ty_new (x, m, ty) st + | Expr.Val (a, b, m) -> + p_byte 2 st + p_tup4 + p_vref_new + p_vrefFlags + p_dummy_range + (p_non_null_slot p_Val_new) + (a, b, m, a.binding) + st + | Expr.Op (a, b, c, d) -> p_byte 3 st; p_tup4 p_op_new p_tys_new p_exprs_new p_dummy_range (a, b, c, d) st + | Expr.Sequential (a, b, c, d) -> p_byte 4 st; p_tup4 p_expr_new p_expr_new p_int p_dummy_range (a, b, (match c with NormalSeq -> 0 | ThenDoSeq -> 1), d) st + | Expr.Lambda (_, a1, b0, b1, c, d, e) -> p_byte 5 st; p_tup6 (p_option p_Val) (p_option p_Val) p_Vals p_expr_new p_dummy_range p_ty_new (a1, b0, b1, c, d, e) st + | Expr.TyLambda (_, b, c, d, e) -> p_byte 6 st; p_tup4 p_tyar_specs_new p_expr_new p_dummy_range p_ty_new (b, c, d, e) st + | Expr.App (funcExpr, formalType, typeArgs, args, range) -> + p_byte 7 st + + p_expr_new funcExpr st + p_ty_new formalType st + p_tys_new typeArgs st + p_exprs_new args st + p_dummy_range range st + | Expr.LetRec (a, b, c, _) -> p_byte 8 st; p_tup3 p_binds p_expr_new p_dummy_range (a, b, c) st + | Expr.Let (a, b, c, _) -> p_byte 9 st; p_tup3 p_bind p_expr_new p_dummy_range (a, b, c) st + | Expr.Match (_, a, b, c, d, e) -> p_byte 10 st; p_tup5 p_dummy_range p_dtree p_targets p_dummy_range p_ty_new (a, b, c, d, e) st + | Expr.Obj (_, b, c, d, e, f, g) -> p_byte 11 st; p_tup6 p_ty_new (p_option p_Val) p_expr_new p_methods p_intfs p_dummy_range (b, c, d, e, f, g) st + | Expr.StaticOptimization (a, b, c, d) -> p_byte 12 st; p_tup4 p_constraints p_expr_new p_expr_new p_dummy_range (a, b, c, d) st + | Expr.TyChoose (a, b, c) -> p_byte 13 st; p_tup3 p_tyar_specs_new p_expr_new p_dummy_range (a, b, c) st + | Expr.Quote (ast, _, _, m, ty) -> p_byte 14 st; p_tup3 p_expr_new p_dummy_range p_ty_new (ast, m, ty) st + | Expr.WitnessArg (traitInfo, m) -> p_byte 15 st; p_trait traitInfo st; p_dummy_range m st + | Expr.DebugPoint (_, innerExpr) -> + p_byte 16 st + p_expr_new innerExpr st + +and p_exprs_new = p_list p_expr_new + +and p_module_or_namespace_contents (x: ModuleOrNamespaceContents) st = + match x with + | TMDefs defs -> + p_byte 0 st + p_list p_module_or_namespace_contents defs st + | TMDefOpens openDecls -> + p_byte 1 st + p_list p_open_decl openDecls st + | TMDefLet (binding, range) -> + p_byte 2 st + p_tup2 + p_bind_new + p_range + (binding, range) + st + | TMDefDo (expr, range) -> + p_byte 3 st + p_tup2 + p_expr_new + p_range + (expr, range) + st + | TMDefRec (isRec, opens, tycons, bindings, range) -> + p_byte 4 st + p_tup5 + p_bool + (p_list p_open_decl) + (p_list p_entity_spec_data_new) + (p_list p_binding) + p_range + (isRec, opens, tycons, bindings, range) + st + +and p_checked_impl_file_contents = p_module_or_namespace_contents + +and p_named_debug_point_key (x: NamedDebugPointKey) st = + p_tup2 + p_range + p_string + (x.Range, x.Name) + st + +and p_named_debug_points = p_Map p_named_debug_point_key p_range + +and p_anon_recd_types = p_stamp_map p_anonInfo + +and p_checked_impl_file file st = + let (CheckedImplFile ( + qualifiedNameOfFile, + pragmas, + signature, + contents, + hasExplicitEntryPoint, + isScript, + anonRecdTypeInfo, + namedDebugPointsForInlinedCode)) = file + + p_tup8 + p_qualified_name_of_file + p_pragmas + p_modul_typ_new + p_checked_impl_file_contents + p_bool + p_bool + p_anon_recd_types + p_named_debug_points + (qualifiedNameOfFile, + pragmas, + signature, + contents, + hasExplicitEntryPoint, + isScript, + anonRecdTypeInfo, + namedDebugPointsForInlinedCode) + st + +and u_tycon_repr st = + let tag1 = u_byte st + match tag1 with + | 0 -> (fun _flagBit -> TNoRepr) + | 1 -> + let tag2 = u_byte st + match tag2 with + // Records historically use a different format to other FSharpTyconRepr + | 0 -> + let v = u_rfield_table st + (fun _flagBit -> + TFSharpTyconRepr + { + fsobjmodel_cases = Construct.MakeUnionCases [] + fsobjmodel_kind=TFSharpRecord + fsobjmodel_vslots=[] + fsobjmodel_rfields=v + }) + + // Unions without static fields historically use a different format to other FSharpTyconRepr + | 1 -> + let v = u_list u_unioncase_spec st + (fun _flagBit -> Construct.MakeUnionRepr v) + + | 2 -> + let v = u_ILType st + // This is the F# 3.0 extension to the format used for F# provider-generated types, which record an ILTypeRef in the format + // You can think of an F# 2.0 reader as always taking the path where 'flagBit' is false. Thus the F# 2.0 reader will + // interpret provider-generated types as TAsmRepr. + (fun flagBit -> + if flagBit then + let iltref = v.TypeRef + match st.iILModule with + | None -> TNoRepr + | Some iILModule -> + try + let rec find acc enclosingTypeNames (tdefs: ILTypeDefs) = + match enclosingTypeNames with + | [] -> List.rev acc, tdefs.FindByName iltref.Name + | h :: t -> + let nestedTypeDef = tdefs.FindByName h + find (nestedTypeDef :: acc) t nestedTypeDef.NestedTypes + let nestedILTypeDefs, ilTypeDef = find [] iltref.Enclosing iILModule.TypeDefs + TILObjectRepr(TILObjectReprData(st.iilscope, nestedILTypeDefs, ilTypeDef)) + with _ -> + System.Diagnostics.Debug.Assert(false, sprintf "failed to find IL backing metadata for cross-assembly generated type %s" iltref.FullName) + TNoRepr + else + TAsmRepr v) + + | 3 -> + let v = u_tycon_objmodel_data st + (fun _flagBit -> TFSharpTyconRepr v) + + | 4 -> + let v = u_ty st + (fun _flagBit -> TMeasureableRepr v) + + | _ -> ufailwith st "u_tycon_repr" + + // Unions with static fields use a different format to other FSharpTyconRepr + | 2 -> + let cases = u_array u_unioncase_spec st + let data = u_tycon_objmodel_data st + fun _flagBit -> TFSharpTyconRepr { data with fsobjmodel_cases = Construct.MakeUnionCases (Array.toList cases) } + | _ -> ufailwith st "u_tycon_repr" + + +and u_tycon_repr_new st = + let tag1 = u_byte st + match tag1 with + | 0 -> (fun _flagBit -> TNoRepr) + | 1 -> + let tag2 = u_byte st + match tag2 with + // Records historically use a different format to other FSharpTyconRepr + | 0 -> + let v = u_rfield_table st + (fun _flagBit -> + TFSharpTyconRepr + { + fsobjmodel_cases = Construct.MakeUnionCases [] + fsobjmodel_kind=TFSharpRecord + fsobjmodel_vslots=[] + fsobjmodel_rfields=v + }) + + // Unions without static fields historically use a different format to other FSharpTyconRepr + | 1 -> + let v = u_list u_unioncase_spec st + (fun _flagBit -> Construct.MakeUnionRepr v) + + | 2 -> + let v = u_ILType st + // This is the F# 3.0 extension to the format used for F# provider-generated types, which record an ILTypeRef in the format + // You can think of an F# 2.0 reader as always taking the path where 'flagBit' is false. Thus the F# 2.0 reader will + // interpret provider-generated types as TAsmRepr. + (fun flagBit -> + if flagBit then + let iltref = v.TypeRef + match st.iILModule with + | None -> TNoRepr + | Some iILModule -> + try + let rec find acc enclosingTypeNames (tdefs: ILTypeDefs) = + match enclosingTypeNames with + | [] -> List.rev acc, tdefs.FindByName iltref.Name + | h :: t -> + let nestedTypeDef = tdefs.FindByName h + find (nestedTypeDef :: acc) t nestedTypeDef.NestedTypes + let nestedILTypeDefs, ilTypeDef = find [] iltref.Enclosing iILModule.TypeDefs + TILObjectRepr(TILObjectReprData(st.iilscope, nestedILTypeDefs, ilTypeDef)) + with _ -> + System.Diagnostics.Debug.Assert(false, sprintf "failed to find IL backing metadata for cross-assembly generated type %s" iltref.FullName) + TNoRepr + else + TAsmRepr v) + + | 3 -> + let v = u_tycon_objmodel_data st + (fun _flagBit -> TFSharpTyconRepr v) + + | 4 -> + let v = u_ty st + (fun _flagBit -> TMeasureableRepr v) + + | _ -> ufailwith st "u_tycon_repr" + + // Unions with static fields use a different format to other FSharpTyconRepr + | 2 -> + let cases = u_array u_unioncase_spec st + let data = u_tycon_objmodel_data st + fun _flagBit -> TFSharpTyconRepr { data with fsobjmodel_cases = Construct.MakeUnionCases (Array.toList cases) } + + | 5 -> + // | TILObjectRepr (TILObjectReprData (scope, nesting, td)) -> + let scope = u_ILScopeRef st + let nesting = u_list u_ILTypeDef st + let definition = u_ILTypeDef st + + (fun _flagBit -> TILObjectRepr (TILObjectReprData (scope, nesting, definition))) + + | _ -> ufailwith st "u_tycon_repr" + + +and u_tycon_objmodel_data st = + let x1, x2, x3 = u_tup3 u_tycon_objmodel_kind u_vrefs u_rfield_table st + { + fsobjmodel_cases = Construct.MakeUnionCases [] + fsobjmodel_kind=x1 + fsobjmodel_vslots=x2 + fsobjmodel_rfields=x3 + } + +and u_attribs_ext extraf st = u_list_ext extraf u_attrib st +and u_unioncase_spec st = + let a = u_rfield_table st + let b = u_ty st // The union case compiled name is now computed from Id field when needed and is not stored in UnionCase record. let _c = u_string st @@ -2368,6 +3066,59 @@ and u_entity_spec_data st : Entity = entity_exn_info = x14 } } +and u_entity_spec_data_new st : Entity = + let x1, x2a, x2b, x2c, stamp, x3, (x4a, x4b), x6, x7, x8, x9, _x10, x10b, x11, x12, x13, x14, x15 = + u_tup18 + u_tyar_specs_new + u_string + (u_option u_string) + u_range + u_stamp + (u_option u_pubpath) + (u_tup2 u_access u_access) + u_attribs + u_tycon_repr_new + (u_option u_ty_new) + u_tcaug_new + u_string + u_kind + u_int64 + (u_option u_cpath ) + (u_lazy u_modul_typ_new) + u_exnc_repr + (u_used_space1 u_xmldoc) + st + // We use a bit that was unused in the F# 2.0 format to indicate two possible representations in the F# 3.0 tycon_repr format + //let x7 = x7f (x11 &&& EntityFlags.ReservedBitForPickleFormatTyconReprFlag <> 0L) + //let x11 = x11 &&& ~~~EntityFlags.ReservedBitForPickleFormatTyconReprFlag + + { entity_typars=LazyWithContext.NotLazy x1 + entity_stamp=stamp + entity_logical_name=x2a + entity_range=x2c + entity_pubpath=x3 + entity_attribs=x6 + entity_tycon_repr=x7 false + entity_tycon_tcaug=x9 + entity_flags=EntityFlags x11 + entity_cpath=x12 + entity_modul_type=MaybeLazy.Lazy x13 + entity_il_repr_cache=newCache() + entity_opt_data= + match x2b, x10b, x15, x8, x4a, x4b, x14 with + | None, TyparKind.Type, None, None, TAccess [], TAccess [], TExnNone -> None + | _ -> + Some { Entity.NewEmptyEntityOptData() with + entity_compiled_name = x2b + entity_kind = x10b + entity_xmldoc= defaultArg x15 XmlDoc.Empty + entity_xmldocsig = System.String.Empty + entity_tycon_abbrev = x8 + entity_accessibility = x4a + entity_tycon_repr_accessibility = x4b + entity_exn_info = x14 } + } + and u_tcaug st = let a1, a2, a3, b2, c, d, e, g, _space = u_tup9 @@ -2395,9 +3146,39 @@ and u_tcaug st = tcaug_closed=true tcaug_abstract=g} +and u_tcaug_new st : TyconAugmentation = + let a1, a2, a3, b2, c, d, e, g, _space = + u_tup9 + (u_option (u_tup2 u_vref u_vref)) + (u_option u_vref) + (u_option (u_tup3 u_vref u_vref u_vref)) + (u_option (u_tup2 u_vref u_vref)) + (u_list (u_tup2 u_string u_vref)) + (u_list (u_tup3 u_ty_new u_bool u_dummy_range)) + (u_option u_ty_new) + u_bool + (u_space 1) + st + {tcaug_compare=a1 + tcaug_compare_withc=a2 + tcaug_hash_and_equals_withc=a3 |> Option.map (fun (v1, v2, v3) -> (v1, v2, v3, None)) + tcaug_equals=b2 + // only used for code generation and checking - hence don't care about the values when reading back in + tcaug_hasObjectGetHashCode=false + tcaug_adhoc_list= ResizeArray<_>(c |> List.map (fun (_, vref) -> (false, vref))) + tcaug_adhoc=NameMultiMap.ofList c + tcaug_interfaces=d + tcaug_super=e + // pickled type definitions are always closed (i.e. no more intrinsic members allowed) + tcaug_closed=true + tcaug_abstract=g} + and u_entity_spec st = u_osgn_decl st.ientities u_entity_spec_data st +and u_entity_spec_new st = + u_osgn_decl st.ientities u_entity_spec_data_new st + and u_parentref st = let tag = u_byte st match tag with @@ -2431,81 +3212,565 @@ and u_member_info st : ValMemberInfo = ImplementedSlotSigs=x4 IsImplemented=x5 } -and u_tycon_objmodel_kind st = - let tag = u_byte st - match tag with - | 0 -> TFSharpClass - | 1 -> TFSharpInterface - | 2 -> TFSharpStruct - | 3 -> u_slotsig st |> TFSharpDelegate - | 4 -> TFSharpEnum - | 5 -> TFSharpUnion - | 6 -> TFSharpRecord - | _ -> ufailwith st "u_tycon_objmodel_kind" +and u_tycon_objmodel_kind st = + let tag = u_byte st + match tag with + | 0 -> TFSharpClass + | 1 -> TFSharpInterface + | 2 -> TFSharpStruct + | 3 -> u_slotsig st |> TFSharpDelegate + | 4 -> TFSharpEnum + | 5 -> TFSharpUnion + | 6 -> TFSharpRecord + | _ -> ufailwith st "u_tycon_objmodel_kind" + +and u_vrefFlags st = + match u_byte st with + | 0 -> NormalValUse + | 1 -> CtorValUsedAsSuperInit + | 2 -> CtorValUsedAsSelfInit + | 3 -> PossibleConstrainedCall (u_ty st) + | 4 -> VSlotDirectCall + | _ -> ufailwith st "u_vrefFlags" + +and u_ValData st = + let x1, x1z, x1a, x2, x4, x8, x9, x10, x12, x13, x13b, x14, x15 = + u_tup13 + u_string + (u_option u_string) + u_ranges + u_ty + u_int64 + (u_option u_member_info) + u_attribs + (u_option u_ValReprInfo) + u_string + u_access + u_parentref + (u_option u_const) + (u_used_space1 u_xmldoc) + st + + { val_logical_name = x1 + val_range = (match x1a with None -> range0 | Some(a, _) -> a) + val_type = x2 + val_stamp = newStamp() + val_flags = ValFlags x4 + val_opt_data = + match x1z, x1a, x10, x14, x13, x15, x8, x13b, x12, x9 with + | None, None, None, None, TAccess [], None, None, ParentNone, "", [] -> None + | _ -> + Some { val_compiled_name = x1z + val_other_range = (match x1a with None -> None | Some(_, b) -> Some(b, true)) + val_defn = None + val_repr_info = x10 + val_repr_info_for_display = None + arg_repr_info_for_display = None + val_const = x14 + val_access = x13 + val_xmldoc = defaultArg x15 XmlDoc.Empty + val_other_xmldoc = None + val_member_info = x8 + val_declaring_entity = x13b + val_xmldocsig = x12 + val_attribs = x9 } + } + + +and u_ValData_new st = + let x1, x1z, x1a, x2, stamp, x4, x8, x9, x10, x12, x13, x13b, x14, x15 = + u_tup14 + u_string + (u_option u_string) + u_ranges + u_ty_new + u_stamp + u_int64 + (u_option u_member_info) + u_attribs + (u_option u_ValReprInfo) + u_string + u_access + u_parentref + (u_option u_const) + (u_used_space1 u_xmldoc) + st + + { val_logical_name = x1 + val_range = (match x1a with None -> range0 | Some(a, _) -> a) + val_type = x2 + val_stamp = stamp + val_flags = ValFlags x4 + val_opt_data = + match x1z, x1a, x10, x14, x13, x15, x8, x13b, x12, x9 with + | None, None, None, None, TAccess [], None, None, ParentNone, "", [] -> None + | _ -> + Some { val_compiled_name = x1z + val_other_range = (match x1a with None -> None | Some(_, b) -> Some(b, true)) + val_defn = None + val_repr_info = x10 + val_repr_info_for_display = None + arg_repr_info_for_display = None + val_const = x14 + val_access = x13 + val_xmldoc = defaultArg x15 XmlDoc.Empty + val_other_xmldoc = None + val_member_info = x8 + val_declaring_entity = x13b + val_xmldocsig = x12 + val_attribs = x9 } + } + +and u_Val st = u_osgn_decl st.ivals u_ValData st + +and u_Val_new st = u_osgn_decl st.ivals u_ValData_new st + +and u_modul_typ st = + let x1, x3, x5 = + u_tup3 + u_istype + (u_qlist u_Val) + (u_qlist u_entity_spec) st + ModuleOrNamespaceType(x1, x3, x5) + +and u_modul_typ_new st = + let x1, x3, x5 = + u_tup3 + u_istype + (u_qlist u_Val_new) + (u_qlist u_entity_spec_new) st + ModuleOrNamespaceType(x1, x3, x5) + +and u_qualified_name_of_file st = + let ident = u_ident st + QualifiedNameOfFile(ident) + +and u_pragma st = + let range, warningNumber = + u_tup2 + u_range + u_int + st + + ScopedPragma.WarningOff (range, warningNumber) + +and u_pragmas st = + u_list u_pragma st + +and u_long_ident st = + u_list u_ident st + +and u_trivia st : SyntaxTrivia.IdentTrivia = + ufailwith st (nameof p_trivia) + +and u_syn_long_ident st = + let id, dotRanges, trivia = + u_tup3 + u_long_ident + (u_list u_range) + (u_list (u_option u_trivia)) + st + + SynLongIdent (id, dotRanges, trivia) + +and u_syn_type st : SynType = + ufailwith st (nameof u_syn_type) + +and u_syn_open_decl_target st : SynOpenDeclTarget = + let tag = u_byte st + match tag with + | 0 -> + let longId, range = + u_tup2 + u_syn_long_ident + u_range + st + + SynOpenDeclTarget.ModuleOrNamespace (longId, range) + | 1 -> + let typeName, range = + u_tup2 + u_syn_type + u_range + st + SynOpenDeclTarget.Type (typeName, range) + | _ -> + ufailwith st (nameof u_syn_open_decl_target) + +and u_ccu_data st : CcuData = + let fileName = u_option u_string st + let ilScopeRef = u_ILScopeRef st + let stamp = u_stamp st + let qualifiedName = u_option u_string st + let sourceCodeDirectory = u_string st + let isFSharp = u_bool st +#if !NO_TYPEPROVIDERS + let isProviderGenerated = u_bool st +#endif + let usesFSharp20PlusQuotations = u_bool st + let contents = u_entity_spec_data_new st + + { + FileName = fileName + ILScopeRef = ilScopeRef + Stamp = stamp + QualifiedName = qualifiedName + SourceCodeDirectory = sourceCodeDirectory + IsFSharp = isFSharp +#if !NO_TYPEPROVIDERS + IsProviderGenerated = isProviderGenerated + InvalidateEvent = Unchecked.defaultof<_> + ImportProvidedType = Unchecked.defaultof<_> +#endif + UsesFSharp20PlusQuotations = usesFSharp20PlusQuotations + Contents = contents + TryGetILModuleDef = Unchecked.defaultof<_> + MemberSignatureEquality = Unchecked.defaultof<_> + TypeForwarders = Unchecked.defaultof<_> + XmlDocumentationInfo = Unchecked.defaultof<_> + } + +and u_ccuref_new st : CcuThunk = + let target, name = + u_tup2 + u_ccu_data + u_string + st + + { + target = target + name = name + } + +and u_nleref_new st = + let ccu, strings = + u_tup2 + u_ccuref_new + (u_array u_string) + st + + NonLocalEntityRef (ccu, strings) + +and u_tcref_new st : EntityRef = + let tag = u_byte st + match tag with + | 0 -> u_local_item_ref st.ientities st |> ERefLocal + | 1 -> u_nleref_new st |> ERefNonLocal + | _ -> ufailwith st "u_item_ref" + +and u_nonlocal_val_ref_new st : NonLocalValOrMemberRef = + let a = u_tcref_new st + let b1 = u_option u_string st + let b2 = u_bool st + let b3 = u_string st + let c = u_int st + let d = u_option u_ty_new st + { EnclosingEntity = a + ItemKey=ValLinkageFullKey({ MemberParentMangledName=b1; MemberIsOverride=b2;LogicalName=b3; TotalArgCount=c }, d) } + +and u_vref_new st : ValRef = + let tag = u_byte st + match tag with + | 0 -> u_local_item_ref st.ivals st |> VRefLocal + | 1 -> u_nonlocal_val_ref_new st |> VRefNonLocal + | _ -> ufailwith st "u_item_ref" + +and u_open_decl st : OpenDeclaration = + let target, range, modules, types, appliedScope, isOwnNamespace = + u_tup6 + u_syn_open_decl_target + (u_option u_range) + (u_list u_tcref_new) + u_tys + u_range + u_bool + st + + { + Target = target + Range = range + Modules = modules + Types = types + AppliedScope = appliedScope + IsOwnNamespace = isOwnNamespace + } + +and u_binding st : ModuleOrNamespaceBinding = + let tag = u_byte st + match tag with + | 0 -> + let binding = u_bind st + ModuleOrNamespaceBinding.Binding binding + | 1 -> + let moduleOrNamespace, moduleOrNamespaceContents = + u_tup2 + u_entity_spec_new + u_module_or_namespace_contents + st + ModuleOrNamespaceBinding.Module (moduleOrNamespace, moduleOrNamespaceContents) + | _ -> + ufailwith st (nameof u_binding) + +and u_tup_info st : TupInfo = + let c = u_bool st + TupInfo.Const c + +and u_nullness st = + let tag = u_byte st + let nullnessInfo = + match tag with + | 0 -> NullnessInfo.WithNull + | 1 -> NullnessInfo.WithoutNull + | 2 -> NullnessInfo.AmbivalentToNull + | _ -> ufailwith st (nameof u_nullness) + + Nullness.Known nullnessInfo + +and u_typars = u_list u_tpref + +and u_ty_new st : TType = + let tag = u_byte st + match tag with + | 0 -> + let tupInfo, l = + u_tup2 + u_tup_info + u_tys_new + st + TType_tuple (tupInfo, l) + + | 1 -> + let tyconRef, typeInstantiation, nullness, binding = + u_tup4 + u_tcref + u_tys_new + u_nullness + (u_non_null_slot u_entity_spec_new) + st + + tyconRef.binding <- binding + TType_app (tyconRef, typeInstantiation, nullness) + + | 2 -> + let (domainType, rangeType, nullness) = + u_tup3 + u_ty_new + u_ty_new + u_nullness + st + TType_fun (domainType, rangeType, nullness) + + | 3 -> + let (typar, nullness, solution, stamp) = + u_tup4 + u_tpref + u_nullness + (u_option u_ty_new) + u_stamp + st + + typar.typar_solution <- solution + typar.typar_stamp <- stamp + TType_var (typar, nullness) + + | 4 -> + let (tps, r) = + u_tup2 + u_typars + u_ty_new + st -and u_vrefFlags st = - match u_byte st with - | 0 -> NormalValUse - | 1 -> CtorValUsedAsSuperInit - | 2 -> CtorValUsedAsSelfInit - | 3 -> PossibleConstrainedCall (u_ty st) - | 4 -> VSlotDirectCall - | _ -> ufailwith st "u_vrefFlags" + TType_forall (tps, r) -and u_ValData st = - let x1, x1z, x1a, x2, x4, x8, x9, x10, x12, x13, x13b, x14, x15 = - u_tup13 - u_string - (u_option u_string) - u_ranges - u_ty - u_int64 - (u_option u_member_info) - u_attribs - (u_option u_ValReprInfo) - u_string - u_access - u_parentref - (u_option u_const) - (u_used_space1 u_xmldoc) - st + | 5 -> + let unt = u_measure_expr st + TType_measure unt - { val_logical_name = x1 - val_range = (match x1a with None -> range0 | Some(a, _) -> a) - val_type = x2 - val_stamp = newStamp() - val_flags = ValFlags x4 - val_opt_data = - match x1z, x1a, x10, x14, x13, x15, x8, x13b, x12, x9 with - | None, None, None, None, TAccess [], None, None, ParentNone, "", [] -> None - | _ -> - Some { val_compiled_name = x1z - val_other_range = (match x1a with None -> None | Some(_, b) -> Some(b, true)) - val_defn = None - val_repr_info = x10 - val_repr_info_for_display = None - arg_repr_info_for_display = None - val_const = x14 - val_access = x13 - val_xmldoc = defaultArg x15 XmlDoc.Empty - val_other_xmldoc = None - val_member_info = x8 - val_declaring_entity = x13b - val_xmldocsig = x12 - val_attribs = x9 } - } + | 6 -> + let uc, tinst = + u_tup2 + u_ucref + u_tys_new + st + TType_ucase (uc, tinst) -and u_Val st = u_osgn_decl st.ivals u_ValData st + | 7 -> + let anonInfo, l = + u_tup2 + u_anonInfo + u_tys_new + st + TType_anon (anonInfo, l) + | _ -> + ufailwith st (nameof u_ty_new) +and u_tys_new = u_list u_ty_new -and u_modul_typ st = - let x1, x3, x5 = - u_tup3 - u_istype - (u_qlist u_Val) - (u_qlist u_entity_spec) st - ModuleOrNamespaceType(x1, x3, x5) +and u_expr_new st : Expr = + let tag = u_byte st + match tag with + | 0 -> let e = u_expr_new st + let r = ref e + Expr.Link r + | 1 -> let a = u_const st + let b = u_dummy_range st + let c = u_ty_new st + Expr.Const (a, b, c) + | 2 -> let valRef = u_vref_new st + let flags = u_vrefFlags st + let range = u_dummy_range st + let binding = (u_non_null_slot u_Val_new) st + + valRef.binding <- binding + let expr = Expr.Val (valRef, flags, range) + expr + | 3 -> let a = u_op_new st + let b = u_tys_new st + let c = u_exprs_new st + let d = u_dummy_range st + Expr.Op (a, b, c, d) + | 4 -> let a = u_expr_new st + let b = u_expr_new st + let c = u_int st + let d = u_dummy_range st + let dir = match c with 0 -> NormalSeq | 1 -> ThenDoSeq | _ -> ufailwith st "specialSeqFlag" + Expr.Sequential (a, b, dir, d) + | 5 -> let a0 = u_option u_Val st + let b0 = u_option u_Val st + let b1 = u_Vals st + let c = u_expr_new st + let d = u_dummy_range st + let e = u_ty_new st + Expr.Lambda (newUnique(), a0, b0, b1, c, d, e) + | 6 -> let b = u_tyar_specs_new st + let c = u_expr_new st + let d = u_dummy_range st + let e = u_ty_new st + Expr.TyLambda (newUnique(), b, c, d, e) + | 7 -> let a1 = u_expr_new st + let a2 = u_ty_new st + let b = u_tys_new st + let c = u_exprs_new st + let d = u_dummy_range st + let expr = Expr.App (a1, a2, b, c, d) + expr + | 8 -> let a = u_binds st + let b = u_expr_new st + let c = u_dummy_range st + Expr.LetRec (a, b, c, Construct.NewFreeVarsCache()) + | 9 -> let a = u_bind st + let b = u_expr_new st + let c = u_dummy_range st + Expr.Let (a, b, c, Construct.NewFreeVarsCache()) + | 10 -> let a = u_dummy_range st + let b = u_dtree st + let c = u_targets st + let d = u_dummy_range st + let e = u_ty_new st + Expr.Match (DebugPointAtBinding.NoneAtSticky, a, b, c, d, e) + | 11 -> let b = u_ty_new st + let c = (u_option u_Val) st + let d = u_expr_new st + let e = u_methods st + let f = u_intfs st + let g = u_dummy_range st + Expr.Obj (newUnique(), b, c, d, e, f, g) + | 12 -> let a = u_constraints st + let b = u_expr_new st + let c = u_expr_new st + let d = u_dummy_range st + Expr.StaticOptimization (a, b, c, d) + | 13 -> let a = u_tyar_specs_new st + let b = u_expr_new st + let c = u_dummy_range st + Expr.TyChoose (a, b, c) + | 14 -> let b = u_expr_new st + let c = u_dummy_range st + let d = u_ty_new st + Expr.Quote (b, ref None, false, c, d) // isFromQueryExpression=false + | 15 -> let traitInfo = u_trait st + let m = u_dummy_range st + Expr.WitnessArg (traitInfo, m) + | 16 -> let m = u_dummy_range st + let expr = u_expr_new st + Expr.DebugPoint (DebugPointAtLeafExpr.Yes m, expr) + | _ -> ufailwith st "u_expr" + +and u_exprs_new = u_list u_expr_new + +and u_module_or_namespace_contents st : ModuleOrNamespaceContents = + let tag = u_byte st + match tag with + | 0 -> + let defs = u_list u_module_or_namespace_contents st + TMDefs defs + | 1 -> + let openDecls = u_list u_open_decl st + TMDefOpens openDecls + | 2 -> + let binding, range = + u_tup2 + u_bind_new + u_range + st + TMDefLet(binding, range) + | 3 -> + let expr, range = + u_tup2 + u_expr_new + u_range + st + TMDefDo(expr, range) + | 4 -> + let isRec, opens, tycons, bindings, range = + u_tup5 + u_bool + (u_list u_open_decl) + (u_list u_entity_spec_data_new) + (u_list u_binding) + u_range + st + TMDefRec (isRec, opens, tycons, bindings, range) + | _ -> + ufailwith st (nameof u_module_or_namespace_contents) + +and u_checked_impl_file_contents = u_module_or_namespace_contents + +and u_named_debug_point_key st : NamedDebugPointKey = + let range, name = + u_tup2 + u_range + u_string + st + { Range = range; Name = name} + +and u_named_debug_points = u_Map u_named_debug_point_key u_range + +and u_anon_recd_types = u_stamp_map u_anonInfo + +and u_checked_impl_file st = + let qualifiedNameOfFile, pragmas, signature, contents, hasExplicitEntryPoint, isScript, anonRecdTypeInfo, namedDebugPointsForInlinedCode = + u_tup8 + u_qualified_name_of_file + u_pragmas + u_modul_typ_new + u_checked_impl_file_contents + u_bool + u_bool + u_anon_recd_types + u_named_debug_points + st + + CheckedImplFile( + qualifiedNameOfFile, + pragmas, + signature, + contents, + hasExplicitEntryPoint, + isScript, + anonRecdTypeInfo, + namedDebugPointsForInlinedCode) //--------------------------------------------------------------------------- // Pickle/unpickle for F# expressions (for optimization data) @@ -2577,6 +3842,8 @@ and p_dtree_discrim x st = and p_target (TTarget(a, b, _)) st = p_tup2 p_Vals p_expr (a, b) st and p_bind (TBind(a, b, _)) st = p_tup2 p_Val p_expr (a, b) st +and p_bind_new (TBind(a, b, _)) st = p_tup2 p_Val_new p_expr_new (a, b) st + and p_lval_op_kind x st = p_byte (match x with LAddrOf _ -> 0 | LByrefGet -> 1 | LSet -> 2 | LByrefSet -> 3) st @@ -2611,6 +3878,11 @@ and u_target st = let a, b = u_tup2 u_Vals u_expr st in (TTarget(a, b, None)) and u_bind st = let a = u_Val st in let b = u_expr st in TBind(a, b, DebugPointAtBinding.NoneAtSticky) +and u_bind_new st = + let a = u_Val_new st + let b = u_expr_new st + TBind(a, b, DebugPointAtBinding.NoneAtSticky) + and u_lval_op_kind st = match u_byte st with | 0 -> LAddrOf false @@ -2619,6 +3891,13 @@ and u_lval_op_kind st = | 3 -> LByrefSet | _ -> ufailwith st "uval_op_kind" +and p_ucref_new (UnionCaseRef(a, b)) st = + p_tup3 + (p_tcref "ucref") + p_string + (p_non_null_slot p_entity_spec_new) + (a, b, a.binding) + st and p_op x st = match x with @@ -2668,6 +3947,68 @@ and p_op x st = | TOp.AnonRecdGet (info, n) -> p_byte 32 st; p_anonInfo info st; p_int n st | TOp.Goto _ | TOp.Label _ | TOp.Return -> failwith "unexpected backend construct in pickled TAST" +and p_op_new x st = + match x with + | TOp.UnionCase c -> + p_byte 0 st + p_ucref_new c st + | TOp.ExnConstr c -> p_byte 1 st; p_tcref "op" c st + | TOp.Tuple tupInfo -> + if evalTupInfoIsStruct tupInfo then + p_byte 29 st + else + p_byte 2 st + | TOp.Recd (a, b) -> p_byte 3 st; p_tup2 p_recdInfo (p_tcref "recd op") (a, b) st + | TOp.ValFieldSet a -> p_byte 4 st; p_rfref a st + | TOp.ValFieldGet a -> p_byte 5 st; p_rfref a st + | TOp.UnionCaseTagGet a -> p_byte 6 st; p_tcref "cnstr op" a st + | TOp.UnionCaseFieldGet (a, b) -> p_byte 7 st; p_tup2 p_ucref p_int (a, b) st + | TOp.UnionCaseFieldSet (a, b) -> p_byte 8 st; p_tup2 p_ucref p_int (a, b) st + | TOp.ExnFieldGet (a, b) -> p_byte 9 st; p_tup2 (p_tcref "exn op") p_int (a, b) st + | TOp.ExnFieldSet (a, b) -> p_byte 10 st; p_tup2 (p_tcref "exn op") p_int (a, b) st + | TOp.TupleFieldGet (tupInfo, a) -> + if evalTupInfoIsStruct tupInfo then + p_byte 30 st; p_int a st + else + p_byte 11 st; p_int a st + | TOp.ILAsm (a, b) -> p_byte 12 st; p_tup2 (p_list p_ILInstr) p_tys (a, b) st + | TOp.RefAddrGet _ -> p_byte 13 st + | TOp.UnionCaseProof a -> p_byte 14 st; p_ucref a st + | TOp.Coerce -> p_byte 15 st + | TOp.TraitCall b -> p_byte 16 st; p_trait b st + | TOp.LValueOp (a, b) -> p_byte 17 st; p_tup2 p_lval_op_kind (p_vref "lval") (a, b) st + | TOp.ILCall (a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) + -> p_byte 18 st; p_tup11 p_bool p_bool p_bool p_bool p_vrefFlags p_bool p_bool p_ILMethodRef p_tys p_tys p_tys (a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) st + | TOp.Array -> p_byte 19 st + | TOp.While _ -> p_byte 20 st + | TOp.IntegerForLoop (_, _, dir) -> p_byte 21 st; p_int (match dir with FSharpForLoopUp -> 0 | CSharpForLoopUp -> 1 | FSharpForLoopDown -> 2) st + | TOp.Bytes bytes -> p_byte 22 st; p_bytes bytes st + | TOp.TryWith _ -> p_byte 23 st + | TOp.TryFinally _ -> p_byte 24 st + | TOp.ValFieldGetAddr (a, _) -> p_byte 25 st; p_rfref a st + | TOp.UInt16s arr -> p_byte 26 st; p_array p_uint16 arr st + | TOp.Reraise -> p_byte 27 st + | TOp.UnionCaseFieldGetAddr (a, b, _) -> p_byte 28 st; p_tup2 p_ucref p_int (a, b) st + // Note tag byte 29 is taken for struct tuples, see above + // Note tag byte 30 is taken for struct tuples, see above + (* 29: TOp.Tuple when evalTupInfoIsStruct tupInfo = true *) + (* 30: TOp.TupleFieldGet when evalTupInfoIsStruct tupInfo = true *) + | TOp.AnonRecd info -> p_byte 31 st; p_anonInfo info st + | TOp.AnonRecdGet (info, n) -> p_byte 32 st; p_anonInfo info st; p_int n st + | TOp.Goto _ | TOp.Label _ | TOp.Return -> failwith "unexpected backend construct in pickled TAST" + +and u_ucref_new st = + let tcref, caseName, binding = + u_tup3 + u_tcref + u_string + (u_non_null_slot u_entity_spec_new) + st + + tcref.binding <- binding + UnionCaseRef(tcref, caseName) + + and u_op st = let tag = u_byte st match tag with @@ -2739,6 +4080,78 @@ and u_op st = TOp.AnonRecdGet (info, n) | _ -> ufailwith st "u_op" +and u_op_new st = + let tag = u_byte st + match tag with + | 0 -> let a = u_ucref_new st + TOp.UnionCase a + | 1 -> let a = u_tcref st + TOp.ExnConstr a + | 2 -> TOp.Tuple tupInfoRef + | 3 -> let b = u_tcref st + TOp.Recd (RecdExpr, b) + | 4 -> let a = u_rfref st + TOp.ValFieldSet a + | 5 -> let a = u_rfref st + TOp.ValFieldGet a + | 6 -> let a = u_tcref st + TOp.UnionCaseTagGet a + | 7 -> let a = u_ucref st + let b = u_int st + TOp.UnionCaseFieldGet (a, b) + | 8 -> let a = u_ucref st + let b = u_int st + TOp.UnionCaseFieldSet (a, b) + | 9 -> let a = u_tcref st + let b = u_int st + TOp.ExnFieldGet (a, b) + | 10 -> let a = u_tcref st + let b = u_int st + TOp.ExnFieldSet (a, b) + | 11 -> let a = u_int st + TOp.TupleFieldGet (tupInfoRef, a) + | 12 -> let a = (u_list u_ILInstr) st + let b = u_tys st + TOp.ILAsm (a, b) + | 13 -> TOp.RefAddrGet false // ok to set the 'readonly' flag on these operands to false on re-read since the flag is only used for typechecking purposes + | 14 -> let a = u_ucref st + TOp.UnionCaseProof a + | 15 -> TOp.Coerce + | 16 -> let a = u_trait st + TOp.TraitCall a + | 17 -> let a = u_lval_op_kind st + let b = u_vref st + TOp.LValueOp (a, b) + | 18 -> let a1, a2, a3, a4, a5, a7, a8, a9 = (u_tup8 u_bool u_bool u_bool u_bool u_vrefFlags u_bool u_bool u_ILMethodRef) st + let b = u_tys st + let c = u_tys st + let d = u_tys st + TOp.ILCall (a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) + | 19 -> TOp.Array + | 20 -> TOp.While (DebugPointAtWhile.No, NoSpecialWhileLoopMarker) + | 21 -> let dir = match u_int st with 0 -> FSharpForLoopUp | 1 -> CSharpForLoopUp | 2 -> FSharpForLoopDown | _ -> failwith "unknown for loop" + TOp.IntegerForLoop (DebugPointAtFor.No, DebugPointAtInOrTo.No, dir) + | 22 -> TOp.Bytes (u_bytes st) + | 23 -> TOp.TryWith (DebugPointAtTry.No, DebugPointAtWith.No) + | 24 -> TOp.TryFinally (DebugPointAtTry.No, DebugPointAtFinally.No) + | 25 -> let a = u_rfref st + TOp.ValFieldGetAddr (a, false) + | 26 -> TOp.UInt16s (u_array u_uint16 st) + | 27 -> TOp.Reraise + | 28 -> let a = u_ucref st + let b = u_int st + TOp.UnionCaseFieldGetAddr (a, b, false) + | 29 -> TOp.Tuple tupInfoStruct + | 30 -> let a = u_int st + TOp.TupleFieldGet (tupInfoStruct, a) + | 31 -> let info = u_anonInfo st + TOp.AnonRecd info + | 32 -> let info = u_anonInfo st + let n = u_int st + TOp.AnonRecdGet (info, n) + | _ -> ufailwith st "u_op" + + and p_expr expr st = match expr with | Expr.Link e -> p_expr e.Value st @@ -2902,8 +4315,33 @@ let pickleModuleOrNamespace mspec st = p_entity_spec mspec st let pickleCcuInfo (minfo: PickledCcuInfo) st = p_tup4 pickleModuleOrNamespace p_string p_bool (p_space 3) (minfo.mspec, minfo.compileTimeWorkingDir, minfo.usesQuotations, ()) st +let pickleTcInfo (tcInfo: PickledTcInfo) (st: WriterState) = + p_tup4 + p_attribs + p_attribs + p_attribs + (p_list p_checked_impl_file) + (tcInfo.MainMethodAttrs, tcInfo.NetModuleAttrs, tcInfo.AssemblyAttrs, tcInfo.DeclaredImpls) + st + let unpickleModuleOrNamespace st = u_entity_spec st let unpickleCcuInfo st = let a, b, c, _space = u_tup4 unpickleModuleOrNamespace u_string u_bool (u_space 3) st { mspec=a; compileTimeWorkingDir=b; usesQuotations=c } + +let unpickleTcInfo st : PickledTcInfo = + let mainMethodAttrs, netModuleAttrs, assemblyAttrs, declaredImpls = + u_tup4 + u_attribs + u_attribs + u_attribs + (u_list u_checked_impl_file) + st + + { + MainMethodAttrs = mainMethodAttrs + NetModuleAttrs = netModuleAttrs + AssemblyAttrs = assemblyAttrs + DeclaredImpls = declaredImpls + } diff --git a/src/Compiler/TypedTree/TypedTreePickle.fsi b/src/Compiler/TypedTree/TypedTreePickle.fsi index 3e3910bd4e1..1b8dbe79152 100644 --- a/src/Compiler/TypedTree/TypedTreePickle.fsi +++ b/src/Compiler/TypedTree/TypedTreePickle.fsi @@ -83,6 +83,9 @@ val internal p_ty: pickler /// Serialize a TAST description of a compilation unit val internal pickleCcuInfo: pickler +/// Serialize typechecking info +val internal pickleTcInfo: pickler + /// Serialize an arbitrary object using the given pickler val pickleObjWithDanglingCcus: inMem: bool -> file: string -> TcGlobals -> scope: CcuThunk -> pickler<'T> -> 'T -> ByteBuffer * ByteBuffer @@ -145,6 +148,9 @@ val internal u_ty: unpickler /// Deserialize a TAST description of a compilation unit val internal unpickleCcuInfo: ReaderState -> PickledCcuInfo +/// Deserialize typechecking info +val internal unpickleTcInfo: ReaderState -> PickledTcInfo + /// Deserialize an arbitrary object which may have holes referring to other compilation units val internal unpickleObjWithDanglingCcus: file: string -> diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index a83be01f432..b2e8152e8e3 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -265,6 +265,7 @@ + diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Activities.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Activities.fs index 1054b4af2a9..aa017d8fb2b 100644 --- a/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Activities.fs +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Activities.fs @@ -139,6 +139,8 @@ type Activities() = let cUnit = FsxFromPath tempPath |> withReuseTcResults + |> withOptions [ "--compressmetadata-" ] + |> withOptions [ "--optimize-" ] cUnit |> compileExisting diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Recompilation.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Recompilation.fs new file mode 100644 index 00000000000..a59e44185d6 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Recompilation.fs @@ -0,0 +1,82 @@ +namespace TypeChecks.ReuseTcResultsTests + +open System.IO + +open FSharp.Test +open FSharp.Test.Compiler + +open Xunit + +open TestFramework + + +[] +type Recompilation() = + + [] + [] + [] + [] + [] + [] + [] + [] + [] + [] + [] + [] + [ 42">] + [] + [] + + [] + [] + [] + [] + [] + [] + + //[] + //[] + //[] + //[] + //[] + //[] + let ``Recompiles using restored TC info`` (code: string) = + let fileName = getTemporaryFileName() + let tempPath = $"{fileName}.fsx" + + File.WriteAllText(tempPath, code) + + let cUnit = + FsxFromPath tempPath + |> withReuseTcResults + |> withOptions [ "--compressmetadata-" ] + |> withOptions [ "--optimize-" ] + + let expected = + cUnit + |> compileExisting + |> shouldSucceed + |> fun r -> ILChecker.generateIL r.Output.OutputPath.Value [] + + let actual = + cUnit + |> compileExisting + |> shouldSucceed + |> fun r -> ILChecker.generateIL r.Output.OutputPath.Value [] + + let outcome, _msg, _actualIL = + ILChecker.compareIL + fileName + actual + [ expected ] + + Assert.True(outcome) + diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl index 1836a6673c1..1f0e9b2464f 100755 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl @@ -845,6 +845,7 @@ FSharp.Compiler.AbstractIL.IL+ILMethodDefs: Microsoft.FSharp.Collections.FSharpL FSharp.Compiler.AbstractIL.IL+ILMethodDefs: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodDef] FindByName(System.String) FSharp.Compiler.AbstractIL.IL+ILMethodDefs: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodDef] TryFindInstanceByNameAndCallingSignature(System.String, ILCallingSignature) FSharp.Compiler.AbstractIL.IL+ILMethodDefs: System.Collections.Generic.IDictionary`2[System.String,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodDef]] CreateDictionary(ILMethodDef[]) +FSharp.Compiler.AbstractIL.IL+ILMethodDefs: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,FSharp.Compiler.AbstractIL.IL+ILMethodDef[]]) FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Boolean Equals(ILMethodImplDef) FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Boolean Equals(ILMethodImplDef, System.Collections.IEqualityComparer) FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Boolean Equals(System.Object) @@ -1568,6 +1569,8 @@ FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILSecurityDecls get_SecurityDecls() FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDef With(Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.TypeAttributes], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout], Microsoft.FSharp.Core.FSharpOption`1[Internal.Utilities.Library.InterruptibleLazy`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+InterfaceImpl]]], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef]], Microsoft.FSharp.Core.FSharpOption`1[Internal.Utilities.Library.InterruptibleLazy`1[Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType]]], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodImplDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILEventDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILPropertyDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefAdditionalFlags], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILAttributesStored], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILSecurityDecls]) FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefAccess Access FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefAccess get_Access() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefAdditionalFlags Flags +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefAdditionalFlags get_Flags() FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefLayout Layout FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefLayout get_Layout() FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefs NestedTypes @@ -2830,12 +2833,20 @@ FSharp.Compiler.Diagnostics.ExtendedData+DiagnosticContextInfo: Int32 GetHashCod FSharp.Compiler.Diagnostics.ExtendedData+DiagnosticContextInfo: Int32 Tag FSharp.Compiler.Diagnostics.ExtendedData+DiagnosticContextInfo: Int32 get_Tag() FSharp.Compiler.Diagnostics.ExtendedData+DiagnosticContextInfo: System.String ToString() +FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] DiagnosticId +FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] UrlFormat +FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_DiagnosticId() +FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_UrlFormat() FSharp.Compiler.Diagnostics.ExtendedData+ExpressionIsAFunctionExtendedData: FSharp.Compiler.Symbols.FSharpType ActualType FSharp.Compiler.Diagnostics.ExtendedData+ExpressionIsAFunctionExtendedData: FSharp.Compiler.Symbols.FSharpType get_ActualType() FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData: FSharp.Compiler.Symbols.FSharpField ImplementationField FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData: FSharp.Compiler.Symbols.FSharpField SignatureField FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData: FSharp.Compiler.Symbols.FSharpField get_ImplementationField() FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData: FSharp.Compiler.Symbols.FSharpField get_SignatureField() +FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] DiagnosticId +FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] UrlFormat +FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_DiagnosticId() +FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_UrlFormat() FSharp.Compiler.Diagnostics.ExtendedData+TypeMismatchDiagnosticExtendedData: DiagnosticContextInfo ContextInfo FSharp.Compiler.Diagnostics.ExtendedData+TypeMismatchDiagnosticExtendedData: DiagnosticContextInfo get_ContextInfo() FSharp.Compiler.Diagnostics.ExtendedData+TypeMismatchDiagnosticExtendedData: FSharp.Compiler.Symbols.FSharpDisplayContext DisplayContext @@ -2851,21 +2862,13 @@ FSharp.Compiler.Diagnostics.ExtendedData+ValueNotContainedDiagnosticExtendedData FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ArgumentsInSigAndImplMismatchExtendedData FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+DefinitionsInSigAndImplNotCompatibleAbbreviationsDifferExtendedData FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+DiagnosticContextInfo +FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ExpressionIsAFunctionExtendedData FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+IFSharpDiagnosticExtendedData FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+TypeMismatchDiagnosticExtendedData FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ValueNotContainedDiagnosticExtendedData -FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] DiagnosticId -FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] UrlFormat -FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_DiagnosticId() -FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_UrlFormat() -FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] DiagnosticId -FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] UrlFormat -FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_DiagnosticId() -FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_UrlFormat() -FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnostic Create(FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity, System.String, Int32, FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity Severity FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity get_Severity() diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl index fabaa710607..1f0e9b2464f 100755 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl @@ -845,6 +845,7 @@ FSharp.Compiler.AbstractIL.IL+ILMethodDefs: Microsoft.FSharp.Collections.FSharpL FSharp.Compiler.AbstractIL.IL+ILMethodDefs: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodDef] FindByName(System.String) FSharp.Compiler.AbstractIL.IL+ILMethodDefs: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodDef] TryFindInstanceByNameAndCallingSignature(System.String, ILCallingSignature) FSharp.Compiler.AbstractIL.IL+ILMethodDefs: System.Collections.Generic.IDictionary`2[System.String,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodDef]] CreateDictionary(ILMethodDef[]) +FSharp.Compiler.AbstractIL.IL+ILMethodDefs: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,FSharp.Compiler.AbstractIL.IL+ILMethodDef[]]) FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Boolean Equals(ILMethodImplDef) FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Boolean Equals(ILMethodImplDef, System.Collections.IEqualityComparer) FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Boolean Equals(System.Object) @@ -1568,6 +1569,8 @@ FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILSecurityDecls get_SecurityDecls() FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDef With(Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.TypeAttributes], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout], Microsoft.FSharp.Core.FSharpOption`1[Internal.Utilities.Library.InterruptibleLazy`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+InterfaceImpl]]], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef]], Microsoft.FSharp.Core.FSharpOption`1[Internal.Utilities.Library.InterruptibleLazy`1[Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType]]], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodImplDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILEventDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILPropertyDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefAdditionalFlags], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILAttributesStored], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILSecurityDecls]) FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefAccess Access FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefAccess get_Access() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefAdditionalFlags Flags +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefAdditionalFlags get_Flags() FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefLayout Layout FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefLayout get_Layout() FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefs NestedTypes @@ -2830,12 +2833,20 @@ FSharp.Compiler.Diagnostics.ExtendedData+DiagnosticContextInfo: Int32 GetHashCod FSharp.Compiler.Diagnostics.ExtendedData+DiagnosticContextInfo: Int32 Tag FSharp.Compiler.Diagnostics.ExtendedData+DiagnosticContextInfo: Int32 get_Tag() FSharp.Compiler.Diagnostics.ExtendedData+DiagnosticContextInfo: System.String ToString() +FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] DiagnosticId +FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] UrlFormat +FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_DiagnosticId() +FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_UrlFormat() FSharp.Compiler.Diagnostics.ExtendedData+ExpressionIsAFunctionExtendedData: FSharp.Compiler.Symbols.FSharpType ActualType FSharp.Compiler.Diagnostics.ExtendedData+ExpressionIsAFunctionExtendedData: FSharp.Compiler.Symbols.FSharpType get_ActualType() FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData: FSharp.Compiler.Symbols.FSharpField ImplementationField FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData: FSharp.Compiler.Symbols.FSharpField SignatureField FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData: FSharp.Compiler.Symbols.FSharpField get_ImplementationField() FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData: FSharp.Compiler.Symbols.FSharpField get_SignatureField() +FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] DiagnosticId +FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] UrlFormat +FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_DiagnosticId() +FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_UrlFormat() FSharp.Compiler.Diagnostics.ExtendedData+TypeMismatchDiagnosticExtendedData: DiagnosticContextInfo ContextInfo FSharp.Compiler.Diagnostics.ExtendedData+TypeMismatchDiagnosticExtendedData: DiagnosticContextInfo get_ContextInfo() FSharp.Compiler.Diagnostics.ExtendedData+TypeMismatchDiagnosticExtendedData: FSharp.Compiler.Symbols.FSharpDisplayContext DisplayContext @@ -2851,22 +2862,13 @@ FSharp.Compiler.Diagnostics.ExtendedData+ValueNotContainedDiagnosticExtendedData FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ArgumentsInSigAndImplMismatchExtendedData FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+DefinitionsInSigAndImplNotCompatibleAbbreviationsDifferExtendedData FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+DiagnosticContextInfo +FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ExpressionIsAFunctionExtendedData FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+FieldNotContainedDiagnosticExtendedData FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+IFSharpDiagnosticExtendedData FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+TypeMismatchDiagnosticExtendedData FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ValueNotContainedDiagnosticExtendedData -FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] DiagnosticId -FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] UrlFormat -FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_DiagnosticId() -FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_UrlFormat() -FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData -FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] DiagnosticId -FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] UrlFormat -FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_DiagnosticId() -FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_UrlFormat() -FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ExperimentalExtendedData FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnostic Create(FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity, System.String, Int32, FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity Severity FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity get_Severity() diff --git a/tests/FSharp.Test.Utilities/ILChecker.fs b/tests/FSharp.Test.Utilities/ILChecker.fs index 69b5d6c6c6a..904061b8fb7 100644 --- a/tests/FSharp.Test.Utilities/ILChecker.fs +++ b/tests/FSharp.Test.Utilities/ILChecker.fs @@ -113,14 +113,14 @@ module ILChecker = ilFilePath - let private generateIL (dllFilePath: string) ildasmArgs = + let generateIL (dllFilePath: string) ildasmArgs = let assemblyName = Some (Path.GetFileNameWithoutExtension dllFilePath) let ilFilePath = generateIlFile dllFilePath ildasmArgs let normalizedText = normalizeILText assemblyName (File.ReadAllText(ilFilePath)) File.WriteAllText(ilFilePath, normalizedText) normalizedText - let private compareIL assemblyName (actualIL: string) expectedIL = + let compareIL assemblyName (actualIL: string) expectedIL = let mutable errorMsgOpt = None From cec808767ce7459a53155ac903822d07e5684c04 Mon Sep 17 00:00:00 2001 From: Petr Date: Mon, 17 Feb 2025 20:02:26 +0100 Subject: [PATCH 3/8] Refactoring --- src/Compiler/Driver/CompilerImports.fs | 48 ------ src/Compiler/Driver/CompilerImports.fsi | 30 ++-- .../Driver/ReuseTcResults/CachingDriver.fs | 21 +-- .../Driver/ReuseTcResults/TcResultsImport.fs | 49 ++++++ .../Driver/ReuseTcResults/TcResultsPickle.fs | 36 ++++ src/Compiler/Driver/fsc.fs | 2 +- src/Compiler/FSharp.Compiler.Service.fsproj | 3 +- src/Compiler/TypedTree/TypedTree.fs | 7 - src/Compiler/TypedTree/TypedTree.fsi | 6 - src/Compiler/TypedTree/TypedTreePickle.fs | 25 --- src/Compiler/TypedTree/TypedTreePickle.fsi | 162 ------------------ tests/FSharp.Test.Utilities/Compiler.fs | 2 +- 12 files changed, 109 insertions(+), 282 deletions(-) create mode 100644 src/Compiler/Driver/ReuseTcResults/TcResultsImport.fs create mode 100644 src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs delete mode 100644 src/Compiler/TypedTree/TypedTreePickle.fsi diff --git a/src/Compiler/Driver/CompilerImports.fs b/src/Compiler/Driver/CompilerImports.fs index 170db2c6f17..ae14ee51157 100644 --- a/src/Compiler/Driver/CompilerImports.fs +++ b/src/Compiler/Driver/CompilerImports.fs @@ -337,54 +337,6 @@ let EncodeOptimizationData (tcGlobals, tcConfig: TcConfig, outfile, exportRemapp else [] -let GetTypecheckingData (file, ilScopeRef, ilModule, byteReaderA, byteReaderB) = - - let memA = byteReaderA () - - let memB = - match byteReaderB with - | None -> ByteMemory.Empty.AsReadOnly() - | Some br -> br () - - unpickleObjWithDanglingCcus file ilScopeRef ilModule unpickleTcInfo memA memB - -let WriteTypecheckingData (tcConfig: TcConfig, tcGlobals, fileName, inMem, ccu, tcInfo) = - - // need to understand the naming and if we even want two resources here... - let rName = "FSharpTypecheckingData" - let rNameB = "FSharpTypecheckingDataB" - - PickleToResource - inMem - fileName - tcGlobals - tcConfig.compressMetadata - ccu - (rName + ccu.AssemblyName) - (rNameB + ccu.AssemblyName) - pickleTcInfo - tcInfo - -let EncodeTypecheckingData (tcConfig: TcConfig, tcGlobals, generatedCcu, outfile, isIncrementalBuild, tcInfo) = - let r1, r2 = - WriteTypecheckingData( - tcConfig, - tcGlobals, - outfile, - isIncrementalBuild, - generatedCcu, - tcInfo) - - let resources = - [ - r1 - match r2 with - | None -> () - | Some r -> r - ] - - resources - exception AssemblyNotResolved of originalName: string * range: range exception MSBuildReferenceResolutionWarning of message: string * warningCode: string * range: range diff --git a/src/Compiler/Driver/CompilerImports.fsi b/src/Compiler/Driver/CompilerImports.fsi index aa885a7b705..3efa43d1236 100644 --- a/src/Compiler/Driver/CompilerImports.fsi +++ b/src/Compiler/Driver/CompilerImports.fsi @@ -53,6 +53,19 @@ val IsReflectedDefinitionsResource: ILResource -> bool val GetResourceNameAndSignatureDataFuncs: ILResource list -> (string * ((unit -> ReadOnlyByteMemory) * (unit -> ReadOnlyByteMemory) option)) list +/// Pickling primitive +val PickleToResource: + inMem: bool -> + file: string -> + g: TcGlobals -> + compress: bool -> + scope: CcuThunk -> + rName: string -> + rNameB: string -> + p: ('a -> WriterState -> unit) -> + x: 'a -> + ILResource * ILResource option + /// Encode the F# interface data into a set of IL attributes and resources val EncodeSignatureData: tcConfig: TcConfig * @@ -72,23 +85,6 @@ val EncodeOptimizationData: isIncrementalBuild: bool -> ILResource list -val GetTypecheckingData: - file: string * - ilScopeRef: ILScopeRef * - ilModule: ILModuleDef option * - byteReaderA: (unit -> ReadOnlyByteMemory) * - byteReaderB: (unit -> ReadOnlyByteMemory) option -> - PickledDataWithReferences - -val EncodeTypecheckingData: - tcConfig: TcConfig * - tcGlobals: TcGlobals * - generatedCcu: CcuThunk * - outfile: string * - isIncrementalBuild: bool * - tcInfo: PickledTcInfo -> - ILResource list - [] type ResolveAssemblyReferenceMode = | Speculative diff --git a/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs b/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs index 89b04537b1e..05bc7631a4b 100644 --- a/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs +++ b/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs @@ -1,4 +1,4 @@ -module internal FSharp.Compiler.ReuseTcResults +module internal FSharp.Compiler.ReuseTcResults.CachingDriver open System.Collections.Generic open System.IO @@ -11,8 +11,8 @@ open FSharp.Compiler.IO open FSharp.Compiler.ParseAndCheckInputs open FSharp.Compiler.Syntax open FSharp.Compiler.Syntax.PrettyNaming -open FSharp.Compiler.TypedTree -open CompilerImports +open FSharp.Compiler.ReuseTcResults.TcResultsImport +open FSharp.Compiler.ReuseTcResults.TcResultsPickle open FSharp.Compiler.AbstractIL.IL type TcData = @@ -164,21 +164,16 @@ type CachingDriver(tcConfig: TcConfig) = let rawData = tcInfo.RawData - let topAttrs: TopAttribs = - { - mainMethodAttrs = rawData.MainMethodAttrs - netModuleAttrs = rawData.NetModuleAttrs - assemblyAttrs = rawData.AssemblyAttrs - } + let topAttribs = rawData.TopAttribs // need to understand if anything can be used here, pickling state is hard tcInitialState, - topAttrs, + topAttribs, rawData.DeclaredImpls, // this is quite definitely wrong, need to figure out what to do with the environment tcInitialState.TcEnvFromImpls - member _.CacheTcResults(tcState: TcState, topAttrs: TopAttribs, declaredImpls, tcEnvAtEndOfLastFile, inputs, tcGlobals, outfile) = + member _.CacheTcResults(tcState: TcState, topAttribs: TopAttribs, declaredImpls, tcEnvAtEndOfLastFile, inputs, tcGlobals, outfile) = let thisTcData = { CmdLine = getThisCompilationCmdLine tcConfig.cmdLineArgs @@ -190,9 +185,7 @@ type CachingDriver(tcConfig: TcConfig) = let tcInfo = { - MainMethodAttrs = topAttrs.mainMethodAttrs - NetModuleAttrs = topAttrs.netModuleAttrs - AssemblyAttrs = topAttrs.assemblyAttrs + TopAttribs = topAttribs DeclaredImpls = declaredImpls } diff --git a/src/Compiler/Driver/ReuseTcResults/TcResultsImport.fs b/src/Compiler/Driver/ReuseTcResults/TcResultsImport.fs new file mode 100644 index 00000000000..9941b48a206 --- /dev/null +++ b/src/Compiler/Driver/ReuseTcResults/TcResultsImport.fs @@ -0,0 +1,49 @@ +module internal FSharp.Compiler.ReuseTcResults.TcResultsImport + +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.IO +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.TypedTreePickle +open FSharp.Compiler.ReuseTcResults.TcResultsPickle + +let GetTypecheckingData (file, ilScopeRef, ilModule, byteReaderA, byteReaderB) = + + let memA = byteReaderA () + + let memB = + match byteReaderB with + | None -> ByteMemory.Empty.AsReadOnly() + | Some br -> br () + + unpickleObjWithDanglingCcus file ilScopeRef ilModule unpickleTcInfo memA memB + +let WriteTypecheckingData (tcConfig: TcConfig, tcGlobals, fileName, inMem, ccu, tcInfo) = + + // need to understand the naming and if we even want two resources here... + let rName = "FSharpTypecheckingData" + let rNameB = "FSharpTypecheckingDataB" + + PickleToResource + inMem + fileName + tcGlobals + tcConfig.compressMetadata + ccu + (rName + ccu.AssemblyName) + (rNameB + ccu.AssemblyName) + pickleTcInfo + tcInfo + +let EncodeTypecheckingData (tcConfig: TcConfig, tcGlobals, generatedCcu, outfile, isIncrementalBuild, tcInfo) = + let r1, r2 = + WriteTypecheckingData(tcConfig, tcGlobals, outfile, isIncrementalBuild, generatedCcu, tcInfo) + + let resources = + [ + r1 + match r2 with + | None -> () + | Some r -> r + ] + + resources diff --git a/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs b/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs new file mode 100644 index 00000000000..38c082afd10 --- /dev/null +++ b/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs @@ -0,0 +1,36 @@ +module internal FSharp.Compiler.ReuseTcResults.TcResultsPickle + +open FSharp.Compiler.CheckDeclarations +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreePickle + +type PickledTcInfo = + { + TopAttribs: TopAttribs + DeclaredImpls: CheckedImplFile list + } + +let pickleTcInfo (tcInfo: PickledTcInfo) (st: WriterState) = + p_tup4 + p_attribs + p_attribs + p_attribs + (p_list p_checked_impl_file) + (tcInfo.TopAttribs.mainMethodAttrs, tcInfo.TopAttribs.netModuleAttrs, tcInfo.TopAttribs.assemblyAttrs, tcInfo.DeclaredImpls) + st + +let unpickleTcInfo st : PickledTcInfo = + let mainMethodAttrs, netModuleAttrs, assemblyAttrs, declaredImpls = + u_tup4 u_attribs u_attribs u_attribs (u_list u_checked_impl_file) st + + let attribs: TopAttribs = + { + mainMethodAttrs = mainMethodAttrs + netModuleAttrs = netModuleAttrs + assemblyAttrs = assemblyAttrs + } + + { + TopAttribs = attribs + DeclaredImpls = declaredImpls + } diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs index 5b9bbb25be3..e66a119d1fa 100644 --- a/src/Compiler/Driver/fsc.fs +++ b/src/Compiler/Driver/fsc.fs @@ -54,7 +54,7 @@ open FSharp.Compiler.TypedTree open FSharp.Compiler.TypedTreeOps open FSharp.Compiler.XmlDocFileWriter open FSharp.Compiler.CheckExpressionsOps -open ReuseTcResults +open FSharp.Compiler.ReuseTcResults.CachingDriver //---------------------------------------------------------------------------- // Reporting - warnings, errors diff --git a/src/Compiler/FSharp.Compiler.Service.fsproj b/src/Compiler/FSharp.Compiler.Service.fsproj index b69652a811f..69b3dc0dbfc 100644 --- a/src/Compiler/FSharp.Compiler.Service.fsproj +++ b/src/Compiler/FSharp.Compiler.Service.fsproj @@ -333,7 +333,6 @@ - @@ -464,6 +463,8 @@ + + diff --git a/src/Compiler/TypedTree/TypedTree.fs b/src/Compiler/TypedTree/TypedTree.fs index 0797dee2d54..e94321ffba0 100644 --- a/src/Compiler/TypedTree/TypedTree.fs +++ b/src/Compiler/TypedTree/TypedTree.fs @@ -5921,13 +5921,6 @@ type PickledCcuInfo = override _.ToString() = "PickledCcuInfo(...)" -type PickledTcInfo = { - MainMethodAttrs: Attribs - NetModuleAttrs: Attribs - AssemblyAttrs: Attribs - DeclaredImpls: CheckedImplFile list -} - /// Represents a set of free local values. Computed and cached by later phases /// (never cached type checking). Cached in expressions. Not pickled. type FreeLocals = Zset diff --git a/src/Compiler/TypedTree/TypedTree.fsi b/src/Compiler/TypedTree/TypedTree.fsi index 761daa7105a..eedbaef44f4 100644 --- a/src/Compiler/TypedTree/TypedTree.fsi +++ b/src/Compiler/TypedTree/TypedTree.fsi @@ -4301,12 +4301,6 @@ type PickledCcuInfo = [] member DebugText: string -type PickledTcInfo = - { MainMethodAttrs: Attribs - NetModuleAttrs: Attribs - AssemblyAttrs: Attribs - DeclaredImpls: CheckedImplFile list } - /// Represents a set of free local values. Computed type cached by later phases /// (never cached type checking). Cached in expressions. Not pickled. type FreeLocals = Zset diff --git a/src/Compiler/TypedTree/TypedTreePickle.fs b/src/Compiler/TypedTree/TypedTreePickle.fs index c8fdf4127d7..88b08f1cf26 100644 --- a/src/Compiler/TypedTree/TypedTreePickle.fs +++ b/src/Compiler/TypedTree/TypedTreePickle.fs @@ -4315,33 +4315,8 @@ let pickleModuleOrNamespace mspec st = p_entity_spec mspec st let pickleCcuInfo (minfo: PickledCcuInfo) st = p_tup4 pickleModuleOrNamespace p_string p_bool (p_space 3) (minfo.mspec, minfo.compileTimeWorkingDir, minfo.usesQuotations, ()) st -let pickleTcInfo (tcInfo: PickledTcInfo) (st: WriterState) = - p_tup4 - p_attribs - p_attribs - p_attribs - (p_list p_checked_impl_file) - (tcInfo.MainMethodAttrs, tcInfo.NetModuleAttrs, tcInfo.AssemblyAttrs, tcInfo.DeclaredImpls) - st - let unpickleModuleOrNamespace st = u_entity_spec st let unpickleCcuInfo st = let a, b, c, _space = u_tup4 unpickleModuleOrNamespace u_string u_bool (u_space 3) st { mspec=a; compileTimeWorkingDir=b; usesQuotations=c } - -let unpickleTcInfo st : PickledTcInfo = - let mainMethodAttrs, netModuleAttrs, assemblyAttrs, declaredImpls = - u_tup4 - u_attribs - u_attribs - u_attribs - (u_list u_checked_impl_file) - st - - { - MainMethodAttrs = mainMethodAttrs - NetModuleAttrs = netModuleAttrs - AssemblyAttrs = assemblyAttrs - DeclaredImpls = declaredImpls - } diff --git a/src/Compiler/TypedTree/TypedTreePickle.fsi b/src/Compiler/TypedTree/TypedTreePickle.fsi deleted file mode 100644 index 1b8dbe79152..00000000000 --- a/src/Compiler/TypedTree/TypedTreePickle.fsi +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -/// Defines the framework for serializing and de-serializing TAST data structures as binary blobs for the F# metadata format. -module internal FSharp.Compiler.TypedTreePickle - -open FSharp.Compiler.IO -open Internal.Utilities.Library -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.TypedTree -open FSharp.Compiler.TcGlobals - -/// Represents deserialized data with a dangling set of CCU fixup thunks indexed by name -[] -type PickledDataWithReferences<'RawData> = - { - /// The data that uses a collection of CcuThunks internally - RawData: 'RawData - - /// The assumptions that need to be fixed up - FixupThunks: CcuThunk[] - } - - member Fixup: (CcuReference -> CcuThunk) -> 'RawData - - /// Like Fixup but loader may return None, in which case there is no fixup. - member OptionalFixup: (CcuReference -> CcuThunk option) -> 'RawData - -/// The type of state written to by picklers -type WriterState - -/// A function to pickle a value into a given stateful writer -type pickler<'T> = 'T -> WriterState -> unit - -/// Serialize a byte -val internal p_byte: int -> WriterState -> unit - -/// Serialize a boolean value -val internal p_bool: bool -> WriterState -> unit - -/// Serialize an integer -val internal p_int: int -> WriterState -> unit - -/// Serialize a string -val internal p_string: string -> WriterState -> unit - -/// Serialize a lazy value (eagerly) -val internal p_lazy: pickler<'T> -> InterruptibleLazy<'T> pickler - -/// Serialize a tuple of data -val inline internal p_tup2: pickler<'T1> -> pickler<'T2> -> pickler<'T1 * 'T2> - -/// Serialize a tuple of data -val inline internal p_tup3: pickler<'T1> -> pickler<'T2> -> pickler<'T3> -> pickler<'T1 * 'T2 * 'T3> - -/// Serialize a tuple of data -val inline internal p_tup4: - pickler<'T1> -> pickler<'T2> -> pickler<'T3> -> pickler<'T4> -> pickler<'T1 * 'T2 * 'T3 * 'T4> - -/// Serialize an array of data -val internal p_array: pickler<'T> -> pickler<'T[]> - -/// Serialize a namemap of data -val internal p_namemap: pickler<'T> -> pickler> - -/// Serialize a TAST constant -val internal p_const: pickler - -/// Serialize a TAST value reference -val internal p_vref: string -> pickler - -/// Serialize a TAST type or entity reference -val internal p_tcref: string -> pickler - -/// Serialize a TAST union case reference -val internal p_ucref: pickler - -/// Serialize a TAST expression -val internal p_expr: pickler - -/// Serialize a TAST type -val internal p_ty: pickler - -/// Serialize a TAST description of a compilation unit -val internal pickleCcuInfo: pickler - -/// Serialize typechecking info -val internal pickleTcInfo: pickler - -/// Serialize an arbitrary object using the given pickler -val pickleObjWithDanglingCcus: - inMem: bool -> file: string -> TcGlobals -> scope: CcuThunk -> pickler<'T> -> 'T -> ByteBuffer * ByteBuffer - -/// The type of state unpicklers read from -type ReaderState - -/// A function to read a value from a given state -type unpickler<'T> = ReaderState -> 'T - -/// Deserialize a byte -val internal u_byte: ReaderState -> int - -/// Deserialize a bool -val internal u_bool: ReaderState -> bool - -/// Deserialize an integer -val internal u_int: ReaderState -> int - -/// Deserialize a string -val internal u_string: ReaderState -> string - -/// Deserialize a lazy value (eagerly) -val internal u_lazy: unpickler<'T> -> unpickler> - -/// Deserialize a tuple -val inline internal u_tup2: unpickler<'T2> -> unpickler<'T3> -> unpickler<'T2 * 'T3> - -/// Deserialize a tuple -val inline internal u_tup3: unpickler<'T2> -> unpickler<'T3> -> unpickler<'T4> -> unpickler<'T2 * 'T3 * 'T4> - -/// Deserialize a tuple -val inline internal u_tup4: - unpickler<'T2> -> unpickler<'T3> -> unpickler<'T4> -> unpickler<'T5> -> unpickler<'T2 * 'T3 * 'T4 * 'T5> - -/// Deserialize an array of values -val internal u_array: unpickler<'T> -> unpickler<'T[]> - -/// Deserialize a namemap -val internal u_namemap: unpickler<'T> -> unpickler> - -/// Deserialize a TAST constant -val internal u_const: unpickler - -/// Deserialize a TAST value reference -val internal u_vref: unpickler - -/// Deserialize a TAST type reference -val internal u_tcref: unpickler - -/// Deserialize a TAST union case reference -val internal u_ucref: unpickler - -/// Deserialize a TAST expression -val internal u_expr: unpickler - -/// Deserialize a TAST type -val internal u_ty: unpickler - -/// Deserialize a TAST description of a compilation unit -val internal unpickleCcuInfo: ReaderState -> PickledCcuInfo - -/// Deserialize typechecking info -val internal unpickleTcInfo: ReaderState -> PickledTcInfo - -/// Deserialize an arbitrary object which may have holes referring to other compilation units -val internal unpickleObjWithDanglingCcus: - file: string -> - viewedScope: ILScopeRef -> - ilModule: ILModuleDef option -> - 'T unpickler -> - ReadOnlyByteMemory -> - ReadOnlyByteMemory -> - PickledDataWithReferences<'T> diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs index e4e2fbeda23..1b1679b763a 100644 --- a/tests/FSharp.Test.Utilities/Compiler.fs +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -947,7 +947,7 @@ module rec Compiler = failwith "File doesn't exist. Create it to use this function." let outputFilePath = Path.ChangeExtension(sourceFilePath, ".dll") - let err, _, _ = rawCompile outputFilePath false fs.Options TargetFramework.Current [ fs.Source ] + let err, _, _ = rawCompile outputFilePath false fs.Options TargetFramework.Current (fs.Source :: fs.AdditionalSources) let diagnostics = err |> fromFSharpDiagnostic let result = { From d3788bf3a01cf58372f8c046855d3fa98ed85ccc Mon Sep 17 00:00:00 2001 From: Petr Date: Wed, 19 Feb 2025 10:56:04 +0100 Subject: [PATCH 4/8] Store typechecking data per file (#18328) --- .../Driver/ReuseTcResults/CachingDriver.fs | 236 +++++++++++++----- .../Driver/ReuseTcResults/TcResultsImport.fs | 56 ++++- .../Driver/ReuseTcResults/TcResultsPickle.fs | 35 ++- src/Compiler/Driver/fsc.fs | 8 +- .../ReuseTcResults/Recompilation.fs | 45 ++++ 5 files changed, 295 insertions(+), 85 deletions(-) diff --git a/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs b/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs index 05bc7631a4b..755fd9d0cfd 100644 --- a/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs +++ b/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs @@ -1,9 +1,7 @@ module internal FSharp.Compiler.ReuseTcResults.CachingDriver -open System.Collections.Generic open System.IO -open FSharp.Compiler.CheckDeclarations open FSharp.Compiler.CompilerConfig open FSharp.Compiler.Diagnostics open FSharp.Compiler.GraphChecking @@ -12,39 +10,56 @@ open FSharp.Compiler.ParseAndCheckInputs open FSharp.Compiler.Syntax open FSharp.Compiler.Syntax.PrettyNaming open FSharp.Compiler.ReuseTcResults.TcResultsImport -open FSharp.Compiler.ReuseTcResults.TcResultsPickle open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.ReuseTcResults.TcResultsPickle -type TcData = +type TcCompilationData = { CmdLine: string array - Graph: string array References: string array } +type GraphFileLine = + { + Index: int + FileName: string + Stamp: int64 + } + +type Graph = + { + Files: GraphFileLine list + Dependencies: string list + } + +type GraphComparisonResult = (ParsedInput * bool) list + +[] +type TcCacheState = + | Empty + | Present of GraphComparisonResult + [] type CachingDriver(tcConfig: TcConfig) = let outputDir = tcConfig.outputDir |> Option.defaultValue "" let tcDataFilePath = Path.Combine(outputDir, FSharpTcDataResourceName) + let graphFilePath = Path.Combine(outputDir, "tcGraph") + let tcSharedDataFilePath = Path.Combine(outputDir, "tcSharedData") + let tcInputFilePath = Path.Combine(outputDir, "tcInput") [] let CmdLineHeader = "CMDLINE" - [] - let GraphHeader = "GRAPH" - [] let ReferencesHeader = "REFERENCES" - let writeThisTcData (tcData: TcData) = + let writeThisTcData tcData = use tcDataFile = FileSystem.OpenFileForWriteShim tcDataFilePath let lines = ResizeArray() lines.Add $"BEGIN {CmdLineHeader}" lines.AddRange tcData.CmdLine - lines.Add $"BEGIN {GraphHeader}" - lines.AddRange tcData.Graph lines.Add $"BEGIN {ReferencesHeader}" lines.AddRange tcData.References @@ -55,7 +70,6 @@ type CachingDriver(tcConfig: TcConfig) = use tcDataFile = FileSystem.OpenFileForReadShim tcDataFilePath let cmdLine = ResizeArray() - let graph = ResizeArray() let refs = ResizeArray() let mutable currentHeader = "" @@ -67,20 +81,53 @@ type CachingDriver(tcConfig: TcConfig) = | line -> match currentHeader with | CmdLineHeader -> cmdLine.Add line - | GraphHeader -> graph.Add line | ReferencesHeader -> refs.Add line | _ -> invalidOp "broken tc cache") Some { CmdLine = cmdLine.ToArray() - Graph = graph.ToArray() References = refs.ToArray() } else None + let writeThisGraph graph = + use tcDataFile = FileSystem.OpenFileForWriteShim graphFilePath + + let formatGraphFileLine l = + sprintf "%i,%s,%i" l.Index l.FileName l.Stamp + + (graph.Files |> List.map formatGraphFileLine) @ graph.Dependencies + |> tcDataFile.WriteAllLines + + let readPrevGraph () = + if FileSystem.FileExistsShim graphFilePath then + use graphFile = FileSystem.OpenFileForReadShim graphFilePath + + let parseGraphFileLine (l: string) = + let parts = l.Split(',') |> Array.toList + + { + Index = int parts[0] + FileName = parts[1] + Stamp = int64 parts[2] + } + + let depLines, fileLines = + graphFile.ReadAllLines() + |> Array.toList + |> List.partition (fun l -> l.Contains "-->") + + Some + { + Files = fileLines |> List.map parseGraphFileLine + Dependencies = depLines + } + else + None + let formatAssemblyReference (r: AssemblyReference) = let fileName = r.Text let lastWriteTime = FileSystem.GetLastWriteTimeShim fileName @@ -103,28 +150,62 @@ type CachingDriver(tcConfig: TcConfig) = let filePairs = FilePairMap sourceFiles let graph, _ = DependencyResolution.mkGraph filePairs sourceFiles - let list = List() + let graphFileLines = + [ + for KeyValue(idx, _) in graph do + let fileName = sourceFiles[idx].FileName + let lastWriteTime = FileSystem.GetLastWriteTimeShim fileName + + let graphFileLine = + { + Index = idx + FileName = fileName + Stamp = lastWriteTime.Ticks + } + + yield graphFileLine + ] + + let dependencies = + [ + for KeyValue(idx, deps) in graph do + for depIdx in deps do + yield $"%i{idx} --> %i{depIdx}" + ] + + { + Files = graphFileLines + Dependencies = dependencies + } - for KeyValue(idx, _) in graph do - let fileName = sourceFiles[idx].FileName - let lastWriteTime = FileSystem.GetLastWriteTimeShim fileName - list.Add(sprintf "%i,%s,%i" idx fileName lastWriteTime.Ticks) + let getThisCompilationReferences = Seq.map formatAssemblyReference >> Seq.toArray - for KeyValue(idx, deps) in graph do - for depIdx in deps do - list.Add $"%i{idx} --> %i{depIdx}" + // TODO: don't ignore dependencies + let compareGraphs (inputs: ParsedInput list) thisGraph baseGraph : GraphComparisonResult = - list.ToArray() + let isPresentInBaseGraph thisLine = + baseGraph.Files + |> Seq.tryFind (fun baseLine -> baseLine.FileName = baseLine.FileName) + |> Option.exists (fun baseLine -> baseLine.Stamp = thisLine.Stamp) - let getThisCompilationReferences = Seq.map formatAssemblyReference >> Seq.toArray + // TODO: make this robust + let findMatchingInput thisLine = + inputs + |> Seq.where (fun input -> input.FileName = thisLine.FileName) + |> Seq.exactlyOne - member _.CanReuseTcResults inputs = + thisGraph.Files + |> List.map (fun thisLine -> + let input = findMatchingInput thisLine + let canReuse = isPresentInBaseGraph thisLine + input, canReuse) + + member _.GetTcCacheState inputs = let prevTcDataOpt = readPrevTcData () let thisTcData = { CmdLine = getThisCompilationCmdLine tcConfig.cmdLineArgs - Graph = getThisCompilationGraph inputs References = getThisCompilationReferences tcConfig.referencedDLLs } @@ -133,64 +214,103 @@ type CachingDriver(tcConfig: TcConfig) = use _ = Activity.start Activity.Events.reuseTcResultsCachePresent [] if prevTcData = thisTcData then - use _ = Activity.start Activity.Events.reuseTcResultsCacheHit [] - true + match readPrevGraph () with + | Some graph -> + let thisGraph = getThisCompilationGraph inputs + + let graphComparisonResult = graph |> compareGraphs inputs thisGraph + + // we'll need more events do distinguish scenarios here + use _ = + if graphComparisonResult |> Seq.forall (fun (_file, canUse) -> canUse) then + Activity.start Activity.Events.reuseTcResultsCacheHit [] + else + Activity.start Activity.Events.reuseTcResultsCacheMissed [] + + TcCacheState.Present graphComparisonResult + | None -> + use _ = Activity.start Activity.Events.reuseTcResultsCacheMissed [] + TcCacheState.Empty else use _ = Activity.start Activity.Events.reuseTcResultsCacheMissed [] - writeThisTcData thisTcData - false + TcCacheState.Empty | None -> use _ = Activity.start Activity.Events.reuseTcResultsCacheAbsent [] - writeThisTcData thisTcData - false - - member _.ReuseTcResults inputs (tcInitialState: TcState) = + TcCacheState.Empty - let bytes = File.ReadAllBytes("tc") + member private _.ReuseSharedData() = + let bytes = File.ReadAllBytes(tcSharedDataFilePath) let memory = ByteMemory.FromArray(bytes) let byteReaderA () = ReadOnlyByteMemory(memory) - let byteReaderB = None + let data = + GetSharedData( + "", // assembly.FileName, + ILScopeRef.Local, // assembly.ILScopeRef, + None, //assembly.RawMetadata.TryGetILModuleDef(), + byteReaderA, + None + ) + + data.RawData - let tcInfo = - GetTypecheckingData( + member private _.ReuseDeclaredImpl(implFile: ParsedInput) = + let fileName = Path.GetFileNameWithoutExtension(implFile.FileName) + let bytes = File.ReadAllBytes($"{tcInputFilePath}{fileName}") + let memory = ByteMemory.FromArray(bytes) + let byteReaderA () = ReadOnlyByteMemory(memory) + + let data = + GetCheckedImplFile( "", // assembly.FileName, ILScopeRef.Local, // assembly.ILScopeRef, None, //assembly.RawMetadata.TryGetILModuleDef(), byteReaderA, - byteReaderB + None ) - let rawData = tcInfo.RawData + data.RawData - let topAttribs = rawData.TopAttribs + member this.ReuseTcResults (inputs: ParsedInput list) (tcInitialState: TcState) = + let sharedData = this.ReuseSharedData() + let declaredImpls = inputs |> List.map this.ReuseDeclaredImpl - // need to understand if anything can be used here, pickling state is hard - tcInitialState, - topAttribs, - rawData.DeclaredImpls, - // this is quite definitely wrong, need to figure out what to do with the environment - tcInitialState.TcEnvFromImpls + tcInitialState, sharedData.TopAttribs, declaredImpls, tcInitialState.TcEnvFromImpls - member _.CacheTcResults(tcState: TcState, topAttribs: TopAttribs, declaredImpls, tcEnvAtEndOfLastFile, inputs, tcGlobals, outfile) = + member private _.CacheSharedData(tcState: TcState, sharedData, tcGlobals, outfile) = + let encodedData = + EncodeSharedData(tcConfig, tcGlobals, tcState.Ccu, outfile, false, sharedData) + + let resource = encodedData[0].GetBytes().ToArray() + File.WriteAllBytes(tcSharedDataFilePath, resource) + + member private _.CacheDeclaredImpl(tcState: TcState, impl, tcGlobals, outfile) = + let encodedData = + EncodeCheckedImplFile(tcConfig, tcGlobals, tcState.Ccu, outfile, false, impl) + + // TODO: bare file name is not enough + let fileName = + Path.GetFileNameWithoutExtension(impl.QualifiedNameOfFile.Range.FileName) + + let resource = encodedData[0].GetBytes().ToArray() + File.WriteAllBytes($"{tcInputFilePath}{fileName}", resource) + + member this.CacheTcResults(tcState: TcState, topAttribs, declaredImpls, _tcEnvAtEndOfLastFile, inputs, tcGlobals, outfile) = let thisTcData = { CmdLine = getThisCompilationCmdLine tcConfig.cmdLineArgs - Graph = getThisCompilationGraph inputs References = getThisCompilationReferences tcConfig.referencedDLLs } writeThisTcData thisTcData - let tcInfo = - { - TopAttribs = topAttribs - DeclaredImpls = declaredImpls - } + let thisGraph = getThisCompilationGraph inputs + writeThisGraph thisGraph - let encodedData = - EncodeTypecheckingData(tcConfig, tcGlobals, tcState.Ccu, outfile, false, tcInfo) + let sharedData = { TopAttribs = topAttribs } - let resource = encodedData[0].GetBytes().ToArray() - File.WriteAllBytes("tc", resource) + this.CacheSharedData(tcState, sharedData, tcGlobals, outfile) + + declaredImpls + |> List.iter (fun impl -> this.CacheDeclaredImpl(tcState, impl, tcGlobals, outfile)) diff --git a/src/Compiler/Driver/ReuseTcResults/TcResultsImport.fs b/src/Compiler/Driver/ReuseTcResults/TcResultsImport.fs index 9941b48a206..966c533cedc 100644 --- a/src/Compiler/Driver/ReuseTcResults/TcResultsImport.fs +++ b/src/Compiler/Driver/ReuseTcResults/TcResultsImport.fs @@ -6,7 +6,7 @@ open FSharp.Compiler.CompilerImports open FSharp.Compiler.TypedTreePickle open FSharp.Compiler.ReuseTcResults.TcResultsPickle -let GetTypecheckingData (file, ilScopeRef, ilModule, byteReaderA, byteReaderB) = +let GetSharedData (file, ilScopeRef, ilModule, byteReaderA, byteReaderB) = let memA = byteReaderA () @@ -15,9 +15,20 @@ let GetTypecheckingData (file, ilScopeRef, ilModule, byteReaderA, byteReaderB) = | None -> ByteMemory.Empty.AsReadOnly() | Some br -> br () - unpickleObjWithDanglingCcus file ilScopeRef ilModule unpickleTcInfo memA memB + unpickleObjWithDanglingCcus file ilScopeRef ilModule unpickleSharedData memA memB -let WriteTypecheckingData (tcConfig: TcConfig, tcGlobals, fileName, inMem, ccu, tcInfo) = +let GetCheckedImplFile (file, ilScopeRef, ilModule, byteReaderA, byteReaderB) = + + let memA = byteReaderA () + + let memB = + match byteReaderB with + | None -> ByteMemory.Empty.AsReadOnly() + | Some br -> br () + + unpickleObjWithDanglingCcus file ilScopeRef ilModule unpickleCheckedImplFile memA memB + +let WriteSharedData (tcConfig: TcConfig, tcGlobals, fileName, inMem, ccu, sharedData) = // need to understand the naming and if we even want two resources here... let rName = "FSharpTypecheckingData" @@ -31,12 +42,43 @@ let WriteTypecheckingData (tcConfig: TcConfig, tcGlobals, fileName, inMem, ccu, ccu (rName + ccu.AssemblyName) (rNameB + ccu.AssemblyName) - pickleTcInfo - tcInfo + pickleSharedData + sharedData + +let WriteCheckedImplFile (tcConfig: TcConfig, tcGlobals, fileName, inMem, ccu, checkedImplFile) = + + // need to understand the naming and if we even want two resources here... + let rName = "FSharpTypecheckingData" + let rNameB = "FSharpTypecheckingDataB" + + PickleToResource + inMem + fileName + tcGlobals + tcConfig.compressMetadata + ccu + (rName + ccu.AssemblyName) + (rNameB + ccu.AssemblyName) + pickleCheckedImplFile + checkedImplFile + +let EncodeSharedData (tcConfig: TcConfig, tcGlobals, generatedCcu, outfile, isIncrementalBuild, sharedData) = + let r1, r2 = + WriteSharedData(tcConfig, tcGlobals, outfile, isIncrementalBuild, generatedCcu, sharedData) + + let resources = + [ + r1 + match r2 with + | None -> () + | Some r -> r + ] + + resources -let EncodeTypecheckingData (tcConfig: TcConfig, tcGlobals, generatedCcu, outfile, isIncrementalBuild, tcInfo) = +let EncodeCheckedImplFile (tcConfig: TcConfig, tcGlobals, generatedCcu, outfile, isIncrementalBuild, checkedImplFile) = let r1, r2 = - WriteTypecheckingData(tcConfig, tcGlobals, outfile, isIncrementalBuild, generatedCcu, tcInfo) + WriteCheckedImplFile(tcConfig, tcGlobals, outfile, isIncrementalBuild, generatedCcu, checkedImplFile) let resources = [ diff --git a/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs b/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs index 38c082afd10..384014617d2 100644 --- a/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs +++ b/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs @@ -1,36 +1,35 @@ module internal FSharp.Compiler.ReuseTcResults.TcResultsPickle open FSharp.Compiler.CheckDeclarations -open FSharp.Compiler.TypedTree open FSharp.Compiler.TypedTreePickle -type PickledTcInfo = - { - TopAttribs: TopAttribs - DeclaredImpls: CheckedImplFile list - } +type TcSharedData = { TopAttribs: TopAttribs } -let pickleTcInfo (tcInfo: PickledTcInfo) (st: WriterState) = - p_tup4 +// pickling + +let pickleSharedData sharedData st = + p_tup3 p_attribs p_attribs p_attribs - (p_list p_checked_impl_file) - (tcInfo.TopAttribs.mainMethodAttrs, tcInfo.TopAttribs.netModuleAttrs, tcInfo.TopAttribs.assemblyAttrs, tcInfo.DeclaredImpls) + (sharedData.TopAttribs.mainMethodAttrs, sharedData.TopAttribs.netModuleAttrs, sharedData.TopAttribs.assemblyAttrs) st -let unpickleTcInfo st : PickledTcInfo = - let mainMethodAttrs, netModuleAttrs, assemblyAttrs, declaredImpls = - u_tup4 u_attribs u_attribs u_attribs (u_list u_checked_impl_file) st +let pickleCheckedImplFile checkedImplFile st = p_checked_impl_file checkedImplFile st + +// unpickling - let attribs: TopAttribs = +let unpickleSharedData st = + let mainMethodAttrs, netModuleAttrs, assemblyAttrs = + u_tup3 u_attribs u_attribs u_attribs st + + let attribs = { mainMethodAttrs = mainMethodAttrs netModuleAttrs = netModuleAttrs assemblyAttrs = assemblyAttrs } - { - TopAttribs = attribs - DeclaredImpls = declaredImpls - } + { TopAttribs = attribs } + +let unpickleCheckedImplFile st = u_checked_impl_file st diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs index e66a119d1fa..92bc855e3aa 100644 --- a/src/Compiler/Driver/fsc.fs +++ b/src/Compiler/Driver/fsc.fs @@ -167,9 +167,13 @@ let TypeCheck if tcConfig.reuseTcResults = ReuseTcResults.On then let cachingDriver = CachingDriver(tcConfig) - if cachingDriver.CanReuseTcResults(inputs) then + let tcCacheState = cachingDriver.GetTcCacheState(inputs) + + match tcCacheState with + | TcCacheState.Present files when files |> List.forall (fun (_file, canReuse) -> canReuse) -> cachingDriver.ReuseTcResults inputs tcInitialState - else + + | _ -> let tcState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile = CheckClosedInputSet( ctok, diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Recompilation.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Recompilation.fs index a59e44185d6..e1d57afcf37 100644 --- a/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Recompilation.fs +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Recompilation.fs @@ -80,3 +80,48 @@ printfn "hello world!" """>] Assert.True(outcome) + [] + let ``Multiple files`` () = + let tempDir = createTemporaryDirectory().FullName + + let code1 = """module M1 +let helloWorld = "hello world!" """ + + let code2 = """module M2 +printfn $"{M1.helloWorld}" """ + + let fileName1 = "File0" + let fileName2 = "File1" + + let tempPath1 = tempDir ++ $"{fileName1}.fs" + let tempPath2 = tempDir ++ $"{fileName2}.fs" + + File.WriteAllText(tempPath1, code1) + File.WriteAllText(tempPath2, code2) + + let cUnit = + FsFromPath tempPath1 + |> withAdditionalSourceFile (SourceCodeFileKind.Create tempPath2) + |> withReuseTcResults + |> withOptions [ "--compressmetadata-" ] + |> withOptions [ "--optimize-" ] + + let expected = + cUnit + |> compileExisting + |> shouldSucceed + |> fun r -> ILChecker.generateIL r.Output.OutputPath.Value [] + + let actual = + cUnit + |> compileExisting + |> shouldSucceed + |> fun r -> ILChecker.generateIL r.Output.OutputPath.Value [] + + let outcome, _msg, _actualIL = + ILChecker.compareIL + fileName1 + actual + [ expected ] + + Assert.True(outcome) From 3130685821468e7d7baba7697e0dd6078dc00fd2 Mon Sep 17 00:00:00 2001 From: Petr Date: Wed, 26 Feb 2025 14:03:25 +0100 Subject: [PATCH 5/8] Cache and restore typechecking state (#18336) --- src/Compiler/Driver/ParseAndCheckInputs.fs | 88 +++-- src/Compiler/Driver/ParseAndCheckInputs.fsi | 20 +- .../Driver/ReuseTcResults/CachingDriver.fs | 64 +++- .../Driver/ReuseTcResults/TcResultsImport.fs | 42 +++ .../Driver/ReuseTcResults/TcResultsPickle.fs | 307 ++++++++++++++++++ src/Compiler/Driver/fsc.fs | 80 ++++- src/Compiler/Interactive/fsi.fs | 2 +- src/Compiler/TypedTree/TypedTreePickle.fs | 3 +- .../ReuseTcResults/Recompilation.fs | 57 ++++ 9 files changed, 596 insertions(+), 67 deletions(-) diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs index 975bfeef66f..ad1a74f8df5 100644 --- a/src/Compiler/Driver/ParseAndCheckInputs.fs +++ b/src/Compiler/Driver/ParseAndCheckInputs.fs @@ -1478,8 +1478,19 @@ let CheckClosedInputSetFinish (declaredImpls: CheckedImplFile list, tcState) = tcState, declaredImpls, ccuContents let CheckMultipleInputsSequential (ctok, checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt, tcState, inputs) = - (tcState, inputs) - ||> List.mapFold (CheckOneInputEntry(ctok, checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt)) + let checkOneInputEntry = + CheckOneInputEntry(ctok, checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt) + + let mutable state = tcState + + let results = + inputs + |> List.map (fun input -> + let result, newState = checkOneInputEntry state input + state <- newState // Update state for the next iteration + result, newState) + + results |> List.map fst, state, results |> List.map snd open FSharp.Compiler.GraphChecking @@ -1833,7 +1844,7 @@ let CheckMultipleInputsUsingGraphMode TcState * (PhasedDiagnostic -> PhasedDiagnostic) * ParsedInput list) - : FinalFileResult list * TcState = + : FinalFileResult list * TcState * TcState list = use cts = new CancellationTokenSource() let sourceFiles: FileInProject array = @@ -1931,40 +1942,44 @@ let CheckMultipleInputsUsingGraphMode partialResult, state) ) - UseMultipleDiagnosticLoggers (inputs, diagnosticsLogger, Some eagerFormat) (fun inputsWithLoggers -> - // Equip loggers to locally filter w.r.t. scope pragmas in each input - let inputsWithLoggers = - inputsWithLoggers - |> List.toArray - |> Array.map (fun (input, oldLogger) -> - let logger = DiagnosticsLoggerForInput(tcConfig, input, oldLogger) - input, logger) - - let processFile (node: NodeToTypeCheck) (state: State) : Finisher = - match node with - | NodeToTypeCheck.ArtificialImplFile idx -> - let parsedInput, _ = inputsWithLoggers[idx] - processArtificialImplFile node parsedInput state - | NodeToTypeCheck.PhysicalFile idx -> - let parsedInput, logger = inputsWithLoggers[idx] - processFile node (parsedInput, logger) state - - let state: State = tcState, priorErrors - - let partialResults, (tcState, _) = - TypeCheckingGraphProcessing.processTypeCheckingGraph nodeGraph processFile state cts.Token - - let partialResults = - partialResults - // Bring back the original, index-based file order. - |> List.sortBy fst - |> List.map snd - - partialResults, tcState) + let results, state = + UseMultipleDiagnosticLoggers (inputs, diagnosticsLogger, Some eagerFormat) (fun inputsWithLoggers -> + // Equip loggers to locally filter w.r.t. scope pragmas in each input + let inputsWithLoggers = + inputsWithLoggers + |> List.toArray + |> Array.map (fun (input, oldLogger) -> + let logger = DiagnosticsLoggerForInput(tcConfig, input, oldLogger) + input, logger) + + let processFile (node: NodeToTypeCheck) (state: State) : Finisher = + match node with + | NodeToTypeCheck.ArtificialImplFile idx -> + let parsedInput, _ = inputsWithLoggers[idx] + processArtificialImplFile node parsedInput state + | NodeToTypeCheck.PhysicalFile idx -> + let parsedInput, logger = inputsWithLoggers[idx] + processFile node (parsedInput, logger) state + + let state: State = tcState, priorErrors + + let partialResults, (tcState, _) = + TypeCheckingGraphProcessing.processTypeCheckingGraph nodeGraph processFile state cts.Token + + let partialResults = + partialResults + // Bring back the original, index-based file order. + |> List.sortBy fst + |> List.map snd + + partialResults, tcState) + + // TODO: collect states here also + results, state, [] let CheckClosedInputSet (ctok, checkForErrors, tcConfig: TcConfig, tcImports, tcGlobals, prefixPathOpt, tcState, eagerFormat, inputs) = // tcEnvAtEndOfLastFile is the environment required by fsi.exe when incrementally adding definitions - let results, tcState = + let results, lastState, tcStates = match tcConfig.typeCheckingConfig.Mode with | TypeCheckingMode.Graph when (not tcConfig.isInteractive && not tcConfig.compilingFSharpCore) -> CheckMultipleInputsUsingGraphMode( @@ -1981,10 +1996,11 @@ let CheckClosedInputSet (ctok, checkForErrors, tcConfig: TcConfig, tcImports, tc | _ -> CheckMultipleInputsSequential(ctok, checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt, tcState, inputs) let (tcEnvAtEndOfLastFile, topAttrs, implFiles, _), tcState = - CheckMultipleInputsFinish(results, tcState) + CheckMultipleInputsFinish(results, lastState) let tcState, declaredImpls, ccuContents = CheckClosedInputSetFinish(implFiles, tcState) tcState.Ccu.Deref.Contents <- ccuContents - tcState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile + + tcState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile, tcStates diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fsi b/src/Compiler/Driver/ParseAndCheckInputs.fsi index fb32a4557cd..f00fac9b229 100644 --- a/src/Compiler/Driver/ParseAndCheckInputs.fsi +++ b/src/Compiler/Driver/ParseAndCheckInputs.fsi @@ -3,7 +3,9 @@ /// Contains logic to coordinate the parsing and checking of one or a group of files module internal FSharp.Compiler.ParseAndCheckInputs +open System.Collections.Generic open System.IO +open Internal.Utilities.Collections open Internal.Utilities.Library open FSharp.Compiler.CheckBasics open FSharp.Compiler.CheckDeclarations @@ -143,9 +145,23 @@ val ParseInputFiles: /// applying the InternalsVisibleTo in referenced assemblies and opening 'Checked' if requested. val GetInitialTcEnv: assemblyName: string * range * TcConfig * TcImports * TcGlobals -> TcEnv * OpenDeclaration list +type RootSigs = Zmap + +type RootImpls = Zset + +val qnameOrder: IComparer + /// Represents the incremental type checking state for a set of inputs -[] type TcState = + { tcsCcu: CcuThunk + tcsTcSigEnv: TcEnv + tcsTcImplEnv: TcEnv + tcsCreatesGeneratedProvidedTypes: bool + tcsRootSigs: RootSigs + tcsRootImpls: RootImpls + tcsCcuSig: ModuleOrNamespaceType + tcsImplicitOpenDeclarations: OpenDeclaration list } + /// The CcuThunk for the current assembly being checked member Ccu: CcuThunk @@ -239,7 +255,7 @@ val CheckClosedInputSet: tcState: TcState * eagerFormat: (PhasedDiagnostic -> PhasedDiagnostic) * inputs: ParsedInput list -> - TcState * TopAttribs * CheckedImplFile list * TcEnv + TcState * TopAttribs * CheckedImplFile list * TcEnv * TcState list /// Check a single input and finish the checking val CheckOneInputAndFinish: diff --git a/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs b/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs index 755fd9d0cfd..b583b9e45b7 100644 --- a/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs +++ b/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs @@ -1,5 +1,7 @@ module internal FSharp.Compiler.ReuseTcResults.CachingDriver +#nowarn "3261" + open System.IO open FSharp.Compiler.CompilerConfig @@ -12,6 +14,7 @@ open FSharp.Compiler.Syntax.PrettyNaming open FSharp.Compiler.ReuseTcResults.TcResultsImport open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.ReuseTcResults.TcResultsPickle +open FSharp.Compiler.TypedTree type TcCompilationData = { @@ -39,6 +42,13 @@ type TcCacheState = | Empty | Present of GraphComparisonResult +type TcResult = + { + Input: ParsedInput + DeclaredImpl: CheckedImplFile + State: TcState + } + [] type CachingDriver(tcConfig: TcConfig) = @@ -47,6 +57,7 @@ type CachingDriver(tcConfig: TcConfig) = let graphFilePath = Path.Combine(outputDir, "tcGraph") let tcSharedDataFilePath = Path.Combine(outputDir, "tcSharedData") let tcInputFilePath = Path.Combine(outputDir, "tcInput") + let tcStateFilePath = Path.Combine(outputDir, "tcState") [] let CmdLineHeader = "CMDLINE" @@ -185,7 +196,7 @@ type CachingDriver(tcConfig: TcConfig) = let isPresentInBaseGraph thisLine = baseGraph.Files - |> Seq.tryFind (fun baseLine -> baseLine.FileName = baseLine.FileName) + |> Seq.tryFind (fun baseLine -> baseLine.FileName = thisLine.FileName) |> Option.exists (fun baseLine -> baseLine.Stamp = thisLine.Stamp) // TODO: make this robust @@ -272,11 +283,31 @@ type CachingDriver(tcConfig: TcConfig) = data.RawData - member this.ReuseTcResults (inputs: ParsedInput list) (tcInitialState: TcState) = + member private _.ReuseTcState(name: string) : TcState = + let bytes = File.ReadAllBytes($"{tcStateFilePath}{name}") + let memory = ByteMemory.FromArray(bytes) + let byteReaderA () = ReadOnlyByteMemory(memory) + + let data = + GetTypecheckingDataTcState( + "", // assembly.FileName, + ILScopeRef.Local, // assembly.ILScopeRef, + None, //assembly.RawMetadata.TryGetILModuleDef(), + byteReaderA, + None + ) + + data.RawData + + member this.ReuseTcResults inputs = let sharedData = this.ReuseSharedData() let declaredImpls = inputs |> List.map this.ReuseDeclaredImpl - tcInitialState, sharedData.TopAttribs, declaredImpls, tcInitialState.TcEnvFromImpls + let lastInput = inputs |> List.last + let fileName = Path.GetFileNameWithoutExtension(lastInput.FileName) + let lastState = this.ReuseTcState fileName + + lastState, sharedData.TopAttribs, declaredImpls, lastState.TcEnvFromImpls member private _.CacheSharedData(tcState: TcState, sharedData, tcGlobals, outfile) = let encodedData = @@ -285,18 +316,21 @@ type CachingDriver(tcConfig: TcConfig) = let resource = encodedData[0].GetBytes().ToArray() File.WriteAllBytes(tcSharedDataFilePath, resource) - member private _.CacheDeclaredImpl(tcState: TcState, impl, tcGlobals, outfile) = + member private _.CacheDeclaredImpl(fileName: string, tcState: TcState, impl, tcGlobals, outfile) = let encodedData = EncodeCheckedImplFile(tcConfig, tcGlobals, tcState.Ccu, outfile, false, impl) - // TODO: bare file name is not enough - let fileName = - Path.GetFileNameWithoutExtension(impl.QualifiedNameOfFile.Range.FileName) - let resource = encodedData[0].GetBytes().ToArray() File.WriteAllBytes($"{tcInputFilePath}{fileName}", resource) - member this.CacheTcResults(tcState: TcState, topAttribs, declaredImpls, _tcEnvAtEndOfLastFile, inputs, tcGlobals, outfile) = + member private _.CacheTcState(fileName: string, tcState: TcState, tcGlobals, outfile) = + let encodedData = + EncodeTypecheckingDataTcState(tcConfig, tcGlobals, tcState.Ccu, outfile, false, tcState) + + let resource = encodedData[0].GetBytes().ToArray() + File.WriteAllBytes($"{tcStateFilePath}{fileName}", resource) + + member this.CacheTcResults(tcResults, topAttribs, _tcEnvAtEndOfLastFile, tcGlobals, outfile) = let thisTcData = { CmdLine = getThisCompilationCmdLine tcConfig.cmdLineArgs @@ -305,12 +339,18 @@ type CachingDriver(tcConfig: TcConfig) = writeThisTcData thisTcData + let inputs = tcResults |> List.map (fun r -> r.Input) let thisGraph = getThisCompilationGraph inputs writeThisGraph thisGraph let sharedData = { TopAttribs = topAttribs } - this.CacheSharedData(tcState, sharedData, tcGlobals, outfile) + let lastState = tcResults |> List.map (fun r -> r.State) |> List.last + this.CacheSharedData(lastState, sharedData, tcGlobals, outfile) - declaredImpls - |> List.iter (fun impl -> this.CacheDeclaredImpl(tcState, impl, tcGlobals, outfile)) + tcResults + |> List.iter (fun r -> + // TODO: bare file name is not enough + let fileName = Path.GetFileNameWithoutExtension(r.Input.FileName) + this.CacheDeclaredImpl(fileName, r.State, r.DeclaredImpl, tcGlobals, outfile) + this.CacheTcState(fileName, r.State, tcGlobals, outfile)) diff --git a/src/Compiler/Driver/ReuseTcResults/TcResultsImport.fs b/src/Compiler/Driver/ReuseTcResults/TcResultsImport.fs index 966c533cedc..a0fb35e0a82 100644 --- a/src/Compiler/Driver/ReuseTcResults/TcResultsImport.fs +++ b/src/Compiler/Driver/ReuseTcResults/TcResultsImport.fs @@ -28,6 +28,17 @@ let GetCheckedImplFile (file, ilScopeRef, ilModule, byteReaderA, byteReaderB) = unpickleObjWithDanglingCcus file ilScopeRef ilModule unpickleCheckedImplFile memA memB +let GetTypecheckingDataTcState (file, ilScopeRef, ilModule, byteReaderA, byteReaderB) = + + let memA = byteReaderA () + + let memB = + match byteReaderB with + | None -> ByteMemory.Empty.AsReadOnly() + | Some br -> br () + + unpickleObjWithDanglingCcus file ilScopeRef ilModule unpickleTcState memA memB + let WriteSharedData (tcConfig: TcConfig, tcGlobals, fileName, inMem, ccu, sharedData) = // need to understand the naming and if we even want two resources here... @@ -62,6 +73,23 @@ let WriteCheckedImplFile (tcConfig: TcConfig, tcGlobals, fileName, inMem, ccu, c pickleCheckedImplFile checkedImplFile +let WriteTypecheckingDataTcState (tcConfig: TcConfig, tcGlobals, fileName, inMem, ccu, tcState) = + + // need to understand the naming and if we even want two resources here... + let rName = "FSharpTypecheckingData" + let rNameB = "FSharpTypecheckingDataB" + + PickleToResource + inMem + fileName + tcGlobals + tcConfig.compressMetadata + ccu + (rName + ccu.AssemblyName) + (rNameB + ccu.AssemblyName) + pickleTcState + tcState + let EncodeSharedData (tcConfig: TcConfig, tcGlobals, generatedCcu, outfile, isIncrementalBuild, sharedData) = let r1, r2 = WriteSharedData(tcConfig, tcGlobals, outfile, isIncrementalBuild, generatedCcu, sharedData) @@ -89,3 +117,17 @@ let EncodeCheckedImplFile (tcConfig: TcConfig, tcGlobals, generatedCcu, outfile, ] resources + +let EncodeTypecheckingDataTcState (tcConfig: TcConfig, tcGlobals, generatedCcu, outfile, isIncrementalBuild, tcState) = + let r1, r2 = + WriteTypecheckingDataTcState(tcConfig, tcGlobals, outfile, isIncrementalBuild, generatedCcu, tcState) + + let resources = + [ + r1 + match r2 with + | None -> () + | Some r -> r + ] + + resources diff --git a/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs b/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs index 384014617d2..e46e154291f 100644 --- a/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs +++ b/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs @@ -1,12 +1,137 @@ module internal FSharp.Compiler.ReuseTcResults.TcResultsPickle +open FSharp.Compiler.AccessibilityLogic +open FSharp.Compiler.CheckBasics open FSharp.Compiler.CheckDeclarations +open FSharp.Compiler.ConstraintSolver +open FSharp.Compiler.NameResolution +open FSharp.Compiler.ParseAndCheckInputs +open FSharp.Compiler.Infos +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.TypedTree open FSharp.Compiler.TypedTreePickle +open Internal.Utilities.Collections +open Internal.Utilities.Library type TcSharedData = { TopAttribs: TopAttribs } // pickling +let p_context_info (x: ContextInfo) st = + match x with + | ContextInfo.NoContext -> p_byte 0 st + | ContextInfo.IfExpression range -> + p_byte 1 st + p_range range st + | ContextInfo.OmittedElseBranch range -> + p_byte 2 st + p_range range st + | ContextInfo.ElseBranchResult range -> + p_byte 3 st + p_range range st + | ContextInfo.RecordFields -> p_byte 4 st + | ContextInfo.TupleInRecordFields -> p_byte 5 st + | ContextInfo.CollectionElement(bool, range) -> + p_byte 6 st + p_bool bool st + p_range range st + | ContextInfo.ReturnInComputationExpression -> p_byte 7 st + | ContextInfo.YieldInComputationExpression -> p_byte 8 st + | ContextInfo.RuntimeTypeTest bool -> + p_byte 9 st + p_bool bool st + | ContextInfo.DowncastUsedInsteadOfUpcast bool -> + p_byte 10 st + p_bool bool st + | ContextInfo.FollowingPatternMatchClause range -> + p_byte 11 st + p_range range st + | ContextInfo.PatternMatchGuard range -> + p_byte 12 st + p_range range st + | ContextInfo.SequenceExpression ttype -> + p_byte 13 st + p_ty ttype st + +let p_safe_init_data (x: SafeInitData) st = + match x with + | SafeInitField(recdFieldRef, recdField) -> + p_byte 0 st + p_rfref recdFieldRef st + p_recdfield_spec recdField st + | NoSafeInitInfo -> p_byte 1 st + +let p_ctor_info (x: CtorInfo) st = + p_int x.ctorShapeCounter st + p_option p_Val x.safeThisValOpt st + p_safe_init_data x.safeInitInfo st + p_bool x.ctorIsImplicit st + +let p_module_and_namespace (s: string, l: ModuleOrNamespaceRef list) st = + p_string s st + p_list (p_tcref "test") l st + +let p_union_case_info (UnionCaseInfo(typeInst, ucref)) st = + p_tys_new typeInst st + p_ucref ucref st + +let p_item (x: Item) st = + match x with + | Item.Value vref -> + p_byte 0 st + p_vref "test" vref st + p_non_null_slot p_Val_new vref.binding st + | Item.UnqualifiedType tcrefs -> + p_byte 1 st + p_list (p_tcref "test") tcrefs st + | Item.UnionCase(unionCaseInfo, hasAttrs) -> + p_byte 2 st + p_union_case_info unionCaseInfo st + p_bool hasAttrs st + | Item.ExnCase tcref -> + p_byte 3 st + p_tcref "test" tcref st + | _ -> () + +let p_name_resolution_env (env: NameResolutionEnv) st = + // eDisplayEnv + p_Map p_string p_item env.eUnqualifiedItems st + // eUnqualifiedEnclosingTypeInsts + // ePatItems + (p_list p_module_and_namespace) (env.eModulesAndNamespaces |> Map.toList) st +// eFullyQualifiedModulesAndNamespaces +// eFieldLabels +// eUnqualifiedRecordOrUnionTypeInsts +// eTyconsByAccessNames +// eFullyQualifiedTyconsByAccessNames +// eTyconsByDemangledNameAndArity +// eFullyQualifiedTyconsByDemangledNameAndArity +// eIndexedExtensionMembers +// eUnindexedExtensionMembers +// eTypars + +let p_tc_env (tcEnv: TcEnv) (st: WriterState) = + p_name_resolution_env tcEnv.eNameResEnv st + // tcEnv.eUngeneralizableItems + p_list p_ident tcEnv.ePath st + p_cpath tcEnv.eCompPath st + p_cpath tcEnv.eAccessPath st + // tcEnv.eAccessRights + p_list p_cpath tcEnv.eInternalsVisibleCompPaths st + p_modul_typ tcEnv.eModuleOrNamespaceTypeAccumulator.Value st + p_context_info tcEnv.eContextInfo st + p_option (p_tcref "test") tcEnv.eFamilyType st + p_option p_ctor_info tcEnv.eCtorInfo st + p_option p_string tcEnv.eCallerMemberName st + p_list (p_list (p_ArgReprInfo)) tcEnv.eLambdaArgInfos st + p_bool tcEnv.eIsControlFlow st +// tcEnv.eCachedImplicitYieldExpressions + +let p_tcs_root_sig (qualifiedNameOfFile, moduleOrNamespaceType) st = + p_tup2 p_qualified_name_of_file p_modul_typ_new (qualifiedNameOfFile, moduleOrNamespaceType) st + +// pickling top + let pickleSharedData sharedData st = p_tup3 p_attribs @@ -17,8 +142,169 @@ let pickleSharedData sharedData st = let pickleCheckedImplFile checkedImplFile st = p_checked_impl_file checkedImplFile st +let pickleTcState (tcState: TcState) (st: WriterState) = + p_ccuref_new tcState.tcsCcu st + p_tc_env tcState.tcsTcSigEnv st + p_tc_env tcState.tcsTcImplEnv st + p_bool tcState.tcsCreatesGeneratedProvidedTypes st + (p_list p_tcs_root_sig) (tcState.tcsRootSigs.ToList()) st + p_list p_qualified_name_of_file (tcState.tcsRootImpls.ToList()) st + p_modul_typ_new tcState.tcsCcuSig st + p_list p_open_decl tcState.tcsImplicitOpenDeclarations st + // unpickling +let u_context_info st : ContextInfo = + let tag = u_byte st + + match tag with + | 0 -> ContextInfo.NoContext + | 1 -> + let range = u_range st + ContextInfo.IfExpression range + | 2 -> + let range = u_range st + ContextInfo.OmittedElseBranch range + | 3 -> + let range = u_range st + ContextInfo.ElseBranchResult range + | 4 -> ContextInfo.RecordFields + | 5 -> ContextInfo.TupleInRecordFields + | 6 -> + let bool = u_bool st + let range = u_range st + ContextInfo.CollectionElement(bool, range) + | 7 -> ContextInfo.ReturnInComputationExpression + | 8 -> ContextInfo.YieldInComputationExpression + | 9 -> + let bool = u_bool st + ContextInfo.RuntimeTypeTest bool + | 10 -> + let bool = u_bool st + ContextInfo.DowncastUsedInsteadOfUpcast bool + | 11 -> + let range = u_range st + ContextInfo.FollowingPatternMatchClause range + | 12 -> + let range = u_range st + ContextInfo.PatternMatchGuard range + | 13 -> + let ttype = u_ty st + ContextInfo.SequenceExpression ttype + | _ -> ufailwith st "u_context_info" + +let u_safe_init_data st : SafeInitData = + let tag = u_byte st + + match tag with + | 0 -> + let recdFieldRef = u_rfref st + let recdField = u_recdfield_spec st + SafeInitField(recdFieldRef, recdField) + | 1 -> NoSafeInitInfo + | _ -> ufailwith st "u_safe_init_data" + +let u_ctor_info st : CtorInfo = + let ctorShapeCounter = u_int st + let safeThisValOpt = u_option u_Val st + let safeInitInfo = u_safe_init_data st + let ctorIsImplicit = u_bool st + + { + ctorShapeCounter = ctorShapeCounter + safeThisValOpt = safeThisValOpt + safeInitInfo = safeInitInfo + ctorIsImplicit = ctorIsImplicit + } + +let u_module_and_namespace st : string * ModuleOrNamespaceRef list = + let s = u_string st + let l = u_list u_tcref st + s, l + +let u_union_case_info st = + let typeInst = u_tys_new st + let ucref = u_ucref st + UnionCaseInfo(typeInst, ucref) + +let u_item st : Item = + let tag = u_byte st + + match tag with + | 0 -> + let vref = u_vref st + let binding = u_non_null_slot u_Val_new st + vref.binding <- binding + Item.Value vref + | 1 -> + let tcrefs = u_list u_tcref st + Item.UnqualifiedType tcrefs + + | 2 -> + let unionCaseInfo = u_union_case_info st + let hasAttrs = u_bool st + Item.UnionCase(unionCaseInfo, hasAttrs) + | 3 -> + let tcref = u_tcref st + Item.ExnCase tcref + | _ -> ufailwith st "u_item" + +let u_name_resolution_env st : NameResolutionEnv = + let eUnqualifiedItems = u_Map u_string u_item st + + let eModulesAndNamespaces: NameMultiMap = + u_list u_module_and_namespace st |> Map.ofList + + let g: TcGlobals = Unchecked.defaultof<_> + + { NameResolutionEnv.Empty g with + eUnqualifiedItems = eUnqualifiedItems + eModulesAndNamespaces = eModulesAndNamespaces + } + +let u_tc_env (st: ReaderState) : TcEnv = + let eNameResEnv = u_name_resolution_env st + //let eUngeneralizableItems + let ePath = u_list u_ident st + let eCompPath = u_cpath st + let eAccessPath = u_cpath st + // eAccessRights + let eInternalsVisibleCompPaths = u_list u_cpath st + let eModuleOrNamespaceTypeAccumulator = u_modul_typ st + let eContextInfo = u_context_info st + let eFamilyType = u_option u_tcref st + let eCtorInfo = u_option u_ctor_info st + let eCallerMemberName = u_option u_string st + let eLambdaArgInfos = u_list (u_list u_ArgReprInfo) st + let eIsControlFlow = u_bool st + // eCachedImplicitYieldExpressions + + { + eNameResEnv = eNameResEnv + eUngeneralizableItems = List.empty + ePath = ePath + eCompPath = eCompPath + eAccessPath = eAccessPath + eAccessRights = AccessibleFromEverywhere + eInternalsVisibleCompPaths = eInternalsVisibleCompPaths + eModuleOrNamespaceTypeAccumulator = ref eModuleOrNamespaceTypeAccumulator + eContextInfo = eContextInfo + eFamilyType = eFamilyType + eCtorInfo = eCtorInfo + eCallerMemberName = eCallerMemberName + eLambdaArgInfos = eLambdaArgInfos + eIsControlFlow = eIsControlFlow + eCachedImplicitYieldExpressions = HashMultiMap(HashIdentity.Structural) + } + +let u_tcs_root_sig st = + let qualifiedNameOfFile, moduleOrNamespaceType = + u_tup2 u_qualified_name_of_file u_modul_typ_new st + + qualifiedNameOfFile, moduleOrNamespaceType + +// unpickling top + let unpickleSharedData st = let mainMethodAttrs, netModuleAttrs, assemblyAttrs = u_tup3 u_attribs u_attribs u_attribs st @@ -33,3 +319,24 @@ let unpickleSharedData st = { TopAttribs = attribs } let unpickleCheckedImplFile st = u_checked_impl_file st + +let unpickleTcState (st: ReaderState) : TcState = + let tcsCcu = u_ccuref_new st + let tcsTcSigEnv = u_tc_env st + let tcsTcImplEnv = u_tc_env st + let tcsCreatesGeneratedProvidedTypes = u_bool st + let tcsRootSigs = u_list u_tcs_root_sig st + let tcsRootImpls = u_list u_qualified_name_of_file st + let tcsCcuSig = u_modul_typ_new st + let tcsImplicitOpenDeclarations = u_list u_open_decl st + + { + tcsCcu = tcsCcu + tcsCreatesGeneratedProvidedTypes = tcsCreatesGeneratedProvidedTypes + tcsTcSigEnv = tcsTcSigEnv + tcsTcImplEnv = tcsTcImplEnv + tcsRootSigs = RootSigs.FromList(qnameOrder, tcsRootSigs) + tcsRootImpls = RootImpls.Create(qnameOrder, tcsRootImpls) + tcsCcuSig = tcsCcuSig + tcsImplicitOpenDeclarations = tcsImplicitOpenDeclarations + } diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs index 92bc855e3aa..8c1fc1d1d23 100644 --- a/src/Compiler/Driver/fsc.fs +++ b/src/Compiler/Driver/fsc.fs @@ -171,10 +171,48 @@ let TypeCheck match tcCacheState with | TcCacheState.Present files when files |> List.forall (fun (_file, canReuse) -> canReuse) -> - cachingDriver.ReuseTcResults inputs tcInitialState + // TODO: last state should be sent back here, not the initial state + let _lastState, topAttrs, declaredImpls, tcEnvFromImpls = + cachingDriver.ReuseTcResults inputs + + tcInitialState, topAttrs, declaredImpls, tcEnvFromImpls + | TcCacheState.Present files when files |> List.exists (fun (_file, canReuse) -> canReuse) -> + let canReuse, cannotReuse = + files + |> List.partition (fun (_file, canReuse) -> canReuse) + |> fun (a, b) -> a |> List.map fst, b |> List.map fst + + let tcCurrentState, _, reusedImpls, _ = cachingDriver.ReuseTcResults canReuse + + let lastState, topAttrs, newImpls, tcEnvAtEndOfLastFile, tcStates = + CheckClosedInputSet( + ctok, + diagnosticsLogger.CheckForErrors, + tcConfig, + tcImports, + tcGlobals, + None, + tcCurrentState, + eagerFormat, + cannotReuse + ) + + let _tcResults = + List.zip3 cannotReuse newImpls tcStates + |> List.map (fun (input, impl, state) -> + { + Input = input + DeclaredImpl = impl + State = state + }) + + // TODO: cache new stuff + // cachingDriver.CacheTcResults(tcResults, topAttrs, tcEnvAtEndOfLastFile, tcGlobals, outfile) + + lastState, topAttrs, reusedImpls @ newImpls, tcEnvAtEndOfLastFile | _ -> - let tcState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile = + let lastState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile, tcStates = CheckClosedInputSet( ctok, diagnosticsLogger.CheckForErrors, @@ -187,20 +225,32 @@ let TypeCheck inputs ) - cachingDriver.CacheTcResults(tcState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile, inputs, tcGlobals, outfile) - tcState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile + let tcResults = + List.zip3 inputs declaredImpls tcStates + |> List.map (fun (input, impl, state) -> + { + Input = input + DeclaredImpl = impl + State = state + }) + + cachingDriver.CacheTcResults(tcResults, topAttrs, tcEnvAtEndOfLastFile, tcGlobals, outfile) + lastState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile else - CheckClosedInputSet( - ctok, - (fun () -> diagnosticsLogger.CheckForRealErrorsIgnoringWarnings), - tcConfig, - tcImports, - tcGlobals, - None, - tcInitialState, - eagerFormat, - inputs - ) + let lastState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile, _ = + CheckClosedInputSet( + ctok, + (fun () -> diagnosticsLogger.CheckForRealErrorsIgnoringWarnings), + tcConfig, + tcImports, + tcGlobals, + None, + tcInitialState, + eagerFormat, + inputs + ) + + lastState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile with exn -> errorRecovery exn rangeStartup exiter.Exit 1 diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs index eaba5aa6582..e03537bd111 100644 --- a/src/Compiler/Interactive/fsi.fs +++ b/src/Compiler/Interactive/fsi.fs @@ -2200,7 +2200,7 @@ type internal FsiDynamicCompiler // Typecheck. The lock stops the type checker running at the same time as the // server intellisense implementation (which is currently incomplete and #if disabled) - let tcState, topCustomAttrs, declaredImpls, tcEnvAtEndOfLastInput = + let tcState, topCustomAttrs, declaredImpls, tcEnvAtEndOfLastInput, _ = lock tcLockObject (fun _ -> CheckClosedInputSet( ctok, diff --git a/src/Compiler/TypedTree/TypedTreePickle.fs b/src/Compiler/TypedTree/TypedTreePickle.fs index 88b08f1cf26..632e53a7424 100644 --- a/src/Compiler/TypedTree/TypedTreePickle.fs +++ b/src/Compiler/TypedTree/TypedTreePickle.fs @@ -1067,7 +1067,8 @@ let u_ILTypeDef st : ILTypeDef = let properties = Unchecked.defaultof<_> let additionalFlags = u_ILTypeDefAdditionalFlags st let securityDeclsStored = ILSecurityDecls([||]) - let customAttrsStored = Unchecked.defaultof<_> + // TODO: fill this in + let customAttrsStored = ILAttributesStored.Given (ILAttributes.Empty) ILTypeDef(name, attributes, diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Recompilation.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Recompilation.fs index e1d57afcf37..afa78a2d0c5 100644 --- a/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Recompilation.fs +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/Recompilation.fs @@ -125,3 +125,60 @@ printfn $"{M1.helloWorld}" """ [ expected ] Assert.True(outcome) + + [] + [] +// [] + let ``Multiple files - partial TC info reuse`` (code1: string) (code2: string) = + let tempDir = createTemporaryDirectory().FullName + + let fileName1 = "File0" + let fileName2 = "File1" + + let tempPath1 = tempDir ++ $"{fileName1}.fs" + let tempPath2 = tempDir ++ $"{fileName2}.fs" + + File.WriteAllText(tempPath1, code1) + File.WriteAllText(tempPath2, code2) + + let cUnit = + FsFromPath tempPath1 + |> withAdditionalSourceFile (SourceCodeFileKind.Create tempPath2) + |> withReuseTcResults + |> withNoInterfaceData + |> withOptions [ "--compressmetadata-" ] + |> withOptions [ "--optimize-" ] + + let expected = + cUnit + |> compileExisting + |> shouldSucceed + |> fun r -> ILChecker.generateIL r.Output.OutputPath.Value [] + + File.WriteAllText(tempPath2, code2) + + let actual = + cUnit + |> compileExisting + |> shouldSucceed + |> fun r -> ILChecker.generateIL r.Output.OutputPath.Value [] + + let outcome, _msg, _actualIL = + ILChecker.compareIL + fileName1 + actual + [ expected ] + + Assert.True(outcome) From 46ff11bc0c2ea1fdb68cc59997bbe569248b87d6 Mon Sep 17 00:00:00 2001 From: Petr Date: Mon, 3 Mar 2025 12:36:10 +0100 Subject: [PATCH 6/8] Refactoring --- .../.FSharp.Compiler.Service/9.0.200.md | 1 - .../Driver/ReuseTcResults/CachingDriver.fs | 5 +- .../Driver/ReuseTcResults/TcResultsPickle.fs | 1423 +++++++++++++- src/Compiler/SyntaxTree/PrettyNaming.fs | 2 - src/Compiler/SyntaxTree/PrettyNaming.fsi | 2 - src/Compiler/TypedTree/TypedTreePickle.fs | 1696 ++--------------- 6 files changed, 1558 insertions(+), 1571 deletions(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md index b106b96a268..0a05f20bf45 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md @@ -27,7 +27,6 @@ ### Added -* New flag `--reusetypecheckingresults`, for skipping recompilation in some cases * Let `dotnet fsi --help` print a link to the documentation website. ([PR #18006](https://github.com/dotnet/fsharp/pull/18006)) * Deprecate places where `seq` can be omitted. ([Language suggestion #1033](https://github.com/fsharp/fslang-suggestions/issues/1033), [PR #17772](https://github.com/dotnet/fsharp/pull/17772)) * Support literal attribute on decimals ([PR #17769](https://github.com/dotnet/fsharp/pull/17769)) diff --git a/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs b/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs index b583b9e45b7..e6baf3aff8d 100644 --- a/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs +++ b/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs @@ -4,15 +4,14 @@ module internal FSharp.Compiler.ReuseTcResults.CachingDriver open System.IO +open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.CompilerConfig open FSharp.Compiler.Diagnostics open FSharp.Compiler.GraphChecking open FSharp.Compiler.IO open FSharp.Compiler.ParseAndCheckInputs open FSharp.Compiler.Syntax -open FSharp.Compiler.Syntax.PrettyNaming open FSharp.Compiler.ReuseTcResults.TcResultsImport -open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.ReuseTcResults.TcResultsPickle open FSharp.Compiler.TypedTree @@ -53,7 +52,7 @@ type TcResult = type CachingDriver(tcConfig: TcConfig) = let outputDir = tcConfig.outputDir |> Option.defaultValue "" - let tcDataFilePath = Path.Combine(outputDir, FSharpTcDataResourceName) + let tcDataFilePath = Path.Combine(outputDir, "tcComplilationData") let graphFilePath = Path.Combine(outputDir, "tcGraph") let tcSharedDataFilePath = Path.Combine(outputDir, "tcSharedData") let tcInputFilePath = Path.Combine(outputDir, "tcInput") diff --git a/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs b/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs index e46e154291f..ef330c9f0f3 100644 --- a/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs +++ b/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs @@ -1,22 +1,623 @@ module internal FSharp.Compiler.ReuseTcResults.TcResultsPickle +open FSharp.Compiler +open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.AccessibilityLogic open FSharp.Compiler.CheckBasics open FSharp.Compiler.CheckDeclarations +open FSharp.Compiler.CompilerGlobalState open FSharp.Compiler.ConstraintSolver +open FSharp.Compiler.DiagnosticsLogger open FSharp.Compiler.NameResolution open FSharp.Compiler.ParseAndCheckInputs open FSharp.Compiler.Infos +open FSharp.Compiler.Syntax open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text.Range open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps open FSharp.Compiler.TypedTreePickle +open FSharp.Compiler.Xml + +open Internal.Utilities open Internal.Utilities.Collections open Internal.Utilities.Library +open Internal.Utilities.Library.Extras + + type TcSharedData = { TopAttribs: TopAttribs } // pickling +let p_stamp = p_int64 + +let p_stamp_map pv = p_Map p_stamp pv + +let p_non_null_slot f (x: 'a | null) st = + match x with + | null -> p_byte 0 st + | h -> p_byte 1 st; f h st + +let p_ILTypeDefAdditionalFlags (x: ILTypeDefAdditionalFlags) st = + p_int32 (int x) st + +let p_ILTypeDef (x: ILTypeDef) st = + p_string x.Name st + //p_type_attributes x.Attributes + //p_il_type_def_layout x.Layout + //x.Implements + //x.Extends + //x.Methods + //x.NestedTypes + //x.Fields + //x.MethodImpls + //x.Events + //x.Properties + p_ILTypeDefAdditionalFlags x.Flags st + //x.SecurityDeclsStored + //x.CustomAttrsStored + //p_il + //p_int32 x.MetadataIndex st + +let p_tyar_spec_data_new (x: Typar) st = + p_tup6 + p_ident + p_attribs + p_int64 + p_tyar_constraints + p_xmldoc + p_stamp + (x.typar_id, x.Attribs, int64 x.typar_flags.PickledBits, x.Constraints, x.XmlDoc, x.Stamp) st + +let p_tyar_spec_new (x: Typar) st = + //Disabled, workaround for bug 2721: if x.Rigidity <> TyparRigidity.Rigid then warning(Error(sprintf "p_tyar_spec: typar#%d is not rigid" x.Stamp, x.Range)) + if x.IsFromError then warning(Error((0, "p_tyar_spec: from error"), x.Range)) + p_osgn_decl st.otypars p_tyar_spec_data_new x st + +let p_tyar_specs_new = (p_list p_tyar_spec_new) + +let rec p_ty_new (ty: TType) st : unit = + match ty with + | TType_tuple (tupInfo, l) -> + p_byte 0 st + p_tup2 + p_tup_info + p_tys_new + (tupInfo, l) + st + + | TType_app (tyconRef, typeInstantiation, nullness) -> + p_byte 1 st + p_tup4 + (p_tcref "app") + p_tys_new + p_nullness + (p_non_null_slot p_entity_spec_new) + (tyconRef, typeInstantiation, nullness, tyconRef.binding) + st + + | TType_fun (domainType, rangeType, nullness) -> + p_byte 2 st + p_ty_new domainType st + p_ty_new rangeType st + p_nullness nullness st + + | TType_var (typar, nullness) -> + p_byte 3 st + p_tup4 + p_tpref + p_nullness + (p_option p_ty_new) + p_stamp + (typar, nullness, typar.Solution, typar.Stamp) + st + + | TType_forall (tps, r) -> + p_byte 4 st + p_tup2 + p_typars + p_ty_new + (tps, r) + st + + | TType_measure unt -> + p_byte 5 st + p_measure_expr unt st + + | TType_ucase (uc, tinst) -> + p_byte 6 st + p_tup2 + p_ucref + p_tys_new + (uc, tinst) + st + + | TType_anon (anonInfo, l) -> + p_byte 7 st + p_tup2 + p_anonInfo + p_tys_new + (anonInfo, l) + st + +and p_tys_new l = + let _count = l.Length + p_list p_ty_new l + +and p_expr_new (expr: Expr) st = + match expr with + | Expr.Link e -> p_byte 0 st; p_expr_new e.Value st + | Expr.Const (x, m, ty) -> p_byte 1 st; p_tup3 p_const p_dummy_range p_ty_new (x, m, ty) st + | Expr.Val (a, b, m) -> + p_byte 2 st + p_tup4 + p_vref_new + p_vrefFlags + p_dummy_range + (p_non_null_slot p_Val_new) + (a, b, m, a.binding) + st + | Expr.Op (a, b, c, d) -> p_byte 3 st; p_tup4 p_op_new p_tys_new p_exprs_new p_dummy_range (a, b, c, d) st + | Expr.Sequential (a, b, c, d) -> p_byte 4 st; p_tup4 p_expr_new p_expr_new p_int p_dummy_range (a, b, (match c with NormalSeq -> 0 | ThenDoSeq -> 1), d) st + | Expr.Lambda (_, a1, b0, b1, c, d, e) -> p_byte 5 st; p_tup6 (p_option p_Val) (p_option p_Val) p_Vals p_expr_new p_dummy_range p_ty_new (a1, b0, b1, c, d, e) st + | Expr.TyLambda (_, b, c, d, e) -> p_byte 6 st; p_tup4 p_tyar_specs_new p_expr_new p_dummy_range p_ty_new (b, c, d, e) st + | Expr.App (funcExpr, formalType, typeArgs, args, range) -> + p_byte 7 st + + p_expr_new funcExpr st + p_ty_new formalType st + p_tys_new typeArgs st + p_exprs_new args st + p_dummy_range range st + | Expr.LetRec (a, b, c, _) -> p_byte 8 st; p_tup3 p_binds p_expr_new p_dummy_range (a, b, c) st + | Expr.Let (a, b, c, _) -> p_byte 9 st; p_tup3 p_bind p_expr_new p_dummy_range (a, b, c) st + | Expr.Match (_, a, b, c, d, e) -> p_byte 10 st; p_tup5 p_dummy_range p_dtree p_targets p_dummy_range p_ty_new (a, b, c, d, e) st + | Expr.Obj (_, b, c, d, e, f, g) -> p_byte 11 st; p_tup6 p_ty_new (p_option p_Val) p_expr_new p_methods p_intfs p_dummy_range (b, c, d, e, f, g) st + | Expr.StaticOptimization (a, b, c, d) -> p_byte 12 st; p_tup4 p_constraints p_expr_new p_expr_new p_dummy_range (a, b, c, d) st + | Expr.TyChoose (a, b, c) -> p_byte 13 st; p_tup3 p_tyar_specs_new p_expr_new p_dummy_range (a, b, c) st + | Expr.Quote (ast, _, _, m, ty) -> p_byte 14 st; p_tup3 p_expr_new p_dummy_range p_ty_new (ast, m, ty) st + | Expr.WitnessArg (traitInfo, m) -> p_byte 15 st; p_trait traitInfo st; p_dummy_range m st + | Expr.DebugPoint (_, innerExpr) -> + p_byte 16 st + p_expr_new innerExpr st + +and p_exprs_new = p_list p_expr_new + +and p_ucref_new (UnionCaseRef(a, b)) st = + p_tup3 + (p_tcref "ucref") + p_string + (p_non_null_slot p_entity_spec_new) + (a, b, a.binding) + st + +and p_op_new x st = + match x with + | TOp.UnionCase c -> + p_byte 0 st + p_ucref_new c st + | TOp.ExnConstr c -> p_byte 1 st; p_tcref "op" c st + | TOp.Tuple tupInfo -> + if evalTupInfoIsStruct tupInfo then + p_byte 29 st + else + p_byte 2 st + | TOp.Recd (a, b) -> p_byte 3 st; p_tup2 p_recdInfo (p_tcref "recd op") (a, b) st + | TOp.ValFieldSet a -> p_byte 4 st; p_rfref a st + | TOp.ValFieldGet a -> p_byte 5 st; p_rfref a st + | TOp.UnionCaseTagGet a -> p_byte 6 st; p_tcref "cnstr op" a st + | TOp.UnionCaseFieldGet (a, b) -> p_byte 7 st; p_tup2 p_ucref p_int (a, b) st + | TOp.UnionCaseFieldSet (a, b) -> p_byte 8 st; p_tup2 p_ucref p_int (a, b) st + | TOp.ExnFieldGet (a, b) -> p_byte 9 st; p_tup2 (p_tcref "exn op") p_int (a, b) st + | TOp.ExnFieldSet (a, b) -> p_byte 10 st; p_tup2 (p_tcref "exn op") p_int (a, b) st + | TOp.TupleFieldGet (tupInfo, a) -> + if evalTupInfoIsStruct tupInfo then + p_byte 30 st; p_int a st + else + p_byte 11 st; p_int a st + | TOp.ILAsm (a, b) -> p_byte 12 st; p_tup2 (p_list p_ILInstr) p_tys (a, b) st + | TOp.RefAddrGet _ -> p_byte 13 st + | TOp.UnionCaseProof a -> p_byte 14 st; p_ucref a st + | TOp.Coerce -> p_byte 15 st + | TOp.TraitCall b -> p_byte 16 st; p_trait b st + | TOp.LValueOp (a, b) -> p_byte 17 st; p_tup2 p_lval_op_kind (p_vref "lval") (a, b) st + | TOp.ILCall (a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) + -> p_byte 18 st; p_tup11 p_bool p_bool p_bool p_bool p_vrefFlags p_bool p_bool p_ILMethodRef p_tys p_tys p_tys (a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) st + | TOp.Array -> p_byte 19 st + | TOp.While _ -> p_byte 20 st + | TOp.IntegerForLoop (_, _, dir) -> p_byte 21 st; p_int (match dir with FSharpForLoopUp -> 0 | CSharpForLoopUp -> 1 | FSharpForLoopDown -> 2) st + | TOp.Bytes bytes -> p_byte 22 st; p_bytes bytes st + | TOp.TryWith _ -> p_byte 23 st + | TOp.TryFinally _ -> p_byte 24 st + | TOp.ValFieldGetAddr (a, _) -> p_byte 25 st; p_rfref a st + | TOp.UInt16s arr -> p_byte 26 st; p_array p_uint16 arr st + | TOp.Reraise -> p_byte 27 st + | TOp.UnionCaseFieldGetAddr (a, b, _) -> p_byte 28 st; p_tup2 p_ucref p_int (a, b) st + // Note tag byte 29 is taken for struct tuples, see above + // Note tag byte 30 is taken for struct tuples, see above + (* 29: TOp.Tuple when evalTupInfoIsStruct tupInfo = true *) + (* 30: TOp.TupleFieldGet when evalTupInfoIsStruct tupInfo = true *) + | TOp.AnonRecd info -> p_byte 31 st; p_anonInfo info st + | TOp.AnonRecdGet (info, n) -> p_byte 32 st; p_anonInfo info st; p_int n st + | TOp.Goto _ | TOp.Label _ | TOp.Return -> failwith "unexpected backend construct in pickled TAST" + +and p_entity_spec_data_new (x: Entity) st = + p_tyar_specs_new (x.entity_typars.Force(x.entity_range)) st + p_string x.entity_logical_name st + p_option p_string x.EntityCompiledName st + p_range x.entity_range st + p_stamp x.entity_stamp st + p_option p_pubpath x.entity_pubpath st + p_access x.Accessibility st + p_access x.TypeReprAccessibility st + p_attribs x.entity_attribs st + let _ = p_tycon_repr_new x.entity_tycon_repr st + p_option p_ty_new x.TypeAbbrev st + p_tcaug_new x.entity_tycon_tcaug st + p_string System.String.Empty st + p_kind x.TypeOrMeasureKind st + p_int64 x.entity_flags.Flags st + p_option p_cpath x.entity_cpath st + p_maybe_lazy p_modul_typ_new x.entity_modul_type st + p_exnc_repr x.ExceptionInfo st + if st.oInMem then + p_used_space1 (p_xmldoc x.XmlDoc) st + else + p_space 1 () st + +and p_entity_spec_new x st = p_osgn_decl st.oentities p_entity_spec_data_new x st + +and p_ValData_new x st = + p_string x.val_logical_name st + p_option p_string x.ValCompiledName st + // only keep range information on published values, not on optimization data + p_ranges (x.ValReprInfo |> Option.map (fun _ -> x.val_range, x.DefinitionRange)) st + + p_ty_new x.val_type st + p_stamp x.val_stamp st + + p_int64 x.val_flags.Flags st + p_option p_member_info x.MemberInfo st + p_attribs x.Attribs st + p_option p_ValReprInfo x.ValReprInfo st + p_string x.XmlDocSig st + p_access x.Accessibility st + p_parentref x.TryDeclaringEntity st + p_option p_const x.LiteralValue st + if st.oInMem then + p_used_space1 (p_xmldoc x.XmlDoc) st + else + p_space 1 () st + +and p_Val_new x st = + p_osgn_decl st.ovals p_ValData_new x st + +and p_modul_typ_new (x: ModuleOrNamespaceType) st = + p_tup3 + p_istype + (p_qlist p_Val_new) + (p_qlist p_entity_spec_new) + (x.ModuleOrNamespaceKind, x.AllValsAndMembers, x.AllEntities) + st + +and p_tcaug_new (p: TyconAugmentation) st = + p_tup9 + (p_option (p_tup2 (p_vref "compare_obj") (p_vref "compare"))) + (p_option (p_vref "compare_withc")) + (p_option (p_tup3 (p_vref "hash_obj") (p_vref "hash_withc") (p_vref "equals_withc"))) + (p_option (p_tup2 (p_vref "hash") (p_vref "equals"))) + (p_list (p_tup2 p_string (p_vref "adhoc"))) + (p_list (p_tup3 p_ty_new p_bool p_dummy_range)) + (p_option p_ty_new) + p_bool + (p_space 1) + (p.tcaug_compare, + p.tcaug_compare_withc, + p.tcaug_hash_and_equals_withc |> Option.map (fun (v1, v2, v3, _) -> (v1, v2, v3)), + p.tcaug_equals, + (p.tcaug_adhoc_list + |> ResizeArray.toList + // Explicit impls of interfaces only get kept in the adhoc list + // in order to get check the well-formedness of an interface. + // Keeping them across assembly boundaries is not valid, because relinking their ValRefs + // does not work correctly (they may get incorrectly relinked to a default member) + |> List.filter (fun (isExplicitImpl, _) -> not isExplicitImpl) + |> List.map (fun (_, vref) -> vref.LogicalName, vref)), + p.tcaug_interfaces, + p.tcaug_super, + p.tcaug_abstract, + space) st + + +and p_ccu_data (x: CcuData) st = + p_option p_string x.FileName st + p_ILScopeRef x.ILScopeRef st + p_stamp x.Stamp st + p_option p_string x.QualifiedName st + p_string x.SourceCodeDirectory st + p_bool x.IsFSharp st +#if !NO_TYPEPROVIDERS + p_bool x.IsProviderGenerated st +#endif + p_bool x.UsesFSharp20PlusQuotations st + p_entity_spec_data_new x.Contents st + +and p_ccuref_new (x: CcuThunk) st = + p_tup2 + p_ccu_data + p_string + (x.target, x.name) + st + +and p_nleref_new (x: NonLocalEntityRef) st = + let (NonLocalEntityRef (ccu, strings)) = x + p_tup2 + p_ccuref_new + (p_array p_string) + (ccu, strings) + st + + +and p_tcref_new (x: EntityRef) st = + match x with + | ERefLocal x -> p_byte 0 st; p_local_item_ref "tcref" st.oentities x st + | ERefNonLocal x -> p_byte 1 st; p_nleref_new x st + +and p_nonlocal_val_ref_new (nlv: NonLocalValOrMemberRef) st = + let a = nlv.EnclosingEntity + let key = nlv.ItemKey + let pkey = key.PartialKey + p_tcref_new a st + p_option p_string pkey.MemberParentMangledName st + p_bool pkey.MemberIsOverride st + p_string pkey.LogicalName st + p_int pkey.TotalArgCount st + let isStructThisArgPos = + match key.TypeForLinkage with + | None -> false + | Some ty -> checkForInRefStructThisArg st ty + p_option p_ty_new key.TypeForLinkage st + + +and p_vref_new (x: ValRef) st = + match x with + | VRefLocal x -> p_byte 0 st; p_local_item_ref "valref" st.ovals x st + | VRefNonLocal x -> p_byte 1 st; p_nonlocal_val_ref_new x st + +and p_bind_new (TBind(a, b, _)) st = p_tup2 p_Val_new p_expr_new (a, b) st + +and p_binding (x: ModuleOrNamespaceBinding) st = + match x with + | ModuleOrNamespaceBinding.Binding binding -> + p_byte 0 st + p_bind binding st + | ModuleOrNamespaceBinding.Module (moduleOrNamespace, moduleOrNamespaceContents) -> + p_byte 1 st + p_tup2 + p_entity_spec_new + p_module_or_namespace_contents + (moduleOrNamespace, moduleOrNamespaceContents) + st + +and p_tycon_repr_new (x: TyconRepresentation) 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. + + match x with + // Records + | TFSharpTyconRepr { fsobjmodel_rfields = fs; fsobjmodel_kind = TFSharpRecord } -> + p_byte 1 st + p_byte 0 st + p_rfield_table fs st + false + + // Unions without static fields + | TFSharpTyconRepr { fsobjmodel_cases = x; fsobjmodel_kind = TFSharpUnion; fsobjmodel_rfields = fs } when fs.FieldsByIndex.Length = 0 -> + p_byte 1 st + p_byte 1 st + p_array p_unioncase_spec x.CasesTable.CasesByIndex st + false + + // Unions with static fields, added to format + | TFSharpTyconRepr ({ fsobjmodel_cases = cases; fsobjmodel_kind = TFSharpUnion } as r) -> + if st.oglobals.compilingFSharpCore then + let fields = r.fsobjmodel_rfields.FieldsByIndex + let firstFieldRange = fields[0].DefinitionRange + let allFieldsText = fields |> Array.map (fun f -> f.LogicalName) |> String.concat System.Environment.NewLine + raise (Error(FSComp.SR.pickleFsharpCoreBackwardsCompatible("fields in union",allFieldsText), firstFieldRange)) + + p_byte 2 st + p_array p_unioncase_spec cases.CasesTable.CasesByIndex st + p_tycon_objmodel_data r st + false + + | TAsmRepr ilTy -> + p_byte 1 st + p_byte 2 st + p_ILType ilTy st + false + + | TFSharpTyconRepr r -> + p_byte 1 st + p_byte 3 st + p_tycon_objmodel_data r st + false + + | TMeasureableRepr ty -> + p_byte 1 st + p_byte 4 st + p_ty ty st + false + + | TNoRepr -> + p_byte 0 st + false + +#if !NO_TYPEPROVIDERS + | TProvidedTypeRepr info -> + if info.IsErased then + // Pickle erased type definitions as a NoRepr + p_byte 0 st + false + else + // Pickle generated type definitions as a TAsmRepr + p_byte 1 st + p_byte 2 st + p_ILType (mkILBoxedType(ILTypeSpec.Create(TypeProviders.GetILTypeRefOfProvidedType(info.ProvidedType, range0), []))) st + true + + | TProvidedNamespaceRepr _ -> + p_byte 0 st + false +#endif + + | TILObjectRepr (TILObjectReprData (scope, nesting, td)) -> + p_byte 5 st + p_ILScopeRef scope st + (p_list p_ILTypeDef) nesting st + p_ILTypeDef td st + false + +and p_qualified_name_of_file qualifiedNameOfFile st = + let (QualifiedNameOfFile ident) = qualifiedNameOfFile + p_ident ident st + +and p_pragma pragma st = + let (ScopedPragma.WarningOff (range, warningNumber)) = pragma + p_tup2 + p_range + p_int + (range, warningNumber) + st + +and p_pragmas x st = + p_list p_pragma x st + +and p_long_ident (x: LongIdent) st = + p_list p_ident x st + +and p_trivia (x: SyntaxTrivia.IdentTrivia) st = + pfailwith st (nameof p_trivia) + +and p_syn_long_ident (x: SynLongIdent) st = + let (SynLongIdent (id, dotRanges, trivia)) = x + p_tup3 + p_long_ident + (p_list p_range) + (p_list (p_option p_trivia)) + (id, dotRanges, trivia) + st + +and p_syn_type (x: SynType) st = + pfailwith st (nameof p_syn_type) + +and p_syn_open_decl_target (x: SynOpenDeclTarget) st = + match x with + | SynOpenDeclTarget.ModuleOrNamespace (longId, range)-> + p_byte 0 st + p_tup2 + p_syn_long_ident + p_range + (longId, range) + st + | SynOpenDeclTarget.Type (typeName, range) -> + p_byte 1 st + p_tup2 + p_syn_type + p_range + (typeName, range) + st + +and p_tup_info (tupInfo: TupInfo) st = + let (TupInfo.Const c) = tupInfo + p_bool c st + +and p_nullness (nullness: Nullness) st = + match nullness.Evaluate() with + | NullnessInfo.WithNull -> p_byte 0 st + | NullnessInfo.WithoutNull -> p_byte 1 st + | NullnessInfo.AmbivalentToNull -> p_byte 2 st + +and p_typars = p_list p_tpref + +and p_module_or_namespace_contents (x: ModuleOrNamespaceContents) st = + match x with + | TMDefs defs -> + p_byte 0 st + p_list p_module_or_namespace_contents defs st + | TMDefOpens openDecls -> + p_byte 1 st + p_list p_open_decl openDecls st + | TMDefLet (binding, range) -> + p_byte 2 st + p_tup2 + p_bind_new + p_range + (binding, range) + st + | TMDefDo (expr, range) -> + p_byte 3 st + p_tup2 + p_expr_new + p_range + (expr, range) + st + | TMDefRec (isRec, opens, tycons, bindings, range) -> + p_byte 4 st + p_tup5 + p_bool + (p_list p_open_decl) + (p_list p_entity_spec_data_new) + (p_list p_binding) + p_range + (isRec, opens, tycons, bindings, range) + st + +and p_checked_impl_file_contents = p_module_or_namespace_contents + +and p_named_debug_point_key (x: NamedDebugPointKey) st = + p_tup2 + p_range + p_string + (x.Range, x.Name) + st + +and p_named_debug_points = p_Map p_named_debug_point_key p_range + +and p_anon_recd_types = p_stamp_map p_anonInfo + +and p_open_decl (x: OpenDeclaration) st = + p_tup6 + p_syn_open_decl_target + (p_option p_range) + (p_list p_tcref_new) + p_tys + p_range + p_bool + (x.Target, x.Range, x.Modules, x.Types, x.AppliedScope, x.IsOwnNamespace) + st + +and p_checked_impl_file file st = + let (CheckedImplFile ( + qualifiedNameOfFile, + pragmas, + signature, + contents, + hasExplicitEntryPoint, + isScript, + anonRecdTypeInfo, + namedDebugPointsForInlinedCode)) = file + + p_qualified_name_of_file qualifiedNameOfFile st + p_pragmas pragmas st + p_modul_typ_new signature st + p_checked_impl_file_contents contents st + p_bool hasExplicitEntryPoint st + p_bool isScript st + p_anon_recd_types anonRecdTypeInfo st + p_named_debug_points namedDebugPointsForInlinedCode st + let p_context_info (x: ContextInfo) st = match x with | ContextInfo.NoContext -> p_byte 0 st @@ -99,16 +700,16 @@ let p_name_resolution_env (env: NameResolutionEnv) st = // eUnqualifiedEnclosingTypeInsts // ePatItems (p_list p_module_and_namespace) (env.eModulesAndNamespaces |> Map.toList) st -// eFullyQualifiedModulesAndNamespaces -// eFieldLabels -// eUnqualifiedRecordOrUnionTypeInsts -// eTyconsByAccessNames -// eFullyQualifiedTyconsByAccessNames -// eTyconsByDemangledNameAndArity -// eFullyQualifiedTyconsByDemangledNameAndArity -// eIndexedExtensionMembers -// eUnindexedExtensionMembers -// eTypars + // eFullyQualifiedModulesAndNamespaces + // eFieldLabels + // eUnqualifiedRecordOrUnionTypeInsts + // eTyconsByAccessNames + // eFullyQualifiedTyconsByAccessNames + // eTyconsByDemangledNameAndArity + // eFullyQualifiedTyconsByDemangledNameAndArity + // eIndexedExtensionMembers + // eUnindexedExtensionMembers + // eTypars let p_tc_env (tcEnv: TcEnv) (st: WriterState) = p_name_resolution_env tcEnv.eNameResEnv st @@ -130,6 +731,7 @@ let p_tc_env (tcEnv: TcEnv) (st: WriterState) = let p_tcs_root_sig (qualifiedNameOfFile, moduleOrNamespaceType) st = p_tup2 p_qualified_name_of_file p_modul_typ_new (qualifiedNameOfFile, moduleOrNamespaceType) st + // pickling top let pickleSharedData sharedData st = @@ -154,6 +756,805 @@ let pickleTcState (tcState: TcState) (st: WriterState) = // unpickling +let u_stamp = u_int64 + +let u_stamp_map uv = u_Map u_stamp uv + +let u_non_null_slot f st = + let tag = u_byte st + match tag with + | 0 -> Unchecked.defaultof<_> + | 1 -> f st + | n -> ufailwith st ("u_option: found number " + string n) + + +let u_ILTypeDefAdditionalFlags st : ILTypeDefAdditionalFlags = + let i = u_int32 st + enum i + +let u_ILTypeDef st : ILTypeDef = + let name = u_string st + let attributes = System.Reflection.TypeAttributes.Public + let layout = ILTypeDefLayout.Auto + let implements = Unchecked.defaultof<_> + let genericParams = [] + let extends = Unchecked.defaultof<_> + let methods = ILMethodDefs(fun () -> [||]) + let nestedTypes = Unchecked.defaultof<_> + let fields = Unchecked.defaultof<_> + let methodImpls = Unchecked.defaultof<_> + let events = Unchecked.defaultof<_> + let properties = Unchecked.defaultof<_> + let additionalFlags = u_ILTypeDefAdditionalFlags st + let securityDeclsStored = ILSecurityDecls([||]) + // TODO: fill this in + let customAttrsStored = ILAttributesStored.Given (ILAttributes.Empty) + + ILTypeDef(name, + attributes, + layout, + implements, + genericParams, + extends, + methods, + nestedTypes, + fields, + methodImpls, + events, + properties, + additionalFlags, + securityDeclsStored, + customAttrsStored) + +let u_tyar_spec_data_new st = + let a, c, d, e, g, stamp = u_tup6 u_ident u_attribs u_int64 u_tyar_constraints u_xmldoc u_stamp st + { typar_id=a + typar_stamp=stamp + typar_flags=TyparFlags(int32 d) + typar_solution=None + typar_astype= Unchecked.defaultof<_> + typar_opt_data= + match g, e, c with + | doc, [], [] when doc.IsEmpty -> None + | _ -> Some { typar_il_name = None; typar_xmldoc = g; typar_constraints = e; typar_attribs = c;typar_is_contravariant = false } } + +let u_tyar_spec_new st = + u_osgn_decl st.itypars u_tyar_spec_data_new st + +let u_tyar_specs_new = u_list u_tyar_spec_new + +let rec u_ty_new st : TType = + let tag = u_byte st + match tag with + | 0 -> + let tupInfo, l = + u_tup2 + u_tup_info + u_tys_new + st + TType_tuple (tupInfo, l) + + | 1 -> + let tyconRef, typeInstantiation, nullness, binding = + u_tup4 + u_tcref + u_tys_new + u_nullness + (u_non_null_slot u_entity_spec_new) + st + + tyconRef.binding <- binding + TType_app (tyconRef, typeInstantiation, nullness) + + | 2 -> + let (domainType, rangeType, nullness) = + u_tup3 + u_ty_new + u_ty_new + u_nullness + st + TType_fun (domainType, rangeType, nullness) + + | 3 -> + let (typar, nullness, solution, stamp) = + u_tup4 + u_tpref + u_nullness + (u_option u_ty_new) + u_stamp + st + + typar.typar_solution <- solution + typar.typar_stamp <- stamp + TType_var (typar, nullness) + + | 4 -> + let (tps, r) = + u_tup2 + u_typars + u_ty_new + st + + TType_forall (tps, r) + + | 5 -> + let unt = u_measure_expr st + TType_measure unt + + | 6 -> + let uc, tinst = + u_tup2 + u_ucref + u_tys_new + st + TType_ucase (uc, tinst) + + | 7 -> + let anonInfo, l = + u_tup2 + u_anonInfo + u_tys_new + st + TType_anon (anonInfo, l) + | _ -> + ufailwith st (nameof u_ty_new) + +and u_tys_new = u_list u_ty_new + +and u_expr_new st : Expr = + let tag = u_byte st + match tag with + | 0 -> let e = u_expr_new st + let r = ref e + Expr.Link r + | 1 -> let a = u_const st + let b = u_dummy_range st + let c = u_ty_new st + Expr.Const (a, b, c) + | 2 -> let valRef = u_vref_new st + let flags = u_vrefFlags st + let range = u_dummy_range st + let binding = (u_non_null_slot u_Val_new) st + + valRef.binding <- binding + let expr = Expr.Val (valRef, flags, range) + expr + | 3 -> let a = u_op_new st + let b = u_tys_new st + let c = u_exprs_new st + let d = u_dummy_range st + Expr.Op (a, b, c, d) + | 4 -> let a = u_expr_new st + let b = u_expr_new st + let c = u_int st + let d = u_dummy_range st + let dir = match c with 0 -> NormalSeq | 1 -> ThenDoSeq | _ -> ufailwith st "specialSeqFlag" + Expr.Sequential (a, b, dir, d) + | 5 -> let a0 = u_option u_Val st + let b0 = u_option u_Val st + let b1 = u_Vals st + let c = u_expr_new st + let d = u_dummy_range st + let e = u_ty_new st + Expr.Lambda (newUnique(), a0, b0, b1, c, d, e) + | 6 -> let b = u_tyar_specs_new st + let c = u_expr_new st + let d = u_dummy_range st + let e = u_ty_new st + Expr.TyLambda (newUnique(), b, c, d, e) + | 7 -> let a1 = u_expr_new st + let a2 = u_ty_new st + let b = u_tys_new st + let c = u_exprs_new st + let d = u_dummy_range st + let expr = Expr.App (a1, a2, b, c, d) + expr + | 8 -> let a = u_binds st + let b = u_expr_new st + let c = u_dummy_range st + Expr.LetRec (a, b, c, Construct.NewFreeVarsCache()) + | 9 -> let a = u_bind st + let b = u_expr_new st + let c = u_dummy_range st + Expr.Let (a, b, c, Construct.NewFreeVarsCache()) + | 10 -> let a = u_dummy_range st + let b = u_dtree st + let c = u_targets st + let d = u_dummy_range st + let e = u_ty_new st + Expr.Match (DebugPointAtBinding.NoneAtSticky, a, b, c, d, e) + | 11 -> let b = u_ty_new st + let c = (u_option u_Val) st + let d = u_expr_new st + let e = u_methods st + let f = u_intfs st + let g = u_dummy_range st + Expr.Obj (newUnique(), b, c, d, e, f, g) + | 12 -> let a = u_constraints st + let b = u_expr_new st + let c = u_expr_new st + let d = u_dummy_range st + Expr.StaticOptimization (a, b, c, d) + | 13 -> let a = u_tyar_specs_new st + let b = u_expr_new st + let c = u_dummy_range st + Expr.TyChoose (a, b, c) + | 14 -> let b = u_expr_new st + let c = u_dummy_range st + let d = u_ty_new st + Expr.Quote (b, ref None, false, c, d) // isFromQueryExpression=false + | 15 -> let traitInfo = u_trait st + let m = u_dummy_range st + Expr.WitnessArg (traitInfo, m) + | 16 -> let m = u_dummy_range st + let expr = u_expr_new st + Expr.DebugPoint (DebugPointAtLeafExpr.Yes m, expr) + | _ -> ufailwith st "u_expr" + +and u_exprs_new = u_list u_expr_new + +and u_ucref_new st = + let tcref, caseName, binding = + u_tup3 + u_tcref + u_string + (u_non_null_slot u_entity_spec_new) + st + + tcref.binding <- binding + UnionCaseRef(tcref, caseName) + +and u_op_new st = + let tag = u_byte st + match tag with + | 0 -> let a = u_ucref_new st + TOp.UnionCase a + | 1 -> let a = u_tcref st + TOp.ExnConstr a + | 2 -> TOp.Tuple tupInfoRef + | 3 -> let b = u_tcref st + TOp.Recd (RecdExpr, b) + | 4 -> let a = u_rfref st + TOp.ValFieldSet a + | 5 -> let a = u_rfref st + TOp.ValFieldGet a + | 6 -> let a = u_tcref st + TOp.UnionCaseTagGet a + | 7 -> let a = u_ucref st + let b = u_int st + TOp.UnionCaseFieldGet (a, b) + | 8 -> let a = u_ucref st + let b = u_int st + TOp.UnionCaseFieldSet (a, b) + | 9 -> let a = u_tcref st + let b = u_int st + TOp.ExnFieldGet (a, b) + | 10 -> let a = u_tcref st + let b = u_int st + TOp.ExnFieldSet (a, b) + | 11 -> let a = u_int st + TOp.TupleFieldGet (tupInfoRef, a) + | 12 -> let a = (u_list u_ILInstr) st + let b = u_tys st + TOp.ILAsm (a, b) + | 13 -> TOp.RefAddrGet false // ok to set the 'readonly' flag on these operands to false on re-read since the flag is only used for typechecking purposes + | 14 -> let a = u_ucref st + TOp.UnionCaseProof a + | 15 -> TOp.Coerce + | 16 -> let a = u_trait st + TOp.TraitCall a + | 17 -> let a = u_lval_op_kind st + let b = u_vref st + TOp.LValueOp (a, b) + | 18 -> let a1, a2, a3, a4, a5, a7, a8, a9 = (u_tup8 u_bool u_bool u_bool u_bool u_vrefFlags u_bool u_bool u_ILMethodRef) st + let b = u_tys st + let c = u_tys st + let d = u_tys st + TOp.ILCall (a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) + | 19 -> TOp.Array + | 20 -> TOp.While (DebugPointAtWhile.No, NoSpecialWhileLoopMarker) + | 21 -> let dir = match u_int st with 0 -> FSharpForLoopUp | 1 -> CSharpForLoopUp | 2 -> FSharpForLoopDown | _ -> failwith "unknown for loop" + TOp.IntegerForLoop (DebugPointAtFor.No, DebugPointAtInOrTo.No, dir) + | 22 -> TOp.Bytes (u_bytes st) + | 23 -> TOp.TryWith (DebugPointAtTry.No, DebugPointAtWith.No) + | 24 -> TOp.TryFinally (DebugPointAtTry.No, DebugPointAtFinally.No) + | 25 -> let a = u_rfref st + TOp.ValFieldGetAddr (a, false) + | 26 -> TOp.UInt16s (u_array u_uint16 st) + | 27 -> TOp.Reraise + | 28 -> let a = u_ucref st + let b = u_int st + TOp.UnionCaseFieldGetAddr (a, b, false) + | 29 -> TOp.Tuple tupInfoStruct + | 30 -> let a = u_int st + TOp.TupleFieldGet (tupInfoStruct, a) + | 31 -> let info = u_anonInfo st + TOp.AnonRecd info + | 32 -> let info = u_anonInfo st + let n = u_int st + TOp.AnonRecdGet (info, n) + | _ -> ufailwith st "u_op" + +and u_entity_spec_data_new st : Entity = + let typars = u_tyar_specs_new st + let logicalName = u_string st + let compiledName = u_option u_string st + let range = u_range st + let stamp = u_stamp st + let pubPath = u_option u_pubpath st + let access = u_access st + let tyconReprAccess = u_access st + let attribs = u_attribs st + let tyconRepr = u_tycon_repr_new st + let typeAbbrev = u_option u_ty_new st + let tyconTcaug = u_tcaug_new st + let _x10 = u_string st + let kind = u_kind st + let flags = u_int64 st + let cpath = u_option u_cpath st + let modulType = u_lazy u_modul_typ_new st + let exnInfo = u_exnc_repr st + let xmlDoc = u_used_space1 u_xmldoc st + + // We use a bit that was unused in the F# 2.0 format to indicate two possible representations in the F# 3.0 tycon_repr format + //let x7 = x7f (x11 &&& EntityFlags.ReservedBitForPickleFormatTyconReprFlag <> 0L) + //let x11 = x11 &&& ~~~EntityFlags.ReservedBitForPickleFormatTyconReprFlag + + { entity_typars=LazyWithContext.NotLazy typars + entity_stamp=stamp + entity_logical_name=logicalName + entity_range=range + entity_pubpath=pubPath + entity_attribs=attribs + entity_tycon_repr=tyconRepr false + entity_tycon_tcaug=tyconTcaug + entity_flags=EntityFlags flags + entity_cpath=cpath + entity_modul_type=MaybeLazy.Lazy modulType + entity_il_repr_cache=newCache() + entity_opt_data= + match compiledName, kind, xmlDoc, typeAbbrev, access, tyconReprAccess, exnInfo with + | None, TyparKind.Type, None, None, TAccess [], TAccess [], TExnNone -> None + | _ -> + Some { Entity.NewEmptyEntityOptData() with + entity_compiled_name = compiledName + entity_kind = kind + entity_xmldoc= defaultArg xmlDoc XmlDoc.Empty + entity_xmldocsig = System.String.Empty + entity_tycon_abbrev = typeAbbrev + entity_accessibility = access + entity_tycon_repr_accessibility = tyconReprAccess + entity_exn_info = exnInfo } + } + +and u_entity_spec_new st = + u_osgn_decl st.ientities u_entity_spec_data_new st + +and u_ValData_new st = + let logicalName = u_string st + let compiledName = u_option u_string st + let ranges = u_ranges st + let valType = u_ty_new st + let stamp = u_stamp st + let flags = u_int64 st + let memberInfo = u_option u_member_info st + let attribs = u_attribs st + let valReprInfo = u_option u_ValReprInfo st + let xmlDocSig = u_string st + let valAccess = u_access st + let declEntity = u_parentref st + let valConst = u_option u_const st + let xmlDoc = u_used_space1 u_xmldoc st + + { val_logical_name = logicalName + val_range = (match ranges with None -> range0 | Some(a, _) -> a) + val_type = valType + val_stamp = stamp + val_flags = ValFlags flags + val_opt_data = + match compiledName, ranges, valReprInfo, valConst, valAccess, xmlDoc, memberInfo, declEntity, xmlDocSig, attribs with + | None, None, None, None, TAccess [], None, None, ParentNone, "", [] -> None + | _ -> + Some { val_compiled_name = compiledName + val_other_range = (match ranges with None -> None | Some(_, b) -> Some(b, true)) + val_defn = None + val_repr_info = valReprInfo + val_repr_info_for_display = None + arg_repr_info_for_display = None + val_const = valConst + val_access = valAccess + val_xmldoc = defaultArg xmlDoc XmlDoc.Empty + val_other_xmldoc = None + val_member_info = memberInfo + val_declaring_entity = declEntity + val_xmldocsig = xmlDocSig + val_attribs = attribs } + } + +and u_Val_new st = u_osgn_decl st.ivals u_ValData_new st + +and u_modul_typ_new st = + let x1, x3, x5 = + u_tup3 + u_istype + (u_qlist u_Val_new) + (u_qlist u_entity_spec_new) st + ModuleOrNamespaceType(x1, x3, x5) + +and u_tcaug_new st : TyconAugmentation = + let a1, a2, a3, b2, c, d, e, g, _space = + u_tup9 + (u_option (u_tup2 u_vref u_vref)) + (u_option u_vref) + (u_option (u_tup3 u_vref u_vref u_vref)) + (u_option (u_tup2 u_vref u_vref)) + (u_list (u_tup2 u_string u_vref)) + (u_list (u_tup3 u_ty_new u_bool u_dummy_range)) + (u_option u_ty_new) + u_bool + (u_space 1) + st + {tcaug_compare=a1 + tcaug_compare_withc=a2 + tcaug_hash_and_equals_withc=a3 |> Option.map (fun (v1, v2, v3) -> (v1, v2, v3, None)) + tcaug_equals=b2 + // only used for code generation and checking - hence don't care about the values when reading back in + tcaug_hasObjectGetHashCode=false + tcaug_adhoc_list= ResizeArray<_>(c |> List.map (fun (_, vref) -> (false, vref))) + tcaug_adhoc=NameMultiMap.ofList c + tcaug_interfaces=d + tcaug_super=e + // pickled type definitions are always closed (i.e. no more intrinsic members allowed) + tcaug_closed=true + tcaug_abstract=g} + + +and u_ccu_data st : CcuData = + let fileName = u_option u_string st + let ilScopeRef = u_ILScopeRef st + let stamp = u_stamp st + let qualifiedName = u_option u_string st + let sourceCodeDirectory = u_string st + let isFSharp = u_bool st +#if !NO_TYPEPROVIDERS + let isProviderGenerated = u_bool st +#endif + let usesFSharp20PlusQuotations = u_bool st + let contents = u_entity_spec_data_new st + + { + FileName = fileName + ILScopeRef = ilScopeRef + Stamp = stamp + QualifiedName = qualifiedName + SourceCodeDirectory = sourceCodeDirectory + IsFSharp = isFSharp +#if !NO_TYPEPROVIDERS + IsProviderGenerated = isProviderGenerated + InvalidateEvent = Unchecked.defaultof<_> + ImportProvidedType = Unchecked.defaultof<_> +#endif + UsesFSharp20PlusQuotations = usesFSharp20PlusQuotations + Contents = contents + TryGetILModuleDef = Unchecked.defaultof<_> + MemberSignatureEquality = Unchecked.defaultof<_> + TypeForwarders = Unchecked.defaultof<_> + XmlDocumentationInfo = Unchecked.defaultof<_> + } + +and u_ccuref_new st : CcuThunk = + let target, name = + u_tup2 + u_ccu_data + u_string + st + + { + target = target + name = name + } + +and u_nleref_new st = + let ccu, strings = + u_tup2 + u_ccuref_new + (u_array u_string) + st + + NonLocalEntityRef (ccu, strings) + +and u_tcref_new st : EntityRef = + let tag = u_byte st + match tag with + | 0 -> u_local_item_ref st.ientities st |> ERefLocal + | 1 -> u_nleref_new st |> ERefNonLocal + | _ -> ufailwith st "u_item_ref" + +and u_nonlocal_val_ref_new st : NonLocalValOrMemberRef = + let a = u_tcref_new st + let b1 = u_option u_string st + let b2 = u_bool st + let b3 = u_string st + let c = u_int st + let d = u_option u_ty_new st + { EnclosingEntity = a + ItemKey=ValLinkageFullKey({ MemberParentMangledName=b1; MemberIsOverride=b2;LogicalName=b3; TotalArgCount=c }, d) } + +and u_vref_new st : ValRef = + let tag = u_byte st + match tag with + | 0 -> u_local_item_ref st.ivals st |> VRefLocal + | 1 -> u_nonlocal_val_ref_new st |> VRefNonLocal + | _ -> ufailwith st "u_item_ref" + +and u_bind_new st = + let a = u_Val_new st + let b = u_expr_new st + TBind(a, b, DebugPointAtBinding.NoneAtSticky) + +and u_binding st : ModuleOrNamespaceBinding = + let tag = u_byte st + match tag with + | 0 -> + let binding = u_bind st + ModuleOrNamespaceBinding.Binding binding + | 1 -> + let moduleOrNamespace, moduleOrNamespaceContents = + u_tup2 + u_entity_spec_new + u_module_or_namespace_contents + st + ModuleOrNamespaceBinding.Module (moduleOrNamespace, moduleOrNamespaceContents) + | _ -> + ufailwith st (nameof u_binding) + + +and u_tycon_repr_new st = + let tag1 = u_byte st + match tag1 with + | 0 -> (fun _flagBit -> TNoRepr) + | 1 -> + let tag2 = u_byte st + match tag2 with + // Records historically use a different format to other FSharpTyconRepr + | 0 -> + let v = u_rfield_table st + (fun _flagBit -> + TFSharpTyconRepr + { + fsobjmodel_cases = Construct.MakeUnionCases [] + fsobjmodel_kind=TFSharpRecord + fsobjmodel_vslots=[] + fsobjmodel_rfields=v + }) + + // Unions without static fields historically use a different format to other FSharpTyconRepr + | 1 -> + let v = u_list u_unioncase_spec st + (fun _flagBit -> Construct.MakeUnionRepr v) + + | 2 -> + let v = u_ILType st + // This is the F# 3.0 extension to the format used for F# provider-generated types, which record an ILTypeRef in the format + // You can think of an F# 2.0 reader as always taking the path where 'flagBit' is false. Thus the F# 2.0 reader will + // interpret provider-generated types as TAsmRepr. + (fun flagBit -> + if flagBit then + let iltref = v.TypeRef + match st.iILModule with + | None -> TNoRepr + | Some iILModule -> + try + let rec find acc enclosingTypeNames (tdefs: ILTypeDefs) = + match enclosingTypeNames with + | [] -> List.rev acc, tdefs.FindByName iltref.Name + | h :: t -> + let nestedTypeDef = tdefs.FindByName h + find (nestedTypeDef :: acc) t nestedTypeDef.NestedTypes + let nestedILTypeDefs, ilTypeDef = find [] iltref.Enclosing iILModule.TypeDefs + TILObjectRepr(TILObjectReprData(st.iilscope, nestedILTypeDefs, ilTypeDef)) + with _ -> + System.Diagnostics.Debug.Assert(false, sprintf "failed to find IL backing metadata for cross-assembly generated type %s" iltref.FullName) + TNoRepr + else + TAsmRepr v) + + | 3 -> + let v = u_tycon_objmodel_data st + (fun _flagBit -> TFSharpTyconRepr v) + + | 4 -> + let v = u_ty st + (fun _flagBit -> TMeasureableRepr v) + + | _ -> ufailwith st "u_tycon_repr" + + // Unions with static fields use a different format to other FSharpTyconRepr + | 2 -> + let cases = u_array u_unioncase_spec st + let data = u_tycon_objmodel_data st + fun _flagBit -> TFSharpTyconRepr { data with fsobjmodel_cases = Construct.MakeUnionCases (Array.toList cases) } + + | 5 -> + // | TILObjectRepr (TILObjectReprData (scope, nesting, td)) -> + let scope = u_ILScopeRef st + let nesting = u_list u_ILTypeDef st + let definition = u_ILTypeDef st + + (fun _flagBit -> TILObjectRepr (TILObjectReprData (scope, nesting, definition))) + + | _ -> ufailwith st "u_tycon_repr" + + + +and u_qualified_name_of_file st = + let ident = u_ident st + QualifiedNameOfFile(ident) + +and u_pragma st = + let range, warningNumber = + u_tup2 + u_range + u_int + st + + ScopedPragma.WarningOff (range, warningNumber) + +and u_pragmas st = + u_list u_pragma st + +and u_long_ident st = + u_list u_ident st + +and u_trivia st : SyntaxTrivia.IdentTrivia = + ufailwith st (nameof p_trivia) + +and u_syn_long_ident st = + let id, dotRanges, trivia = + u_tup3 + u_long_ident + (u_list u_range) + (u_list (u_option u_trivia)) + st + + SynLongIdent (id, dotRanges, trivia) + +and u_syn_type st : SynType = + ufailwith st (nameof u_syn_type) + +and u_syn_open_decl_target st : SynOpenDeclTarget = + let tag = u_byte st + match tag with + | 0 -> + let longId, range = + u_tup2 + u_syn_long_ident + u_range + st + + SynOpenDeclTarget.ModuleOrNamespace (longId, range) + | 1 -> + let typeName, range = + u_tup2 + u_syn_type + u_range + st + SynOpenDeclTarget.Type (typeName, range) + | _ -> + ufailwith st (nameof u_syn_open_decl_target) + +and u_tup_info st : TupInfo = + let c = u_bool st + TupInfo.Const c + +and u_nullness st = + let tag = u_byte st + let nullnessInfo = + match tag with + | 0 -> NullnessInfo.WithNull + | 1 -> NullnessInfo.WithoutNull + | 2 -> NullnessInfo.AmbivalentToNull + | _ -> ufailwith st (nameof u_nullness) + + Nullness.Known nullnessInfo + +and u_typars = u_list u_tpref + +and u_module_or_namespace_contents st : ModuleOrNamespaceContents = + let tag = u_byte st + match tag with + | 0 -> + let defs = u_list u_module_or_namespace_contents st + TMDefs defs + | 1 -> + let openDecls = u_list u_open_decl st + TMDefOpens openDecls + | 2 -> + let binding, range = + u_tup2 + u_bind_new + u_range + st + TMDefLet(binding, range) + | 3 -> + let expr, range = + u_tup2 + u_expr_new + u_range + st + TMDefDo(expr, range) + | 4 -> + let isRec, opens, tycons, bindings, range = + u_tup5 + u_bool + (u_list u_open_decl) + (u_list u_entity_spec_data_new) + (u_list u_binding) + u_range + st + TMDefRec (isRec, opens, tycons, bindings, range) + | _ -> + ufailwith st (nameof u_module_or_namespace_contents) + +and u_checked_impl_file_contents = u_module_or_namespace_contents + +and u_named_debug_point_key st : NamedDebugPointKey = + let range, name = + u_tup2 + u_range + u_string + st + + { Range = range; Name = name} + +and u_named_debug_points = u_Map u_named_debug_point_key u_range + +and u_anon_recd_types = u_stamp_map u_anonInfo + +and u_open_decl st : OpenDeclaration = + let target, range, modules, types, appliedScope, isOwnNamespace = + u_tup6 + u_syn_open_decl_target + (u_option u_range) + (u_list u_tcref_new) + u_tys + u_range + u_bool + st + + { + Target = target + Range = range + Modules = modules + Types = types + AppliedScope = appliedScope + IsOwnNamespace = isOwnNamespace + } + +and u_checked_impl_file st = + let qualifiedNameOfFile, pragmas, signature, contents, hasExplicitEntryPoint, isScript, anonRecdTypeInfo, namedDebugPointsForInlinedCode = + u_tup8 + u_qualified_name_of_file + u_pragmas + u_modul_typ_new + u_checked_impl_file_contents + u_bool + u_bool + u_anon_recd_types + u_named_debug_points + st + + CheckedImplFile( + qualifiedNameOfFile, + pragmas, + signature, + contents, + hasExplicitEntryPoint, + isScript, + anonRecdTypeInfo, + namedDebugPointsForInlinedCode) + + let u_context_info st : ContextInfo = let tag = u_byte st @@ -303,6 +1704,8 @@ let u_tcs_root_sig st = qualifiedNameOfFile, moduleOrNamespaceType + + // unpickling top let unpickleSharedData st = diff --git a/src/Compiler/SyntaxTree/PrettyNaming.fs b/src/Compiler/SyntaxTree/PrettyNaming.fs index ec9303271e7..b0ef32edaf0 100755 --- a/src/Compiler/SyntaxTree/PrettyNaming.fs +++ b/src/Compiler/SyntaxTree/PrettyNaming.fs @@ -1132,8 +1132,6 @@ let FSharpSignatureCompressedDataResourceNameB = "FSharpSignatureCompressedDataB let FSharpOptimizationDataResourceName2 = "FSharpOptimizationInfo." let FSharpSignatureDataResourceName2 = "FSharpSignatureInfo." -let FSharpTcDataResourceName = "FSharpTypecheckingData" - [] let suffixForVariablesThatMayNotBeEliminated = "$cont" diff --git a/src/Compiler/SyntaxTree/PrettyNaming.fsi b/src/Compiler/SyntaxTree/PrettyNaming.fsi index 59c33a664d5..9843656e46f 100644 --- a/src/Compiler/SyntaxTree/PrettyNaming.fsi +++ b/src/Compiler/SyntaxTree/PrettyNaming.fsi @@ -284,8 +284,6 @@ val internal FSharpOptimizationDataResourceName2: string val internal FSharpSignatureDataResourceName2: string -val internal FSharpTcDataResourceName: string - val GetLongNameFromString: string -> string list val FormatAndOtherOverloadsString: int -> string diff --git a/src/Compiler/TypedTree/TypedTreePickle.fs b/src/Compiler/TypedTree/TypedTreePickle.fs index 632e53a7424..291139e892f 100644 --- a/src/Compiler/TypedTree/TypedTreePickle.fs +++ b/src/Compiler/TypedTree/TypedTreePickle.fs @@ -284,9 +284,6 @@ let inline p_tup5 p1 p2 p3 p4 p5 (a, b, c, d, e) (st: WriterState) = let inline p_tup6 p1 p2 p3 p4 p5 p6 (a, b, c, d, e, f) (st: WriterState) = (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit); (p6 f st : unit) -let inline p_tup8 p1 p2 p3 p4 p5 p6 p7 p8 (a, b, c, d, e, f, g, h) (st: WriterState) = - (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit); (p6 f st : unit); (p7 g st : unit); (p8 h st : unit) - let inline p_tup9 p1 p2 p3 p4 p5 p6 p7 p8 p9 (a, b, c, d, e, f, x7, x8, x9) (st: WriterState) = (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit); (p6 f st : unit); (p7 x7 st : unit); (p8 x8 st : unit); (p9 x9 st : unit) @@ -423,13 +420,6 @@ let inline u_tup13 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 (st: ReaderState) let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12, x13) -let inline u_tup14 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 (st: ReaderState) = - let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in - let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in - let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in let x14 = p14 st in - (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12, x13, x14) - - let inline u_tup17 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 (st: ReaderState) = let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in @@ -437,12 +427,6 @@ let inline u_tup17 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 (s let x14 = p14 st in let x15 = p15 st in let x16 = p16 st in let x17 = p17 st in (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) -let inline u_tup18 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 (st: ReaderState) = - let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in - let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in - let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in - let x14 = p14 st in let x15 = p15 st in let x16 = p16 st in let x17 = p17 st in let x18 = p18 st in - (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) //--------------------------------------------------------------------------- // Pickle/unpickle operations for observably shared graph nodes @@ -533,11 +517,6 @@ let p_option f x st = | None -> p_byte 0 st | Some h -> p_byte 1 st; f h st -let p_non_null_slot f (x: 'a | null) st = - match x with - | null -> p_byte 0 st - | h -> p_byte 1 st; f h st - // Pickle lazy values in such a way that they can, in some future F# compiler version, be read back // lazily. However, a lazy reader is not used in this version because the value may contain the definitions of some // OSGN nodes. @@ -641,13 +620,6 @@ let u_option f st = | 1 -> Some (f st) | n -> ufailwith st ("u_option: found number " + string n) -let u_non_null_slot f st = - let tag = u_byte st - match tag with - | 0 -> Unchecked.defaultof<_> - | 1 -> f st - | n -> ufailwith st ("u_option: found number " + string n) - let u_lazy u st = // Read the number of bytes in the record @@ -1005,27 +977,6 @@ and p_ILCallSig x st = p_tup3 p_ILCallConv p_ILTypes p_ILType (x.CallingConv, x. and p_ILTypeRef (x: ILTypeRef) st = p_tup3 p_ILScopeRef p_strings p_string (x.Scope, x.Enclosing, x.Name) st -and p_ILTypeDefAdditionalFlags (x: ILTypeDefAdditionalFlags) st = - p_int32 (int x) st - -and p_ILTypeDef (x: ILTypeDef) st = - p_string x.Name st - //p_type_attributes x.Attributes - //p_il_type_def_layout x.Layout - //x.Implements - //x.Extends - //x.Methods - //x.NestedTypes - //x.Fields - //x.MethodImpls - //x.Events - //x.Properties - p_ILTypeDefAdditionalFlags x.Flags st - //x.SecurityDeclsStored - //x.CustomAttrsStored - //p_il - //p_int32 x.MetadataIndex st - and p_ILTypeSpec (a: ILTypeSpec) st = p_tup2 p_ILTypeRef p_ILTypes (a.TypeRef, a.GenericArgs) st let u_ILBasicCallConv st = @@ -1047,45 +998,6 @@ let u_ILHasThis st = let u_ILCallConv st = let a, b = u_tup2 u_ILHasThis u_ILBasicCallConv st in Callconv(a, b) let u_ILTypeRef st = let a, b, c = u_tup3 u_ILScopeRef u_strings u_string st in ILTypeRef.Create(a, b, c) - -let u_ILTypeDefAdditionalFlags st : ILTypeDefAdditionalFlags = - let i = u_int32 st - enum i - -let u_ILTypeDef st : ILTypeDef = - let name = u_string st - let attributes = System.Reflection.TypeAttributes.Public - let layout = ILTypeDefLayout.Auto - let implements = Unchecked.defaultof<_> - let genericParams = [] - let extends = Unchecked.defaultof<_> - let methods = ILMethodDefs(fun () -> [||]) - let nestedTypes = Unchecked.defaultof<_> - let fields = Unchecked.defaultof<_> - let methodImpls = Unchecked.defaultof<_> - let events = Unchecked.defaultof<_> - let properties = Unchecked.defaultof<_> - let additionalFlags = u_ILTypeDefAdditionalFlags st - let securityDeclsStored = ILSecurityDecls([||]) - // TODO: fill this in - let customAttrsStored = ILAttributesStored.Given (ILAttributes.Empty) - - ILTypeDef(name, - attributes, - layout, - implements, - genericParams, - extends, - methods, - nestedTypes, - fields, - methodImpls, - events, - properties, - additionalFlags, - securityDeclsStored, - customAttrsStored) - let u_ILArrayShape = u_wrap (ILArrayShape) (u_list (u_tup2 (u_option u_int32) (u_option u_int32))) @@ -1384,9 +1296,6 @@ let p_Map pk pv x st = let p_qlist pv = p_wrap QueueList.toList (p_list pv) let p_namemap p = p_Map p_string p -let p_stamp = p_int64 -let p_stamp_map pv = p_Map p_stamp pv - let u_Map_core uk uv n st = Map.ofSeq (seq { for _ in 1..n -> (uk st, uv st) }) @@ -1397,9 +1306,6 @@ let u_Map uk uv st = let u_qlist uv = u_wrap QueueList.ofList (u_list uv) let u_namemap u = u_Map u_string u -let u_stamp = u_int64 -let u_stamp_map uv = u_Map u_stamp uv - let p_pos (x: pos) st = p_tup2 p_int p_int (x.Line, x.Column) st let p_range (x: range) st = @@ -1768,31 +1674,13 @@ let p_tyar_spec_data (x: Typar) st = p_xmldoc (x.typar_id, x.Attribs, int64 x.typar_flags.PickledBits, x.Constraints, x.XmlDoc) st -let p_tyar_spec_data_new (x: Typar) st = - p_tup6 - p_ident - p_attribs - p_int64 - p_tyar_constraints - p_xmldoc - p_stamp - (x.typar_id, x.Attribs, int64 x.typar_flags.PickledBits, x.Constraints, x.XmlDoc, x.Stamp) st - let p_tyar_spec (x: Typar) st = //Disabled, workaround for bug 2721: if x.Rigidity <> TyparRigidity.Rigid then warning(Error(sprintf "p_tyar_spec: typar#%d is not rigid" x.Stamp, x.Range)) if x.IsFromError then warning(Error((0, "p_tyar_spec: from error"), x.Range)) p_osgn_decl st.otypars p_tyar_spec_data x st -let p_tyar_spec_new (x: Typar) st = - //Disabled, workaround for bug 2721: if x.Rigidity <> TyparRigidity.Rigid then warning(Error(sprintf "p_tyar_spec: typar#%d is not rigid" x.Stamp, x.Range)) - if x.IsFromError then warning(Error((0, "p_tyar_spec: from error"), x.Range)) - p_osgn_decl st.otypars p_tyar_spec_data_new x st - - let p_tyar_specs = (p_list p_tyar_spec) -let p_tyar_specs_new = (p_list p_tyar_spec_new) - let u_tyar_spec_data st = let a, c, d, e, g = u_tup5 u_ident u_attribs u_int64 u_tyar_constraints u_xmldoc st { typar_id=a @@ -1805,28 +1693,11 @@ let u_tyar_spec_data st = | doc, [], [] when doc.IsEmpty -> None | _ -> Some { typar_il_name = None; typar_xmldoc = g; typar_constraints = e; typar_attribs = c;typar_is_contravariant = false } } -let u_tyar_spec_data_new st = - let a, c, d, e, g, stamp = u_tup6 u_ident u_attribs u_int64 u_tyar_constraints u_xmldoc u_stamp st - { typar_id=a - typar_stamp=stamp - typar_flags=TyparFlags(int32 d) - typar_solution=None - typar_astype= Unchecked.defaultof<_> - typar_opt_data= - match g, e, c with - | doc, [], [] when doc.IsEmpty -> None - | _ -> Some { typar_il_name = None; typar_xmldoc = g; typar_constraints = e; typar_attribs = c;typar_is_contravariant = false } } - let u_tyar_spec st = u_osgn_decl st.itypars u_tyar_spec_data st -let u_tyar_spec_new st = - u_osgn_decl st.itypars u_tyar_spec_data_new st - let u_tyar_specs = (u_list u_tyar_spec) -let u_tyar_specs_new = (u_list u_tyar_spec_new) - let _ = fill_p_ty2 (fun isStructThisArgPos ty st -> let ty = stripTyparEqns ty @@ -2128,84 +1999,6 @@ let rec p_tycon_repr x st = | TILObjectRepr (TILObjectReprData (_, _, td)) -> error (Failure("Unexpected IL type definition"+td.Name)) -and p_tycon_repr_new (x: TyconRepresentation) 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. - - match x with - // Records - | TFSharpTyconRepr { fsobjmodel_rfields = fs; fsobjmodel_kind = TFSharpRecord } -> - p_byte 1 st - p_byte 0 st - p_rfield_table fs st - false - - // Unions without static fields - | TFSharpTyconRepr { fsobjmodel_cases = x; fsobjmodel_kind = TFSharpUnion; fsobjmodel_rfields = fs } when fs.FieldsByIndex.Length = 0 -> - p_byte 1 st - p_byte 1 st - p_array p_unioncase_spec x.CasesTable.CasesByIndex st - false - - // Unions with static fields, added to format - | TFSharpTyconRepr ({ fsobjmodel_cases = cases; fsobjmodel_kind = TFSharpUnion } as r) -> - if st.oglobals.compilingFSharpCore then - let fields = r.fsobjmodel_rfields.FieldsByIndex - let firstFieldRange = fields[0].DefinitionRange - let allFieldsText = fields |> Array.map (fun f -> f.LogicalName) |> String.concat System.Environment.NewLine - raise (Error(FSComp.SR.pickleFsharpCoreBackwardsCompatible("fields in union",allFieldsText), firstFieldRange)) - - p_byte 2 st - p_array p_unioncase_spec cases.CasesTable.CasesByIndex st - p_tycon_objmodel_data r st - false - - | TAsmRepr ilTy -> - p_byte 1 st - p_byte 2 st - p_ILType ilTy st - false - - | TFSharpTyconRepr r -> - p_byte 1 st - p_byte 3 st - p_tycon_objmodel_data r st - false - - | TMeasureableRepr ty -> - p_byte 1 st - p_byte 4 st - p_ty ty st - false - - | TNoRepr -> - p_byte 0 st - false - -#if !NO_TYPEPROVIDERS - | TProvidedTypeRepr info -> - if info.IsErased then - // Pickle erased type definitions as a NoRepr - p_byte 0 st - false - else - // Pickle generated type definitions as a TAsmRepr - p_byte 1 st - p_byte 2 st - p_ILType (mkILBoxedType(ILTypeSpec.Create(TypeProviders.GetILTypeRefOfProvidedType(info.ProvidedType, range0), []))) st - true - - | TProvidedNamespaceRepr _ -> - p_byte 0 st - false -#endif - - | TILObjectRepr (TILObjectReprData (scope, nesting, td)) -> - p_byte 5 st - p_ILScopeRef scope st - (p_list p_ILTypeDef) nesting st - p_ILTypeDef td st - false - and p_tycon_objmodel_data x st = p_tycon_objmodel_kind x.fsobjmodel_kind st p_vrefs "vslots" x.fsobjmodel_vslots st @@ -2273,29 +2066,6 @@ and p_entity_spec_data (x: Entity) st = else p_space 1 () st -and p_entity_spec_data_new (x: Entity) st = - p_tyar_specs_new (x.entity_typars.Force(x.entity_range)) st - p_string x.entity_logical_name st - p_option p_string x.EntityCompiledName st - p_range x.entity_range st - p_stamp x.entity_stamp st - p_option p_pubpath x.entity_pubpath st - p_access x.Accessibility st - p_access x.TypeReprAccessibility st - p_attribs x.entity_attribs st - let _ = p_tycon_repr_new x.entity_tycon_repr st - p_option p_ty_new x.TypeAbbrev st - p_tcaug_new x.entity_tycon_tcaug st - p_string System.String.Empty st - p_kind x.TypeOrMeasureKind st - p_int64 x.entity_flags.Flags st - p_option p_cpath x.entity_cpath st - p_maybe_lazy p_modul_typ_new x.entity_modul_type st - p_exnc_repr x.ExceptionInfo st - if st.oInMem then - p_used_space1 (p_xmldoc x.XmlDoc) st - else - p_space 1 () st and p_tcaug p st = p_tup9 @@ -2325,38 +2095,8 @@ and p_tcaug p st = p.tcaug_abstract, space) st -and p_tcaug_new (p: TyconAugmentation) st = - p_tup9 - (p_option (p_tup2 (p_vref "compare_obj") (p_vref "compare"))) - (p_option (p_vref "compare_withc")) - (p_option (p_tup3 (p_vref "hash_obj") (p_vref "hash_withc") (p_vref "equals_withc"))) - (p_option (p_tup2 (p_vref "hash") (p_vref "equals"))) - (p_list (p_tup2 p_string (p_vref "adhoc"))) - (p_list (p_tup3 p_ty_new p_bool p_dummy_range)) - (p_option p_ty_new) - p_bool - (p_space 1) - (p.tcaug_compare, - p.tcaug_compare_withc, - p.tcaug_hash_and_equals_withc |> Option.map (fun (v1, v2, v3, _) -> (v1, v2, v3)), - p.tcaug_equals, - (p.tcaug_adhoc_list - |> ResizeArray.toList - // Explicit impls of interfaces only get kept in the adhoc list - // in order to get check the well-formedness of an interface. - // Keeping them across assembly boundaries is not valid, because relinking their ValRefs - // does not work correctly (they may get incorrectly relinked to a default member) - |> List.filter (fun (isExplicitImpl, _) -> not isExplicitImpl) - |> List.map (fun (_, vref) -> vref.LogicalName, vref)), - p.tcaug_interfaces, - p.tcaug_super, - p.tcaug_abstract, - space) st - and p_entity_spec x st = p_osgn_decl st.oentities p_entity_spec_data x st -and p_entity_spec_new x st = p_osgn_decl st.oentities p_entity_spec_data_new x st - and p_parentref x st = match x with | ParentNone -> p_byte 0 st @@ -2426,34 +2166,9 @@ and p_ValData x st = else p_space 1 () st -and p_ValData_new x st = - p_string x.val_logical_name st - p_option p_string x.ValCompiledName st - // only keep range information on published values, not on optimization data - p_ranges (x.ValReprInfo |> Option.map (fun _ -> x.val_range, x.DefinitionRange)) st - - p_ty_new x.val_type st - p_stamp x.val_stamp st - - p_int64 x.val_flags.Flags st - p_option p_member_info x.MemberInfo st - p_attribs x.Attribs st - p_option p_ValReprInfo x.ValReprInfo st - p_string x.XmlDocSig st - p_access x.Accessibility st - p_parentref x.TryDeclaringEntity st - p_option p_const x.LiteralValue st - if st.oInMem then - p_used_space1 (p_xmldoc x.XmlDoc) st - else - p_space 1 () st - and p_Val x st = p_osgn_decl st.ovals p_ValData x st -and p_Val_new x st = - p_osgn_decl st.ovals p_ValData_new x st - and p_modul_typ (x: ModuleOrNamespaceType) st = p_tup3 p_istype @@ -2462,491 +2177,81 @@ and p_modul_typ (x: ModuleOrNamespaceType) st = (x.ModuleOrNamespaceKind, x.AllValsAndMembers, x.AllEntities) st -and p_modul_typ_new (x: ModuleOrNamespaceType) st = - p_tup3 - p_istype - (p_qlist p_Val_new) - (p_qlist p_entity_spec_new) - (x.ModuleOrNamespaceKind, x.AllValsAndMembers, x.AllEntities) - st - -and p_qualified_name_of_file qualifiedNameOfFile st = - let (QualifiedNameOfFile ident) = qualifiedNameOfFile - p_ident ident st +and u_tycon_repr st = + let tag1 = u_byte st + match tag1 with + | 0 -> (fun _flagBit -> TNoRepr) + | 1 -> + let tag2 = u_byte st + match tag2 with + // Records historically use a different format to other FSharpTyconRepr + | 0 -> + let v = u_rfield_table st + (fun _flagBit -> + TFSharpTyconRepr + { + fsobjmodel_cases = Construct.MakeUnionCases [] + fsobjmodel_kind=TFSharpRecord + fsobjmodel_vslots=[] + fsobjmodel_rfields=v + }) -and p_pragma pragma st = - let (ScopedPragma.WarningOff (range, warningNumber)) = pragma - p_tup2 - p_range - p_int - (range, warningNumber) - st + // Unions without static fields historically use a different format to other FSharpTyconRepr + | 1 -> + let v = u_list u_unioncase_spec st + (fun _flagBit -> Construct.MakeUnionRepr v) -and p_pragmas x st = - p_list p_pragma x st + | 2 -> + let v = u_ILType st + // This is the F# 3.0 extension to the format used for F# provider-generated types, which record an ILTypeRef in the format + // You can think of an F# 2.0 reader as always taking the path where 'flagBit' is false. Thus the F# 2.0 reader will + // interpret provider-generated types as TAsmRepr. + (fun flagBit -> + if flagBit then + let iltref = v.TypeRef + match st.iILModule with + | None -> TNoRepr + | Some iILModule -> + try + let rec find acc enclosingTypeNames (tdefs: ILTypeDefs) = + match enclosingTypeNames with + | [] -> List.rev acc, tdefs.FindByName iltref.Name + | h :: t -> + let nestedTypeDef = tdefs.FindByName h + find (nestedTypeDef :: acc) t nestedTypeDef.NestedTypes + let nestedILTypeDefs, ilTypeDef = find [] iltref.Enclosing iILModule.TypeDefs + TILObjectRepr(TILObjectReprData(st.iilscope, nestedILTypeDefs, ilTypeDef)) + with _ -> + System.Diagnostics.Debug.Assert(false, sprintf "failed to find IL backing metadata for cross-assembly generated type %s" iltref.FullName) + TNoRepr + else + TAsmRepr v) -and p_long_ident (x: LongIdent) st = - p_list p_ident x st + | 3 -> + let v = u_tycon_objmodel_data st + (fun _flagBit -> TFSharpTyconRepr v) -and p_trivia (x: SyntaxTrivia.IdentTrivia) st = - pfailwith st (nameof p_trivia) + | 4 -> + let v = u_ty st + (fun _flagBit -> TMeasureableRepr v) -and p_syn_long_ident (x: SynLongIdent) st = - let (SynLongIdent (id, dotRanges, trivia)) = x - p_tup3 - p_long_ident - (p_list p_range) - (p_list (p_option p_trivia)) - (id, dotRanges, trivia) - st + | _ -> ufailwith st "u_tycon_repr" -and p_syn_type (x: SynType) st = - pfailwith st (nameof p_syn_type) + // Unions with static fields use a different format to other FSharpTyconRepr + | 2 -> + let cases = u_array u_unioncase_spec st + let data = u_tycon_objmodel_data st + fun _flagBit -> TFSharpTyconRepr { data with fsobjmodel_cases = Construct.MakeUnionCases (Array.toList cases) } + | _ -> ufailwith st "u_tycon_repr" -and p_syn_open_decl_target (x: SynOpenDeclTarget) st = - match x with - | SynOpenDeclTarget.ModuleOrNamespace (longId, range)-> - p_byte 0 st - p_tup2 - p_syn_long_ident - p_range - (longId, range) - st - | SynOpenDeclTarget.Type (typeName, range) -> - p_byte 1 st - p_tup2 - p_syn_type - p_range - (typeName, range) - st - -and p_ccu_data (x: CcuData) st = - p_option p_string x.FileName st - p_ILScopeRef x.ILScopeRef st - p_stamp x.Stamp st - p_option p_string x.QualifiedName st - p_string x.SourceCodeDirectory st - p_bool x.IsFSharp st -#if !NO_TYPEPROVIDERS - p_bool x.IsProviderGenerated st -#endif - p_bool x.UsesFSharp20PlusQuotations st - p_entity_spec_data_new x.Contents st - -and p_ccuref_new (x: CcuThunk) st = - p_tup2 - p_ccu_data - p_string - (x.target, x.name) - st - -and p_nleref_new (x: NonLocalEntityRef) st = - let (NonLocalEntityRef (ccu, strings)) = x - p_tup2 - p_ccuref_new - (p_array p_string) - (ccu, strings) - st - - -and p_tcref_new (x: EntityRef) st = - match x with - | ERefLocal x -> p_byte 0 st; p_local_item_ref "tcref" st.oentities x st - | ERefNonLocal x -> p_byte 1 st; p_nleref_new x st - -and p_nonlocal_val_ref_new (nlv: NonLocalValOrMemberRef) st = - let a = nlv.EnclosingEntity - let key = nlv.ItemKey - let pkey = key.PartialKey - p_tcref_new a st - p_option p_string pkey.MemberParentMangledName st - p_bool pkey.MemberIsOverride st - p_string pkey.LogicalName st - p_int pkey.TotalArgCount st - let isStructThisArgPos = - match key.TypeForLinkage with - | None -> false - | Some ty -> checkForInRefStructThisArg st ty - p_option p_ty_new key.TypeForLinkage st - - -and p_vref_new (x: ValRef) st = - match x with - | VRefLocal x -> p_byte 0 st; p_local_item_ref "valref" st.ovals x st - | VRefNonLocal x -> p_byte 1 st; p_nonlocal_val_ref_new x st - -and p_open_decl (x: OpenDeclaration) st = - p_tup6 - p_syn_open_decl_target - (p_option p_range) - (p_list p_tcref_new) - p_tys - p_range - p_bool - (x.Target, x.Range, x.Modules, x.Types, x.AppliedScope, x.IsOwnNamespace) - st - -and p_binding (x: ModuleOrNamespaceBinding) st = - match x with - | ModuleOrNamespaceBinding.Binding binding -> - p_byte 0 st - p_bind binding st - | ModuleOrNamespaceBinding.Module (moduleOrNamespace, moduleOrNamespaceContents) -> - p_byte 1 st - p_tup2 - p_entity_spec_new - p_module_or_namespace_contents - (moduleOrNamespace, moduleOrNamespaceContents) - st - -and p_tup_info (tupInfo: TupInfo) st = - let (TupInfo.Const c) = tupInfo - p_bool c st - -and p_nullness (nullness: Nullness) st = - match nullness.Evaluate() with - | NullnessInfo.WithNull -> p_byte 0 st - | NullnessInfo.WithoutNull -> p_byte 1 st - | NullnessInfo.AmbivalentToNull -> p_byte 2 st - -and p_typars = p_list p_tpref - -and p_ty_new (ty: TType) st : unit = - match ty with - | TType_tuple (tupInfo, l) -> - p_byte 0 st - p_tup2 - p_tup_info - p_tys_new - (tupInfo, l) - st - - | TType_app (tyconRef, typeInstantiation, nullness) -> - p_byte 1 st - p_tup4 - (p_tcref "app") - p_tys_new - p_nullness - (p_non_null_slot p_entity_spec_new) - (tyconRef, typeInstantiation, nullness, tyconRef.binding) - st - - | TType_fun (domainType, rangeType, nullness) -> - p_byte 2 st - p_ty_new domainType st - p_ty_new rangeType st - p_nullness nullness st - - | TType_var (typar, nullness) -> - p_byte 3 st - p_tup4 - p_tpref - p_nullness - (p_option p_ty_new) - p_stamp - (typar, nullness, typar.Solution, typar.Stamp) - st - - | TType_forall (tps, r) -> - p_byte 4 st - p_tup2 - p_typars - p_ty_new - (tps, r) - st - - | TType_measure unt -> - p_byte 5 st - p_measure_expr unt st - - | TType_ucase (uc, tinst) -> - p_byte 6 st - p_tup2 - p_ucref - p_tys_new - (uc, tinst) - st - - | TType_anon (anonInfo, l) -> - p_byte 7 st - p_tup2 - p_anonInfo - p_tys_new - (anonInfo, l) - st - -and p_tys_new l = - let _count = l.Length - p_list p_ty_new l - -and p_expr_new (expr: Expr) st = - match expr with - | Expr.Link e -> p_byte 0 st; p_expr_new e.Value st - | Expr.Const (x, m, ty) -> p_byte 1 st; p_tup3 p_const p_dummy_range p_ty_new (x, m, ty) st - | Expr.Val (a, b, m) -> - p_byte 2 st - p_tup4 - p_vref_new - p_vrefFlags - p_dummy_range - (p_non_null_slot p_Val_new) - (a, b, m, a.binding) - st - | Expr.Op (a, b, c, d) -> p_byte 3 st; p_tup4 p_op_new p_tys_new p_exprs_new p_dummy_range (a, b, c, d) st - | Expr.Sequential (a, b, c, d) -> p_byte 4 st; p_tup4 p_expr_new p_expr_new p_int p_dummy_range (a, b, (match c with NormalSeq -> 0 | ThenDoSeq -> 1), d) st - | Expr.Lambda (_, a1, b0, b1, c, d, e) -> p_byte 5 st; p_tup6 (p_option p_Val) (p_option p_Val) p_Vals p_expr_new p_dummy_range p_ty_new (a1, b0, b1, c, d, e) st - | Expr.TyLambda (_, b, c, d, e) -> p_byte 6 st; p_tup4 p_tyar_specs_new p_expr_new p_dummy_range p_ty_new (b, c, d, e) st - | Expr.App (funcExpr, formalType, typeArgs, args, range) -> - p_byte 7 st - - p_expr_new funcExpr st - p_ty_new formalType st - p_tys_new typeArgs st - p_exprs_new args st - p_dummy_range range st - | Expr.LetRec (a, b, c, _) -> p_byte 8 st; p_tup3 p_binds p_expr_new p_dummy_range (a, b, c) st - | Expr.Let (a, b, c, _) -> p_byte 9 st; p_tup3 p_bind p_expr_new p_dummy_range (a, b, c) st - | Expr.Match (_, a, b, c, d, e) -> p_byte 10 st; p_tup5 p_dummy_range p_dtree p_targets p_dummy_range p_ty_new (a, b, c, d, e) st - | Expr.Obj (_, b, c, d, e, f, g) -> p_byte 11 st; p_tup6 p_ty_new (p_option p_Val) p_expr_new p_methods p_intfs p_dummy_range (b, c, d, e, f, g) st - | Expr.StaticOptimization (a, b, c, d) -> p_byte 12 st; p_tup4 p_constraints p_expr_new p_expr_new p_dummy_range (a, b, c, d) st - | Expr.TyChoose (a, b, c) -> p_byte 13 st; p_tup3 p_tyar_specs_new p_expr_new p_dummy_range (a, b, c) st - | Expr.Quote (ast, _, _, m, ty) -> p_byte 14 st; p_tup3 p_expr_new p_dummy_range p_ty_new (ast, m, ty) st - | Expr.WitnessArg (traitInfo, m) -> p_byte 15 st; p_trait traitInfo st; p_dummy_range m st - | Expr.DebugPoint (_, innerExpr) -> - p_byte 16 st - p_expr_new innerExpr st - -and p_exprs_new = p_list p_expr_new - -and p_module_or_namespace_contents (x: ModuleOrNamespaceContents) st = - match x with - | TMDefs defs -> - p_byte 0 st - p_list p_module_or_namespace_contents defs st - | TMDefOpens openDecls -> - p_byte 1 st - p_list p_open_decl openDecls st - | TMDefLet (binding, range) -> - p_byte 2 st - p_tup2 - p_bind_new - p_range - (binding, range) - st - | TMDefDo (expr, range) -> - p_byte 3 st - p_tup2 - p_expr_new - p_range - (expr, range) - st - | TMDefRec (isRec, opens, tycons, bindings, range) -> - p_byte 4 st - p_tup5 - p_bool - (p_list p_open_decl) - (p_list p_entity_spec_data_new) - (p_list p_binding) - p_range - (isRec, opens, tycons, bindings, range) - st - -and p_checked_impl_file_contents = p_module_or_namespace_contents - -and p_named_debug_point_key (x: NamedDebugPointKey) st = - p_tup2 - p_range - p_string - (x.Range, x.Name) - st - -and p_named_debug_points = p_Map p_named_debug_point_key p_range - -and p_anon_recd_types = p_stamp_map p_anonInfo - -and p_checked_impl_file file st = - let (CheckedImplFile ( - qualifiedNameOfFile, - pragmas, - signature, - contents, - hasExplicitEntryPoint, - isScript, - anonRecdTypeInfo, - namedDebugPointsForInlinedCode)) = file - - p_tup8 - p_qualified_name_of_file - p_pragmas - p_modul_typ_new - p_checked_impl_file_contents - p_bool - p_bool - p_anon_recd_types - p_named_debug_points - (qualifiedNameOfFile, - pragmas, - signature, - contents, - hasExplicitEntryPoint, - isScript, - anonRecdTypeInfo, - namedDebugPointsForInlinedCode) - st - -and u_tycon_repr st = - let tag1 = u_byte st - match tag1 with - | 0 -> (fun _flagBit -> TNoRepr) - | 1 -> - let tag2 = u_byte st - match tag2 with - // Records historically use a different format to other FSharpTyconRepr - | 0 -> - let v = u_rfield_table st - (fun _flagBit -> - TFSharpTyconRepr - { - fsobjmodel_cases = Construct.MakeUnionCases [] - fsobjmodel_kind=TFSharpRecord - fsobjmodel_vslots=[] - fsobjmodel_rfields=v - }) - - // Unions without static fields historically use a different format to other FSharpTyconRepr - | 1 -> - let v = u_list u_unioncase_spec st - (fun _flagBit -> Construct.MakeUnionRepr v) - - | 2 -> - let v = u_ILType st - // This is the F# 3.0 extension to the format used for F# provider-generated types, which record an ILTypeRef in the format - // You can think of an F# 2.0 reader as always taking the path where 'flagBit' is false. Thus the F# 2.0 reader will - // interpret provider-generated types as TAsmRepr. - (fun flagBit -> - if flagBit then - let iltref = v.TypeRef - match st.iILModule with - | None -> TNoRepr - | Some iILModule -> - try - let rec find acc enclosingTypeNames (tdefs: ILTypeDefs) = - match enclosingTypeNames with - | [] -> List.rev acc, tdefs.FindByName iltref.Name - | h :: t -> - let nestedTypeDef = tdefs.FindByName h - find (nestedTypeDef :: acc) t nestedTypeDef.NestedTypes - let nestedILTypeDefs, ilTypeDef = find [] iltref.Enclosing iILModule.TypeDefs - TILObjectRepr(TILObjectReprData(st.iilscope, nestedILTypeDefs, ilTypeDef)) - with _ -> - System.Diagnostics.Debug.Assert(false, sprintf "failed to find IL backing metadata for cross-assembly generated type %s" iltref.FullName) - TNoRepr - else - TAsmRepr v) - - | 3 -> - let v = u_tycon_objmodel_data st - (fun _flagBit -> TFSharpTyconRepr v) - - | 4 -> - let v = u_ty st - (fun _flagBit -> TMeasureableRepr v) - - | _ -> ufailwith st "u_tycon_repr" - - // Unions with static fields use a different format to other FSharpTyconRepr - | 2 -> - let cases = u_array u_unioncase_spec st - let data = u_tycon_objmodel_data st - fun _flagBit -> TFSharpTyconRepr { data with fsobjmodel_cases = Construct.MakeUnionCases (Array.toList cases) } - | _ -> ufailwith st "u_tycon_repr" - - -and u_tycon_repr_new st = - let tag1 = u_byte st - match tag1 with - | 0 -> (fun _flagBit -> TNoRepr) - | 1 -> - let tag2 = u_byte st - match tag2 with - // Records historically use a different format to other FSharpTyconRepr - | 0 -> - let v = u_rfield_table st - (fun _flagBit -> - TFSharpTyconRepr - { - fsobjmodel_cases = Construct.MakeUnionCases [] - fsobjmodel_kind=TFSharpRecord - fsobjmodel_vslots=[] - fsobjmodel_rfields=v - }) - - // Unions without static fields historically use a different format to other FSharpTyconRepr - | 1 -> - let v = u_list u_unioncase_spec st - (fun _flagBit -> Construct.MakeUnionRepr v) - - | 2 -> - let v = u_ILType st - // This is the F# 3.0 extension to the format used for F# provider-generated types, which record an ILTypeRef in the format - // You can think of an F# 2.0 reader as always taking the path where 'flagBit' is false. Thus the F# 2.0 reader will - // interpret provider-generated types as TAsmRepr. - (fun flagBit -> - if flagBit then - let iltref = v.TypeRef - match st.iILModule with - | None -> TNoRepr - | Some iILModule -> - try - let rec find acc enclosingTypeNames (tdefs: ILTypeDefs) = - match enclosingTypeNames with - | [] -> List.rev acc, tdefs.FindByName iltref.Name - | h :: t -> - let nestedTypeDef = tdefs.FindByName h - find (nestedTypeDef :: acc) t nestedTypeDef.NestedTypes - let nestedILTypeDefs, ilTypeDef = find [] iltref.Enclosing iILModule.TypeDefs - TILObjectRepr(TILObjectReprData(st.iilscope, nestedILTypeDefs, ilTypeDef)) - with _ -> - System.Diagnostics.Debug.Assert(false, sprintf "failed to find IL backing metadata for cross-assembly generated type %s" iltref.FullName) - TNoRepr - else - TAsmRepr v) - - | 3 -> - let v = u_tycon_objmodel_data st - (fun _flagBit -> TFSharpTyconRepr v) - - | 4 -> - let v = u_ty st - (fun _flagBit -> TMeasureableRepr v) - - | _ -> ufailwith st "u_tycon_repr" - - // Unions with static fields use a different format to other FSharpTyconRepr - | 2 -> - let cases = u_array u_unioncase_spec st - let data = u_tycon_objmodel_data st - fun _flagBit -> TFSharpTyconRepr { data with fsobjmodel_cases = Construct.MakeUnionCases (Array.toList cases) } - - | 5 -> - // | TILObjectRepr (TILObjectReprData (scope, nesting, td)) -> - let scope = u_ILScopeRef st - let nesting = u_list u_ILTypeDef st - let definition = u_ILTypeDef st - - (fun _flagBit -> TILObjectRepr (TILObjectReprData (scope, nesting, definition))) - - | _ -> ufailwith st "u_tycon_repr" - - -and u_tycon_objmodel_data st = - let x1, x2, x3 = u_tup3 u_tycon_objmodel_kind u_vrefs u_rfield_table st - { - fsobjmodel_cases = Construct.MakeUnionCases [] - fsobjmodel_kind=x1 - fsobjmodel_vslots=x2 - fsobjmodel_rfields=x3 - } +and u_tycon_objmodel_data st = + let x1, x2, x3 = u_tup3 u_tycon_objmodel_kind u_vrefs u_rfield_table st + { + fsobjmodel_cases = Construct.MakeUnionCases [] + fsobjmodel_kind=x1 + fsobjmodel_vslots=x2 + fsobjmodel_rfields=x3 + } and u_attribs_ext extraf st = u_list_ext extraf u_attrib st and u_unioncase_spec st = @@ -3067,59 +2372,6 @@ and u_entity_spec_data st : Entity = entity_exn_info = x14 } } -and u_entity_spec_data_new st : Entity = - let x1, x2a, x2b, x2c, stamp, x3, (x4a, x4b), x6, x7, x8, x9, _x10, x10b, x11, x12, x13, x14, x15 = - u_tup18 - u_tyar_specs_new - u_string - (u_option u_string) - u_range - u_stamp - (u_option u_pubpath) - (u_tup2 u_access u_access) - u_attribs - u_tycon_repr_new - (u_option u_ty_new) - u_tcaug_new - u_string - u_kind - u_int64 - (u_option u_cpath ) - (u_lazy u_modul_typ_new) - u_exnc_repr - (u_used_space1 u_xmldoc) - st - // We use a bit that was unused in the F# 2.0 format to indicate two possible representations in the F# 3.0 tycon_repr format - //let x7 = x7f (x11 &&& EntityFlags.ReservedBitForPickleFormatTyconReprFlag <> 0L) - //let x11 = x11 &&& ~~~EntityFlags.ReservedBitForPickleFormatTyconReprFlag - - { entity_typars=LazyWithContext.NotLazy x1 - entity_stamp=stamp - entity_logical_name=x2a - entity_range=x2c - entity_pubpath=x3 - entity_attribs=x6 - entity_tycon_repr=x7 false - entity_tycon_tcaug=x9 - entity_flags=EntityFlags x11 - entity_cpath=x12 - entity_modul_type=MaybeLazy.Lazy x13 - entity_il_repr_cache=newCache() - entity_opt_data= - match x2b, x10b, x15, x8, x4a, x4b, x14 with - | None, TyparKind.Type, None, None, TAccess [], TAccess [], TExnNone -> None - | _ -> - Some { Entity.NewEmptyEntityOptData() with - entity_compiled_name = x2b - entity_kind = x10b - entity_xmldoc= defaultArg x15 XmlDoc.Empty - entity_xmldocsig = System.String.Empty - entity_tycon_abbrev = x8 - entity_accessibility = x4a - entity_tycon_repr_accessibility = x4b - entity_exn_info = x14 } - } - and u_tcaug st = let a1, a2, a3, b2, c, d, e, g, _space = u_tup9 @@ -3147,39 +2399,9 @@ and u_tcaug st = tcaug_closed=true tcaug_abstract=g} -and u_tcaug_new st : TyconAugmentation = - let a1, a2, a3, b2, c, d, e, g, _space = - u_tup9 - (u_option (u_tup2 u_vref u_vref)) - (u_option u_vref) - (u_option (u_tup3 u_vref u_vref u_vref)) - (u_option (u_tup2 u_vref u_vref)) - (u_list (u_tup2 u_string u_vref)) - (u_list (u_tup3 u_ty_new u_bool u_dummy_range)) - (u_option u_ty_new) - u_bool - (u_space 1) - st - {tcaug_compare=a1 - tcaug_compare_withc=a2 - tcaug_hash_and_equals_withc=a3 |> Option.map (fun (v1, v2, v3) -> (v1, v2, v3, None)) - tcaug_equals=b2 - // only used for code generation and checking - hence don't care about the values when reading back in - tcaug_hasObjectGetHashCode=false - tcaug_adhoc_list= ResizeArray<_>(c |> List.map (fun (_, vref) -> (false, vref))) - tcaug_adhoc=NameMultiMap.ofList c - tcaug_interfaces=d - tcaug_super=e - // pickled type definitions are always closed (i.e. no more intrinsic members allowed) - tcaug_closed=true - tcaug_abstract=g} - and u_entity_spec st = u_osgn_decl st.ientities u_entity_spec_data st -and u_entity_spec_new st = - u_osgn_decl st.ientities u_entity_spec_data_new st - and u_parentref st = let tag = u_byte st match tag with @@ -3204,574 +2426,90 @@ and u_attrib_expr st = and u_attrib_arg st = let a, b, c, d = u_tup4 u_string u_ty u_bool u_attrib_expr st - AttribNamedArg(a, b, c, d) - -and u_member_info st : ValMemberInfo = - let x2, x3, x4, x5 = u_tup4 u_tcref u_MemberFlags (u_list u_slotsig) u_bool st - { ApparentEnclosingEntity=x2 - MemberFlags=x3 - ImplementedSlotSigs=x4 - IsImplemented=x5 } - -and u_tycon_objmodel_kind st = - let tag = u_byte st - match tag with - | 0 -> TFSharpClass - | 1 -> TFSharpInterface - | 2 -> TFSharpStruct - | 3 -> u_slotsig st |> TFSharpDelegate - | 4 -> TFSharpEnum - | 5 -> TFSharpUnion - | 6 -> TFSharpRecord - | _ -> ufailwith st "u_tycon_objmodel_kind" - -and u_vrefFlags st = - match u_byte st with - | 0 -> NormalValUse - | 1 -> CtorValUsedAsSuperInit - | 2 -> CtorValUsedAsSelfInit - | 3 -> PossibleConstrainedCall (u_ty st) - | 4 -> VSlotDirectCall - | _ -> ufailwith st "u_vrefFlags" - -and u_ValData st = - let x1, x1z, x1a, x2, x4, x8, x9, x10, x12, x13, x13b, x14, x15 = - u_tup13 - u_string - (u_option u_string) - u_ranges - u_ty - u_int64 - (u_option u_member_info) - u_attribs - (u_option u_ValReprInfo) - u_string - u_access - u_parentref - (u_option u_const) - (u_used_space1 u_xmldoc) - st - - { val_logical_name = x1 - val_range = (match x1a with None -> range0 | Some(a, _) -> a) - val_type = x2 - val_stamp = newStamp() - val_flags = ValFlags x4 - val_opt_data = - match x1z, x1a, x10, x14, x13, x15, x8, x13b, x12, x9 with - | None, None, None, None, TAccess [], None, None, ParentNone, "", [] -> None - | _ -> - Some { val_compiled_name = x1z - val_other_range = (match x1a with None -> None | Some(_, b) -> Some(b, true)) - val_defn = None - val_repr_info = x10 - val_repr_info_for_display = None - arg_repr_info_for_display = None - val_const = x14 - val_access = x13 - val_xmldoc = defaultArg x15 XmlDoc.Empty - val_other_xmldoc = None - val_member_info = x8 - val_declaring_entity = x13b - val_xmldocsig = x12 - val_attribs = x9 } - } - - -and u_ValData_new st = - let x1, x1z, x1a, x2, stamp, x4, x8, x9, x10, x12, x13, x13b, x14, x15 = - u_tup14 - u_string - (u_option u_string) - u_ranges - u_ty_new - u_stamp - u_int64 - (u_option u_member_info) - u_attribs - (u_option u_ValReprInfo) - u_string - u_access - u_parentref - (u_option u_const) - (u_used_space1 u_xmldoc) - st - - { val_logical_name = x1 - val_range = (match x1a with None -> range0 | Some(a, _) -> a) - val_type = x2 - val_stamp = stamp - val_flags = ValFlags x4 - val_opt_data = - match x1z, x1a, x10, x14, x13, x15, x8, x13b, x12, x9 with - | None, None, None, None, TAccess [], None, None, ParentNone, "", [] -> None - | _ -> - Some { val_compiled_name = x1z - val_other_range = (match x1a with None -> None | Some(_, b) -> Some(b, true)) - val_defn = None - val_repr_info = x10 - val_repr_info_for_display = None - arg_repr_info_for_display = None - val_const = x14 - val_access = x13 - val_xmldoc = defaultArg x15 XmlDoc.Empty - val_other_xmldoc = None - val_member_info = x8 - val_declaring_entity = x13b - val_xmldocsig = x12 - val_attribs = x9 } - } - -and u_Val st = u_osgn_decl st.ivals u_ValData st - -and u_Val_new st = u_osgn_decl st.ivals u_ValData_new st - -and u_modul_typ st = - let x1, x3, x5 = - u_tup3 - u_istype - (u_qlist u_Val) - (u_qlist u_entity_spec) st - ModuleOrNamespaceType(x1, x3, x5) - -and u_modul_typ_new st = - let x1, x3, x5 = - u_tup3 - u_istype - (u_qlist u_Val_new) - (u_qlist u_entity_spec_new) st - ModuleOrNamespaceType(x1, x3, x5) - -and u_qualified_name_of_file st = - let ident = u_ident st - QualifiedNameOfFile(ident) - -and u_pragma st = - let range, warningNumber = - u_tup2 - u_range - u_int - st - - ScopedPragma.WarningOff (range, warningNumber) - -and u_pragmas st = - u_list u_pragma st - -and u_long_ident st = - u_list u_ident st - -and u_trivia st : SyntaxTrivia.IdentTrivia = - ufailwith st (nameof p_trivia) - -and u_syn_long_ident st = - let id, dotRanges, trivia = - u_tup3 - u_long_ident - (u_list u_range) - (u_list (u_option u_trivia)) - st - - SynLongIdent (id, dotRanges, trivia) - -and u_syn_type st : SynType = - ufailwith st (nameof u_syn_type) - -and u_syn_open_decl_target st : SynOpenDeclTarget = - let tag = u_byte st - match tag with - | 0 -> - let longId, range = - u_tup2 - u_syn_long_ident - u_range - st - - SynOpenDeclTarget.ModuleOrNamespace (longId, range) - | 1 -> - let typeName, range = - u_tup2 - u_syn_type - u_range - st - SynOpenDeclTarget.Type (typeName, range) - | _ -> - ufailwith st (nameof u_syn_open_decl_target) - -and u_ccu_data st : CcuData = - let fileName = u_option u_string st - let ilScopeRef = u_ILScopeRef st - let stamp = u_stamp st - let qualifiedName = u_option u_string st - let sourceCodeDirectory = u_string st - let isFSharp = u_bool st -#if !NO_TYPEPROVIDERS - let isProviderGenerated = u_bool st -#endif - let usesFSharp20PlusQuotations = u_bool st - let contents = u_entity_spec_data_new st - - { - FileName = fileName - ILScopeRef = ilScopeRef - Stamp = stamp - QualifiedName = qualifiedName - SourceCodeDirectory = sourceCodeDirectory - IsFSharp = isFSharp -#if !NO_TYPEPROVIDERS - IsProviderGenerated = isProviderGenerated - InvalidateEvent = Unchecked.defaultof<_> - ImportProvidedType = Unchecked.defaultof<_> -#endif - UsesFSharp20PlusQuotations = usesFSharp20PlusQuotations - Contents = contents - TryGetILModuleDef = Unchecked.defaultof<_> - MemberSignatureEquality = Unchecked.defaultof<_> - TypeForwarders = Unchecked.defaultof<_> - XmlDocumentationInfo = Unchecked.defaultof<_> - } - -and u_ccuref_new st : CcuThunk = - let target, name = - u_tup2 - u_ccu_data - u_string - st - - { - target = target - name = name - } - -and u_nleref_new st = - let ccu, strings = - u_tup2 - u_ccuref_new - (u_array u_string) - st - - NonLocalEntityRef (ccu, strings) - -and u_tcref_new st : EntityRef = - let tag = u_byte st - match tag with - | 0 -> u_local_item_ref st.ientities st |> ERefLocal - | 1 -> u_nleref_new st |> ERefNonLocal - | _ -> ufailwith st "u_item_ref" - -and u_nonlocal_val_ref_new st : NonLocalValOrMemberRef = - let a = u_tcref_new st - let b1 = u_option u_string st - let b2 = u_bool st - let b3 = u_string st - let c = u_int st - let d = u_option u_ty_new st - { EnclosingEntity = a - ItemKey=ValLinkageFullKey({ MemberParentMangledName=b1; MemberIsOverride=b2;LogicalName=b3; TotalArgCount=c }, d) } - -and u_vref_new st : ValRef = - let tag = u_byte st - match tag with - | 0 -> u_local_item_ref st.ivals st |> VRefLocal - | 1 -> u_nonlocal_val_ref_new st |> VRefNonLocal - | _ -> ufailwith st "u_item_ref" - -and u_open_decl st : OpenDeclaration = - let target, range, modules, types, appliedScope, isOwnNamespace = - u_tup6 - u_syn_open_decl_target - (u_option u_range) - (u_list u_tcref_new) - u_tys - u_range - u_bool - st - - { - Target = target - Range = range - Modules = modules - Types = types - AppliedScope = appliedScope - IsOwnNamespace = isOwnNamespace - } - -and u_binding st : ModuleOrNamespaceBinding = - let tag = u_byte st - match tag with - | 0 -> - let binding = u_bind st - ModuleOrNamespaceBinding.Binding binding - | 1 -> - let moduleOrNamespace, moduleOrNamespaceContents = - u_tup2 - u_entity_spec_new - u_module_or_namespace_contents - st - ModuleOrNamespaceBinding.Module (moduleOrNamespace, moduleOrNamespaceContents) - | _ -> - ufailwith st (nameof u_binding) - -and u_tup_info st : TupInfo = - let c = u_bool st - TupInfo.Const c - -and u_nullness st = - let tag = u_byte st - let nullnessInfo = - match tag with - | 0 -> NullnessInfo.WithNull - | 1 -> NullnessInfo.WithoutNull - | 2 -> NullnessInfo.AmbivalentToNull - | _ -> ufailwith st (nameof u_nullness) - - Nullness.Known nullnessInfo - -and u_typars = u_list u_tpref - -and u_ty_new st : TType = - let tag = u_byte st - match tag with - | 0 -> - let tupInfo, l = - u_tup2 - u_tup_info - u_tys_new - st - TType_tuple (tupInfo, l) - - | 1 -> - let tyconRef, typeInstantiation, nullness, binding = - u_tup4 - u_tcref - u_tys_new - u_nullness - (u_non_null_slot u_entity_spec_new) - st - - tyconRef.binding <- binding - TType_app (tyconRef, typeInstantiation, nullness) - - | 2 -> - let (domainType, rangeType, nullness) = - u_tup3 - u_ty_new - u_ty_new - u_nullness - st - TType_fun (domainType, rangeType, nullness) - - | 3 -> - let (typar, nullness, solution, stamp) = - u_tup4 - u_tpref - u_nullness - (u_option u_ty_new) - u_stamp - st - - typar.typar_solution <- solution - typar.typar_stamp <- stamp - TType_var (typar, nullness) + AttribNamedArg(a, b, c, d) - | 4 -> - let (tps, r) = - u_tup2 - u_typars - u_ty_new - st +and u_member_info st : ValMemberInfo = + let x2, x3, x4, x5 = u_tup4 u_tcref u_MemberFlags (u_list u_slotsig) u_bool st + { ApparentEnclosingEntity=x2 + MemberFlags=x3 + ImplementedSlotSigs=x4 + IsImplemented=x5 } - TType_forall (tps, r) +and u_tycon_objmodel_kind st = + let tag = u_byte st + match tag with + | 0 -> TFSharpClass + | 1 -> TFSharpInterface + | 2 -> TFSharpStruct + | 3 -> u_slotsig st |> TFSharpDelegate + | 4 -> TFSharpEnum + | 5 -> TFSharpUnion + | 6 -> TFSharpRecord + | _ -> ufailwith st "u_tycon_objmodel_kind" - | 5 -> - let unt = u_measure_expr st - TType_measure unt +and u_vrefFlags st = + match u_byte st with + | 0 -> NormalValUse + | 1 -> CtorValUsedAsSuperInit + | 2 -> CtorValUsedAsSelfInit + | 3 -> PossibleConstrainedCall (u_ty st) + | 4 -> VSlotDirectCall + | _ -> ufailwith st "u_vrefFlags" - | 6 -> - let uc, tinst = - u_tup2 - u_ucref - u_tys_new - st - TType_ucase (uc, tinst) +and u_ValData st = + let x1, x1z, x1a, x2, x4, x8, x9, x10, x12, x13, x13b, x14, x15 = + u_tup13 + u_string + (u_option u_string) + u_ranges + u_ty + u_int64 + (u_option u_member_info) + u_attribs + (u_option u_ValReprInfo) + u_string + u_access + u_parentref + (u_option u_const) + (u_used_space1 u_xmldoc) + st - | 7 -> - let anonInfo, l = - u_tup2 - u_anonInfo - u_tys_new - st - TType_anon (anonInfo, l) - | _ -> - ufailwith st (nameof u_ty_new) + { val_logical_name = x1 + val_range = (match x1a with None -> range0 | Some(a, _) -> a) + val_type = x2 + val_stamp = newStamp() + val_flags = ValFlags x4 + val_opt_data = + match x1z, x1a, x10, x14, x13, x15, x8, x13b, x12, x9 with + | None, None, None, None, TAccess [], None, None, ParentNone, "", [] -> None + | _ -> + Some { val_compiled_name = x1z + val_other_range = (match x1a with None -> None | Some(_, b) -> Some(b, true)) + val_defn = None + val_repr_info = x10 + val_repr_info_for_display = None + arg_repr_info_for_display = None + val_const = x14 + val_access = x13 + val_xmldoc = defaultArg x15 XmlDoc.Empty + val_other_xmldoc = None + val_member_info = x8 + val_declaring_entity = x13b + val_xmldocsig = x12 + val_attribs = x9 } + } -and u_tys_new = u_list u_ty_new +and u_Val st = u_osgn_decl st.ivals u_ValData st -and u_expr_new st : Expr = - let tag = u_byte st - match tag with - | 0 -> let e = u_expr_new st - let r = ref e - Expr.Link r - | 1 -> let a = u_const st - let b = u_dummy_range st - let c = u_ty_new st - Expr.Const (a, b, c) - | 2 -> let valRef = u_vref_new st - let flags = u_vrefFlags st - let range = u_dummy_range st - let binding = (u_non_null_slot u_Val_new) st - - valRef.binding <- binding - let expr = Expr.Val (valRef, flags, range) - expr - | 3 -> let a = u_op_new st - let b = u_tys_new st - let c = u_exprs_new st - let d = u_dummy_range st - Expr.Op (a, b, c, d) - | 4 -> let a = u_expr_new st - let b = u_expr_new st - let c = u_int st - let d = u_dummy_range st - let dir = match c with 0 -> NormalSeq | 1 -> ThenDoSeq | _ -> ufailwith st "specialSeqFlag" - Expr.Sequential (a, b, dir, d) - | 5 -> let a0 = u_option u_Val st - let b0 = u_option u_Val st - let b1 = u_Vals st - let c = u_expr_new st - let d = u_dummy_range st - let e = u_ty_new st - Expr.Lambda (newUnique(), a0, b0, b1, c, d, e) - | 6 -> let b = u_tyar_specs_new st - let c = u_expr_new st - let d = u_dummy_range st - let e = u_ty_new st - Expr.TyLambda (newUnique(), b, c, d, e) - | 7 -> let a1 = u_expr_new st - let a2 = u_ty_new st - let b = u_tys_new st - let c = u_exprs_new st - let d = u_dummy_range st - let expr = Expr.App (a1, a2, b, c, d) - expr - | 8 -> let a = u_binds st - let b = u_expr_new st - let c = u_dummy_range st - Expr.LetRec (a, b, c, Construct.NewFreeVarsCache()) - | 9 -> let a = u_bind st - let b = u_expr_new st - let c = u_dummy_range st - Expr.Let (a, b, c, Construct.NewFreeVarsCache()) - | 10 -> let a = u_dummy_range st - let b = u_dtree st - let c = u_targets st - let d = u_dummy_range st - let e = u_ty_new st - Expr.Match (DebugPointAtBinding.NoneAtSticky, a, b, c, d, e) - | 11 -> let b = u_ty_new st - let c = (u_option u_Val) st - let d = u_expr_new st - let e = u_methods st - let f = u_intfs st - let g = u_dummy_range st - Expr.Obj (newUnique(), b, c, d, e, f, g) - | 12 -> let a = u_constraints st - let b = u_expr_new st - let c = u_expr_new st - let d = u_dummy_range st - Expr.StaticOptimization (a, b, c, d) - | 13 -> let a = u_tyar_specs_new st - let b = u_expr_new st - let c = u_dummy_range st - Expr.TyChoose (a, b, c) - | 14 -> let b = u_expr_new st - let c = u_dummy_range st - let d = u_ty_new st - Expr.Quote (b, ref None, false, c, d) // isFromQueryExpression=false - | 15 -> let traitInfo = u_trait st - let m = u_dummy_range st - Expr.WitnessArg (traitInfo, m) - | 16 -> let m = u_dummy_range st - let expr = u_expr_new st - Expr.DebugPoint (DebugPointAtLeafExpr.Yes m, expr) - | _ -> ufailwith st "u_expr" - -and u_exprs_new = u_list u_expr_new -and u_module_or_namespace_contents st : ModuleOrNamespaceContents = - let tag = u_byte st - match tag with - | 0 -> - let defs = u_list u_module_or_namespace_contents st - TMDefs defs - | 1 -> - let openDecls = u_list u_open_decl st - TMDefOpens openDecls - | 2 -> - let binding, range = - u_tup2 - u_bind_new - u_range - st - TMDefLet(binding, range) - | 3 -> - let expr, range = - u_tup2 - u_expr_new - u_range - st - TMDefDo(expr, range) - | 4 -> - let isRec, opens, tycons, bindings, range = - u_tup5 - u_bool - (u_list u_open_decl) - (u_list u_entity_spec_data_new) - (u_list u_binding) - u_range - st - TMDefRec (isRec, opens, tycons, bindings, range) - | _ -> - ufailwith st (nameof u_module_or_namespace_contents) - -and u_checked_impl_file_contents = u_module_or_namespace_contents - -and u_named_debug_point_key st : NamedDebugPointKey = - let range, name = - u_tup2 - u_range - u_string - st +and u_modul_typ st = + let x1, x3, x5 = + u_tup3 + u_istype + (u_qlist u_Val) + (u_qlist u_entity_spec) st + ModuleOrNamespaceType(x1, x3, x5) - { Range = range; Name = name} - -and u_named_debug_points = u_Map u_named_debug_point_key u_range - -and u_anon_recd_types = u_stamp_map u_anonInfo - -and u_checked_impl_file st = - let qualifiedNameOfFile, pragmas, signature, contents, hasExplicitEntryPoint, isScript, anonRecdTypeInfo, namedDebugPointsForInlinedCode = - u_tup8 - u_qualified_name_of_file - u_pragmas - u_modul_typ_new - u_checked_impl_file_contents - u_bool - u_bool - u_anon_recd_types - u_named_debug_points - st - - CheckedImplFile( - qualifiedNameOfFile, - pragmas, - signature, - contents, - hasExplicitEntryPoint, - isScript, - anonRecdTypeInfo, - namedDebugPointsForInlinedCode) //--------------------------------------------------------------------------- // Pickle/unpickle for F# expressions (for optimization data) @@ -3843,8 +2581,6 @@ and p_dtree_discrim x st = and p_target (TTarget(a, b, _)) st = p_tup2 p_Vals p_expr (a, b) st and p_bind (TBind(a, b, _)) st = p_tup2 p_Val p_expr (a, b) st -and p_bind_new (TBind(a, b, _)) st = p_tup2 p_Val_new p_expr_new (a, b) st - and p_lval_op_kind x st = p_byte (match x with LAddrOf _ -> 0 | LByrefGet -> 1 | LSet -> 2 | LByrefSet -> 3) st @@ -3879,11 +2615,6 @@ and u_target st = let a, b = u_tup2 u_Vals u_expr st in (TTarget(a, b, None)) and u_bind st = let a = u_Val st in let b = u_expr st in TBind(a, b, DebugPointAtBinding.NoneAtSticky) -and u_bind_new st = - let a = u_Val_new st - let b = u_expr_new st - TBind(a, b, DebugPointAtBinding.NoneAtSticky) - and u_lval_op_kind st = match u_byte st with | 0 -> LAddrOf false @@ -3892,13 +2623,6 @@ and u_lval_op_kind st = | 3 -> LByrefSet | _ -> ufailwith st "uval_op_kind" -and p_ucref_new (UnionCaseRef(a, b)) st = - p_tup3 - (p_tcref "ucref") - p_string - (p_non_null_slot p_entity_spec_new) - (a, b, a.binding) - st and p_op x st = match x with @@ -3948,68 +2672,6 @@ and p_op x st = | TOp.AnonRecdGet (info, n) -> p_byte 32 st; p_anonInfo info st; p_int n st | TOp.Goto _ | TOp.Label _ | TOp.Return -> failwith "unexpected backend construct in pickled TAST" -and p_op_new x st = - match x with - | TOp.UnionCase c -> - p_byte 0 st - p_ucref_new c st - | TOp.ExnConstr c -> p_byte 1 st; p_tcref "op" c st - | TOp.Tuple tupInfo -> - if evalTupInfoIsStruct tupInfo then - p_byte 29 st - else - p_byte 2 st - | TOp.Recd (a, b) -> p_byte 3 st; p_tup2 p_recdInfo (p_tcref "recd op") (a, b) st - | TOp.ValFieldSet a -> p_byte 4 st; p_rfref a st - | TOp.ValFieldGet a -> p_byte 5 st; p_rfref a st - | TOp.UnionCaseTagGet a -> p_byte 6 st; p_tcref "cnstr op" a st - | TOp.UnionCaseFieldGet (a, b) -> p_byte 7 st; p_tup2 p_ucref p_int (a, b) st - | TOp.UnionCaseFieldSet (a, b) -> p_byte 8 st; p_tup2 p_ucref p_int (a, b) st - | TOp.ExnFieldGet (a, b) -> p_byte 9 st; p_tup2 (p_tcref "exn op") p_int (a, b) st - | TOp.ExnFieldSet (a, b) -> p_byte 10 st; p_tup2 (p_tcref "exn op") p_int (a, b) st - | TOp.TupleFieldGet (tupInfo, a) -> - if evalTupInfoIsStruct tupInfo then - p_byte 30 st; p_int a st - else - p_byte 11 st; p_int a st - | TOp.ILAsm (a, b) -> p_byte 12 st; p_tup2 (p_list p_ILInstr) p_tys (a, b) st - | TOp.RefAddrGet _ -> p_byte 13 st - | TOp.UnionCaseProof a -> p_byte 14 st; p_ucref a st - | TOp.Coerce -> p_byte 15 st - | TOp.TraitCall b -> p_byte 16 st; p_trait b st - | TOp.LValueOp (a, b) -> p_byte 17 st; p_tup2 p_lval_op_kind (p_vref "lval") (a, b) st - | TOp.ILCall (a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) - -> p_byte 18 st; p_tup11 p_bool p_bool p_bool p_bool p_vrefFlags p_bool p_bool p_ILMethodRef p_tys p_tys p_tys (a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) st - | TOp.Array -> p_byte 19 st - | TOp.While _ -> p_byte 20 st - | TOp.IntegerForLoop (_, _, dir) -> p_byte 21 st; p_int (match dir with FSharpForLoopUp -> 0 | CSharpForLoopUp -> 1 | FSharpForLoopDown -> 2) st - | TOp.Bytes bytes -> p_byte 22 st; p_bytes bytes st - | TOp.TryWith _ -> p_byte 23 st - | TOp.TryFinally _ -> p_byte 24 st - | TOp.ValFieldGetAddr (a, _) -> p_byte 25 st; p_rfref a st - | TOp.UInt16s arr -> p_byte 26 st; p_array p_uint16 arr st - | TOp.Reraise -> p_byte 27 st - | TOp.UnionCaseFieldGetAddr (a, b, _) -> p_byte 28 st; p_tup2 p_ucref p_int (a, b) st - // Note tag byte 29 is taken for struct tuples, see above - // Note tag byte 30 is taken for struct tuples, see above - (* 29: TOp.Tuple when evalTupInfoIsStruct tupInfo = true *) - (* 30: TOp.TupleFieldGet when evalTupInfoIsStruct tupInfo = true *) - | TOp.AnonRecd info -> p_byte 31 st; p_anonInfo info st - | TOp.AnonRecdGet (info, n) -> p_byte 32 st; p_anonInfo info st; p_int n st - | TOp.Goto _ | TOp.Label _ | TOp.Return -> failwith "unexpected backend construct in pickled TAST" - -and u_ucref_new st = - let tcref, caseName, binding = - u_tup3 - u_tcref - u_string - (u_non_null_slot u_entity_spec_new) - st - - tcref.binding <- binding - UnionCaseRef(tcref, caseName) - - and u_op st = let tag = u_byte st match tag with @@ -4081,78 +2743,6 @@ and u_op st = TOp.AnonRecdGet (info, n) | _ -> ufailwith st "u_op" -and u_op_new st = - let tag = u_byte st - match tag with - | 0 -> let a = u_ucref_new st - TOp.UnionCase a - | 1 -> let a = u_tcref st - TOp.ExnConstr a - | 2 -> TOp.Tuple tupInfoRef - | 3 -> let b = u_tcref st - TOp.Recd (RecdExpr, b) - | 4 -> let a = u_rfref st - TOp.ValFieldSet a - | 5 -> let a = u_rfref st - TOp.ValFieldGet a - | 6 -> let a = u_tcref st - TOp.UnionCaseTagGet a - | 7 -> let a = u_ucref st - let b = u_int st - TOp.UnionCaseFieldGet (a, b) - | 8 -> let a = u_ucref st - let b = u_int st - TOp.UnionCaseFieldSet (a, b) - | 9 -> let a = u_tcref st - let b = u_int st - TOp.ExnFieldGet (a, b) - | 10 -> let a = u_tcref st - let b = u_int st - TOp.ExnFieldSet (a, b) - | 11 -> let a = u_int st - TOp.TupleFieldGet (tupInfoRef, a) - | 12 -> let a = (u_list u_ILInstr) st - let b = u_tys st - TOp.ILAsm (a, b) - | 13 -> TOp.RefAddrGet false // ok to set the 'readonly' flag on these operands to false on re-read since the flag is only used for typechecking purposes - | 14 -> let a = u_ucref st - TOp.UnionCaseProof a - | 15 -> TOp.Coerce - | 16 -> let a = u_trait st - TOp.TraitCall a - | 17 -> let a = u_lval_op_kind st - let b = u_vref st - TOp.LValueOp (a, b) - | 18 -> let a1, a2, a3, a4, a5, a7, a8, a9 = (u_tup8 u_bool u_bool u_bool u_bool u_vrefFlags u_bool u_bool u_ILMethodRef) st - let b = u_tys st - let c = u_tys st - let d = u_tys st - TOp.ILCall (a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) - | 19 -> TOp.Array - | 20 -> TOp.While (DebugPointAtWhile.No, NoSpecialWhileLoopMarker) - | 21 -> let dir = match u_int st with 0 -> FSharpForLoopUp | 1 -> CSharpForLoopUp | 2 -> FSharpForLoopDown | _ -> failwith "unknown for loop" - TOp.IntegerForLoop (DebugPointAtFor.No, DebugPointAtInOrTo.No, dir) - | 22 -> TOp.Bytes (u_bytes st) - | 23 -> TOp.TryWith (DebugPointAtTry.No, DebugPointAtWith.No) - | 24 -> TOp.TryFinally (DebugPointAtTry.No, DebugPointAtFinally.No) - | 25 -> let a = u_rfref st - TOp.ValFieldGetAddr (a, false) - | 26 -> TOp.UInt16s (u_array u_uint16 st) - | 27 -> TOp.Reraise - | 28 -> let a = u_ucref st - let b = u_int st - TOp.UnionCaseFieldGetAddr (a, b, false) - | 29 -> TOp.Tuple tupInfoStruct - | 30 -> let a = u_int st - TOp.TupleFieldGet (tupInfoStruct, a) - | 31 -> let info = u_anonInfo st - TOp.AnonRecd info - | 32 -> let info = u_anonInfo st - let n = u_int st - TOp.AnonRecdGet (info, n) - | _ -> ufailwith st "u_op" - - and p_expr expr st = match expr with | Expr.Link e -> p_expr e.Value st From c053c70087df9c96660ca70f5014e7abd66c9605 Mon Sep 17 00:00:00 2001 From: Petr Date: Mon, 3 Mar 2025 17:22:08 +0100 Subject: [PATCH 7/8] Fantomas --- .../Driver/ReuseTcResults/TcResultsPickle.fs | 1453 +++++++++-------- 1 file changed, 759 insertions(+), 694 deletions(-) diff --git a/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs b/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs index ef330c9f0f3..e61c96c9d74 100644 --- a/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs +++ b/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs @@ -25,25 +25,24 @@ open Internal.Utilities.Collections open Internal.Utilities.Library open Internal.Utilities.Library.Extras - - type TcSharedData = { TopAttribs: TopAttribs } // pickling let p_stamp = p_int64 -let p_stamp_map pv = p_Map p_stamp pv +let p_stamp_map pv = p_Map p_stamp pv let p_non_null_slot f (x: 'a | null) st = match x with | null -> p_byte 0 st - | h -> p_byte 1 st; f h st + | h -> + p_byte 1 st + f h st -let p_ILTypeDefAdditionalFlags (x: ILTypeDefAdditionalFlags) st = - p_int32 (int x) st +let p_ILTypeDefAdditionalFlags (x: ILTypeDefAdditionalFlags) st = p_int32 (int x) st -let p_ILTypeDef (x: ILTypeDef) st = +let p_ILTypeDef (x: ILTypeDef) st = p_string x.Name st //p_type_attributes x.Attributes //p_il_type_def_layout x.Layout @@ -56,40 +55,40 @@ let p_ILTypeDef (x: ILTypeDef) st = //x.Events //x.Properties p_ILTypeDefAdditionalFlags x.Flags st - //x.SecurityDeclsStored - //x.CustomAttrsStored - //p_il - //p_int32 x.MetadataIndex st +//x.SecurityDeclsStored +//x.CustomAttrsStored +//p_il +//p_int32 x.MetadataIndex st let p_tyar_spec_data_new (x: Typar) st = p_tup6 - p_ident - p_attribs - p_int64 - p_tyar_constraints - p_xmldoc - p_stamp - (x.typar_id, x.Attribs, int64 x.typar_flags.PickledBits, x.Constraints, x.XmlDoc, x.Stamp) st + p_ident + p_attribs + p_int64 + p_tyar_constraints + p_xmldoc + p_stamp + (x.typar_id, x.Attribs, int64 x.typar_flags.PickledBits, x.Constraints, x.XmlDoc, x.Stamp) + st let p_tyar_spec_new (x: Typar) st = //Disabled, workaround for bug 2721: if x.Rigidity <> TyparRigidity.Rigid then warning(Error(sprintf "p_tyar_spec: typar#%d is not rigid" x.Stamp, x.Range)) - if x.IsFromError then warning(Error((0, "p_tyar_spec: from error"), x.Range)) + if x.IsFromError then + warning (Error((0, "p_tyar_spec: from error"), x.Range)) + p_osgn_decl st.otypars p_tyar_spec_data_new x st let p_tyar_specs_new = (p_list p_tyar_spec_new) let rec p_ty_new (ty: TType) st : unit = match ty with - | TType_tuple (tupInfo, l) -> + | TType_tuple(tupInfo, l) -> p_byte 0 st - p_tup2 - p_tup_info - p_tys_new - (tupInfo, l) - st + p_tup2 p_tup_info p_tys_new (tupInfo, l) st - | TType_app (tyconRef, typeInstantiation, nullness) -> + | TType_app(tyconRef, typeInstantiation, nullness) -> p_byte 1 st + p_tup4 (p_tcref "app") p_tys_new @@ -98,160 +97,238 @@ let rec p_ty_new (ty: TType) st : unit = (tyconRef, typeInstantiation, nullness, tyconRef.binding) st - | TType_fun (domainType, rangeType, nullness) -> + | TType_fun(domainType, rangeType, nullness) -> p_byte 2 st p_ty_new domainType st p_ty_new rangeType st p_nullness nullness st - | TType_var (typar, nullness) -> + | TType_var(typar, nullness) -> p_byte 3 st - p_tup4 - p_tpref - p_nullness - (p_option p_ty_new) - p_stamp - (typar, nullness, typar.Solution, typar.Stamp) - st + p_tup4 p_tpref p_nullness (p_option p_ty_new) p_stamp (typar, nullness, typar.Solution, typar.Stamp) st - | TType_forall (tps, r) -> + | TType_forall(tps, r) -> p_byte 4 st - p_tup2 - p_typars - p_ty_new - (tps, r) - st + p_tup2 p_typars p_ty_new (tps, r) st | TType_measure unt -> p_byte 5 st p_measure_expr unt st - | TType_ucase (uc, tinst) -> + | TType_ucase(uc, tinst) -> p_byte 6 st - p_tup2 - p_ucref - p_tys_new - (uc, tinst) - st + p_tup2 p_ucref p_tys_new (uc, tinst) st - | TType_anon (anonInfo, l) -> - p_byte 7 st - p_tup2 - p_anonInfo - p_tys_new - (anonInfo, l) - st + | TType_anon(anonInfo, l) -> + p_byte 7 st + p_tup2 p_anonInfo p_tys_new (anonInfo, l) st -and p_tys_new l = +and p_tys_new l = let _count = l.Length p_list p_ty_new l and p_expr_new (expr: Expr) st = match expr with - | Expr.Link e -> p_byte 0 st; p_expr_new e.Value st - | Expr.Const (x, m, ty) -> p_byte 1 st; p_tup3 p_const p_dummy_range p_ty_new (x, m, ty) st - | Expr.Val (a, b, m) -> + | Expr.Link e -> + p_byte 0 st + p_expr_new e.Value st + | Expr.Const(x, m, ty) -> + p_byte 1 st + p_tup3 p_const p_dummy_range p_ty_new (x, m, ty) st + | Expr.Val(a, b, m) -> p_byte 2 st - p_tup4 - p_vref_new - p_vrefFlags - p_dummy_range - (p_non_null_slot p_Val_new) - (a, b, m, a.binding) + p_tup4 p_vref_new p_vrefFlags p_dummy_range (p_non_null_slot p_Val_new) (a, b, m, a.binding) st + | Expr.Op(a, b, c, d) -> + p_byte 3 st + p_tup4 p_op_new p_tys_new p_exprs_new p_dummy_range (a, b, c, d) st + | Expr.Sequential(a, b, c, d) -> + p_byte 4 st + + p_tup4 + p_expr_new + p_expr_new + p_int + p_dummy_range + (a, + b, + (match c with + | NormalSeq -> 0 + | ThenDoSeq -> 1), + d) st - | Expr.Op (a, b, c, d) -> p_byte 3 st; p_tup4 p_op_new p_tys_new p_exprs_new p_dummy_range (a, b, c, d) st - | Expr.Sequential (a, b, c, d) -> p_byte 4 st; p_tup4 p_expr_new p_expr_new p_int p_dummy_range (a, b, (match c with NormalSeq -> 0 | ThenDoSeq -> 1), d) st - | Expr.Lambda (_, a1, b0, b1, c, d, e) -> p_byte 5 st; p_tup6 (p_option p_Val) (p_option p_Val) p_Vals p_expr_new p_dummy_range p_ty_new (a1, b0, b1, c, d, e) st - | Expr.TyLambda (_, b, c, d, e) -> p_byte 6 st; p_tup4 p_tyar_specs_new p_expr_new p_dummy_range p_ty_new (b, c, d, e) st - | Expr.App (funcExpr, formalType, typeArgs, args, range) -> + | Expr.Lambda(_, a1, b0, b1, c, d, e) -> + p_byte 5 st + p_tup6 (p_option p_Val) (p_option p_Val) p_Vals p_expr_new p_dummy_range p_ty_new (a1, b0, b1, c, d, e) st + | Expr.TyLambda(_, b, c, d, e) -> + p_byte 6 st + p_tup4 p_tyar_specs_new p_expr_new p_dummy_range p_ty_new (b, c, d, e) st + | Expr.App(funcExpr, formalType, typeArgs, args, range) -> p_byte 7 st - + p_expr_new funcExpr st p_ty_new formalType st p_tys_new typeArgs st p_exprs_new args st p_dummy_range range st - | Expr.LetRec (a, b, c, _) -> p_byte 8 st; p_tup3 p_binds p_expr_new p_dummy_range (a, b, c) st - | Expr.Let (a, b, c, _) -> p_byte 9 st; p_tup3 p_bind p_expr_new p_dummy_range (a, b, c) st - | Expr.Match (_, a, b, c, d, e) -> p_byte 10 st; p_tup5 p_dummy_range p_dtree p_targets p_dummy_range p_ty_new (a, b, c, d, e) st - | Expr.Obj (_, b, c, d, e, f, g) -> p_byte 11 st; p_tup6 p_ty_new (p_option p_Val) p_expr_new p_methods p_intfs p_dummy_range (b, c, d, e, f, g) st - | Expr.StaticOptimization (a, b, c, d) -> p_byte 12 st; p_tup4 p_constraints p_expr_new p_expr_new p_dummy_range (a, b, c, d) st - | Expr.TyChoose (a, b, c) -> p_byte 13 st; p_tup3 p_tyar_specs_new p_expr_new p_dummy_range (a, b, c) st - | Expr.Quote (ast, _, _, m, ty) -> p_byte 14 st; p_tup3 p_expr_new p_dummy_range p_ty_new (ast, m, ty) st - | Expr.WitnessArg (traitInfo, m) -> p_byte 15 st; p_trait traitInfo st; p_dummy_range m st - | Expr.DebugPoint (_, innerExpr) -> + | Expr.LetRec(a, b, c, _) -> + p_byte 8 st + p_tup3 p_binds p_expr_new p_dummy_range (a, b, c) st + | Expr.Let(a, b, c, _) -> + p_byte 9 st + p_tup3 p_bind p_expr_new p_dummy_range (a, b, c) st + | Expr.Match(_, a, b, c, d, e) -> + p_byte 10 st + p_tup5 p_dummy_range p_dtree p_targets p_dummy_range p_ty_new (a, b, c, d, e) st + | Expr.Obj(_, b, c, d, e, f, g) -> + p_byte 11 st + p_tup6 p_ty_new (p_option p_Val) p_expr_new p_methods p_intfs p_dummy_range (b, c, d, e, f, g) st + | Expr.StaticOptimization(a, b, c, d) -> + p_byte 12 st + p_tup4 p_constraints p_expr_new p_expr_new p_dummy_range (a, b, c, d) st + | Expr.TyChoose(a, b, c) -> + p_byte 13 st + p_tup3 p_tyar_specs_new p_expr_new p_dummy_range (a, b, c) st + | Expr.Quote(ast, _, _, m, ty) -> + p_byte 14 st + p_tup3 p_expr_new p_dummy_range p_ty_new (ast, m, ty) st + | Expr.WitnessArg(traitInfo, m) -> + p_byte 15 st + p_trait traitInfo st + p_dummy_range m st + | Expr.DebugPoint(_, innerExpr) -> p_byte 16 st p_expr_new innerExpr st - + and p_exprs_new = p_list p_expr_new and p_ucref_new (UnionCaseRef(a, b)) st = - p_tup3 - (p_tcref "ucref") - p_string - (p_non_null_slot p_entity_spec_new) - (a, b, a.binding) - st + p_tup3 (p_tcref "ucref") p_string (p_non_null_slot p_entity_spec_new) (a, b, a.binding) st and p_op_new x st = match x with - | TOp.UnionCase c -> + | TOp.UnionCase c -> p_byte 0 st p_ucref_new c st - | TOp.ExnConstr c -> p_byte 1 st; p_tcref "op" c st - | TOp.Tuple tupInfo -> - if evalTupInfoIsStruct tupInfo then - p_byte 29 st - else - p_byte 2 st - | TOp.Recd (a, b) -> p_byte 3 st; p_tup2 p_recdInfo (p_tcref "recd op") (a, b) st - | TOp.ValFieldSet a -> p_byte 4 st; p_rfref a st - | TOp.ValFieldGet a -> p_byte 5 st; p_rfref a st - | TOp.UnionCaseTagGet a -> p_byte 6 st; p_tcref "cnstr op" a st - | TOp.UnionCaseFieldGet (a, b) -> p_byte 7 st; p_tup2 p_ucref p_int (a, b) st - | TOp.UnionCaseFieldSet (a, b) -> p_byte 8 st; p_tup2 p_ucref p_int (a, b) st - | TOp.ExnFieldGet (a, b) -> p_byte 9 st; p_tup2 (p_tcref "exn op") p_int (a, b) st - | TOp.ExnFieldSet (a, b) -> p_byte 10 st; p_tup2 (p_tcref "exn op") p_int (a, b) st - | TOp.TupleFieldGet (tupInfo, a) -> - if evalTupInfoIsStruct tupInfo then - p_byte 30 st; p_int a st - else - p_byte 11 st; p_int a st - | TOp.ILAsm (a, b) -> p_byte 12 st; p_tup2 (p_list p_ILInstr) p_tys (a, b) st - | TOp.RefAddrGet _ -> p_byte 13 st - | TOp.UnionCaseProof a -> p_byte 14 st; p_ucref a st - | TOp.Coerce -> p_byte 15 st - | TOp.TraitCall b -> p_byte 16 st; p_trait b st - | TOp.LValueOp (a, b) -> p_byte 17 st; p_tup2 p_lval_op_kind (p_vref "lval") (a, b) st - | TOp.ILCall (a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) - -> p_byte 18 st; p_tup11 p_bool p_bool p_bool p_bool p_vrefFlags p_bool p_bool p_ILMethodRef p_tys p_tys p_tys (a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) st - | TOp.Array -> p_byte 19 st - | TOp.While _ -> p_byte 20 st - | TOp.IntegerForLoop (_, _, dir) -> p_byte 21 st; p_int (match dir with FSharpForLoopUp -> 0 | CSharpForLoopUp -> 1 | FSharpForLoopDown -> 2) st - | TOp.Bytes bytes -> p_byte 22 st; p_bytes bytes st - | TOp.TryWith _ -> p_byte 23 st - | TOp.TryFinally _ -> p_byte 24 st - | TOp.ValFieldGetAddr (a, _) -> p_byte 25 st; p_rfref a st - | TOp.UInt16s arr -> p_byte 26 st; p_array p_uint16 arr st - | TOp.Reraise -> p_byte 27 st - | TOp.UnionCaseFieldGetAddr (a, b, _) -> p_byte 28 st; p_tup2 p_ucref p_int (a, b) st - // Note tag byte 29 is taken for struct tuples, see above - // Note tag byte 30 is taken for struct tuples, see above + | TOp.ExnConstr c -> + p_byte 1 st + p_tcref "op" c st + | TOp.Tuple tupInfo -> + if evalTupInfoIsStruct tupInfo then + p_byte 29 st + else + p_byte 2 st + | TOp.Recd(a, b) -> + p_byte 3 st + p_tup2 p_recdInfo (p_tcref "recd op") (a, b) st + | TOp.ValFieldSet a -> + p_byte 4 st + p_rfref a st + | TOp.ValFieldGet a -> + p_byte 5 st + p_rfref a st + | TOp.UnionCaseTagGet a -> + p_byte 6 st + p_tcref "cnstr op" a st + | TOp.UnionCaseFieldGet(a, b) -> + p_byte 7 st + p_tup2 p_ucref p_int (a, b) st + | TOp.UnionCaseFieldSet(a, b) -> + p_byte 8 st + p_tup2 p_ucref p_int (a, b) st + | TOp.ExnFieldGet(a, b) -> + p_byte 9 st + p_tup2 (p_tcref "exn op") p_int (a, b) st + | TOp.ExnFieldSet(a, b) -> + p_byte 10 st + p_tup2 (p_tcref "exn op") p_int (a, b) st + | TOp.TupleFieldGet(tupInfo, a) -> + if evalTupInfoIsStruct tupInfo then + p_byte 30 st + p_int a st + else + p_byte 11 st + p_int a st + | TOp.ILAsm(a, b) -> + p_byte 12 st + p_tup2 (p_list p_ILInstr) p_tys (a, b) st + | TOp.RefAddrGet _ -> p_byte 13 st + | TOp.UnionCaseProof a -> + p_byte 14 st + p_ucref a st + | TOp.Coerce -> p_byte 15 st + | TOp.TraitCall b -> + p_byte 16 st + p_trait b st + | TOp.LValueOp(a, b) -> + p_byte 17 st + p_tup2 p_lval_op_kind (p_vref "lval") (a, b) st + | TOp.ILCall(a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) -> + p_byte 18 st + + p_tup11 + p_bool + p_bool + p_bool + p_bool + p_vrefFlags + p_bool + p_bool + p_ILMethodRef + p_tys + p_tys + p_tys + (a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) + st + | TOp.Array -> p_byte 19 st + | TOp.While _ -> p_byte 20 st + | TOp.IntegerForLoop(_, _, dir) -> + p_byte 21 st + + p_int + (match dir with + | FSharpForLoopUp -> 0 + | CSharpForLoopUp -> 1 + | FSharpForLoopDown -> 2) + st + | TOp.Bytes bytes -> + p_byte 22 st + p_bytes bytes st + | TOp.TryWith _ -> p_byte 23 st + | TOp.TryFinally _ -> p_byte 24 st + | TOp.ValFieldGetAddr(a, _) -> + p_byte 25 st + p_rfref a st + | TOp.UInt16s arr -> + p_byte 26 st + p_array p_uint16 arr st + | TOp.Reraise -> p_byte 27 st + | TOp.UnionCaseFieldGetAddr(a, b, _) -> + p_byte 28 st + p_tup2 p_ucref p_int (a, b) st + // Note tag byte 29 is taken for struct tuples, see above + // Note tag byte 30 is taken for struct tuples, see above (* 29: TOp.Tuple when evalTupInfoIsStruct tupInfo = true *) (* 30: TOp.TupleFieldGet when evalTupInfoIsStruct tupInfo = true *) - | TOp.AnonRecd info -> p_byte 31 st; p_anonInfo info st - | TOp.AnonRecdGet (info, n) -> p_byte 32 st; p_anonInfo info st; p_int n st - | TOp.Goto _ | TOp.Label _ | TOp.Return -> failwith "unexpected backend construct in pickled TAST" + | TOp.AnonRecd info -> + p_byte 31 st + p_anonInfo info st + | TOp.AnonRecdGet(info, n) -> + p_byte 32 st + p_anonInfo info st + p_int n st + | TOp.Goto _ + | TOp.Label _ + | TOp.Return -> failwith "unexpected backend construct in pickled TAST" and p_entity_spec_data_new (x: Entity) st = p_tyar_specs_new (x.entity_typars.Force(x.entity_range)) st p_string x.entity_logical_name st p_option p_string x.EntityCompiledName st - p_range x.entity_range st + p_range x.entity_range st p_stamp x.entity_stamp st p_option p_pubpath x.entity_pubpath st p_access x.Accessibility st - p_access x.TypeReprAccessibility st + p_access x.TypeReprAccessibility st p_attribs x.entity_attribs st let _ = p_tycon_repr_new x.entity_tycon_repr st p_option p_ty_new x.TypeAbbrev st @@ -262,12 +339,14 @@ and p_entity_spec_data_new (x: Entity) st = p_option p_cpath x.entity_cpath st p_maybe_lazy p_modul_typ_new x.entity_modul_type st p_exnc_repr x.ExceptionInfo st + if st.oInMem then p_used_space1 (p_xmldoc x.XmlDoc) st else p_space 1 () st -and p_entity_spec_new x st = p_osgn_decl st.oentities p_entity_spec_data_new x st +and p_entity_spec_new x st = + p_osgn_decl st.oentities p_entity_spec_data_new x st and p_ValData_new x st = p_string x.val_logical_name st @@ -286,50 +365,46 @@ and p_ValData_new x st = p_access x.Accessibility st p_parentref x.TryDeclaringEntity st p_option p_const x.LiteralValue st + if st.oInMem then p_used_space1 (p_xmldoc x.XmlDoc) st else p_space 1 () st -and p_Val_new x st = - p_osgn_decl st.ovals p_ValData_new x st +and p_Val_new x st = p_osgn_decl st.ovals p_ValData_new x st and p_modul_typ_new (x: ModuleOrNamespaceType) st = - p_tup3 - p_istype - (p_qlist p_Val_new) - (p_qlist p_entity_spec_new) - (x.ModuleOrNamespaceKind, x.AllValsAndMembers, x.AllEntities) - st + p_tup3 p_istype (p_qlist p_Val_new) (p_qlist p_entity_spec_new) (x.ModuleOrNamespaceKind, x.AllValsAndMembers, x.AllEntities) st and p_tcaug_new (p: TyconAugmentation) st = p_tup9 - (p_option (p_tup2 (p_vref "compare_obj") (p_vref "compare"))) - (p_option (p_vref "compare_withc")) - (p_option (p_tup3 (p_vref "hash_obj") (p_vref "hash_withc") (p_vref "equals_withc"))) - (p_option (p_tup2 (p_vref "hash") (p_vref "equals"))) - (p_list (p_tup2 p_string (p_vref "adhoc"))) - (p_list (p_tup3 p_ty_new p_bool p_dummy_range)) - (p_option p_ty_new) - p_bool - (p_space 1) - (p.tcaug_compare, - p.tcaug_compare_withc, - p.tcaug_hash_and_equals_withc |> Option.map (fun (v1, v2, v3, _) -> (v1, v2, v3)), - p.tcaug_equals, - (p.tcaug_adhoc_list - |> ResizeArray.toList - // Explicit impls of interfaces only get kept in the adhoc list - // in order to get check the well-formedness of an interface. - // Keeping them across assembly boundaries is not valid, because relinking their ValRefs - // does not work correctly (they may get incorrectly relinked to a default member) - |> List.filter (fun (isExplicitImpl, _) -> not isExplicitImpl) - |> List.map (fun (_, vref) -> vref.LogicalName, vref)), - p.tcaug_interfaces, - p.tcaug_super, - p.tcaug_abstract, - space) st - + (p_option (p_tup2 (p_vref "compare_obj") (p_vref "compare"))) + (p_option (p_vref "compare_withc")) + (p_option (p_tup3 (p_vref "hash_obj") (p_vref "hash_withc") (p_vref "equals_withc"))) + (p_option (p_tup2 (p_vref "hash") (p_vref "equals"))) + (p_list (p_tup2 p_string (p_vref "adhoc"))) + (p_list (p_tup3 p_ty_new p_bool p_dummy_range)) + (p_option p_ty_new) + p_bool + (p_space 1) + (p.tcaug_compare, + p.tcaug_compare_withc, + p.tcaug_hash_and_equals_withc + |> Option.map (fun (v1, v2, v3, _) -> (v1, v2, v3)), + p.tcaug_equals, + (p.tcaug_adhoc_list + |> ResizeArray.toList + // Explicit impls of interfaces only get kept in the adhoc list + // in order to get check the well-formedness of an interface. + // Keeping them across assembly boundaries is not valid, because relinking their ValRefs + // does not work correctly (they may get incorrectly relinked to a default member) + |> List.filter (fun (isExplicitImpl, _) -> not isExplicitImpl) + |> List.map (fun (_, vref) -> vref.LogicalName, vref)), + p.tcaug_interfaces, + p.tcaug_super, + p.tcaug_abstract, + space) + st and p_ccu_data (x: CcuData) st = p_option p_string x.FileName st @@ -345,25 +420,20 @@ and p_ccu_data (x: CcuData) st = p_entity_spec_data_new x.Contents st and p_ccuref_new (x: CcuThunk) st = - p_tup2 - p_ccu_data - p_string - (x.target, x.name) - st + p_tup2 p_ccu_data p_string (x.target, x.name) st and p_nleref_new (x: NonLocalEntityRef) st = - let (NonLocalEntityRef (ccu, strings)) = x - p_tup2 - p_ccuref_new - (p_array p_string) - (ccu, strings) - st - + let (NonLocalEntityRef(ccu, strings)) = x + p_tup2 p_ccuref_new (p_array p_string) (ccu, strings) st and p_tcref_new (x: EntityRef) st = match x with - | ERefLocal x -> p_byte 0 st; p_local_item_ref "tcref" st.oentities x st - | ERefNonLocal x -> p_byte 1 st; p_nleref_new x st + | ERefLocal x -> + p_byte 0 st + p_local_item_ref "tcref" st.oentities x st + | ERefNonLocal x -> + p_byte 1 st + p_nleref_new x st and p_nonlocal_val_ref_new (nlv: NonLocalValOrMemberRef) st = let a = nlv.EnclosingEntity @@ -374,17 +444,22 @@ and p_nonlocal_val_ref_new (nlv: NonLocalValOrMemberRef) st = p_bool pkey.MemberIsOverride st p_string pkey.LogicalName st p_int pkey.TotalArgCount st + let isStructThisArgPos = match key.TypeForLinkage with | None -> false | Some ty -> checkForInRefStructThisArg st ty - p_option p_ty_new key.TypeForLinkage st + p_option p_ty_new key.TypeForLinkage st and p_vref_new (x: ValRef) st = match x with - | VRefLocal x -> p_byte 0 st; p_local_item_ref "valref" st.ovals x st - | VRefNonLocal x -> p_byte 1 st; p_nonlocal_val_ref_new x st + | VRefLocal x -> + p_byte 0 st + p_local_item_ref "valref" st.ovals x st + | VRefNonLocal x -> + p_byte 1 st + p_nonlocal_val_ref_new x st and p_bind_new (TBind(a, b, _)) st = p_tup2 p_Val_new p_expr_new (a, b) st @@ -393,40 +468,51 @@ and p_binding (x: ModuleOrNamespaceBinding) st = | ModuleOrNamespaceBinding.Binding binding -> p_byte 0 st p_bind binding st - | ModuleOrNamespaceBinding.Module (moduleOrNamespace, moduleOrNamespaceContents) -> + | ModuleOrNamespaceBinding.Module(moduleOrNamespace, moduleOrNamespaceContents) -> p_byte 1 st - p_tup2 - p_entity_spec_new - p_module_or_namespace_contents - (moduleOrNamespace, moduleOrNamespaceContents) - st + p_tup2 p_entity_spec_new p_module_or_namespace_contents (moduleOrNamespace, moduleOrNamespaceContents) st and p_tycon_repr_new (x: TyconRepresentation) 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. match x with // Records - | TFSharpTyconRepr { fsobjmodel_rfields = fs; fsobjmodel_kind = TFSharpRecord } -> + | TFSharpTyconRepr { + fsobjmodel_rfields = fs + fsobjmodel_kind = TFSharpRecord + } -> p_byte 1 st p_byte 0 st p_rfield_table fs st false // Unions without static fields - | TFSharpTyconRepr { fsobjmodel_cases = x; fsobjmodel_kind = TFSharpUnion; fsobjmodel_rfields = fs } when fs.FieldsByIndex.Length = 0 -> + | TFSharpTyconRepr { + fsobjmodel_cases = x + fsobjmodel_kind = TFSharpUnion + fsobjmodel_rfields = fs + } when fs.FieldsByIndex.Length = 0 -> p_byte 1 st p_byte 1 st p_array p_unioncase_spec x.CasesTable.CasesByIndex st false // Unions with static fields, added to format - | TFSharpTyconRepr ({ fsobjmodel_cases = cases; fsobjmodel_kind = TFSharpUnion } as r) -> + | TFSharpTyconRepr({ + fsobjmodel_cases = cases + fsobjmodel_kind = TFSharpUnion + } as r) -> if st.oglobals.compilingFSharpCore then let fields = r.fsobjmodel_rfields.FieldsByIndex let firstFieldRange = fields[0].DefinitionRange - let allFieldsText = fields |> Array.map (fun f -> f.LogicalName) |> String.concat System.Environment.NewLine - raise (Error(FSComp.SR.pickleFsharpCoreBackwardsCompatible("fields in union",allFieldsText), firstFieldRange)) - + + let allFieldsText = + fields + |> Array.map (fun f -> f.LogicalName) + |> String.concat System.Environment.NewLine + + raise (Error(FSComp.SR.pickleFsharpCoreBackwardsCompatible ("fields in union", allFieldsText), firstFieldRange)) + p_byte 2 st p_array p_unioncase_spec cases.CasesTable.CasesByIndex st p_tycon_objmodel_data r st @@ -438,13 +524,13 @@ and p_tycon_repr_new (x: TyconRepresentation) st = p_ILType ilTy st false - | TFSharpTyconRepr r -> + | TFSharpTyconRepr r -> p_byte 1 st p_byte 3 st p_tycon_objmodel_data r st false - | TMeasureableRepr ty -> + | TMeasureableRepr ty -> p_byte 1 st p_byte 4 st p_ty ty st @@ -464,7 +550,7 @@ and p_tycon_repr_new (x: TyconRepresentation) st = // Pickle generated type definitions as a TAsmRepr p_byte 1 st p_byte 2 st - p_ILType (mkILBoxedType(ILTypeSpec.Create(TypeProviders.GetILTypeRefOfProvidedType(info.ProvidedType, range0), []))) st + p_ILType (mkILBoxedType (ILTypeSpec.Create(TypeProviders.GetILTypeRefOfProvidedType(info.ProvidedType, range0), []))) st true | TProvidedNamespaceRepr _ -> @@ -472,7 +558,7 @@ and p_tycon_repr_new (x: TyconRepresentation) st = false #endif - | TILObjectRepr (TILObjectReprData (scope, nesting, td)) -> + | TILObjectRepr(TILObjectReprData(scope, nesting, td)) -> p_byte 5 st p_ILScopeRef scope st (p_list p_ILTypeDef) nesting st @@ -484,57 +570,36 @@ and p_qualified_name_of_file qualifiedNameOfFile st = p_ident ident st and p_pragma pragma st = - let (ScopedPragma.WarningOff (range, warningNumber)) = pragma - p_tup2 - p_range - p_int - (range, warningNumber) - st + let (ScopedPragma.WarningOff(range, warningNumber)) = pragma + p_tup2 p_range p_int (range, warningNumber) st -and p_pragmas x st = - p_list p_pragma x st +and p_pragmas x st = p_list p_pragma x st -and p_long_ident (x: LongIdent) st = - p_list p_ident x st +and p_long_ident (x: LongIdent) st = p_list p_ident x st -and p_trivia (x: SyntaxTrivia.IdentTrivia) st = - pfailwith st (nameof p_trivia) +and p_trivia (x: SyntaxTrivia.IdentTrivia) st = pfailwith st (nameof p_trivia) and p_syn_long_ident (x: SynLongIdent) st = - let (SynLongIdent (id, dotRanges, trivia)) = x - p_tup3 - p_long_ident - (p_list p_range) - (p_list (p_option p_trivia)) - (id, dotRanges, trivia) - st + let (SynLongIdent(id, dotRanges, trivia)) = x + p_tup3 p_long_ident (p_list p_range) (p_list (p_option p_trivia)) (id, dotRanges, trivia) st -and p_syn_type (x: SynType) st = - pfailwith st (nameof p_syn_type) +and p_syn_type (x: SynType) st = pfailwith st (nameof p_syn_type) and p_syn_open_decl_target (x: SynOpenDeclTarget) st = match x with - | SynOpenDeclTarget.ModuleOrNamespace (longId, range)-> + | SynOpenDeclTarget.ModuleOrNamespace(longId, range) -> p_byte 0 st - p_tup2 - p_syn_long_ident - p_range - (longId, range) - st - | SynOpenDeclTarget.Type (typeName, range) -> + p_tup2 p_syn_long_ident p_range (longId, range) st + | SynOpenDeclTarget.Type(typeName, range) -> p_byte 1 st - p_tup2 - p_syn_type - p_range - (typeName, range) - st + p_tup2 p_syn_type p_range (typeName, range) st and p_tup_info (tupInfo: TupInfo) st = let (TupInfo.Const c) = tupInfo p_bool c st and p_nullness (nullness: Nullness) st = - match nullness.Evaluate() with + match nullness.Evaluate() with | NullnessInfo.WithNull -> p_byte 0 st | NullnessInfo.WithoutNull -> p_byte 1 st | NullnessInfo.AmbivalentToNull -> p_byte 2 st @@ -543,28 +608,21 @@ and p_typars = p_list p_tpref and p_module_or_namespace_contents (x: ModuleOrNamespaceContents) st = match x with - | TMDefs defs -> + | TMDefs defs -> p_byte 0 st p_list p_module_or_namespace_contents defs st | TMDefOpens openDecls -> p_byte 1 st p_list p_open_decl openDecls st - | TMDefLet (binding, range) -> + | TMDefLet(binding, range) -> p_byte 2 st - p_tup2 - p_bind_new - p_range - (binding, range) - st - | TMDefDo (expr, range) -> + p_tup2 p_bind_new p_range (binding, range) st + | TMDefDo(expr, range) -> p_byte 3 st - p_tup2 - p_expr_new - p_range - (expr, range) - st - | TMDefRec (isRec, opens, tycons, bindings, range) -> + p_tup2 p_expr_new p_range (expr, range) st + | TMDefRec(isRec, opens, tycons, bindings, range) -> p_byte 4 st + p_tup5 p_bool (p_list p_open_decl) @@ -577,11 +635,7 @@ and p_module_or_namespace_contents (x: ModuleOrNamespaceContents) st = and p_checked_impl_file_contents = p_module_or_namespace_contents and p_named_debug_point_key (x: NamedDebugPointKey) st = - p_tup2 - p_range - p_string - (x.Range, x.Name) - st + p_tup2 p_range p_string (x.Range, x.Name) st and p_named_debug_points = p_Map p_named_debug_point_key p_range @@ -599,15 +653,15 @@ and p_open_decl (x: OpenDeclaration) st = st and p_checked_impl_file file st = - let (CheckedImplFile ( - qualifiedNameOfFile, - pragmas, - signature, - contents, - hasExplicitEntryPoint, - isScript, - anonRecdTypeInfo, - namedDebugPointsForInlinedCode)) = file + let (CheckedImplFile(qualifiedNameOfFile, + pragmas, + signature, + contents, + hasExplicitEntryPoint, + isScript, + anonRecdTypeInfo, + namedDebugPointsForInlinedCode)) = + file p_qualified_name_of_file qualifiedNameOfFile st p_pragmas pragmas st @@ -700,16 +754,16 @@ let p_name_resolution_env (env: NameResolutionEnv) st = // eUnqualifiedEnclosingTypeInsts // ePatItems (p_list p_module_and_namespace) (env.eModulesAndNamespaces |> Map.toList) st - // eFullyQualifiedModulesAndNamespaces - // eFieldLabels - // eUnqualifiedRecordOrUnionTypeInsts - // eTyconsByAccessNames - // eFullyQualifiedTyconsByAccessNames - // eTyconsByDemangledNameAndArity - // eFullyQualifiedTyconsByDemangledNameAndArity - // eIndexedExtensionMembers - // eUnindexedExtensionMembers - // eTypars +// eFullyQualifiedModulesAndNamespaces +// eFieldLabels +// eUnqualifiedRecordOrUnionTypeInsts +// eTyconsByAccessNames +// eFullyQualifiedTyconsByAccessNames +// eTyconsByDemangledNameAndArity +// eFullyQualifiedTyconsByDemangledNameAndArity +// eIndexedExtensionMembers +// eUnindexedExtensionMembers +// eTypars let p_tc_env (tcEnv: TcEnv) (st: WriterState) = p_name_resolution_env tcEnv.eNameResEnv st @@ -731,7 +785,6 @@ let p_tc_env (tcEnv: TcEnv) (st: WriterState) = let p_tcs_root_sig (qualifiedNameOfFile, moduleOrNamespaceType) st = p_tup2 p_qualified_name_of_file p_modul_typ_new (qualifiedNameOfFile, moduleOrNamespaceType) st - // pickling top let pickleSharedData sharedData st = @@ -758,21 +811,21 @@ let pickleTcState (tcState: TcState) (st: WriterState) = let u_stamp = u_int64 -let u_stamp_map uv = u_Map u_stamp uv +let u_stamp_map uv = u_Map u_stamp uv let u_non_null_slot f st = let tag = u_byte st + match tag with | 0 -> Unchecked.defaultof<_> | 1 -> f st | n -> ufailwith st ("u_option: found number " + string n) - let u_ILTypeDefAdditionalFlags st : ILTypeDefAdditionalFlags = let i = u_int32 st enum i -let u_ILTypeDef st : ILTypeDef = +let u_ILTypeDef st : ILTypeDef = let name = u_string st let attributes = System.Reflection.TypeAttributes.Public let layout = ILTypeDefLayout.Auto @@ -788,9 +841,10 @@ let u_ILTypeDef st : ILTypeDef = let additionalFlags = u_ILTypeDefAdditionalFlags st let securityDeclsStored = ILSecurityDecls([||]) // TODO: fill this in - let customAttrsStored = ILAttributesStored.Given (ILAttributes.Empty) + let customAttrsStored = ILAttributesStored.Given(ILAttributes.Empty) - ILTypeDef(name, + ILTypeDef( + name, attributes, layout, implements, @@ -804,19 +858,32 @@ let u_ILTypeDef st : ILTypeDef = properties, additionalFlags, securityDeclsStored, - customAttrsStored) + customAttrsStored + ) let u_tyar_spec_data_new st = - let a, c, d, e, g, stamp = u_tup6 u_ident u_attribs u_int64 u_tyar_constraints u_xmldoc u_stamp st - { typar_id=a - typar_stamp=stamp - typar_flags=TyparFlags(int32 d) - typar_solution=None - typar_astype= Unchecked.defaultof<_> - typar_opt_data= - match g, e, c with - | doc, [], [] when doc.IsEmpty -> None - | _ -> Some { typar_il_name = None; typar_xmldoc = g; typar_constraints = e; typar_attribs = c;typar_is_contravariant = false } } + let a, c, d, e, g, stamp = + u_tup6 u_ident u_attribs u_int64 u_tyar_constraints u_xmldoc u_stamp st + + { + typar_id = a + typar_stamp = stamp + typar_flags = TyparFlags(int32 d) + typar_solution = None + typar_astype = Unchecked.defaultof<_> + typar_opt_data = + match g, e, c with + | doc, [], [] when doc.IsEmpty -> None + | _ -> + Some + { + typar_il_name = None + typar_xmldoc = g + typar_constraints = e + typar_attribs = c + typar_is_contravariant = false + } + } let u_tyar_spec_new st = u_osgn_decl st.itypars u_tyar_spec_data_new st @@ -825,254 +892,274 @@ let u_tyar_specs_new = u_list u_tyar_spec_new let rec u_ty_new st : TType = let tag = u_byte st + match tag with | 0 -> - let tupInfo, l = - u_tup2 - u_tup_info - u_tys_new - st - TType_tuple (tupInfo, l) + let tupInfo, l = u_tup2 u_tup_info u_tys_new st + TType_tuple(tupInfo, l) | 1 -> let tyconRef, typeInstantiation, nullness, binding = - u_tup4 - u_tcref - u_tys_new - u_nullness - (u_non_null_slot u_entity_spec_new) - st - + u_tup4 u_tcref u_tys_new u_nullness (u_non_null_slot u_entity_spec_new) st + tyconRef.binding <- binding - TType_app (tyconRef, typeInstantiation, nullness) + TType_app(tyconRef, typeInstantiation, nullness) | 2 -> - let (domainType, rangeType, nullness) = - u_tup3 - u_ty_new - u_ty_new - u_nullness - st - TType_fun (domainType, rangeType, nullness) + let (domainType, rangeType, nullness) = u_tup3 u_ty_new u_ty_new u_nullness st + TType_fun(domainType, rangeType, nullness) | 3 -> let (typar, nullness, solution, stamp) = - u_tup4 - u_tpref - u_nullness - (u_option u_ty_new) - u_stamp - st - + u_tup4 u_tpref u_nullness (u_option u_ty_new) u_stamp st + typar.typar_solution <- solution typar.typar_stamp <- stamp - TType_var (typar, nullness) + TType_var(typar, nullness) | 4 -> - let (tps, r) = - u_tup2 - u_typars - u_ty_new - st + let (tps, r) = u_tup2 u_typars u_ty_new st - TType_forall (tps, r) + TType_forall(tps, r) | 5 -> let unt = u_measure_expr st TType_measure unt | 6 -> - let uc, tinst = - u_tup2 - u_ucref - u_tys_new - st - TType_ucase (uc, tinst) + let uc, tinst = u_tup2 u_ucref u_tys_new st + TType_ucase(uc, tinst) | 7 -> - let anonInfo, l = - u_tup2 - u_anonInfo - u_tys_new - st - TType_anon (anonInfo, l) - | _ -> - ufailwith st (nameof u_ty_new) + let anonInfo, l = u_tup2 u_anonInfo u_tys_new st + TType_anon(anonInfo, l) + | _ -> ufailwith st (nameof u_ty_new) and u_tys_new = u_list u_ty_new and u_expr_new st : Expr = let tag = u_byte st + match tag with - | 0 -> let e = u_expr_new st - let r = ref e - Expr.Link r - | 1 -> let a = u_const st - let b = u_dummy_range st - let c = u_ty_new st - Expr.Const (a, b, c) - | 2 -> let valRef = u_vref_new st - let flags = u_vrefFlags st - let range = u_dummy_range st - let binding = (u_non_null_slot u_Val_new) st - - valRef.binding <- binding - let expr = Expr.Val (valRef, flags, range) - expr - | 3 -> let a = u_op_new st - let b = u_tys_new st - let c = u_exprs_new st - let d = u_dummy_range st - Expr.Op (a, b, c, d) - | 4 -> let a = u_expr_new st - let b = u_expr_new st - let c = u_int st - let d = u_dummy_range st - let dir = match c with 0 -> NormalSeq | 1 -> ThenDoSeq | _ -> ufailwith st "specialSeqFlag" - Expr.Sequential (a, b, dir, d) - | 5 -> let a0 = u_option u_Val st - let b0 = u_option u_Val st - let b1 = u_Vals st - let c = u_expr_new st - let d = u_dummy_range st - let e = u_ty_new st - Expr.Lambda (newUnique(), a0, b0, b1, c, d, e) - | 6 -> let b = u_tyar_specs_new st - let c = u_expr_new st - let d = u_dummy_range st - let e = u_ty_new st - Expr.TyLambda (newUnique(), b, c, d, e) - | 7 -> let a1 = u_expr_new st - let a2 = u_ty_new st - let b = u_tys_new st - let c = u_exprs_new st - let d = u_dummy_range st - let expr = Expr.App (a1, a2, b, c, d) - expr - | 8 -> let a = u_binds st - let b = u_expr_new st - let c = u_dummy_range st - Expr.LetRec (a, b, c, Construct.NewFreeVarsCache()) - | 9 -> let a = u_bind st - let b = u_expr_new st - let c = u_dummy_range st - Expr.Let (a, b, c, Construct.NewFreeVarsCache()) - | 10 -> let a = u_dummy_range st - let b = u_dtree st - let c = u_targets st - let d = u_dummy_range st - let e = u_ty_new st - Expr.Match (DebugPointAtBinding.NoneAtSticky, a, b, c, d, e) - | 11 -> let b = u_ty_new st - let c = (u_option u_Val) st - let d = u_expr_new st - let e = u_methods st - let f = u_intfs st - let g = u_dummy_range st - Expr.Obj (newUnique(), b, c, d, e, f, g) - | 12 -> let a = u_constraints st - let b = u_expr_new st - let c = u_expr_new st - let d = u_dummy_range st - Expr.StaticOptimization (a, b, c, d) - | 13 -> let a = u_tyar_specs_new st - let b = u_expr_new st - let c = u_dummy_range st - Expr.TyChoose (a, b, c) - | 14 -> let b = u_expr_new st - let c = u_dummy_range st - let d = u_ty_new st - Expr.Quote (b, ref None, false, c, d) // isFromQueryExpression=false - | 15 -> let traitInfo = u_trait st - let m = u_dummy_range st - Expr.WitnessArg (traitInfo, m) - | 16 -> let m = u_dummy_range st - let expr = u_expr_new st - Expr.DebugPoint (DebugPointAtLeafExpr.Yes m, expr) + | 0 -> + let e = u_expr_new st + let r = ref e + Expr.Link r + | 1 -> + let a = u_const st + let b = u_dummy_range st + let c = u_ty_new st + Expr.Const(a, b, c) + | 2 -> + let valRef = u_vref_new st + let flags = u_vrefFlags st + let range = u_dummy_range st + let binding = (u_non_null_slot u_Val_new) st + + valRef.binding <- binding + let expr = Expr.Val(valRef, flags, range) + expr + | 3 -> + let a = u_op_new st + let b = u_tys_new st + let c = u_exprs_new st + let d = u_dummy_range st + Expr.Op(a, b, c, d) + | 4 -> + let a = u_expr_new st + let b = u_expr_new st + let c = u_int st + let d = u_dummy_range st + + let dir = + match c with + | 0 -> NormalSeq + | 1 -> ThenDoSeq + | _ -> ufailwith st "specialSeqFlag" + + Expr.Sequential(a, b, dir, d) + | 5 -> + let a0 = u_option u_Val st + let b0 = u_option u_Val st + let b1 = u_Vals st + let c = u_expr_new st + let d = u_dummy_range st + let e = u_ty_new st + Expr.Lambda(newUnique (), a0, b0, b1, c, d, e) + | 6 -> + let b = u_tyar_specs_new st + let c = u_expr_new st + let d = u_dummy_range st + let e = u_ty_new st + Expr.TyLambda(newUnique (), b, c, d, e) + | 7 -> + let a1 = u_expr_new st + let a2 = u_ty_new st + let b = u_tys_new st + let c = u_exprs_new st + let d = u_dummy_range st + let expr = Expr.App(a1, a2, b, c, d) + expr + | 8 -> + let a = u_binds st + let b = u_expr_new st + let c = u_dummy_range st + Expr.LetRec(a, b, c, Construct.NewFreeVarsCache()) + | 9 -> + let a = u_bind st + let b = u_expr_new st + let c = u_dummy_range st + Expr.Let(a, b, c, Construct.NewFreeVarsCache()) + | 10 -> + let a = u_dummy_range st + let b = u_dtree st + let c = u_targets st + let d = u_dummy_range st + let e = u_ty_new st + Expr.Match(DebugPointAtBinding.NoneAtSticky, a, b, c, d, e) + | 11 -> + let b = u_ty_new st + let c = (u_option u_Val) st + let d = u_expr_new st + let e = u_methods st + let f = u_intfs st + let g = u_dummy_range st + Expr.Obj(newUnique (), b, c, d, e, f, g) + | 12 -> + let a = u_constraints st + let b = u_expr_new st + let c = u_expr_new st + let d = u_dummy_range st + Expr.StaticOptimization(a, b, c, d) + | 13 -> + let a = u_tyar_specs_new st + let b = u_expr_new st + let c = u_dummy_range st + Expr.TyChoose(a, b, c) + | 14 -> + let b = u_expr_new st + let c = u_dummy_range st + let d = u_ty_new st + Expr.Quote(b, ref None, false, c, d) // isFromQueryExpression=false + | 15 -> + let traitInfo = u_trait st + let m = u_dummy_range st + Expr.WitnessArg(traitInfo, m) + | 16 -> + let m = u_dummy_range st + let expr = u_expr_new st + Expr.DebugPoint(DebugPointAtLeafExpr.Yes m, expr) | _ -> ufailwith st "u_expr" - + and u_exprs_new = u_list u_expr_new -and u_ucref_new st = - let tcref, caseName, binding = - u_tup3 - u_tcref - u_string - (u_non_null_slot u_entity_spec_new) - st +and u_ucref_new st = + let tcref, caseName, binding = + u_tup3 u_tcref u_string (u_non_null_slot u_entity_spec_new) st tcref.binding <- binding UnionCaseRef(tcref, caseName) -and u_op_new st = +and u_op_new st = let tag = u_byte st + match tag with - | 0 -> let a = u_ucref_new st - TOp.UnionCase a - | 1 -> let a = u_tcref st - TOp.ExnConstr a + | 0 -> + let a = u_ucref_new st + TOp.UnionCase a + | 1 -> + let a = u_tcref st + TOp.ExnConstr a | 2 -> TOp.Tuple tupInfoRef - | 3 -> let b = u_tcref st - TOp.Recd (RecdExpr, b) - | 4 -> let a = u_rfref st - TOp.ValFieldSet a - | 5 -> let a = u_rfref st - TOp.ValFieldGet a - | 6 -> let a = u_tcref st - TOp.UnionCaseTagGet a - | 7 -> let a = u_ucref st - let b = u_int st - TOp.UnionCaseFieldGet (a, b) - | 8 -> let a = u_ucref st - let b = u_int st - TOp.UnionCaseFieldSet (a, b) - | 9 -> let a = u_tcref st - let b = u_int st - TOp.ExnFieldGet (a, b) - | 10 -> let a = u_tcref st - let b = u_int st - TOp.ExnFieldSet (a, b) - | 11 -> let a = u_int st - TOp.TupleFieldGet (tupInfoRef, a) - | 12 -> let a = (u_list u_ILInstr) st - let b = u_tys st - TOp.ILAsm (a, b) + | 3 -> + let b = u_tcref st + TOp.Recd(RecdExpr, b) + | 4 -> + let a = u_rfref st + TOp.ValFieldSet a + | 5 -> + let a = u_rfref st + TOp.ValFieldGet a + | 6 -> + let a = u_tcref st + TOp.UnionCaseTagGet a + | 7 -> + let a = u_ucref st + let b = u_int st + TOp.UnionCaseFieldGet(a, b) + | 8 -> + let a = u_ucref st + let b = u_int st + TOp.UnionCaseFieldSet(a, b) + | 9 -> + let a = u_tcref st + let b = u_int st + TOp.ExnFieldGet(a, b) + | 10 -> + let a = u_tcref st + let b = u_int st + TOp.ExnFieldSet(a, b) + | 11 -> + let a = u_int st + TOp.TupleFieldGet(tupInfoRef, a) + | 12 -> + let a = (u_list u_ILInstr) st + let b = u_tys st + TOp.ILAsm(a, b) | 13 -> TOp.RefAddrGet false // ok to set the 'readonly' flag on these operands to false on re-read since the flag is only used for typechecking purposes - | 14 -> let a = u_ucref st - TOp.UnionCaseProof a + | 14 -> + let a = u_ucref st + TOp.UnionCaseProof a | 15 -> TOp.Coerce - | 16 -> let a = u_trait st - TOp.TraitCall a - | 17 -> let a = u_lval_op_kind st - let b = u_vref st - TOp.LValueOp (a, b) - | 18 -> let a1, a2, a3, a4, a5, a7, a8, a9 = (u_tup8 u_bool u_bool u_bool u_bool u_vrefFlags u_bool u_bool u_ILMethodRef) st - let b = u_tys st - let c = u_tys st - let d = u_tys st - TOp.ILCall (a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) + | 16 -> + let a = u_trait st + TOp.TraitCall a + | 17 -> + let a = u_lval_op_kind st + let b = u_vref st + TOp.LValueOp(a, b) + | 18 -> + let a1, a2, a3, a4, a5, a7, a8, a9 = + (u_tup8 u_bool u_bool u_bool u_bool u_vrefFlags u_bool u_bool u_ILMethodRef) st + + let b = u_tys st + let c = u_tys st + let d = u_tys st + TOp.ILCall(a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) | 19 -> TOp.Array - | 20 -> TOp.While (DebugPointAtWhile.No, NoSpecialWhileLoopMarker) - | 21 -> let dir = match u_int st with 0 -> FSharpForLoopUp | 1 -> CSharpForLoopUp | 2 -> FSharpForLoopDown | _ -> failwith "unknown for loop" - TOp.IntegerForLoop (DebugPointAtFor.No, DebugPointAtInOrTo.No, dir) - | 22 -> TOp.Bytes (u_bytes st) - | 23 -> TOp.TryWith (DebugPointAtTry.No, DebugPointAtWith.No) - | 24 -> TOp.TryFinally (DebugPointAtTry.No, DebugPointAtFinally.No) - | 25 -> let a = u_rfref st - TOp.ValFieldGetAddr (a, false) - | 26 -> TOp.UInt16s (u_array u_uint16 st) + | 20 -> TOp.While(DebugPointAtWhile.No, NoSpecialWhileLoopMarker) + | 21 -> + let dir = + match u_int st with + | 0 -> FSharpForLoopUp + | 1 -> CSharpForLoopUp + | 2 -> FSharpForLoopDown + | _ -> failwith "unknown for loop" + + TOp.IntegerForLoop(DebugPointAtFor.No, DebugPointAtInOrTo.No, dir) + | 22 -> TOp.Bytes(u_bytes st) + | 23 -> TOp.TryWith(DebugPointAtTry.No, DebugPointAtWith.No) + | 24 -> TOp.TryFinally(DebugPointAtTry.No, DebugPointAtFinally.No) + | 25 -> + let a = u_rfref st + TOp.ValFieldGetAddr(a, false) + | 26 -> TOp.UInt16s(u_array u_uint16 st) | 27 -> TOp.Reraise - | 28 -> let a = u_ucref st - let b = u_int st - TOp.UnionCaseFieldGetAddr (a, b, false) + | 28 -> + let a = u_ucref st + let b = u_int st + TOp.UnionCaseFieldGetAddr(a, b, false) | 29 -> TOp.Tuple tupInfoStruct - | 30 -> let a = u_int st - TOp.TupleFieldGet (tupInfoStruct, a) - | 31 -> let info = u_anonInfo st - TOp.AnonRecd info - | 32 -> let info = u_anonInfo st - let n = u_int st - TOp.AnonRecdGet (info, n) + | 30 -> + let a = u_int st + TOp.TupleFieldGet(tupInfoStruct, a) + | 31 -> + let info = u_anonInfo st + TOp.AnonRecd info + | 32 -> + let info = u_anonInfo st + let n = u_int st + TOp.AnonRecdGet(info, n) | _ -> ufailwith st "u_op" and u_entity_spec_data_new st : Entity = @@ -1092,7 +1179,7 @@ and u_entity_spec_data_new st : Entity = let kind = u_kind st let flags = u_int64 st let cpath = u_option u_cpath st - let modulType = u_lazy u_modul_typ_new st + let modulType = u_lazy u_modul_typ_new st let exnInfo = u_exnc_repr st let xmlDoc = u_used_space1 u_xmldoc st @@ -1100,31 +1187,34 @@ and u_entity_spec_data_new st : Entity = //let x7 = x7f (x11 &&& EntityFlags.ReservedBitForPickleFormatTyconReprFlag <> 0L) //let x11 = x11 &&& ~~~EntityFlags.ReservedBitForPickleFormatTyconReprFlag - { entity_typars=LazyWithContext.NotLazy typars - entity_stamp=stamp - entity_logical_name=logicalName - entity_range=range - entity_pubpath=pubPath - entity_attribs=attribs - entity_tycon_repr=tyconRepr false - entity_tycon_tcaug=tyconTcaug - entity_flags=EntityFlags flags - entity_cpath=cpath - entity_modul_type=MaybeLazy.Lazy modulType - entity_il_repr_cache=newCache() - entity_opt_data= - match compiledName, kind, xmlDoc, typeAbbrev, access, tyconReprAccess, exnInfo with - | None, TyparKind.Type, None, None, TAccess [], TAccess [], TExnNone -> None - | _ -> - Some { Entity.NewEmptyEntityOptData() with - entity_compiled_name = compiledName - entity_kind = kind - entity_xmldoc= defaultArg xmlDoc XmlDoc.Empty - entity_xmldocsig = System.String.Empty - entity_tycon_abbrev = typeAbbrev - entity_accessibility = access - entity_tycon_repr_accessibility = tyconReprAccess - entity_exn_info = exnInfo } + { + entity_typars = LazyWithContext.NotLazy typars + entity_stamp = stamp + entity_logical_name = logicalName + entity_range = range + entity_pubpath = pubPath + entity_attribs = attribs + entity_tycon_repr = tyconRepr false + entity_tycon_tcaug = tyconTcaug + entity_flags = EntityFlags flags + entity_cpath = cpath + entity_modul_type = MaybeLazy.Lazy modulType + entity_il_repr_cache = newCache () + entity_opt_data = + match compiledName, kind, xmlDoc, typeAbbrev, access, tyconReprAccess, exnInfo with + | None, TyparKind.Type, None, None, TAccess [], TAccess [], TExnNone -> None + | _ -> + Some + { Entity.NewEmptyEntityOptData() with + entity_compiled_name = compiledName + entity_kind = kind + entity_xmldoc = defaultArg xmlDoc XmlDoc.Empty + entity_xmldocsig = System.String.Empty + entity_tycon_abbrev = typeAbbrev + entity_accessibility = access + entity_tycon_repr_accessibility = tyconReprAccess + entity_exn_info = exnInfo + } } and u_entity_spec_new st = @@ -1146,68 +1236,76 @@ and u_ValData_new st = let valConst = u_option u_const st let xmlDoc = u_used_space1 u_xmldoc st - { val_logical_name = logicalName - val_range = (match ranges with None -> range0 | Some(a, _) -> a) - val_type = valType - val_stamp = stamp - val_flags = ValFlags flags - val_opt_data = - match compiledName, ranges, valReprInfo, valConst, valAccess, xmlDoc, memberInfo, declEntity, xmlDocSig, attribs with - | None, None, None, None, TAccess [], None, None, ParentNone, "", [] -> None - | _ -> - Some { val_compiled_name = compiledName - val_other_range = (match ranges with None -> None | Some(_, b) -> Some(b, true)) - val_defn = None - val_repr_info = valReprInfo - val_repr_info_for_display = None - arg_repr_info_for_display = None - val_const = valConst - val_access = valAccess - val_xmldoc = defaultArg xmlDoc XmlDoc.Empty - val_other_xmldoc = None - val_member_info = memberInfo - val_declaring_entity = declEntity - val_xmldocsig = xmlDocSig - val_attribs = attribs } + { + val_logical_name = logicalName + val_range = + (match ranges with + | None -> range0 + | Some(a, _) -> a) + val_type = valType + val_stamp = stamp + val_flags = ValFlags flags + val_opt_data = + match compiledName, ranges, valReprInfo, valConst, valAccess, xmlDoc, memberInfo, declEntity, xmlDocSig, attribs with + | None, None, None, None, TAccess [], None, None, ParentNone, "", [] -> None + | _ -> + Some + { + val_compiled_name = compiledName + val_other_range = + (match ranges with + | None -> None + | Some(_, b) -> Some(b, true)) + val_defn = None + val_repr_info = valReprInfo + val_repr_info_for_display = None + arg_repr_info_for_display = None + val_const = valConst + val_access = valAccess + val_xmldoc = defaultArg xmlDoc XmlDoc.Empty + val_other_xmldoc = None + val_member_info = memberInfo + val_declaring_entity = declEntity + val_xmldocsig = xmlDocSig + val_attribs = attribs + } } and u_Val_new st = u_osgn_decl st.ivals u_ValData_new st and u_modul_typ_new st = - let x1, x3, x5 = - u_tup3 - u_istype - (u_qlist u_Val_new) - (u_qlist u_entity_spec_new) st + let x1, x3, x5 = u_tup3 u_istype (u_qlist u_Val_new) (u_qlist u_entity_spec_new) st ModuleOrNamespaceType(x1, x3, x5) and u_tcaug_new st : TyconAugmentation = let a1, a2, a3, b2, c, d, e, g, _space = - u_tup9 - (u_option (u_tup2 u_vref u_vref)) - (u_option u_vref) - (u_option (u_tup3 u_vref u_vref u_vref)) - (u_option (u_tup2 u_vref u_vref)) - (u_list (u_tup2 u_string u_vref)) - (u_list (u_tup3 u_ty_new u_bool u_dummy_range)) - (u_option u_ty_new) - u_bool - (u_space 1) - st - {tcaug_compare=a1 - tcaug_compare_withc=a2 - tcaug_hash_and_equals_withc=a3 |> Option.map (fun (v1, v2, v3) -> (v1, v2, v3, None)) - tcaug_equals=b2 - // only used for code generation and checking - hence don't care about the values when reading back in - tcaug_hasObjectGetHashCode=false - tcaug_adhoc_list= ResizeArray<_>(c |> List.map (fun (_, vref) -> (false, vref))) - tcaug_adhoc=NameMultiMap.ofList c - tcaug_interfaces=d - tcaug_super=e - // pickled type definitions are always closed (i.e. no more intrinsic members allowed) - tcaug_closed=true - tcaug_abstract=g} + u_tup9 + (u_option (u_tup2 u_vref u_vref)) + (u_option u_vref) + (u_option (u_tup3 u_vref u_vref u_vref)) + (u_option (u_tup2 u_vref u_vref)) + (u_list (u_tup2 u_string u_vref)) + (u_list (u_tup3 u_ty_new u_bool u_dummy_range)) + (u_option u_ty_new) + u_bool + (u_space 1) + st + { + tcaug_compare = a1 + tcaug_compare_withc = a2 + tcaug_hash_and_equals_withc = a3 |> Option.map (fun (v1, v2, v3) -> (v1, v2, v3, None)) + tcaug_equals = b2 + // only used for code generation and checking - hence don't care about the values when reading back in + tcaug_hasObjectGetHashCode = false + tcaug_adhoc_list = ResizeArray<_>(c |> List.map (fun (_, vref) -> (false, vref))) + tcaug_adhoc = NameMultiMap.ofList c + tcaug_interfaces = d + tcaug_super = e + // pickled type definitions are always closed (i.e. no more intrinsic members allowed) + tcaug_closed = true + tcaug_abstract = g + } and u_ccu_data st : CcuData = let fileName = u_option u_string st @@ -1243,31 +1341,21 @@ and u_ccu_data st : CcuData = } and u_ccuref_new st : CcuThunk = - let target, name = - u_tup2 - u_ccu_data - u_string - st + let target, name = u_tup2 u_ccu_data u_string st - { - target = target - name = name - } + { target = target; name = name } -and u_nleref_new st = - let ccu, strings = - u_tup2 - u_ccuref_new - (u_array u_string) - st +and u_nleref_new st = + let ccu, strings = u_tup2 u_ccuref_new (u_array u_string) st - NonLocalEntityRef (ccu, strings) + NonLocalEntityRef(ccu, strings) and u_tcref_new st : EntityRef = let tag = u_byte st + match tag with - | 0 -> u_local_item_ref st.ientities st |> ERefLocal - | 1 -> u_nleref_new st |> ERefNonLocal + | 0 -> u_local_item_ref st.ientities st |> ERefLocal + | 1 -> u_nleref_new st |> ERefNonLocal | _ -> ufailwith st "u_item_ref" and u_nonlocal_val_ref_new st : NonLocalValOrMemberRef = @@ -1277,60 +1365,73 @@ and u_nonlocal_val_ref_new st : NonLocalValOrMemberRef = let b3 = u_string st let c = u_int st let d = u_option u_ty_new st - { EnclosingEntity = a - ItemKey=ValLinkageFullKey({ MemberParentMangledName=b1; MemberIsOverride=b2;LogicalName=b3; TotalArgCount=c }, d) } + + { + EnclosingEntity = a + ItemKey = + ValLinkageFullKey( + { + MemberParentMangledName = b1 + MemberIsOverride = b2 + LogicalName = b3 + TotalArgCount = c + }, + d + ) + } and u_vref_new st : ValRef = let tag = u_byte st + match tag with | 0 -> u_local_item_ref st.ivals st |> VRefLocal | 1 -> u_nonlocal_val_ref_new st |> VRefNonLocal | _ -> ufailwith st "u_item_ref" -and u_bind_new st = +and u_bind_new st = let a = u_Val_new st let b = u_expr_new st TBind(a, b, DebugPointAtBinding.NoneAtSticky) and u_binding st : ModuleOrNamespaceBinding = let tag = u_byte st + match tag with | 0 -> let binding = u_bind st ModuleOrNamespaceBinding.Binding binding | 1 -> let moduleOrNamespace, moduleOrNamespaceContents = - u_tup2 - u_entity_spec_new - u_module_or_namespace_contents - st - ModuleOrNamespaceBinding.Module (moduleOrNamespace, moduleOrNamespaceContents) - | _ -> - ufailwith st (nameof u_binding) + u_tup2 u_entity_spec_new u_module_or_namespace_contents st + ModuleOrNamespaceBinding.Module(moduleOrNamespace, moduleOrNamespaceContents) + | _ -> ufailwith st (nameof u_binding) and u_tycon_repr_new st = let tag1 = u_byte st + match tag1 with | 0 -> (fun _flagBit -> TNoRepr) | 1 -> let tag2 = u_byte st + match tag2 with // Records historically use a different format to other FSharpTyconRepr | 0 -> let v = u_rfield_table st + (fun _flagBit -> TFSharpTyconRepr { fsobjmodel_cases = Construct.MakeUnionCases [] - fsobjmodel_kind=TFSharpRecord - fsobjmodel_vslots=[] - fsobjmodel_rfields=v + fsobjmodel_kind = TFSharpRecord + fsobjmodel_vslots = [] + fsobjmodel_rfields = v }) // Unions without static fields historically use a different format to other FSharpTyconRepr | 1 -> - let v = u_list u_unioncase_spec st + let v = u_list u_unioncase_spec st (fun _flagBit -> Construct.MakeUnionRepr v) | 2 -> @@ -1341,26 +1442,32 @@ and u_tycon_repr_new st = (fun flagBit -> if flagBit then let iltref = v.TypeRef + match st.iILModule with | None -> TNoRepr | Some iILModule -> - try - let rec find acc enclosingTypeNames (tdefs: ILTypeDefs) = - match enclosingTypeNames with - | [] -> List.rev acc, tdefs.FindByName iltref.Name - | h :: t -> - let nestedTypeDef = tdefs.FindByName h - find (nestedTypeDef :: acc) t nestedTypeDef.NestedTypes - let nestedILTypeDefs, ilTypeDef = find [] iltref.Enclosing iILModule.TypeDefs - TILObjectRepr(TILObjectReprData(st.iilscope, nestedILTypeDefs, ilTypeDef)) - with _ -> - System.Diagnostics.Debug.Assert(false, sprintf "failed to find IL backing metadata for cross-assembly generated type %s" iltref.FullName) - TNoRepr + try + let rec find acc enclosingTypeNames (tdefs: ILTypeDefs) = + match enclosingTypeNames with + | [] -> List.rev acc, tdefs.FindByName iltref.Name + | h :: t -> + let nestedTypeDef = tdefs.FindByName h + find (nestedTypeDef :: acc) t nestedTypeDef.NestedTypes + + let nestedILTypeDefs, ilTypeDef = find [] iltref.Enclosing iILModule.TypeDefs + TILObjectRepr(TILObjectReprData(st.iilscope, nestedILTypeDefs, ilTypeDef)) + with _ -> + System.Diagnostics.Debug.Assert( + false, + sprintf "failed to find IL backing metadata for cross-assembly generated type %s" iltref.FullName + ) + + TNoRepr else TAsmRepr v) | 3 -> - let v = u_tycon_objmodel_data st + let v = u_tycon_objmodel_data st (fun _flagBit -> TFSharpTyconRepr v) | 4 -> @@ -1373,75 +1480,58 @@ and u_tycon_repr_new st = | 2 -> let cases = u_array u_unioncase_spec st let data = u_tycon_objmodel_data st - fun _flagBit -> TFSharpTyconRepr { data with fsobjmodel_cases = Construct.MakeUnionCases (Array.toList cases) } - + + fun _flagBit -> + TFSharpTyconRepr + { data with + fsobjmodel_cases = Construct.MakeUnionCases(Array.toList cases) + } + | 5 -> // | TILObjectRepr (TILObjectReprData (scope, nesting, td)) -> let scope = u_ILScopeRef st let nesting = u_list u_ILTypeDef st let definition = u_ILTypeDef st - (fun _flagBit -> TILObjectRepr (TILObjectReprData (scope, nesting, definition))) + (fun _flagBit -> TILObjectRepr(TILObjectReprData(scope, nesting, definition))) | _ -> ufailwith st "u_tycon_repr" - - -and u_qualified_name_of_file st = +and u_qualified_name_of_file st = let ident = u_ident st QualifiedNameOfFile(ident) and u_pragma st = - let range, warningNumber = - u_tup2 - u_range - u_int - st + let range, warningNumber = u_tup2 u_range u_int st - ScopedPragma.WarningOff (range, warningNumber) + ScopedPragma.WarningOff(range, warningNumber) -and u_pragmas st = - u_list u_pragma st +and u_pragmas st = u_list u_pragma st -and u_long_ident st = - u_list u_ident st +and u_long_ident st = u_list u_ident st -and u_trivia st : SyntaxTrivia.IdentTrivia = - ufailwith st (nameof p_trivia) +and u_trivia st : SyntaxTrivia.IdentTrivia = ufailwith st (nameof p_trivia) and u_syn_long_ident st = - let id, dotRanges, trivia = - u_tup3 - u_long_ident - (u_list u_range) - (u_list (u_option u_trivia)) - st + let id, dotRanges, trivia = + u_tup3 u_long_ident (u_list u_range) (u_list (u_option u_trivia)) st - SynLongIdent (id, dotRanges, trivia) + SynLongIdent(id, dotRanges, trivia) -and u_syn_type st : SynType = - ufailwith st (nameof u_syn_type) +and u_syn_type st : SynType = ufailwith st (nameof u_syn_type) and u_syn_open_decl_target st : SynOpenDeclTarget = let tag = u_byte st + match tag with | 0 -> - let longId, range = - u_tup2 - u_syn_long_ident - u_range - st + let longId, range = u_tup2 u_syn_long_ident u_range st - SynOpenDeclTarget.ModuleOrNamespace (longId, range) + SynOpenDeclTarget.ModuleOrNamespace(longId, range) | 1 -> - let typeName, range = - u_tup2 - u_syn_type - u_range - st - SynOpenDeclTarget.Type (typeName, range) - | _ -> - ufailwith st (nameof u_syn_open_decl_target) + let typeName, range = u_tup2 u_syn_type u_range st + SynOpenDeclTarget.Type(typeName, range) + | _ -> ufailwith st (nameof u_syn_open_decl_target) and u_tup_info st : TupInfo = let c = u_bool st @@ -1449,6 +1539,7 @@ and u_tup_info st : TupInfo = and u_nullness st = let tag = u_byte st + let nullnessInfo = match tag with | 0 -> NullnessInfo.WithNull @@ -1462,6 +1553,7 @@ and u_typars = u_list u_tpref and u_module_or_namespace_contents st : ModuleOrNamespaceContents = let tag = u_byte st + match tag with | 0 -> let defs = u_list u_module_or_namespace_contents st @@ -1470,42 +1562,24 @@ and u_module_or_namespace_contents st : ModuleOrNamespaceContents = let openDecls = u_list u_open_decl st TMDefOpens openDecls | 2 -> - let binding, range = - u_tup2 - u_bind_new - u_range - st + let binding, range = u_tup2 u_bind_new u_range st TMDefLet(binding, range) | 3 -> - let expr, range = - u_tup2 - u_expr_new - u_range - st + let expr, range = u_tup2 u_expr_new u_range st TMDefDo(expr, range) | 4 -> let isRec, opens, tycons, bindings, range = - u_tup5 - u_bool - (u_list u_open_decl) - (u_list u_entity_spec_data_new) - (u_list u_binding) - u_range - st - TMDefRec (isRec, opens, tycons, bindings, range) - | _ -> - ufailwith st (nameof u_module_or_namespace_contents) + u_tup5 u_bool (u_list u_open_decl) (u_list u_entity_spec_data_new) (u_list u_binding) u_range st + + TMDefRec(isRec, opens, tycons, bindings, range) + | _ -> ufailwith st (nameof u_module_or_namespace_contents) and u_checked_impl_file_contents = u_module_or_namespace_contents and u_named_debug_point_key st : NamedDebugPointKey = - let range, name = - u_tup2 - u_range - u_string - st + let range, name = u_tup2 u_range u_string st - { Range = range; Name = name} + { Range = range; Name = name } and u_named_debug_points = u_Map u_named_debug_point_key u_range @@ -1513,14 +1587,7 @@ and u_anon_recd_types = u_stamp_map u_anonInfo and u_open_decl st : OpenDeclaration = let target, range, modules, types, appliedScope, isOwnNamespace = - u_tup6 - u_syn_open_decl_target - (u_option u_range) - (u_list u_tcref_new) - u_tys - u_range - u_bool - st + u_tup6 u_syn_open_decl_target (u_option u_range) (u_list u_tcref_new) u_tys u_range u_bool st { Target = target @@ -1531,7 +1598,7 @@ and u_open_decl st : OpenDeclaration = IsOwnNamespace = isOwnNamespace } -and u_checked_impl_file st = +and u_checked_impl_file st = let qualifiedNameOfFile, pragmas, signature, contents, hasExplicitEntryPoint, isScript, anonRecdTypeInfo, namedDebugPointsForInlinedCode = u_tup8 u_qualified_name_of_file @@ -1552,8 +1619,8 @@ and u_checked_impl_file st = hasExplicitEntryPoint, isScript, anonRecdTypeInfo, - namedDebugPointsForInlinedCode) - + namedDebugPointsForInlinedCode + ) let u_context_info st : ContextInfo = let tag = u_byte st @@ -1704,8 +1771,6 @@ let u_tcs_root_sig st = qualifiedNameOfFile, moduleOrNamespaceType - - // unpickling top let unpickleSharedData st = From 54f82218a410fb6ec3bcbd59af9bbe7f434d32c6 Mon Sep 17 00:00:00 2001 From: Petr Date: Fri, 4 Apr 2025 15:52:42 +0200 Subject: [PATCH 8/8] Post-merge --- src/Compiler/Driver/ParseAndCheckInputs.fs | 102 +++++++----------- .../Driver/ReuseTcResults/TcResultsPickle.fs | 6 +- src/Compiler/Driver/fsc.fs | 6 +- src/Compiler/TypedTree/TypedTreePickle.fs | 4 +- 4 files changed, 49 insertions(+), 69 deletions(-) diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs index ad1a74f8df5..2b822610d5a 100644 --- a/src/Compiler/Driver/ParseAndCheckInputs.fs +++ b/src/Compiler/Driver/ParseAndCheckInputs.fs @@ -352,7 +352,7 @@ type ModuleNamesDict = Map> /// Checks if a module name is already given and deduplicates the name if needed. let DeduplicateModuleName (moduleNamesDict: ModuleNamesDict) (fileName: string) (qualNameOfFile: QualifiedNameOfFile) = - let path = !! Path.GetDirectoryName(fileName) + let path = !!Path.GetDirectoryName(fileName) let path = if FileSystem.IsPathRootedShim path then @@ -433,7 +433,7 @@ let ParseInput "ParseAndCheckFile.parseFile" [| Activity.Tags.fileName, fileName - Activity.Tags.buildPhase, !! BuildPhase.Parse.ToString() + Activity.Tags.buildPhase, !!BuildPhase.Parse.ToString() Activity.Tags.userOpName, userOpName |> Option.defaultValue "" |] @@ -703,15 +703,8 @@ let checkInputFile (tcConfig: TcConfig) fileName = error (Error(FSComp.SR.buildInvalidSourceFileExtension (SanitizeFileName fileName tcConfig.implicitIncludeDir), rangeStartup)) let parseInputStreamAux - ( - tcConfig: TcConfig, - lexResourceManager, - fileName, - isLastCompiland, - diagnosticsLogger, - retryLocked, - stream: Stream - ) = + (tcConfig: TcConfig, lexResourceManager, fileName, isLastCompiland, diagnosticsLogger, retryLocked, stream: Stream) + = use reader = stream.GetReader(tcConfig.inputCodePage, retryLocked) // Set up the LexBuffer for the file @@ -722,14 +715,8 @@ let parseInputStreamAux ParseOneInputLexbuf(tcConfig, lexResourceManager, lexbuf, fileName, isLastCompiland, diagnosticsLogger) let parseInputSourceTextAux - ( - tcConfig: TcConfig, - lexResourceManager, - fileName, - isLastCompiland, - diagnosticsLogger, - sourceText: ISourceText - ) = + (tcConfig: TcConfig, lexResourceManager, fileName, isLastCompiland, diagnosticsLogger, sourceText: ISourceText) + = // Set up the LexBuffer for the file let lexbuf = UnicodeLexing.SourceTextAsLexbuf(not tcConfig.compilingFSharpCore, tcConfig.langVersion, tcConfig.strictIndentation, sourceText) @@ -751,15 +738,8 @@ let parseInputFileAux (tcConfig: TcConfig, lexResourceManager, fileName, isLastC /// Parse an input from stream let ParseOneInputStream - ( - tcConfig: TcConfig, - lexResourceManager, - fileName, - isLastCompiland, - diagnosticsLogger, - retryLocked, - stream: Stream - ) = + (tcConfig: TcConfig, lexResourceManager, fileName, isLastCompiland, diagnosticsLogger, retryLocked, stream: Stream) + = try parseInputStreamAux (tcConfig, lexResourceManager, fileName, isLastCompiland, diagnosticsLogger, retryLocked, stream) with RecoverableException exn -> @@ -768,14 +748,8 @@ let ParseOneInputStream /// Parse an input from source text let ParseOneInputSourceText - ( - tcConfig: TcConfig, - lexResourceManager, - fileName, - isLastCompiland, - diagnosticsLogger, - sourceText: ISourceText - ) = + (tcConfig: TcConfig, lexResourceManager, fileName, isLastCompiland, diagnosticsLogger, sourceText: ISourceText) + = try parseInputSourceTextAux (tcConfig, lexResourceManager, fileName, isLastCompiland, diagnosticsLogger, sourceText) with RecoverableException exn -> @@ -862,9 +836,11 @@ let ParseInputFiles (tcConfig: TcConfig, lexResourceManager, sourceFiles, diagno tcConfig.exiter.Exit 1 let ProcessMetaCommandsFromInput - (nowarnF: 'state -> range * string -> 'state, - hashReferenceF: 'state -> range * string * Directive -> 'state, - loadSourceF: 'state -> range * string -> unit) + ( + nowarnF: 'state -> range * string -> 'state, + hashReferenceF: 'state -> range * string * Directive -> 'state, + loadSourceF: 'state -> range * string -> unit + ) (tcConfig: TcConfigBuilder, inp: ParsedInput, pathOfMetaCommandSource, state0) = @@ -1531,16 +1507,18 @@ type NodeToTypeCheck = /// a callback functions that takes a `TcState` and will add the checked result to it. let CheckOneInputWithCallback (node: NodeToTypeCheck) - ((checkForErrors, - tcConfig: TcConfig, - tcImports: TcImports, - tcGlobals, - prefixPathOpt, - tcSink, - tcState: TcState, - input: ParsedInput, - _skipImplIfSigExists: bool): - (unit -> bool) * TcConfig * TcImports * TcGlobals * LongIdent option * TcResultsSink * TcState * ParsedInput * bool) + ( + (checkForErrors, + tcConfig: TcConfig, + tcImports: TcImports, + tcGlobals, + prefixPathOpt, + tcSink, + tcState: TcState, + input: ParsedInput, + _skipImplIfSigExists: bool): + (unit -> bool) * TcConfig * TcImports * TcGlobals * LongIdent option * TcResultsSink * TcState * ParsedInput * bool + ) : Cancellable> = cancellable { try @@ -1834,16 +1812,18 @@ let TransformDependencyGraph (graph: Graph, filePairs: FilePairMap) = /// Constructs a file dependency graph and type-checks the files in parallel where possible. let CheckMultipleInputsUsingGraphMode - ((ctok, checkForErrors, tcConfig: TcConfig, tcImports: TcImports, tcGlobals, prefixPathOpt, tcState, eagerFormat, inputs): - 'a * - (unit -> bool) * - TcConfig * - TcImports * - TcGlobals * - LongIdent option * - TcState * - (PhasedDiagnostic -> PhasedDiagnostic) * - ParsedInput list) + ( + (ctok, checkForErrors, tcConfig: TcConfig, tcImports: TcImports, tcGlobals, prefixPathOpt, tcState, eagerFormat, inputs): + 'a * + (unit -> bool) * + TcConfig * + TcImports * + TcGlobals * + LongIdent option * + TcState * + (PhasedDiagnostic -> PhasedDiagnostic) * + ParsedInput list + ) : FinalFileResult list * TcState * TcState list = use cts = new CancellationTokenSource() @@ -1875,9 +1855,7 @@ let CheckMultipleInputsUsingGraphMode graph |> Graph.map (fun idx -> let friendlyFileName = - sourceFiles[idx] - .FileName.Replace(tcConfig.implicitIncludeDir, "") - .TrimStart([| '\\'; '/' |]) + sourceFiles[idx].FileName.Replace(tcConfig.implicitIncludeDir, "").TrimStart([| '\\'; '/' |]) (idx, friendlyFileName)) |> Graph.writeMermaidToFile graphFile) diff --git a/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs b/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs index e61c96c9d74..9a4696fae3c 100644 --- a/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs +++ b/src/Compiler/Driver/ReuseTcResults/TcResultsPickle.fs @@ -445,7 +445,7 @@ and p_nonlocal_val_ref_new (nlv: NonLocalValOrMemberRef) st = p_string pkey.LogicalName st p_int pkey.TotalArgCount st - let isStructThisArgPos = + let _isStructThisArgPos = match key.TypeForLinkage with | None -> false | Some ty -> checkForInRefStructThisArg st ty @@ -577,13 +577,13 @@ and p_pragmas x st = p_list p_pragma x st and p_long_ident (x: LongIdent) st = p_list p_ident x st -and p_trivia (x: SyntaxTrivia.IdentTrivia) st = pfailwith st (nameof p_trivia) +and p_trivia (_x: SyntaxTrivia.IdentTrivia) st = pfailwith st (nameof p_trivia) and p_syn_long_ident (x: SynLongIdent) st = let (SynLongIdent(id, dotRanges, trivia)) = x p_tup3 p_long_ident (p_list p_range) (p_list (p_option p_trivia)) (id, dotRanges, trivia) st -and p_syn_type (x: SynType) st = pfailwith st (nameof p_syn_type) +and p_syn_type (_x: SynType) st = pfailwith st (nameof p_syn_type) and p_syn_open_decl_target (x: SynOpenDeclTarget) st = match x with diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs index 3cc0e4743f4..756b8e1aa8f 100644 --- a/src/Compiler/Driver/fsc.fs +++ b/src/Compiler/Driver/fsc.fs @@ -443,7 +443,7 @@ module InterfaceFileWriter = let writeToSeparateFiles (declaredImpls: CheckedImplFile list) = for CheckedImplFile(qualifiedNameOfFile = name) as impl in declaredImpls do let fileName = - !! Path.ChangeExtension(name.Range.FileName, extensionForFile name.Range.FileName) + !!Path.ChangeExtension(name.Range.FileName, extensionForFile name.Range.FileName) printfn "writing impl file to %s" fileName use os = FileSystem.OpenFileForWriteShim(fileName, FileMode.Create).GetWriter() @@ -464,7 +464,7 @@ module InterfaceFileWriter = // 2) If not, but FSharp.Core.dll exists beside the compiler binaries, it will copy it to output directory. // 3) If not, it will produce an error. let CopyFSharpCore (outFile: string, referencedDlls: AssemblyReference list) = - let outDir = !! Path.GetDirectoryName(outFile) + let outDir = !!Path.GetDirectoryName(outFile) let fsharpCoreAssemblyName = GetFSharpCoreLibraryName() + ".dll" let fsharpCoreDestinationPath = Path.Combine(outDir, fsharpCoreAssemblyName) @@ -484,7 +484,7 @@ let CopyFSharpCore (outFile: string, referencedDlls: AssemblyReference list) = | Some referencedFsharpCoreDll -> copyFileIfDifferent referencedFsharpCoreDll.Text fsharpCoreDestinationPath | None -> let executionLocation = Assembly.GetExecutingAssembly().Location - let compilerLocation = !! Path.GetDirectoryName(executionLocation) + let compilerLocation = !!Path.GetDirectoryName(executionLocation) let compilerFsharpCoreDllPath = Path.Combine(compilerLocation, fsharpCoreAssemblyName) diff --git a/src/Compiler/TypedTree/TypedTreePickle.fs b/src/Compiler/TypedTree/TypedTreePickle.fs index 54c22e544ed..c58f24c9ab4 100644 --- a/src/Compiler/TypedTree/TypedTreePickle.fs +++ b/src/Compiler/TypedTree/TypedTreePickle.fs @@ -1015,13 +1015,15 @@ let pickleObjWithDanglingCcus inMem file g scope p x = phase2bytes, phase1bytesB -let check (ilscope: ILScopeRef) (inMap: NodeInTable<_, _>) = +let check (_ilscope: ILScopeRef) (inMap: NodeInTable<_, _>) = for i = 0 to inMap.Count - 1 do let n = inMap.Get i if not (inMap.IsLinked n) then // TODO: do not disable // warning (Error(FSComp.SR.pickleMissingDefinition (i, inMap.Name, ilscope.QualifiedName), range0)) + () + // Note for compiler developers: to get information about which item this index relates to, // enable the conditional in Pickle.p_osgn_ref to refer to the given index number and recompile // an identical copy of the source for the DLL containing the data being unpickled. A message will