Borrow visualizer for the Rust Language Service

And we're finally back! Had a chat with @nikomatsakis early this morning over the next steps here, and we wanted to go back to the design phase. NLL has some interesting behavior that we want to account for and situations to make more obvious. The goal is to try to think of the best possible way to visualize "something" (or somethings..., different visualizations for different information from the code) and only then limit ourselves based on what we can pull from the compiler and what IDEs allow us to draw. The idea being that we might even work with IDE maintainers to expand their functionality to support our designs (thinking BIG here). So here are some of the ideas we came up with this morning, plus what I had worked on before:

From Niko (with some slight formatting improvements for easier readability in a forum vs chat):

... I feel like in Rust the key thing you need to know about any variable, typically, is whether it represents owned or borrowed data ... I imagined the borrow visualizer working sort of like: you highlight a particular borrow and it tells you how long it lasts. ...In order to visualize the overall states of the variable, I would have thought we might color every reference to it, and then, (maybe) if you put the cursor over a borrowed reference, it could put an arrow (or highlight) the place where the borrow occurred. But that doesn't let you see in advance of referencing a variable where it is used. ... My main motivator for the "always on syntax highlighting" was to push people to think about "owned/borrowed".

Example of arrow use in Objective-C tooling

Leads us to:

struct Foo<'a> {
    bar: &'a Bar
}

let foo: Foo<'a>
  • Always on mode: Differentiate owned vs borrowed values (maybe even showing dead values in bad code)
    • "if you have [the struct Foo above] then I had thought that foo would be "owned" but foo.bar would show "borrowed" (as would foo.bar.baz)"
    • Complicated edge cases: How would you highlight something like foo.bar.baz[foo.bar.bax].bay?
  • Highlight mode: Highlight regions when a variable is select to show when it's fully modifiable, readable, locked, moved (i.e., the most recent implementation, which btw, has not been maintained, and would take a huge amount of work to port to be up to date)
    • Expanded with Niko's idea: highlight a borrow, show where the borrow originated with an arrow, and where it ends.
    • Complicated edge cases: If you highlight a borrow, and more borrows are made from that, should you show the borrow mode, or the region mode? Can these modes be combined or should they be separated?

Questions going forward:

  • Does anyone have additional information/modes they'd like to show?
  • Can any improvements be made to these designs?
  • Should we start a new thread or continue within this one?

Side notes for the future: We shouldn't limit this design to visual ideas. Attending RustFest in Kiev, I attended a workshop where one of the speakers (who's name I forget at the moment, but I'm sure @Hoverbear will help me remember) was a blind developer who walked us how he does development. One idea I had for enabling blind developers would be a mode that feeds into a text to speech app that might emit different "hums" depending on the owned/borrowed state or the region highlighting, while the text to speech app is reading the code. Alternatively, a different voice could be used to read each state. There might even be a possibility for overlap, but I don't know at what level the audio streams would become "too noisy".

5 Likes