@@ -157,9 +157,10 @@ impl<'db> SyntaxNode<'db> {
157157    } 
158158} 
159159
160- /// Create a new syntax node. 
161- #[ salsa:: tracked]  
162- pub  fn  new_syntax_node < ' db > ( 
160+ /// Internal function for creating syntax nodes without tracking. 
161+ /// This should only be called from within tracked functions (like `new_root` or `get_children`). 
162+ /// Not public to prevent untracked creation paths. 
163+ pub ( crate )  fn  new_syntax_node < ' db > ( 
163164    db :  & ' db  dyn  Database , 
164165    green :  GreenId < ' db > , 
165166    offset :  TextOffset , 
@@ -168,11 +169,24 @@ pub fn new_syntax_node<'db>(
168169    SyntaxNode ( SyntaxNodeData :: new ( db,  green,  offset,  id) ) 
169170} 
170171
172+ /// Tracked function for creating syntax nodes. 
173+ /// This ensures all SyntaxNode creation happens within a tracked context. 
174+ #[ salsa:: tracked]  
175+ fn  new_tracked_impl < ' db > ( 
176+     db :  & ' db  dyn  Database , 
177+     green :  GreenId < ' db > , 
178+     offset :  TextOffset , 
179+     id :  SyntaxNodeId < ' db > , 
180+ )  -> SyntaxNode < ' db >  { 
181+     new_syntax_node ( db,  green,  offset,  id) 
182+ } 
183+ 
171184// Construction methods 
172185impl < ' a >  SyntaxNode < ' a >  { 
173186    /// Create a new root syntax node. 
187+ /// This is the main public API for creating syntax nodes. 
174188pub  fn  new_root ( db :  & ' a  dyn  Database ,  file_id :  FileId < ' a > ,  green :  GreenId < ' a > )  -> Self  { 
175-         new_syntax_node ( db,  green,  TextOffset :: START ,  SyntaxNodeId :: Root ( file_id) ) 
189+         new_tracked_impl ( db,  green,  TextOffset :: START ,  SyntaxNodeId :: Root ( file_id) ) 
176190    } 
177191
178192    /// Create a new root syntax node with a custom initial offset. 
@@ -182,7 +196,22 @@ impl<'a> SyntaxNode<'a> {
182196        green :  GreenId < ' a > , 
183197        initial_offset :  Option < TextOffset > , 
184198    )  -> Self  { 
185-         new_syntax_node ( db,  green,  initial_offset. unwrap_or_default ( ) ,  SyntaxNodeId :: Root ( file_id) ) 
199+         new_tracked_impl ( 
200+             db, 
201+             green, 
202+             initial_offset. unwrap_or ( TextOffset :: START ) , 
203+             SyntaxNodeId :: Root ( file_id) , 
204+         ) 
205+     } 
206+ 
207+     /// Create a new syntax node using a tracked function. 
208+ pub  fn  new_tracked ( 
209+         db :  & ' a  dyn  Database , 
210+         green :  GreenId < ' a > , 
211+         offset :  TextOffset , 
212+         id :  SyntaxNodeId < ' a > , 
213+     )  -> Self  { 
214+         new_tracked_impl ( db,  green,  offset,  id) 
186215    } 
187216
188217    // Basic accessors 
@@ -258,6 +287,7 @@ impl<'a> SyntaxNode<'a> {
258287            let  index = * key_count; 
259288            * key_count += 1 ; 
260289            // Create the SyntaxNode view for the child. 
290+             // Use untracked creation since we're already in a tracked context (get_children). 
261291            res. push ( new_syntax_node ( 
262292                db, 
263293                * green_id, 
0 commit comments