-
Notifications
You must be signed in to change notification settings - Fork 804
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proof of concept: reusing typecheck results #18354
base: main
Are you sure you want to change the base?
Changes from all commits
e31552c
d9e621f
cec8087
d3788bf
3130685
46ff11b
c053c70
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this is apparently a very dumb mechanism of collecting states. Instead, the state "deltas" should be collected and merged here. |
||
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<NodeToTypeCheck, State, PartialResult> = | ||
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<NodeToTypeCheck, State, PartialResult> = | ||
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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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<QualifiedNameOfFile, ModuleOrNamespaceType> | ||
|
||
type RootImpls = Zset<QualifiedNameOfFile> | ||
|
||
val qnameOrder: IComparer<QualifiedNameOfFile> | ||
|
||
/// Represents the incremental type checking state for a set of inputs | ||
[<Sealed>] | ||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also note, TcState list includes the first state. I just kept the first state separately here to decrease the change surface a bit for now. |
||
|
||
/// Check a single input and finish the checking | ||
val CheckOneInputAndFinish: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is expected, basic APIs will likely have to increase their surface to make them accessible to the new pickling code.