-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
[red-knot] Token system to avoid cross-module query dependencies #16275
base: main
Are you sure you want to change the base?
[red-knot] Token system to avoid cross-module query dependencies #16275
Conversation
b054d43
to
31380ea
Compare
31380ea
to
978af92
Compare
/// It acts as a token of prove that we aren't accessing an AST node from a different file | ||
/// than in which the current enclosing Salsa query (which would lead to cross-file dependencies). |
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.
/// It acts as a token of prove that we aren't accessing an AST node from a different file | |
/// than in which the current enclosing Salsa query (which would lead to cross-file dependencies). | |
/// It acts as a token of proof that we aren't accessing an AST node from a different file | |
/// to the one from which the current enclosing Salsa query is being called. | |
/// Doing so would lead to cross-file dependencies, hurting incremental computation. |
/// It acts as a token of prove that we aren't accessing an AST node from a different file | ||
/// than in which the current enclosing Salsa query (which would lead to cross-file dependencies). |
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.
/// It acts as a token of prove that we aren't accessing an AST node from a different file | |
/// than in which the current enclosing Salsa query (which would lead to cross-file dependencies). | |
/// It acts as a token of proof that we aren't accessing an AST node from a different file | |
/// to the one from which the current enclosing Salsa query is being called. | |
/// Doing so would lead to cross-file dependencies, hurting incremental computation. |
/// `query_file` is the file for which the current query performs type inference. | ||
/// It acts as a token of prove that we aren't accessing an AST node from a different file | ||
/// than in which the current enclosing Salsa query (which would lead to cross-file dependencies). |
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.
/// `query_file` is the file for which the current query performs type inference. | |
/// It acts as a token of prove that we aren't accessing an AST node from a different file | |
/// than in which the current enclosing Salsa query (which would lead to cross-file dependencies). | |
/// `query_file` is the file for which the current query performs type inference. | |
/// It acts as a token of proof that we aren't accessing an AST node from a different file | |
/// to the one from which the current enclosing Salsa query is being called. | |
/// Doing so would lead to cross-file dependencies, hurting incremental computation. |
/// It acts as a token of prove that we aren't accessing an AST node from a different file | ||
/// than in which the current enclosing Salsa query (which would lead to cross-file dependencies). |
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.
/// It acts as a token of prove that we aren't accessing an AST node from a different file | |
/// than in which the current enclosing Salsa query (which would lead to cross-file dependencies). | |
/// It acts as a token of proof that we aren't accessing an AST node from a different file | |
/// to the one from which the current enclosing Salsa query is being called. | |
/// Doing so would lead to cross-file dependencies, hurting incremental computation. |
/// It acts as a token of prove that we aren't accessing an AST node from a different file | ||
/// than in which the current enclosing Salsa query (which would lead to cross-file dependencies). |
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.
/// It acts as a token of prove that we aren't accessing an AST node from a different file | |
/// than in which the current enclosing Salsa query (which would lead to cross-file dependencies). | |
/// It acts as a token of proof that we aren't accessing an AST node from a different file | |
/// to the one from which the current enclosing Salsa query is being called. | |
/// Doing so would lead to cross-file dependencies, hurting incremental computation. |
49e9d81
to
d888cf0
Compare
One caveat. This doesn't protect us fully from cross-module dependencies. For example, a function can still call |
d888cf0
to
82812e0
Compare
I have mixed feelings about this. It feels like it's not protecting the boundary at the layer where we need to protect it in order to get the results we actually want (as mentioned above about Exactly where the "right" layer is is still an open question: it could be set at "anything below Type", which would be I think pretty conceptually clean but might result in too many queries needed? But it seems clear that it ought to be set "above" semantic index at the very least. If you feel this alone would have avoided a significant number of the errors we've made in this area in the past, I'm not opposed to merging it for now and considering other approaches later. |
I do think it would have caught the cross-module use in But I agree that it's not as good as I first thought it would be. |
Summary
This PR introduces a token based system to reduce accidental cross-module query dependencies.
The basic idea is that we create a custom accessor for tracked struct fields that return an
AstNodeRef
and require an extraquery_file: File
argument.The
query_file
is the file of the enclosing query and we compare it against the tracked struct's scope to ensure it is the same.The basic idea here is: You should probably not access the node if don't know in which context your query runs or wrap your code in an extra query.
Getting the file should generally be easy. E.g.
TypeInferenceBuilder
has afile
method.This system doesn't prevent abuse. It's normally easy to get the correct file. E.g. you can call
definition.scope(db).file(db)
to get the filebut let's not do that ;).
The main downside of this approach is that it's sort of annoying. But I take that for extra peace of mind.
This should mitigate/fix #15949
Alternative approach
I considered changing
AstNodeRef::node
to take aFile
instead. But that quickly became annoying because we'd lose theDeref
andDebug
would also need a workaround. It also isn'tAstNodeRef::node
that's the problem, it's accessing the field on the tracked struct. That's why I opted for the custom-accessor on the tracked struct approach.The ideal solution is to solve this problem by restructuring our modules and enforce it with visibility constraints but that's a bit more work.