-
Notifications
You must be signed in to change notification settings - Fork 831
Sort the finisher #15489
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
Sort the finisher #15489
Conversation
I think we do have a good grasp on why processing artificial files before signature files leads to an error - signature files check their contents for duplicates against So processing of a signature file does not affect further duplicate checks, because it doesn't modify Processing of ArtificialImplFile (or real impl file) does add its symbols to This is equivalent to processing an implementation file before its signature (ignoring the fact this would fail at earlier stages). So it makes sense that order should be maintained. The one thing I wasn't sure of was why this wasn't spotted before, given it's a generic issue. This is still not clear to me. The change is definitely the right thing to do regardless. |
0101
left a comment
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.
Nice! I just started investigating this error in Transparent Compiler. Will try to apply the changes there and see if it helps. Even though I'm not using processTypeCheckingGraph or combineResults, it looks like the underlying issue might be the same.
src/Compiler/Driver/GraphChecking/TypeCheckingGraphProcessing.fs
Outdated
Show resolved
Hide resolved
Oh, is it the one when we have wrong data after unpicking? |
I don't mind either way. |
No that's a separate issue. Most likely unrelated to this.
Can we keep it for now in case we'll be able to re-use it in Transparent Compiler? Where we'd potentially need to drag more data through it. Not sure yet if it's possible but would be nice if it was unified. |
I genuinely think it would be great if we could address that situation when it arises. We can easily identify and streamline the code when we notice any duplication. |
Some of you may have seen the following error message when compiling
FSharp.Compiler.Service.fsprojusing the new--test:GraphBasedCheckingflag.You can easily reproduce this problem when you add
in
CheckOneInputWithCallbackinParseAndCheckInputs.fs.It was initially discovered reliably by @safesparrow via
In this example, it would fail after a couple of attempts. And show the
error FS0248: Two modules named 'Continuation' occur in two parts of this assemblymessage from:fsharp/src/Compiler/TypedTree/TypedTreeOps.fs
Line 10164 in 5225dc8
After some investigation, we noticed that when preparing a certain
TcStateto be used inCheckOneInputWithCallback, the order of the folded finishers is random.Initially, this didn't seem to matter. And to me, it is still somewhat unclear whether it does.
To recapitulate what happens before
CheckOneInputWithCallbackto construct theTcState:combineResultsgets called for the next node we wish to processfsharp/src/Compiler/Driver/GraphChecking/TypeCheckingGraphProcessing.fs
Lines 21 to 59 in 1d8aa13
Here, the
firstStateis picked by looking at the biggest dependency, in order to reduce the number of folds that are still required to have all dependencies information of the current node in theTcState.In the concrete case of
Driver\GraphChecking\FileContentMapping.fsthere are four nodes left to fold over thefirstStatein order to get the correct starting state to begin processingFileContentMapping.fs:(What is an
ArtificialImplFileagain? It is adding the results of a typed-check signature file to theTcEnvof implementation files. Mimicking as if we type-checked the actual implementation file).Currently, this order is random. And so far that didn't seem to matter. Eventually, once everything is folded, all information is available in both
TcEnvinTcStateand all is fine.However, given the
Two modules named 'Continuation' occur in two parts of this assemblyerror, the order appears to be relevant after all.The old setting
--test:ParallelCheckingWithSignatureFilesOn, always did respect this order. It used the same gimmick of adding signature information to theTcEnvof implementation files. But it always respected the file order.What currently feels wrong to me here, is that we fold the information of an implementation file to the
TcState.TcEnvFromImplsof implementation files (be it a copy of the signature file) first before the actual physical signature is merged on top of theTcState.TcEnvFromSignaturesof signature files. This means thatNodeToTypeCheck.ArtificialImplFile of Xis folded before theNodeToTypeCheck.PhysicalFile of X. IfXhas both theArtificialImplFile(copy of signature data for implementationTcEnv) andPhysicalFile(real signature), that should always be folded first.This is not the expected way this should happen. For the same reason, your signature file always needs to be above your implementation in your project.
My educated guess is that this might impact the
CcuThunkof theTcStateand thus leads us to the error we see. I have yet to find real evidence for this. Nor can I really put my finger on why this happens forContinuation.fsiand no other files. Speculation is that bothContinuation.fsandContinuation.fsiare very small and this might be related.Once I sorted the order of finishers, I was no longer able to reproduce the problem.
On a side note, the graph-based node code can be a bit confusing to debug at times. That is why I added the
NodeToTypeCheckto theFinisher. I think we might benefit from a few more additions to improve the debugging experience.@safesparrow I would be in favour of removing the generics in
TypeCheckingGraphProcessing.processTypeCheckingGraph, I don't think they add that much, to be honest. Thoughts?Lastly, when you think about it.
Continuation.fsiwould also just be a private module forFileContentMapping.fs. As it really is only used there and contains two helper functions.