File tree Expand file tree Collapse file tree 3 files changed +31
-1
lines changed
crates/red_knot_python_semantic/src Expand file tree Collapse file tree 3 files changed +31
-1
lines changed Original file line number Diff line number Diff line change @@ -13,6 +13,28 @@ use ruff_db::parsed::ParsedModule;
1313///
1414/// ## Equality
1515/// Two `AstNodeRef` are considered equal if their pointer addresses are equal.
16+ ///
17+ /// ## Usage in salsa tracked structs
18+ /// It's important that [`AstNodeRef`] fields in salsa tracked structs are tracked fields
19+ /// (attributed with `#[tracked`]). It prevents that the tracked struct gets a new ID
20+ /// everytime the AST changes, which in turn, invalidates the result of any query
21+ /// that takes said tracked struct as a query argument or returns the tracked struct as part of its result.
22+ ///
23+ /// For example, marking the [`AstNodeRef`] as tracked on `Expression`
24+ /// has the effect that salsa will consider the expression as "unchanged" for as long as it:
25+ ///
26+ /// * belongs to the same file
27+ /// * belongs to the same scope
28+ /// * has the same kind
29+ /// * was created in the same order
30+ ///
31+ /// This means that changes to expressions in other scopes don't invalidate the expression's id, giving
32+ /// us some form of scope-stable identity for expressions. Only queries accessing the node field
33+ /// run on every AST change. All other queries only run when the expression's identity changes.
34+ ///
35+ /// The one exception to this is if it is known that all queries tacking the tracked struct
36+ /// as argument or returning it as part of their result are known to access the node field.
37+ /// Marking the field tracked is then unnecessary.
1638#[ derive( Clone ) ]
1739pub struct AstNodeRef < T > {
1840 /// Owned reference to the node's [`ParsedModule`].
Original file line number Diff line number Diff line change @@ -432,6 +432,13 @@ impl DefinitionCategory {
432432 }
433433}
434434
435+ /// The kind of a definition.
436+ ///
437+ /// ## Usage in salsa tracked structs
438+ ///
439+ /// [`DefinitionKind`] fields in salsa tracked structs should be tracked (attributed with `#[tracked]`)
440+ /// because the kind is a thin wrapper around [`AstNodeRef`]. See the [`AstNodeRef`] documentation
441+ /// for an in-depth explanation of why this is necessary.
435442#[ derive( Clone , Debug , Hash ) ]
436443pub enum DefinitionKind < ' db > {
437444 Import ( AstNodeRef < ast:: Alias > ) ,
Original file line number Diff line number Diff line change @@ -39,8 +39,9 @@ pub(crate) struct Expression<'db> {
3939 pub ( crate ) file_scope : FileScopeId ,
4040
4141 /// The expression node.
42- #[ return_ref ]
42+ #[ no_eq ]
4343 #[ tracked]
44+ #[ return_ref]
4445 pub ( crate ) node_ref : AstNodeRef < ast:: Expr > ,
4546
4647 /// Should this expression be inferred as a normal expression or a type expression?
You can’t perform that action at this time.
0 commit comments