Skip to content

Conversation

@nojaf
Copy link
Member

@nojaf nojaf commented Dec 22, 2025

Fixes #1166

I would test this PR for some time on my local machine to see if there are no regressions.
Feel free this review already.

`${stderr}\n#Done()`,
);

// Re-verify again after second async operation
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the key change for the race problem.
After the second async call, we want to check again if there is no newer request.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes issue #1166 by adding a second token verification after parsing compiler log output to prevent race conditions in incremental compilation. The implementation refactors the compilation flow from callback-based to promise-based using AbortController for better async handling.

Key changes:

  • Migrates from callback-based execFile to promise-based execFilePromise with AbortController for cleaner async/await flow
  • Adds second token verification after parseCompilerLogOutput to catch compilations that became stale during parsing
  • Extracts repetitive code into helper functions (remapCodeActionsToSourceFile, filterIncrementalDiagnostics, logIncrementalCompilationError, processAndPublishDiagnostics)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@zth
Copy link
Member

zth commented Dec 22, 2025

What do you think, is it worth shipping this to the prerelease extension to get broader test coverage?

We should really revamp this whole editor tooling integration now that Rewatch is first class. I'm not sure it has to be that difficult/much work either, but I assume it'd take a few planning sessions to get the structure right. But the end game really is that I think, to revamp it. Currently the extension is guessing about compilation from timestamps etc, but Rewatch already knows all of this and could just as easily drive how the editor tooling syncs/updates.

One route for that is of course to do the LSP in Rust fully and launch it via Rewatch. But just the alternative of having Rewatch push changes to the editor tooling that then distributes them, in the current structure, would be enough to start making serious improvements, I think.

@nojaf
Copy link
Member Author

nojaf commented Dec 22, 2025

What do you think, is it worth shipping this to the prerelease extension to get broader test coverage?

Yeah maybe, but I really need to do some testing. So far, only did the fun coding part.

As for the future, we can definitely craft something beautiful and need do some planning.
For now, I do still see some value in the quick wins we can still make in the current codebase.

@nojaf
Copy link
Member Author

nojaf commented Dec 22, 2025

f94574d and 092863d fix #1168

@zth I think these are worth having as well.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +647 to +655
const notification: p.NotificationMessage = {
jsonrpc: c.jsonrpcVersion,
method: "textDocument/publishDiagnostics",
params: {
uri: fileUri,
diagnostics: res,
},
};
send(notification);
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The refactored code no longer combines incremental diagnostics with compiler diagnostics from the main build. The old implementation called getCurrentCompilerDiagnosticsForFile(fileUri) and merged those diagnostics with the incremental ones before publishing. This logic should be restored to ensure diagnostics from the main build are not lost when incremental compilation completes.

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is the whole point silly.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +549 to +551
hasIgnoredMessages = true;
return true;
}
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tracking of ignored messages has inverted logic. The variable hasIgnoredMessages is set to true inside the filter when returning true (meaning the diagnostic is KEPT), but it should be set when a diagnostic is FILTERED OUT (ignored).

For example:

  • Messages starting with "Uninterpreted extension 'rescript." are filtered out (return false), but hasIgnoredMessages remains false
  • Messages that don't match the filter conditions are kept (return true), but hasIgnoredMessages is set to true

This causes the error logging condition at line 625 (!hasIgnoredMessages) to have opposite behavior: it will be false when diagnostics were kept (preventing legitimate error logging) and true when diagnostics were filtered out (causing incorrect error logging).

Suggested change
hasIgnoredMessages = true;
return true;
}
return true;
}
hasIgnoredMessages = true;

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code didn't change, it was merely extracted so I would not touch it.

);
await sendUpdatedDiagnostics();

if (config.extensionConfiguration.incrementalTypechecking?.enable) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the other relevant change: we check the file with incremental compilation versus looking at potentially stale .compiler.log

@nojaf nojaf merged commit adf96f7 into rescript-lang:master Dec 23, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Potential race condition in incremental compilation

2 participants