rust-analyzer / rowan

Apache License 2.0
704 stars 58 forks source link

Sending `SyntaxNode`s to other threads? #155

Open shilangyu opened 1 year ago

shilangyu commented 1 year ago

I have a need to send SyntaxNodes to other threads, however SyntaxNode is not Send. What is the recommended approach to such usecases? I know green nodes are both send and sync, but they dont provide the needed information (text offsets). SyntaxNode is preferred, as it can be used in typed AST wrappers.

One solution that comes to mind is sending the green node and turning it into a syntax node in the new thread. But this seems wasteful if I already have a syntax node (I would have to turn it into a green node just to rebuild the syntax node in a new thread). Is there a better solution?

tadeokondrak commented 1 year ago

But this seems wasteful if I already have a syntax node (I would have to turn it into a green node just to rebuild the syntax node in a new thread). Is there a better solution?

I don't work on Rowan, but my understanding is that SyntaxNode is a wrapper over GreenNode, meaning that conversion from SyntaxNode to GreenNode is essentially free. Also, SyntaxNode lazily builds other SyntaxNodes when traversing, so creating one should be fine.

edgarogh commented 1 year ago

It's dangerous because SyntaxNode contains a non-atomic reference counter, so your threads could potentially have concurrency issues and free the SyntaxNode when it still has references for instance. That's why it cannot be Send. I guess you'll have to do a deep clone.

matklad commented 1 year ago

Send a pair of a GreenNode and SyntaxNodePtr:

https://docs.rs/rowan/0.15.11/rowan/ast/struct.SyntaxNodePtr.html