Rust extractor: lossy structure and name-only call resolution (generic impls, traits, mods, use-lists, receivers)
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 18/100
Línea de trabajo
Start in graphify/extract.py at extract_rust, plus _make_id, _file_stem and the label_to_nid lookup in extract(), and reproduce with the sample file in the issue. The author has a patch and 10 regression tests, so the work is mostly reviewing the design: scoped IDs, trait impls, receiver-based call resolution and cross-file resolution. Done means the sample's orphan nodes, merged IDs and name-only edges are gone, and the regression tests pass.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Version: graphifyy 0.7.0 (graphify/extract.py, extract_rust)
extract_rust loses most of the structure of idiomatic Rust. Reproduced with this file:
use std::fmt::{self, Display};
pub trait Reader { fn read(&self) -> u8; fn skip(&self) { helper(); } }
pub struct Foo<T> { x: T }
impl<T> Foo<T> { pub fn new(x: T) -> Self { Self { x } } pub fn go(&self) { Self::new(1); helper(); } }
impl Display for Foo<u8> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Ok(()) } }
impl Reader for Foo<u8> { fn read(&self) -> u8 { 0 } }
mod inner { pub fn helper() {} pub struct Foo; }
pub fn helper() { inner::helper(); println!("x"); }
pub type Alias = u8; pub const K: u8 = 1; macro_rules! m { () => {} }
Structure problems
- Generic impls create orphan nodes.
impl<T> Foo<T>/impl Foo<u8>produce nodesFoo<T>/Foo<u8>, separate from theFoostruct node. Methods hang off the orphans. - Trait is dropped from
impl Trait for Type. Noimplementsedge; trait impls look like inherent impls, and several impls of the same method name for one type (e.g. threeimpl From<_> for E) share one ID scheme. trait_itemreturns without descending. Trait methods produce no nodes, so calls from default method bodies (skip -> helper) are lost.- IDs ignore the inline
modpath, and are case-folded.inner::helperand top-levelhelperget the same ID, as doinner::FooandFoo; nodes merge andinner::helper()becomes a dropped self-call. Because_make_idlower-cases,const ITEMandfn item()also collide (first label wins). Across files,_file_stemisparent.stem, so everysrc/lib.rssharessrc.lib. - Missing node kinds:
mod,type,const,static,union,macro_rules!. usehandling is lossy:use std::fmt::{self, Display}yields one edge (the text before{), losingDisplay; nested/aliased lists are not flattened.
Call-resolution problems
The extractor resolves calls by bare name only (label_to_nid[name.lower()], last definition wins), ignoring qualifiers and receivers, so on a real workspace most edges for common names are wrong. Examples found by auditing the old output line by line:
Vec::new(),Cursor::new(..),HashMap::new(),u64::from(x),Default::default()are linked to any localfn new/fn from/fn default.v.len()/s.is_empty()/file.seek(..)on std types are linked to local methods with the same name.Value::Inline(..)/VrIndex(..)(enum variant / tuple-struct constructors) are linked to a function namedinline/ the type node.validator.enter_item(..)is linked to an unrelated freefn enter_item, not the method onvalidator's type.- Conversely, true calls are missed:
self.m()when several types in the file definem,Type::f()whenTypehas several impls, trait-qualified calls (Seek::seek(&mut s)), calls through generic bounds (V: Trait),if let Some(x) = x, loop/closure variables, and everything crossing a file boundary other than by unique name.
Patch
I have a patch (extract_rust replacement + a small Rust pass in extract() for cross-file resolution) and 10 regression tests. Happy to open a PR. Summary of the behaviour:
- IDs scoped by file path +
modpath and tagged by kind; generics stripped soimpl<T> Foo<T>attaches toFoo;implementsedges (also cross-file); trait methods as nodes; nodes for mod/type/const/static/macro; use-trees flattened. - Calls resolved with light receiver-type inference (parameters, typed/constructor
let, struct field types,Self, fn/method return types withResult/Option/Box/Arcunwrapped,if let Some(x), generic bounds,for/closure element types overVec/slice/array). When a call can reach several impls, an edge goes to each candidate withINFERREDconfidence. Calls on external types (Vec::new,u64::from, ...) and enum-variant/tuple-struct constructors produce no edge. Typed calls whose type lives in another file are resolved in a cross-file pass.
Measured on a real workspace
179 .rs files (a DICOM parser; calls counted over the whole graph, incl. cross-file), old extractor vs patched:
| old | patched | |
|---|---|---|
| nodes (in-file extraction) | 2658 | 5782+ |
calls edges |
3544 | 4607 (2482 EXTRACTED, 2125 INFERRED) |
The 134 old call edges that disappear were classified by source line: 68 Type::f() on external types, 43 enum-variant/tuple-struct constructors and chains on external types, 23 recv.f() on std types (len/is_empty/seek/read) — plus 4 validator.enter_* calls that used to point at the wrong free function and now point at the method. None was a Type::f() call on a type defined in the workspace.
Remaining limit
Where the type is only known to a real type checker (results of .map(..) / .collect(), macro-generated code), no edge is emitted rather than a guessed one.
- Lenguaje dominante
- Python
- Estrellas
- 124k
- Forks
- 11.9k
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de Graphify-Labs/graphify
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 86/100
Graphify-Labs/graphify#3763 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Graphify-Labs/graphify#3611 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Nix supportAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
Graphify-Labs/graphify#3193 · 2 reacciones ·
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 92/100
Graphify-Labs/graphify#2871 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
Graphify-Labs/graphify#2865 ·
Los mantenedores suelen responder en 1 día
Todos los issues de Graphify-Labs/graphify
Issues similares
-
vis.image() reports "Unsupported number of image channels: 224" for an HxWxC imagePosiblemente ocupada @piyush182004 la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
fossasia/visdom#1997 · 3 comentarios ·
Los mantenedores suelen responder en 6 días
-
Byse new domainAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
Gujal00/ResolveURL#1525 ·
Los mantenedores suelen responder en 1 día
-
Serialisation fails with pydantic 2.14: wrap serialisers pass SerializationInfo as index_keyPosiblemente ocupada @hugohills-regnosys la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
finos/rune-python-runtime#45 ·
-
[Bug]: LangGraph Store sync put bypasses namespace validationPosiblemente ocupada @ktz03 la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
volcengine/OpenViking#6050 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
hummingbot/condor#283 ·
Los mantenedores suelen responder en 1 día