1111_RUST_USE_RE = re .compile (r"^\s*use\s+(?:crate::)?([a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*)" , re .MULTILINE )
1212_RUST_USE_BRACED_RE = re .compile (r"use\s+(?:crate::)?([\w:]+)::\{([^}]+)\}" , re .MULTILINE )
1313_RUST_MOD_RE = re .compile (r"^\s*(?:pub(?:\([^)]*\))?\s+)?mod\s+([a-z_][a-z0-9_]*)\s*[;{]" , re .MULTILINE )
14- _RUST_EXTERN_CRATE_RE = re .compile (r"^\s*extern\s+crate\s+([a-z_][a-z0-9_]*)" , re .MULTILINE )
1514
1615_RUST_FN_RE = re .compile (r"^\s*(?:pub(?:\([^)]*\))?\s+)?(?:async\s+)?fn\s+([a-z_][a-z0-9_]*)" , re .MULTILINE )
1716_RUST_STRUCT_RE = re .compile (r"^\s*(?:pub(?:\([^)]*\))?\s+)?struct\s+([A-Z]\w*)" , re .MULTILINE )
2423_RUST_FN_CALL_RE = re .compile (r"(?<!\w)([a-z_][a-z0-9_]*)\s?!?\s?\(" )
2524_RUST_PATH_CALL_RE = re .compile (r"([a-z_][a-z0-9_]*)::([a-z_][a-z0-9_]*|[A-Z]\w*)" )
2625
26+ _RUST_COMMON_TYPES = frozenset (
27+ {
28+ "String" ,
29+ "Vec" ,
30+ "Option" ,
31+ "Result" ,
32+ "Box" ,
33+ "Arc" ,
34+ "Rc" ,
35+ "Some" ,
36+ "None" ,
37+ "Ok" ,
38+ "Err" ,
39+ "Self" ,
40+ "HashMap" ,
41+ "HashSet" ,
42+ "BTreeMap" ,
43+ "BTreeSet" ,
44+ "Cow" ,
45+ "Pin" ,
46+ "PhantomData" ,
47+ }
48+ )
49+
50+ _RUST_BUILTIN_MACROS = frozenset (
51+ {
52+ "println" ,
53+ "print" ,
54+ "eprintln" ,
55+ "eprint" ,
56+ "format" ,
57+ "vec" ,
58+ "assert" ,
59+ "assert_eq" ,
60+ "assert_ne" ,
61+ "debug_assert" ,
62+ "debug_assert_eq" ,
63+ "debug_assert_ne" ,
64+ "panic" ,
65+ "todo" ,
66+ "unimplemented" ,
67+ "unreachable" ,
68+ "cfg" ,
69+ "env" ,
70+ "file" ,
71+ "line" ,
72+ "column" ,
73+ "stringify" ,
74+ "concat" ,
75+ "include" ,
76+ "include_str" ,
77+ "include_bytes" ,
78+ "write" ,
79+ "writeln" ,
80+ }
81+ )
82+
2783_RUST_KEYWORDS = frozenset (
2884 {
2985 "if" ,
@@ -109,8 +165,12 @@ def _extract_definitions(content: str) -> tuple[set[str], set[str]]:
109165
110166
111167def _extract_references (content : str ) -> tuple [set [str ], set [str ], set [tuple [str , str ]]]:
112- type_refs = {m .group (1 ) for m in _RUST_TYPE_REF_RE .finditer (content )}
113- fn_calls = {m .group (1 ) for m in _RUST_FN_CALL_RE .finditer (content ) if m .group (1 ) not in _RUST_KEYWORDS }
168+ type_refs = {m .group (1 ) for m in _RUST_TYPE_REF_RE .finditer (content ) if m .group (1 ) not in _RUST_COMMON_TYPES }
169+ fn_calls = {
170+ m .group (1 )
171+ for m in _RUST_FN_CALL_RE .finditer (content )
172+ if m .group (1 ) not in _RUST_KEYWORDS and m .group (1 ) not in _RUST_BUILTIN_MACROS
173+ }
114174 path_calls = {(m .group (1 ), m .group (2 )) for m in _RUST_PATH_CALL_RE .finditer (content )}
115175 return type_refs , fn_calls , path_calls
116176
@@ -204,10 +264,12 @@ def _link_fragment(
204264 ) -> None :
205265 name_to_frags , mod_to_frags , type_defs , fn_defs = indices
206266
267+ type_refs , fn_calls , path_calls = _extract_references (rf .content )
268+
207269 self ._link_uses (rf , mod_to_frags , name_to_frags , edges )
208270 self ._link_declared_mods (rf , name_to_frags , edges )
209- self ._link_refs (rf , type_defs , fn_defs , edges )
210- self ._link_path_calls (rf , mod_to_frags , edges )
271+ self ._link_refs (rf , type_refs , fn_calls , type_defs , fn_defs , edges )
272+ self ._link_path_calls (rf , path_calls , mod_to_frags , edges )
211273 self ._link_same_crate (rf , rust_frags , edges )
212274
213275 def _link_uses (
@@ -247,12 +309,12 @@ def _link_declared_mods(
247309 def _link_refs (
248310 self ,
249311 rf : Fragment ,
312+ type_refs : set [str ],
313+ fn_calls : set [str ],
250314 type_defs : dict [str , list [FragmentId ]],
251315 fn_defs : dict [str , list [FragmentId ]],
252316 edges : EdgeDict ,
253317 ) -> None :
254- type_refs , fn_calls , _ = _extract_references (rf .content )
255-
256318 for type_ref in type_refs :
257319 for fid in type_defs .get (type_ref .lower (), []):
258320 if fid != rf .id :
@@ -266,10 +328,10 @@ def _link_refs(
266328 def _link_path_calls (
267329 self ,
268330 rf : Fragment ,
331+ path_calls : set [tuple [str , str ]],
269332 mod_to_frags : dict [str , list [FragmentId ]],
270333 edges : EdgeDict ,
271334 ) -> None :
272- _ , _ , path_calls = _extract_references (rf .content )
273335 for mod_name , _symbol in path_calls :
274336 for fid in mod_to_frags .get (mod_name .lower (), []):
275337 if fid != rf .id :
0 commit comments