tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (working)
Tim Chevalier ([personal profile] tim) wrote2012-07-20 07:12 pm
Entry tags:

TMI: Pictures - something my work day doesn't usually involve

I got a simple, not-very-smart version of dependency graph generation working, just for types. Here's an example:

Example of a dependency graph for a Rust crate

I used Graphviz to generate the graph image -- all the code that I wrote did was generate a dot program to tell Graphviz what graph to draw.

The graph shows the dependencies for the bank account example that uses Eric's protocol compiler. This isn't the best example, since the graph shows the dependencies post-macro-expansion. But it was one of the few ones that was small enough to be comprehensible.

For each item in the crate, the graph shows what types it depends on. The major inaccuracy in the graph is that it's missing a lot of edges. My dependency generation code looks at the so-called "AST types" in an AST, not the inferred types. The former consist of the types as written by the programmer: for example, representing traits, impls, classes, and other named things as just ty_path types, before the typechecker disambiguates them. Traversing AST types is not good enough, since it means totally ignoring any types that are inferred rather than written explicitly in the program. But I don't see any existing code in the compiler that walks an AST, threading a type context, and looks up each node's type in the type context in order to visit is. This isn't hard or anything, it's just effort.

The item names look a little funny since dot doesn't like node names that contain funny characters -- like the double colons we use as module separators -- so in the printing code, I replaced every :: with a _.

It also appears that there are duplicate edges, which is probably because the graph printing code leaves out type parameters but the code is treating A<B> and A<C> and as two different paths.

So clearly, this needs a lot of work, but it's something. It would also be fun to render the nodes in different colors depending on whether they represent a trait, enum, or class.

The other exciting thing I did today was clear out all my dead git branches, of which there were many. Aside from dependencies, I came up with five issues I'm still (sort of) actively working on:

  • Merging a pull request to add a to_str instance for hashmaps. This should not be hard, but I think it exposes a recently introduced bug in the typechecker (it seems that if an impl has a method M that's not named in the trait T that it implements, M still gets treated as if it's in T; this might have to do with coherence checking).
  • Classes that have polymorphic traits -- I have a fix for the bug, but tragically, it breaks other tests...
  • The total mess when it comes to any runtime code that handles classes-with-destructors -- see #2895, 2834, #2724, and $DEITY help you if you try to use polymorphic logging on a class...
  • A possibly ill-advised rope refactor (I did something that I thought would preserve semantics and got crashes all over the place.)
  • A bitv refactor that may be slightly less ill-advised, but also doesn't work. I'll have to be careful, because since I started on this, typestate was removed, and typestate was the biggest client for the bitv library. So I'll probably need to add more unit tests to make up for that.