Comments (2)
This is really interesting! I took a look at this with a debugger and I think I found the problem. Namely, this line:
let mut query_matches = QueryCursor::new().matches(&query, tree.root_node(), text.as_bytes());
With the code written this way, drop()
is called for the QueryCursor
object. The drop
implementation calls ts_query_cursor_delete()
via ffi, which clears the contents of the array. Then, when you call query_matches.next();
, the underlying cursor object has been deallocated, leading to the assertion triggering due to an array with zero length:
/// Get a pointer to the element at a given `index` in the array.
#define array_get(self, _index) \
(assert((uint32_t)(_index) < (self)->size), &(self)->contents[_index])
Splitting the cursor's creation and the .matches()
call into separate lines, or just referencing the cursor later on to keep the object in scope for the matches()
call can work around the problem. For a more permanent fix, adding a lifetime annotation for the cursor in matches()
's definition appears to fix things:
#[doc(alias = "ts_query_cursor_exec")]
pub fn matches<'query, 'cursor: 'query, 'tree, T: TextProvider<I>, I: AsRef<[u8]>>(
&'cursor mut self,
query: &'query Query,
node: Node<'tree>,
text_provider: T,
) -> QueryMatches<'query, 'tree, T, I> {
let ptr = self.ptr.as_ptr();
unsafe { ffi::ts_query_cursor_exec(ptr, query.ptr.as_ptr(), node.0) };
QueryMatches {
ptr,
query,
text_provider,
buffer1: Vec::default(),
buffer2: Vec::default(),
_phantom: PhantomData,
}
}
Attempting to build your file with the above changes to tree-sitter yields the following error, which seems to correctly describe the problem:
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:10:29
|
10 | let mut query_matches = QueryCursor::new().matches(&query, tree.root_node(), text.as_bytes());
| ^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary value which is freed while still in use
...
13 | query_matches.next();
| ------------- borrow later used here
|
help: consider using a `let` binding to create a longer lived value
|
10 ~ let binding = QueryCursor::new();
11 ~ let mut query_matches = binding.matches(&query, tree.root_node(), text.as_bytes());
|
For more information about this error, try `rustc --explain E0716`.
error: could not compile `ts_test` (bin "ts_test") due to 1 previous error
I'll open up a PR with the fix :)
from tree-sitter.
Wow! I didn't think of that and this isn't the first time I've used Tree-sitter, but probably the first time I've put QueryCursor::new().matches
on the same line.
Thank you!
from tree-sitter.
Related Issues (20)
- `ts_node_is_missing()` fails if missing node wraps hidden rules
- ts_highlighter_add_language CAPI and Rust Implementation signature mismatch HOT 1
- `setTimeoutMicros` doesn't appear to work in the latest versions of `web-tree-sitter` HOT 2
- Rust bindings build script accesses `CARGO_MANIFEST_DIR` at compile time instead of run time
- fails to compile with ld from msys2/mingw with `features = ["wasm"]` HOT 1
- Split tree_sitter_cli::generate off into its own crate
- Segfault when using hardened memory allocator HOT 1
- Support negative/error syntax corpus tests HOT 3
- rust api: recursivly print tree via Debug trait if alternate flag is set HOT 7
- zig no longer works for builds in main branch of nvim-treesitter HOT 2
- Playground in offline mode HOT 4
- Don't minify tree-sitter.js HOT 1
- Support nostd HOT 5
- Swift package template dependencies HOT 4
- Assertion Failed on Terraform Files HOT 2
- "Undefined symbol" exception does not say the name of the symbol HOT 1
- `ts_node_descendant_for_point_range()` and `ts_node_descendant_for_byte_range()` with misspecified ranges
- 'tree-sitter generate src/grammar.json' creates a dummy 'grammar.js' HOT 2
- Assertion `length <= TREE_SITTER_SERIALIZATION_BUFFER_SIZE' failed
- [Feature] hope to be able to replace or modify a specific Node. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tree-sitter.