-
Notifications
You must be signed in to change notification settings - Fork 582
Non-mutating version of resolveConstants
#5532
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
Conversation
This should be safe--if we ever call addMixin after this, we will reset the linearization status on that class. This allows us to call `verifyLinearizationComputed` in `runIncrementalBestEffort` (because our test suite tests an edge case where we run `runIncrementalBestEffort` with `--no-stdlib` so Resolver truly has never been run before).
Mostly uses the technique that froydnj established in #5456.
| Symbols::MAX_SYNTHETIC_TYPEARGUMENT_SYMBOLS); | ||
|
|
||
| installIntrinsics(); | ||
| computeLinearization(); |
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.
Motivation is also in this commit message:
This should be safe--if we ever call addMixin after this, we will reset
the linearization status on that class.
This allows us to call `verifyLinearizationComputed` in
`runIncrementalBestEffort` (because our test suite tests an edge case
where we run `runIncrementalBestEffort` with `--no-stdlib` so Resolver
truly has never been run before).
resolver/resolver.cc
Outdated
| vector<ast::ParsedFile> trees) { | ||
| auto workers = WorkerPool::create(0, gs.tracer()); | ||
| // trees = ResolveConstantsWalk::resolveConstants(gs, std::move(trees), *workers); | ||
| trees = ResolveConstantsWalk::resolveConstants(gs, std::move(trees), *workers); |
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 was accidentally commented out in the original change. It's quite important that it not be commented out (this is basically all the work that resolver does 😅 )
| // If the constant didn't immediately resolve during the initial treewalk, and we're not | ||
| // allowed to mutate GlobalState, it will never resolve. Let's just skip to the error phase. | ||
| if constexpr (isMutableStateType) { |
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 the key insight that makes this change workable at all, and not immeasurably hairy.
The ResolveConstantsWalk will try to avoid enqueuing work into the various todo lists for the sake of speed. That means that if there's anything in the todo lists at the end of the loop, they're there because they were hoping to be resolved / processed once some other todo list item had been processed.
But we won't actually be able to make progress. Making progress requires being able to modify the symbol table, so that other items can discover new state in the symbol table and make their own progress. That will never happen in the immutable resolver mode, so we can skip straight to the final part.
test/pipeline_test_runner.cc
Outdated
| // If no ENFORCE fired, then non-mutating namer is working fine. | ||
| treesCopy = move(resolver::Resolver::runIncremental(immutableGS, move(treesCopy)).result()); | ||
|
|
||
| // If no ENFORCE fired, then immutatable namer + resolver is working fine. |
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.
I've just realized that we probably want to run DefLocSaver and typecheckOne on these resolved trees. Both of those operate on immutable GlobalState already, so it's just a question of do our namer and resolver passes do a good enough job at cleaning up the trees.
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.
I added this.
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.
Was the intent here to ensure that we're able to answer LSP queries when using a stale global state?
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.
yep!
Motivation
This will allow us to make more progress on #5469 (LSP queries on stale state)
Commit summary
Your best bet is to review by commit, ignoring whitespace.
Move computeLinearization to GlobalState (1859b30)
pre-work: Use lambda for better clang-format (9a2d590)
computeLinearization in GlobalState::initEmpty (7303377)
This should be safe--if we ever call addMixin after this, we will reset
the linearization status on that class.
This allows us to call
verifyLinearizationComputedinrunIncrementalBestEffort(because our test suite tests an edge casewhere we run
runIncrementalBestEffortwith--no-stdlibso Resolvertruly has never been run before).
Non-mutating version of
resolveConstants(6c7fd4e)Mostly uses the technique that froydnj established in add a non-mutating incremental resolver interface #5456.
Rest of the failures (598d5ed)
Test plan
This calls the immutable incremental resolver immediately after the immutable
namer and enables all ENFORCEs and sanityChecks, so that we can use our existing
test suite as a test of how well these modes work.