mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 08:13:37 +08:00
test(pipeline): generic Rust impl methods source their own calls (both resolvers)
Sequential and parallel pipeline twin of extract_rust_generic_impl_call_scope_matches_def: the calls in a type-generic and a lifetime-generic impl method are sourced from the method, not from the File node. Refs #763 Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This commit is contained in:
@@ -8757,6 +8757,79 @@ TEST(pipeline_go_rw_usage_never_cross_into_c) {
|
||||
PASS();
|
||||
}
|
||||
|
||||
/* F-R4 (#763, Rust): calls inside a method of a generic impl (`impl<T> Gen<T>`,
|
||||
* `impl<'a> Life<'a>`) were sourced from the File node: the call scope kept the
|
||||
* generic arguments the def side strips. Each method must be the source of its
|
||||
* own call. pad_files > 0 forces the parallel resolver. */
|
||||
static int rust_generic_impl_attribution_case(int pad_files) {
|
||||
char tmp[256];
|
||||
snprintf(tmp, sizeof(tmp), "/tmp/cbm_rust_gimpl_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmp)) {
|
||||
FAIL("tmpdir");
|
||||
}
|
||||
write_temp_file(tmp, "Cargo.toml", "[package]\nname = \"fx\"\nversion = \"0.1.0\"\n");
|
||||
write_temp_file(tmp, "src/lib.rs",
|
||||
"pub struct Gen<T> { v: T }\n"
|
||||
"impl<T> Gen<T> {\n"
|
||||
" pub fn in_generic(&self) -> u32 { helper_a() }\n"
|
||||
"}\n"
|
||||
"pub struct Life<'a> { s: &'a str }\n"
|
||||
"impl<'a> Life<'a> {\n"
|
||||
" pub fn in_lifetime(&self) -> u32 { helper_b() }\n"
|
||||
"}\n"
|
||||
"pub fn helper_a() -> u32 { 1 }\n"
|
||||
"pub fn helper_b() -> u32 { 2 }\n");
|
||||
for (int i = 0; i < pad_files; i++) {
|
||||
char name[64];
|
||||
char body[128];
|
||||
snprintf(name, sizeof(name), "src/filler%d.rs", i);
|
||||
snprintf(body, sizeof(body), "pub fn filler%d() -> u32 {\n %d\n}\n", i, i);
|
||||
write_temp_file(tmp, name, body);
|
||||
}
|
||||
|
||||
char *saved = NULL;
|
||||
if (pad_files > 0) {
|
||||
char *old_workers = getenv("CBM_WORKERS");
|
||||
saved = old_workers ? strdup(old_workers) : NULL;
|
||||
cbm_setenv("CBM_WORKERS", "4", 1);
|
||||
}
|
||||
char db_path[512];
|
||||
snprintf(db_path, sizeof(db_path), "%s/rust_gimpl.db", tmp);
|
||||
cbm_pipeline_t *p = cbm_pipeline_new(tmp, db_path, CBM_MODE_FULL);
|
||||
ASSERT_NOT_NULL(p);
|
||||
ASSERT_EQ(cbm_pipeline_run(p), 0);
|
||||
const char *project = cbm_pipeline_project_name(p);
|
||||
cbm_store_t *s = cbm_store_open_path(db_path);
|
||||
ASSERT_NOT_NULL(s);
|
||||
|
||||
ASSERT_TRUE(cross_file_call_exists(s, project, "in_generic", "helper_a"));
|
||||
ASSERT_TRUE(cross_file_call_exists(s, project, "in_lifetime", "helper_b"));
|
||||
/* ... and not from the file. */
|
||||
ASSERT_FALSE(cross_file_call_exists(s, project, "lib.rs", "helper_a"));
|
||||
ASSERT_FALSE(cross_file_call_exists(s, project, "lib.rs", "helper_b"));
|
||||
|
||||
cbm_store_close(s);
|
||||
cbm_pipeline_free(p);
|
||||
if (pad_files > 0) {
|
||||
if (saved) {
|
||||
cbm_setenv("CBM_WORKERS", saved, 1);
|
||||
free(saved);
|
||||
} else {
|
||||
cbm_unsetenv("CBM_WORKERS");
|
||||
}
|
||||
}
|
||||
th_rmtree(tmp);
|
||||
PASS();
|
||||
}
|
||||
|
||||
TEST(pipeline_rust_generic_impl_method_sources_its_calls) {
|
||||
return rust_generic_impl_attribution_case(0);
|
||||
}
|
||||
|
||||
TEST(pipeline_rust_generic_impl_method_sources_its_calls_parallel) {
|
||||
return rust_generic_impl_attribution_case(52);
|
||||
}
|
||||
|
||||
TEST(pipeline_go_rw_usage_never_cross_into_c_parallel) {
|
||||
/* Parallel twin of the test above: USAGE and WRITES/READS each have a
|
||||
* second, independent resolver in pass_parallel.c (resolve_file_usages /
|
||||
@@ -23615,6 +23688,8 @@ SUITE(pipeline) {
|
||||
RUN_TEST(pipeline_html_embedded_member_call_stays_unbound);
|
||||
RUN_TEST(pipeline_go_rw_usage_never_cross_into_c);
|
||||
RUN_TEST(pipeline_go_rw_usage_never_cross_into_c_parallel);
|
||||
RUN_TEST(pipeline_rust_generic_impl_method_sources_its_calls);
|
||||
RUN_TEST(pipeline_rust_generic_impl_method_sources_its_calls_parallel);
|
||||
RUN_TEST(pipeline_rust_std_receiver_never_binds_project_method);
|
||||
RUN_TEST(pipeline_rust_std_receiver_never_binds_project_method_parallel);
|
||||
RUN_TEST(pipeline_go_bare_ref_never_binds_field);
|
||||
|
||||
Reference in New Issue
Block a user