codegraph extracts no symbol at all for a Rust unit struct (struct Unit;),
so the type is absent from the graph — and so is everything attached to it. The
most visible loss is impl SomeTrait for Unit: the edge never forms, because its
source endpoint does not exist.
Brace structs (struct S { .. }) and tuple structs (struct S(u32);) are
extracted normally. Only the unit form is affected.
The grammar parses the file correctly, so this is in the symbol-extraction layer,
not the grammar.
Environment
- codegraph: 1.5.0 (npm), reproduced again on
main @ d6d1728
- Backend: node:sqlite (WAL)
- Platform: Linux x64
- Both extraction paths affected: the native kernel and the wasm/TS walker
(CODEGRAPH_KERNEL=0)
Repro
src/lib.rs:
pub struct UnitStruct;
pub struct TupleStruct(pub u32);
pub struct BraceStruct { pub x: u32 }
pub trait Greet { fn hi(&self) -> String; }
impl Greet for UnitStruct { fn hi(&self) -> String { "unit".into() } }
impl Greet for TupleStruct { fn hi(&self) -> String { "tuple".into() } }
impl Greet for BraceStruct { fn hi(&self) -> String { "brace".into() } }
codegraph init .
sqlite3 .codegraph/codegraph.db \
"SELECT kind, name FROM nodes WHERE kind IN ('struct','trait') ORDER BY name;"
Expected
Three struct nodes and three implements edges.
Actual
Two of each — UnitStruct is missing, and with it the Greet <- UnitStruct
realization.
struct BraceStruct
struct TupleStruct
trait Greet
Greet <|.. TupleStruct
Greet <|.. BraceStruct
Impact
Unit structs are the idiom for zero-sized markers, test doubles and stub
implementations, so the loss concentrates in test and adapter layers rather than
being spread evenly.
On a 2,669-node Rust/TypeScript repository, re-indexing after a local fix
recovered 13 structs and 9 implements edges — every one of them a unit
struct such as SystemClock, StubTransport, MockEncoder, StubSettings.
Asking for implementors of a trait, or the impact radius of one, silently omitted
these.
Cause
extractStruct treats a missing body field as a forward declaration and returns
before minting the node. That is correct for C/C++ (struct Foo; really is a
forward declaration) but Rust has no forward declarations — a bodiless struct
is always a complete definition.
This looks like the same case two earlier patches already recognised:
Struct kept the unconditional skip, so Rust was never covered.
The kernel's Rust walker mirrors the behavior deliberately — it is listed in
rustlang.rs's bug-for-bug quirk header and in the R7b port checklist — so both
walkers need the same change to stay at parity.
I have a fix ready and will open a PR referencing this issue.
codegraphextracts no symbol at all for a Rust unit struct (struct Unit;),so the type is absent from the graph — and so is everything attached to it. The
most visible loss is
impl SomeTrait for Unit: the edge never forms, because itssource endpoint does not exist.
Brace structs (
struct S { .. }) and tuple structs (struct S(u32);) areextracted normally. Only the unit form is affected.
The grammar parses the file correctly, so this is in the symbol-extraction layer,
not the grammar.
Environment
main@d6d1728(
CODEGRAPH_KERNEL=0)Repro
src/lib.rs:Expected
Three
structnodes and threeimplementsedges.Actual
Two of each —
UnitStructis missing, and with it theGreet <- UnitStructrealization.
Impact
Unit structs are the idiom for zero-sized markers, test doubles and stub
implementations, so the loss concentrates in test and adapter layers rather than
being spread evenly.
On a 2,669-node Rust/TypeScript repository, re-indexing after a local fix
recovered 13 structs and 9
implementsedges — every one of them a unitstruct such as
SystemClock,StubTransport,MockEncoder,StubSettings.Asking for implementors of a trait, or the impact radius of one, silently omitted
these.
Cause
extractStructtreats a missing body field as a forward declaration and returnsbefore minting the node. That is correct for C/C++ (
struct Foo;really is aforward declaration) but Rust has no forward declarations — a bodiless struct
is always a complete definition.
This looks like the same case two earlier patches already recognised:
record struct M(decimal Amount);)as "complete definitions with no body block".
class Foo;) index as phantom class nodes, masking the real definition #1093 addedskipBodilessClassso a bodiless class is kept unless alanguage opts into skipping it.
Struct kept the unconditional skip, so Rust was never covered.
The kernel's Rust walker mirrors the behavior deliberately — it is listed in
rustlang.rs's bug-for-bug quirk header and in the R7b port checklist — so bothwalkers need the same change to stay at parity.
I have a fix ready and will open a PR referencing this issue.