fix(rust): push impl-block class scope so impl-method calls source to the method

A call inside a Rust impl method (impl Calc { fn compute(&self,x) { add(...) } })
was sourced to the Module: impl_item is in rust_class_types, so push_boundary_scopes
routed it through compute_class_qn, which returned NULL because impl_item has no
name field (the implementing type is in the type field). The dedicated impl
handler later in push_boundary_scopes is therefore dead code (the class branch
already consumed impl_item). With no class scope, compute_func_qn produced
proj.file.compute instead of proj.file.Calc.compute, which does not match the
class-qualified def-side Method node, so calls_find_source missed it and fell
back to the file/Module node.

Resolve impl_item's type field in compute_class_qn (mirroring the objc class-name
case), so the impl pushes the Calc scope and impl-method calls attribute to the
method. grammar_core is now fully green.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This commit is contained in:
Martin Vogel
2026-06-28 07:23:37 +02:00
parent e986e777f1
commit 3f76096b74
+11
View File
@@ -377,6 +377,17 @@ static const char *compute_class_qn(CBMExtractCtx *ctx, TSNode node, const WalkS
if (ts_node_is_null(name_node) && ctx->language == CBM_LANG_OBJC) {
name_node = cbm_find_child_by_kind(node, "identifier");
}
/* Rust: impl_item has no `name` field; the implementing type is in the `type`
* field (`impl Calc {...}` / `impl Trait for Calc {...}` both -> Calc). The
* dedicated impl handler in push_boundary_scopes is dead code (impl_item is in
* rust_class_types, so the class branch runs first and lands here), so resolve
* the type here. Without a class scope, an impl method's QN drops the type
* (proj.file.method) and no longer matches the class-qualified def-side Method
* node, so in-body calls fall back to the Module. */
if (ts_node_is_null(name_node) && ctx->language == CBM_LANG_RUST &&
strcmp(ts_node_type(node), "impl_item") == 0) {
name_node = ts_node_child_by_field_name(node, TS_FIELD("type"));
}
if (ts_node_is_null(name_node)) {
return NULL;
}