From 3f76096b74886bf36b0b65aad00a820a25252b77 Mon Sep 17 00:00:00 2001 From: Martin Vogel Date: Sun, 28 Jun 2026 07:23:37 +0200 Subject: [PATCH] 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 --- internal/cbm/extract_unified.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/internal/cbm/extract_unified.c b/internal/cbm/extract_unified.c index 3455807d1..4937b401a 100644 --- a/internal/cbm/extract_unified.c +++ b/internal/cbm/extract_unified.c @@ -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; }