diff --git a/cli/src/tests/query_test.rs b/cli/src/tests/query_test.rs index e769cf89..b8773acb 100644 --- a/cli/src/tests/query_test.rs +++ b/cli/src/tests/query_test.rs @@ -5727,3 +5727,25 @@ fn test_query_with_anonymous_error_node() { vec![(1, vec![("error", "ERROR")]), (0, vec![("error", "ERROR")])] ); } + +#[test] +fn test_query_allows_error_nodes_with_children() { + allocations::record(|| { + let language = get_language("cpp"); + + let code = "SomeStruct foo{.bar{}};"; + + let mut parser = Parser::new(); + parser.set_language(&language).unwrap(); + + let tree = parser.parse(code, None).unwrap(); + let root = tree.root_node(); + + let query = Query::new(&language, "(initializer_list (ERROR) @error)").unwrap(); + let mut cursor = QueryCursor::new(); + + let matches = cursor.matches(&query, root, code.as_bytes()); + let matches = collect_matches(matches, &query, code); + assert_eq!(matches, &[(0, vec![("error", ".bar")])]); + }); +} diff --git a/lib/src/query.c b/lib/src/query.c index 0dc512e7..6c514887 100644 --- a/lib/src/query.c +++ b/lib/src/query.c @@ -1340,7 +1340,12 @@ static void ts_query__perform_analysis( // Determine if this hypothetical child node would match the current step // of the query pattern. bool does_match = false; - if (visible_symbol) { + + // ERROR nodes can appear anywhere, so if the step is + // looking for an ERROR node, consider it potentially matchable. + if (step->symbol == ts_builtin_sym_error) { + does_match = true; + } else if (visible_symbol) { does_match = true; if (step->symbol == WILDCARD_SYMBOL) { if (