markused: fix generic fn instantiation dedup key collision for identical module names#27399
markused: fix generic fn instantiation dedup key collision for identical module names#27399Jengro777 wants to merge 7 commits into
Conversation
…ate module names When multiple modules share the same name (e.g. both declared 'module common' in different directories) and define structs with identical short names, the walker's fn_generic_types_key function used type_to_str() for deduplication. Since type_to_str returns the V type name, types from different modules with the same short name produced identical keys, causing subsequent generic instantiations to be silently dropped. Fix by using typ.str() (the underlying Type ID integer) instead of type_to_str, guaranteeing unique keys per concrete type regardless of module path. Fixes vlang#27398.
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
|
This can solve the problem, but it may make the generated c unreadable |
|
About the generated C readability concern and from what I can see, this key is an internal For the fix itself, maybe a slightly clearer version would be to use Also, if possible, adding a small regression test? Nice catch for the bug/fix. |
thankyou |
|
Yes but the failure may vary between machines in terms of which specialization is missing but the expected behavior is not machine-dependent. No required generic specialization should be silently dropped. So the test does not need to check the exact missing symbol. It only needs to build a reduced project with the same pattern and assert that it compiles/runs. Of course, this is only my personal opinion, so feel free to handle it however you think is best :) |
thank you |
…ate module names When multiple modules share the same name (e.g., both declare 'module common' in different directories) and define structs with identical short names, the walker's fn_generic_types_key used type_to_str() for deduplication. Type names from different same-named modules could produce identical keys, causing subsequent generic instantiations to be silently dropped. Fix by using u32(typ).str() (the raw Type ID) instead of type_to_str, guaranteeing unique keys per concrete type regardless of module path. Adds project_issue_27398 with 100 module pairs to reliably reproduce the bug. Fixes vlang#27398.
|
In order to reproduce the bug on every machine as much as possible, the test files are deliberately written here Please review |
|
The test fixture feels a bit large. Since That would keep the compile/run regression strong, while avoiding ~5k LOC of mechanical fixture files. If CI proves the pair count is too low, it can be raised by changing one constant instead of adding more files? 24 pairs seems like a good compromise, I tested it locally. |
Replace the large static test fixture project_issue_27398/ (202 files, ~5k LOC) with a standalone test that generates the duplicate-module project at runtime using os.write_file in os.vtmp_dir(). - Remove project_issue_27398/ static fixture directory - Remove the associated test from projects_that_should_compile_test.v - Add generic_fn_dedup_collision_issue_27398_test.v: generates 24 module pairs, compiles with -skip-unused run and asserts output is 'ok' - Remove the old test function from projects_that_should_compile_test.v The test uses os.chdir + 'v .' to avoid an existing V bug with absolute path module resolution, and uses @vexe so it always tests the compiler being built. Refs vlang#27398.
Thank you for reviewing |
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
@Jengro777 can you try launching codex review please? :) |
I used Codex Review locally and it worked fine |
|
@codex review |
|
Codex Review: Didn't find any major issues. Can't wait for the next one! ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
|
The error has nothing to do with PR |
|
@codex review |
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
|
Request a review |
|
Sorry to bother you, can this PR be prioritized for review? |
When a V project has two or more modules that share the same name (e.g., both declare
module commonin different directory paths likem0a/common/andm0b/common/), and both define struct types with identical short names, the compiler silently drops some generic function instantiations. The C compilation then fails with "implicit declaration" / "undefined symbol" errors because the generated C code calls functions that were never emitted.This occurs because the markused walker's
fn_generic_types_keyfunction usestype_to_str(typ)(the V type name) to build deduplication keys. When two types from different same-named modules share the same short name,type_to_strcan return identical strings, causing the walker to treat subsequent generic instantiations as duplicates and skip them.Root Cause
In
vlib/v/markused/walker.v, thefn_generic_types_keyfunction:type_to_strreturns the V-level type name string. Types from modules with the same declared name but different import paths could produce the same key string, causing the dedup checkused_fn_generic_type_keys[key]to incorrectly skip needed instantiations.Fix
Use
typ.str()— the underlying Type ID integer — instead oftype_to_str:Type IDs are unique across all type symbols, guaranteeing that every concrete type produces a distinct key regardless of overlapping module paths or short names.
Reproduction
A test with 6 module pairs (12 modules total, all named
common, each defining the same 3 struct type names, each calling the same generic API function) consistently fails before this fix:Tests
examples/hello_world.vcompiles and runsChanged Files
vlib/v/markused/walker.v— 1 line changeFixes #27398.