Flowistry: Information Flow for Rust
Flowistry is a tool that analyzes the information flow of Rust programs. Flowistry understands whether it's possible for one piece of code to affect another. Flowistry integrates into the IDE to provide a "focus mode" which helps you focus on the code that's related to your current task.
For example, this GIF shows the focus mode when reading a function that unions two sets together:
When the user clicks a given variable or expression, Flowistry fades out all code that does not influence that code, and is not influenced by that code. For example,
Flowistry can be helpful when you're reading a function with a lot of code. For example, this GIF shows a real function in the Rust compiler. If you want to understand the role of a specific argument to the function, then Flowistry can filter out most of the code as irrelevant:
Table of contents
Flowistry is available as a VSCode plugin. You can install Flowistry from the Visual Studio Marketplace or the Open VSX Registry. In VSCode:
Note on platform support: Flowistry does not yet support NixOS. Flowistry cannot provide pre-built binaries for ARM targets like M1 Macs, so Flowistry must be installed from scratch on these targets (this is done for you, but will take a few more minutes than usual).
Alternatively, you can install it from source:
If you are interested in the underlying analysis, you can use the
The documentation is published here: https://willcrichton.net/flowistry/flowistry/
Once you have installed Flowistry, open a Rust workspace in VSCode. You should see this icon in the bottom toolbar:
Flowistry starts up by type-checking your codebase. This may take a few minutes if you have many dependencies.
Entering focus mode
Once Flowistry has booted up, the loading icon will disappear. Then you can enter focus mode by running the "Toggle focus mode" command. By default the keyboard shortcut is Ctrl+R Ctrl+A (⌘+R ⌘+A on Mac), or you can use the Flowistry context menu:
In focus mode, Flowistry will automatically compute the information flow within a given function once you put your cursor there. Once Flowistry has finished analysis, the status bar will look like this:
Flowistry infers what you want to focus on based on your cursor. So if you click on a variable, you should see the focus region of that variable. Flowistry will highlight the focused code in gray, and then fade out code outside the focus region. For example, because the user's cursor is on
Setting a mark
Sometimes you want to keep the focus region where it is, and click on other code to inspect it without changing focus. For this purpose, Flowistry has a concept of a "mark". Once you have selected code to focus on, you can run the "Set mark" command (Ctrl+R Ctrl+S / ⌘+R ⌘+S). Then a mark is set at your cursor's current position, and the focus will stay there until you run the "Unset mark" command (Ctrl+R Ctrl+D / ⌘+R ⌘+D).
Selecting the focus region
If you want to modify all the code in the focus region, e.g. to comment it out or copy it, then you can run the "Select focused region" command (Ctrl+R Ctrl+T / ⌘+R ⌘+T). This will add the entire focus region into your editor's selection.
Flowistry is an active research project into the applications of information flow analysis for Rust. It is continually evolving as we experiment with analysis techniques and interaction paradigms. So it's not quite as polished or efficient as tools like Rust Analyzer, but we hope you can still find it useful! Nevertheless, there are a number of important limitations you should understand when using Flowistry to avoid being surprised.
If you have questions or issues, please file a Github issue, join our Discord, or DM @wcrichton on Twitter.
Flowistry does not completely handle interior mutability
When your code has references, Flowistry needs to understand what that reference points-to. Flowistry uses Rust's lifetime information to determine points-to information. However, data structures that use interior mutability such as
Flowistry can determine that
We are researching methods to overcome this limitation, but for now just be aware that this is the main case where Flowistry is known to provide an incorrect answer.
A focus region may include more code than you expect
Flowistry's analysis tries to include all code that could have an influence on a focal point. This analysis makes a number of assumptions for both practical and fundamental reasons. For example, in this snippet:
If you focus on
In general, you should use focus mode as a pruning tool. If code is faded out, then you don't have to read it (minus the limitation mentioned above!). If it isn't faded out, then it might be relevant to your task.
Not all code is selectable
Flowistry works by analyzing the MIR graph for a given function using the Rust compiler's API. Then the IDE extension lifts the analysis results from the MIR level back to the source level. However, a lot of information about the program is lost in the journey from source code to MIR.
For example, if the source contains an expression
This is why the IDE extension highlights the focused code in gray, so you can understand what your cursor's selection actually maps to.
Nested functions cannot be analyzed together (including closures and async)
Flowistry analyzes a single function at a time. If a function contains other functions, e.g.
rustup fails on installation
If rustup fails, especially with an error like "could not rename downloaded file", this is probably because Flowistry is running rustup concurrently with another tool (like rust-analyzer). Until rustup#988 is resolved, there is unfortunately no automated way around this.
To solve the issue, go to the command line and run:
Then go back to VSCode and click "Continue" to let Flowistry continue installing.
Why isn't Flowistry part of Rust Analyzer?
Rust Analyzer does not support MIR and the borrow checker, which are essential parts of Flowistry's analysis. That fact is unlikely to change for a long time, so Flowistry is a standalone tool.
Why does Flowistry highlight (or not) this code?
See Limitations for known issues. If that doesn't explain what you're seeing, please post it in the unexpected highlights issue or ask on Discord.