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 8c19083bb74..b0d0b1d8b59 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md @@ -19,8 +19,9 @@ * 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)) -* Added type conversions cache, only enabled for compiler runs, guarded by language version preview ([PR #17668](https://github.com/dotnet/fsharp/pull/17668)) -* Added project property ParallelCompilation which turns on graph based type checking, parallel ILXGen and parallel optimization. By default on for users of langversion=preview ([PR #17948](https://github.com/dotnet/fsharp/pull/17948)) +* Added type conversions cache, only enabled for compiler runs, guarded by language version preview ([PR#17668](https://github.com/dotnet/fsharp/pull/17668)) +* Added project property ParallelCompilation which turns on graph based type checking, parallel ILXGen and parallel optimization. By default on for users of langversion=preview ([PR#17948](https://github.com/dotnet/fsharp/pull/17948)) +* New flag `--reusetypecheckingresults`, for skipping recompilation in some cases ### Changed diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index 997f7a50aae..eeacd8b84af 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -444,6 +444,11 @@ type TypeCheckingMode = | Sequential | Graph +[] +type ReuseTcResults = + | On + | Off + [] type TypeCheckingConfig = { @@ -651,6 +656,8 @@ type TcConfigBuilder = mutable parallelReferenceResolution: ParallelReferenceResolution + mutable reuseTcResults: ReuseTcResults + mutable captureIdentifiersWhenParsing: bool mutable typeCheckingConfig: TypeCheckingConfig @@ -660,6 +667,8 @@ type TcConfigBuilder = mutable realsig: bool mutable compilationMode: TcGlobals.CompilationMode + + mutable cmdLineArgs: string array } // Directories to start probing in @@ -861,6 +870,7 @@ type TcConfigBuilder = xmlDocInfoLoader = None exiter = QuitProcessExiter parallelReferenceResolution = ParallelReferenceResolution.Off + reuseTcResults = ReuseTcResults.Off captureIdentifiersWhenParsing = false typeCheckingConfig = { @@ -875,6 +885,7 @@ type TcConfigBuilder = realsig = false strictIndentation = None compilationMode = TcGlobals.CompilationMode.Unset + cmdLineArgs = [||] } member tcConfigB.FxResolver = @@ -1415,11 +1426,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 fa7319fd1c2..668b351cef0 100644 --- a/src/Compiler/Driver/CompilerOptions.fs +++ b/src/Compiler/Driver/CompilerOptions.fs @@ -1346,6 +1346,14 @@ let advancedFlagsFsc tcConfigB = None, Some(FSComp.SR.optsEmitDebugInfoInQuotations ()) ) + + 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/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs index 22ea3c7f033..cd3c6073941 100644 --- a/src/Compiler/Driver/ParseAndCheckInputs.fs +++ b/src/Compiler/Driver/ParseAndCheckInputs.fs @@ -31,6 +31,7 @@ open FSharp.Compiler.LexerStore open FSharp.Compiler.Lexhelp open FSharp.Compiler.NameResolution open FSharp.Compiler.ParseHelpers +open FSharp.Compiler.ReuseTcResults open FSharp.Compiler.Syntax open FSharp.Compiler.SyntaxTrivia open FSharp.Compiler.Syntax.PrettyNaming @@ -1960,6 +1961,10 @@ let CheckMultipleInputsUsingGraphMode partialResults, tcState) let CheckClosedInputSet (ctok, checkForErrors, tcConfig: TcConfig, tcImports, tcGlobals, prefixPathOpt, tcState, eagerFormat, inputs) = + + if tcConfig.reuseTcResults = ReuseTcResults.On then + CachingDriver(tcConfig).TryReuseTcResults(inputs) + // tcEnvAtEndOfLastFile is the environment required by fsi.exe when incrementally adding definitions let results, tcState = match tcConfig.typeCheckingConfig.Mode with diff --git a/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs b/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs new file mode 100644 index 00000000000..c740a9d3a4b --- /dev/null +++ b/src/Compiler/Driver/ReuseTcResults/CachingDriver.fs @@ -0,0 +1,144 @@ +module internal FSharp.Compiler.ReuseTcResults + +open System +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 + +open Internal.Utilities.Hashing + +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 getContentHash fileName = + use stream = FileSystem.OpenFileForReadShim fileName + stream.ReadAllBytes() |> Md5Hasher.computeHash |> BitConverter.ToString + + 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 hash = getContentHash sourceFiles[idx].FileName + list.Add($"%i{idx}[\"{hash}\"]") + + for KeyValue(idx, deps) in graph do + for depIdx in deps do + list.Add($"%i{idx} --> %i{depIdx}") + + list.ToArray() + + let getThisCompilationReferences = + List.map (fun (r: AssemblyReference) -> r.Text, getContentHash r.Text) + >> List.map (fun (name, hash) -> $"{name}: {hash}") + >> List.toArray + + member _.TryReuseTcResults inputs = + let prevTcDataOpt = readPrevTcData () + + let thisTcData = + { + CmdLine = getThisCompilationCmdLine tcConfig.cmdLineArgs + Graph = getThisCompilationGraph inputs + References = getThisCompilationReferences tcConfig.referencedDLLs + } + + if prevTcDataOpt.IsSome then + use _ = Activity.start Activity.Events.reuseTcResultsCachePresent [] + + if prevTcDataOpt.Value = thisTcData then + use _ = Activity.start Activity.Events.reuseTcResultsCacheHit [] + + () // do nothing, yet + else + use _ = Activity.start Activity.Events.reuseTcResultsCacheMissed [] + + writeThisTcData thisTcData + else + use _ = Activity.start Activity.Events.reuseTcResultsCacheAbsent [] + + writeThisTcData thisTcData diff --git a/src/Compiler/Driver/ReuseTcResults/CachingDriver.fsi b/src/Compiler/Driver/ReuseTcResults/CachingDriver.fsi new file mode 100644 index 00000000000..af3e467a557 --- /dev/null +++ b/src/Compiler/Driver/ReuseTcResults/CachingDriver.fsi @@ -0,0 +1,11 @@ +module internal FSharp.Compiler.ReuseTcResults + +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.Syntax + +[] +type CachingDriver = + + new: tcConfig: TcConfig -> CachingDriver + + member TryReuseTcResults: inputs: ParsedInput seq -> unit diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs index 1d17950a9ac..373ff72e36b 100644 --- a/src/Compiler/Driver/fsc.fs +++ b/src/Compiler/Driver/fsc.fs @@ -511,6 +511,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 b42500049d2..4bd484ac4c4 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1789,3 +1789,4 @@ featureUseTypeSubsumptionCache,"Use type conversion cache during compilation" featureDontWarnOnUppercaseIdentifiersInBindingPatterns,"Don't warn on uppercase identifiers in binding patterns" 3873,chkDeprecatePlacesWhereSeqCanBeOmitted,"This construct is deprecated. Sequence expressions should be of the form 'seq {{ ... }}'" featureDeprecatePlacesWhereSeqCanBeOmitted,"Deprecate places where 'seq' can be omitted" +optsReuseTcResults,"Reuse previous typechecking results for faster compilation" \ No newline at end of file diff --git a/src/Compiler/FSharp.Compiler.Service.fsproj b/src/Compiler/FSharp.Compiler.Service.fsproj index 419746af6c0..cd2cc2ef12b 100644 --- a/src/Compiler/FSharp.Compiler.Service.fsproj +++ b/src/Compiler/FSharp.Compiler.Service.fsproj @@ -461,6 +461,8 @@ + + diff --git a/src/Compiler/SyntaxTree/PrettyNaming.fs b/src/Compiler/SyntaxTree/PrettyNaming.fs index 8ea10266de8..4b485e92bc3 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 b6fafe1c1b9..9a218363ee9 100644 --- a/src/Compiler/Utilities/Activity.fs +++ b/src/Compiler/Utilities/Activity.fs @@ -69,6 +69,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 ec6a9fbf6f8..06bfd8fc52c 100644 --- a/src/Compiler/Utilities/Activity.fsi +++ b/src/Compiler/Utilities/Activity.fsi @@ -39,6 +39,12 @@ 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 val start: name: string -> tags: (string * string) seq -> IDisposable diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index c74702e5ddc..02b50250730 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -967,6 +967,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 3e0443ea3ba..2e21aac6ecb 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -967,6 +967,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 ecadc24a021..71f5786bbb8 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -967,6 +967,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 7a9769e0d22..f34d54d3266 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -967,6 +967,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 1db94e74c44..0fc25cc25f5 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -967,6 +967,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 67b3ad51f9a..3958df81218 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -967,6 +967,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 d33ad95bff5..f15789fa2fa 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -967,6 +967,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 a992a59bb23..b9a2a07baa2 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -967,6 +967,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 d547f088b3e..39d8b30249d 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -967,6 +967,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 1da17d068ce..379a1579f1b 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -967,6 +967,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 fe29aebcff7..c240679bbf9 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -967,6 +967,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 c1b2b3d4682..ebbf58e5546 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -967,6 +967,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 7c6c76ff2f7..b53b408361d 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -967,6 +967,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 75e32680e65..718c5f68045 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 @@ -114,3 +114,4 @@ Copyright (c) Microsoft Corporation. All Rights Reserved. --highentropyva[+|-] Enable high-entropy ASLR --subsystemversion: Specify subsystem version of this assembly --quotations-debug[+|-] Emit debug information in quotations +--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 a1a46d7a99e..ffd0ce9e94f 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -262,6 +262,7 @@ + diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/ReuseTcResultsTests.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/ReuseTcResultsTests.fs new file mode 100644 index 00000000000..747015c5b3e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/ReuseTcResults/ReuseTcResultsTests.fs @@ -0,0 +1,158 @@ +module TypeChecks.ReuseTcResultsTests + +open System.Collections.Generic +open System.Diagnostics + +open FSharp.Compiler.Diagnostics +open FSharp.Test.Compiler + +open Xunit + +open TestFramework + +type Activities() = + + let tempDir = createTemporaryDirectory() |> Some + let tempName = getTemporaryFileName() + + 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 + ] + + let cUnit = + Fsx "42" + |> withOutputDirectory tempDir + |> withName tempName + + cUnit + |> withReuseTcResults + |> compile + |> shouldSucceed + |> ignore + + let cUnit = + Fsx "43" + |> withOutputDirectory tempDir + |> withName tempName + + cUnit + |> withReuseTcResults + |> compile + |> shouldSucceed + |> ignore + + Assert.Equal>(expectedActivities, actualActivities) + + [] + let ``Recompilation with changed command line``() = + let expectedActivities = List [ + Activity.Events.reuseTcResultsCacheAbsent + Activity.Events.reuseTcResultsCachePresent + Activity.Events.reuseTcResultsCacheMissed + ] + + let cUnit = + Fsx "42" + |> withOutputDirectory tempDir + |> withName tempName + + cUnit + |> withReuseTcResults + |> compile + |> shouldSucceed + |> ignore + + cUnit + |> withReuseTcResults + |> withNoOptimizationData // random option + |> compile + |> shouldSucceed + |> ignore + + Assert.Equal>(expectedActivities, actualActivities) + + [] + let ``Recompilation with changed references``() = + let expectedActivities = List [ + Activity.Events.reuseTcResultsCacheAbsent + Activity.Events.reuseTcResultsCachePresent + Activity.Events.reuseTcResultsCacheMissed + ] + + let reference = + FSharp "module Old" + |> withName "ref" + + let cUnit = + Fsx "42" + |> withReferences [ reference ] + |> withOutputDirectory tempDir + |> withName tempName + + cUnit + |> withReuseTcResults + |> compile + |> shouldSucceed + |> ignore + + let reference = + FSharp "module New" + |> withName "ref" + + let cUnit = + Fsx "42" + |> withReferences [ reference ] + |> withOutputDirectory tempDir + |> withName tempName + + cUnit + |> withReuseTcResults + |> compile + |> shouldSucceed + |> ignore + + Assert.Equal>(expectedActivities, actualActivities) + + [] + let ``Recompilation with everything same``() = + let expectedActivities = List [ + Activity.Events.reuseTcResultsCacheAbsent + Activity.Events.reuseTcResultsCachePresent + Activity.Events.reuseTcResultsCacheHit + ] + + let cUnit = + Fsx "42" + |> withOutputDirectory tempDir + |> withName tempName + + cUnit + |> withReuseTcResults + |> compile + |> shouldSucceed + |> ignore + + cUnit + |> withReuseTcResults + |> compile + |> 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 61cf7105859..16a6d23ae9d 100644 --- a/tests/FSharp.Compiler.Service.Tests/expected-help-output.bsl +++ b/tests/FSharp.Compiler.Service.Tests/expected-help-output.bsl @@ -177,3 +177,5 @@ --subsystemversion: Specify subsystem version of this assembly --quotations-debug[+|-] Emit debug information in quotations +--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 115964702f8..f12e204b390 100644 --- a/tests/FSharp.Test.Utilities/Compiler.fs +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -574,6 +574,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 diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl index d59c7d2adda..1940fdf5e5b 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl @@ -37,10 +37,10 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions+getOptionArgList@307::Invoke([FSharp.Compiler.Service]FSharp.Compiler.CompilerOptions+CompilerOption, string)][offset 0x0000003E][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions+getSwitch@325::Invoke(string)][offset 0x0000000B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions+attempt@373::Invoke([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1)][offset 0x00000E9F][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+Pipe #1 stage #1 at line 1865@1865::Invoke(int32)][offset 0x00000030][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+Pipe #1 stage #1 at line 1865@1865::Invoke(int32)][offset 0x00000039][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x0000062B][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x00000634][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+Pipe #1 stage #1 at line 1866@1866::Invoke(int32)][offset 0x00000030][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+Pipe #1 stage #1 at line 1866@1866::Invoke(int32)][offset 0x00000039][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x00000639][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x00000642][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.PatternMatchCompilation::isProblematicClause([FSharp.Compiler.Service]FSharp.Compiler.PatternMatchCompilation+MatchClause)][offset 0x00000065][found Byte] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharp.Compiler.PatternMatchCompilation::.cctor()][offset 0x00000015][found Boolean] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.TypeProviders::ValidateExpectedName([FSharp.Compiler.Service]FSharp.Compiler.Text.Range, string[], string, [FSharp.Compiler.Service]FSharp.Compiler.Tainted`1)][offset 0x000000AD][found Char] Unexpected type on the stack. diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl index be76953ef7d..1fa47ec85a9 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl @@ -53,11 +53,11 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions+attempt@373::Invoke([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1)][offset 0x00000E9F][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions+processArg@333::Invoke([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1)][offset 0x0000004D][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions+ResponseFile+parseLine@239::Invoke(string)][offset 0x00000031][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+Pipe #1 stage #1 at line 1865@1865::Invoke(int32)][offset 0x00000030][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+Pipe #1 stage #1 at line 1865@1865::Invoke(int32)][offset 0x00000039][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+Pipe #1 stage #1 at line 1866@1866::Invoke(int32)][offset 0x00000030][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+Pipe #1 stage #1 at line 1866@1866::Invoke(int32)][offset 0x00000039][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerImports+line@560-1::Invoke(string)][offset 0x0000000B][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x0000062B][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x00000634][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x00000639][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x00000642][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.PatternMatchCompilation::isProblematicClause([FSharp.Compiler.Service]FSharp.Compiler.PatternMatchCompilation+MatchClause)][offset 0x00000065][found Byte] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharp.Compiler.PatternMatchCompilation::.cctor()][offset 0x00000015][found Boolean] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+TastDefinitionPrinting+meths@2092-3::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Infos+MethInfo)][offset 0x000000BE][found Char] Unexpected type on the stack. diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl index 1c6248ec60a..eb275d298cf 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl @@ -39,10 +39,10 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions::attempt@372([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, string, string, string, string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1)][offset 0x00000A99][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions::AddPathMapping([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, string)][offset 0x0000000B][found Char] Unexpected type on the stack. [IL]: Error [StackUnderflow]: : FSharp.Compiler.CompilerOptions::DoWithColor([System.Console]System.ConsoleColor, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2)][offset 0x0000005E] Stack underflow. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+CheckMultipleInputsUsingGraphMode@1865::Invoke(int32)][offset 0x00000031][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+CheckMultipleInputsUsingGraphMode@1865::Invoke(int32)][offset 0x0000003A][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x0000059C][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x000005A5][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+CheckMultipleInputsUsingGraphMode@1866::Invoke(int32)][offset 0x00000031][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+CheckMultipleInputsUsingGraphMode@1866::Invoke(int32)][offset 0x0000003A][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x000005A8][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x000005B1][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.IlxGen::HashRangeSorted([S.P.CoreLib]System.Collections.Generic.IDictionary`2>)][offset 0x00000011][found ref '[FSharp.Compiler.Service]FSharp.Compiler.IlxGen+HashRangeSorted@1850-1'][expected ref '[FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,int32>'] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.IlxGen::HashRangeSorted([S.P.CoreLib]System.Collections.Generic.IDictionary`2>)][offset 0x00000012][found ref '[FSharp.Compiler.Service]FSharp.Compiler.IlxGen+HashRangeSorted@1850'][expected ref '[FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,T0>'] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.PatternMatchCompilation::isProblematicClause([FSharp.Compiler.Service]FSharp.Compiler.PatternMatchCompilation+MatchClause)][offset 0x00000040][found Byte] Unexpected type on the stack. diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl index fc795ecde1b..5c03fbb0457 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl @@ -55,12 +55,12 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions::subSystemVersionSwitch$cont@656([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, string, [FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x0000000B][found Char] Unexpected type on the stack. [IL]: Error [StackUnderflow]: : FSharp.Compiler.CompilerOptions::DoWithColor([System.Console]System.ConsoleColor, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2)][offset 0x0000005E] Stack underflow. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions+ResponseFile+parseLine@239::Invoke(string)][offset 0x00000026][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+CheckMultipleInputsUsingGraphMode@1865::Invoke(int32)][offset 0x00000031][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+CheckMultipleInputsUsingGraphMode@1865::Invoke(int32)][offset 0x0000003A][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+CheckMultipleInputsUsingGraphMode@1866::Invoke(int32)][offset 0x00000031][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+CheckMultipleInputsUsingGraphMode@1866::Invoke(int32)][offset 0x0000003A][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerImports+TcConfig-TryResolveLibWithDirectories@558-1::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000021][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerImports+TcConfig-TryResolveLibWithDirectories@558-1::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x0000003B][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x0000059C][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x000005A5][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x000005A8][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x000005B1][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.IlxGen::HashRangeSorted([S.P.CoreLib]System.Collections.Generic.IDictionary`2>)][offset 0x00000011][found ref '[FSharp.Compiler.Service]FSharp.Compiler.IlxGen+HashRangeSorted@1850-1'][expected ref '[FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,int32>'] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.IlxGen::HashRangeSorted([S.P.CoreLib]System.Collections.Generic.IDictionary`2>)][offset 0x00000012][found ref '[FSharp.Compiler.Service]FSharp.Compiler.IlxGen+HashRangeSorted@1850'][expected ref '[FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,T0>'] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.PatternMatchCompilation::isProblematicClause([FSharp.Compiler.Service]FSharp.Compiler.PatternMatchCompilation+MatchClause)][offset 0x00000040][found Byte] Unexpected type on the stack.