Flowistry: Powerful IDE Tools for Rust

Overview

Flowistry: Powerful IDE Tools for Rust

tests crates.io

Flowistry is a VSCode extension that helps you understand Rust programs. Flowistry uses dataflow analysis and pointer analysis to analyze Rust programs at a deeper level than just types can offer (e.g. as you can already find in rust-analyzer).

Flowistry is alpha software (see Limitations). I'm seeking early adopters to try it out and provide feedback! If you have questions or issues, please file a Github issue, join our Discord, or DM @wcrichton on Twitter.

Currently, Flowistry's capabilities are:

1. Backward slice: find code that influences a value

Flowistry can compute a backward static slice that identifies every piece of code that affects a value of interest. For example, let's say you're debugging an assertion failure on x. Then you could compute the backward slice of x to quickly rule out lines of code that don't influence its value, as shown here:

demo1

The green marker indicates the selected value, and the grey text indicates code with no influence on that value. Note that "influence" is a bit subtle --- for example, in the program:

if x > 0 {
  *y += 1;
}

Even though x isn't directly used to change y, we would say x influences y because a mutation to y happens conditionally based on the value of x.



2. Forward slice: find code that is influenced by a value

A forward static slice identifies every piece of code that is affected by a value of interest. For example, let's say you have a program that times a calculation, and you want to comment out all the code related to timing. You could compute a forward slice of the timer:

demo2

The timer doesn't affect the value of the computation, so run_expensive_calculation isn't part of the forward slice of start. In this example, Flowistry sets the user's selected text to the slice. Then the user can use other IDE features like bulk-commenting (โŒ˜-/ in VSCode on macOS) on that selection.

Note that this example shows how slices are transitive: start influences elapsed, and elapsed influences println, so start influences println.



3. Function effects

A function's effects are either inputs that it mutates, or values that it returns. The function effects panel helps identify lines of code that either mutate arguments or that could return values. Selecting an effect then shows the backward slice of that effect.

demo mp4

Like before, lines that are outside of a given slice are grayed out. But for this feature, lines that are unique to a given slice are highlighted in orange. This way you can quickly focus on code that is only relevant to an effect of interest.



Installation

You can install Flowistry from the Visual Studio Marketplace or the Open VSX Registry. In VSCode:

  • Go to the Extensions pane by clicking this button in the left margin: Screen Shot 2021-09-20 at 9 30 43 AM
  • Search for "Flowistry" and then click "Install".
  • Open a Rust workspace and wait for the tool to finish installing.

Alternatively, you can install it from source:

# Install flowistry binaries
git clone https://github.com/willcrichton/flowistry
cd flowistry
cargo install --path crates/flowistry_ide

# Install vscode extension
cd ide
npm install
npm run build
ln -s $(pwd) ~/.vscode/extensions/flowistry

Usage

Flowistry has five commands:

  • Flowistry: Backward Highlight: given a selected variable, this command highlights the backward slice of the variable.
  • Flowistry: Backward Select: same as above, but this puts the slice in your selection rather than highlighting it.
  • Flowistry: Forward Highlight and Flowistry: Forward Select: same as above, but for forward slices than backward slices.
  • Flowistry: Effects: given your cursor is within a particular function, this command opens the effects panel for that function.

You can invoke these commands either through the context menu, by right-clicking and opening the "Flowistry" sub-menu. Or you can open the Command Palette (โ‡งโŒ˜P on Mac) and type the name of the command.

Limitations

Flowistry is early-stage software. It inevitably has bugs in both the UI and the analysis. The UI may be unintuitive. The analysis, even if correct, may also be unintuitive.

Flowistry does not support all of Rust's features. Specifically:

  • Raw pointers: Flowistry uses lifetimes to determine what a reference can point-to. However, raw pointers can point to anything and aren't tracked by the compiler. So Flowistry cannot detect the flow of information through a raw pointer. It can, however, detect information flow through a typed wrapper around a raw pointer!
  • Some forms of interior mutability: as a corollary to above, Flowistry does not track the aliases of data wrapped in types like Rc . For example, in the program:
    let x = Rc::new(RefCell::new(1));
    let y = x.clone();
    *x.borrow_mut() = 2;
    Flowistry can detect that x is modified (because borrow_mut uses lifetimes to relate the RefMut to RefCell), but not that y is modified (because nothing statically says that y aliases x).

FAQ

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:

rustup toolchain install nightly-2021-11-26 -c rust-src -c rustc-dev -c llvm-tools-preview

Note: double check the value of "channel" in rust-toolchain.toml if nightly-2021-11-26 is no longer correct.

Then go back to VSCode and click "Continue" to let Flowistry continue installing.

You might also like...
Better Rust/Cargo support for Flycheck

flycheck-rust โ€” Flycheck for Rust This Flycheck extension configures Flycheck automatically for the current Cargo project. Setup Install from MELPA or

NetBeans Rust plugin

Rust NetBeans Plugin A NetBeans plugin for Rust. Linux / OSX Windows Requirements NetBeans 8.2.x Java 8+ Rust Cargo Rustup Features So far, it include

Rust plugin for the IntelliJ Platform

Rust plugin for the IntelliJ Platform Build Status Check Stable Beta Nightly Installation & Usage Available installation options and features are desc

The official Sublime Text 3 package for the Rust Programming Language
The official Sublime Text 3 package for the Rust Programming Language

Rust Enhanced About This is a Sublime Text 3 package which supports Rust starting with version 1.0, it makes no attempt at supporting earlier incompat

Vim configuration for Rust.

rust.vim Description This is a Vim plugin that provides Rust file detection, syntax highlighting, formatting, Syntastic integration, and more. It requ

Rust Cargo command bindings

Vim Cargo Simple vim command bindings to quickly run cargo stuff from vim. Commands Available, mapping with their Cargo equivalant: CargoBench CargoBu

Visual Studio extension for Rust
Visual Studio extension for Rust

Visual Studio extension for Rust Currently in development, and not feature complete. Stable versions are available on the Visual Studio extension gall

Rust extension for Visual Studio 2017 with RLS support

Rust support for Visual Studio 2017 Preview Adds language support for Rust to Visual Studio 2017. Supports: code completion goto definition find all r

crates is an extension aims to help people to manage their dependencies for rust (crates.io & TOML).
crates is an extension aims to help people to manage their dependencies for rust (crates.io & TOML).

crates Hello Rust & VSCode lovers, This is crates, an extension for crates.io dependencies. Aims helping developers to manage dependencies while using

Comments
  • Extend flowistry to types with interior mutability

    Extend flowistry to types with interior mutability

    You mentioned two things during your thesis defense:

    1. There are two analyses that flowistry supports: whole-program analysis, and (very accurate) heuristics using the lifetime annotations people already provide for the borrow checker.
    2. The lifetime annotations only work for exterior mutability; things like AtomicUsize::set are not considered by flowistry to affect the data flow of the program.

    I think it would be possible to extend this to interior mutability by using the intra-procedural analysis that looks into dependencies, but only for types which have interior mutability. The compiler already knows statically which types have interior mutability, because they have to contain an UnsafeCell (anything else is already undefined behavior).

    opened by jyn514 4
  • Crash after following

    Crash after following "rustup fails on installation" instructions

    Problem

    I followed the "rustup fails on installation" instructions the clicked continue in VS Code.

    Logs

    OS: darwin (21.4.0) VSCode: 1.66.1 Error message

    ps: stdin: not a terminal
    tput: No value for $TERM and no -T specified
    /usr/local/bin/bash: line 1: cargo: command not found
    

    Full log: https://paste.rs/nho

    opened by allenap 4
  • Flowistry does not understand inline assembly

    Flowistry does not understand inline assembly

    For the following function:

    pub unsafe fn load_u8(p: *const u8) -> u8 {
        let mut ret: u8;
        std::arch::asm!(
            "mov {ret}, byte ptr [{p}]",
            p = in(reg) p,
            ret = lateout(reg_byte) ret, 
            options(nostack)
        );
        ret
    }
    

    Flowistry does not highlight the use of "p" in the asm! invocation: imagen It also does not highlight that ret is written to by it: imagen

    Since in(reg) p and lateout(reg_byte) ret explicitly specify those 2 things, it should be possible to recognize these. The rust reference has a page explaining the asm! syntax: https://doc.rust-lang.org/nightly/reference/inline-assembly.html

    Tested only with the vscode marketplace extension on windows 10 21H2

    opened by nico-abram 0
  • Flowistry panics if you open any .rs file in vscode not in SourceFiles

    Flowistry panics if you open any .rs file in vscode not in SourceFiles

    If you have a .rs file that's not reachable/compiled for the target flowistry uses (I assume the host?), flowistry opens a window with this error message in vscode:

    Flowistry could not run because your project failed to build with error:
    thread 'rustc' panicked at 'called `Result::unwrap()` on an `Err` value: Could not find SourceFile for path: d:\dev\rs_playground\src\test.rs. Available SourceFiles were: [src\main.rs, src\other.rs, C:\Users\runneradmin\.cargo\registry\src\github.com-1ecc6299db9ec823\libc-0.2.116\src\lib.rs, C:\Users\runneradmin\.cargo\registry\src\github.com-1ecc6299db9ec823\libc-0.2.116\src\macros.rs, C:\Users\runneradmin\.cargo\registry\src\github.com-1ecc6299db9ec823\libc-0.2.116\src\fixed_width_ints.rs, C:\Users\runneradmin\.cargo\registry\src\github.com-1ecc6299db9ec823\libc-0.2.116\src\windows\mod.rs, C:\Users\runneradmin\.cargo\registry\src\github.com-1ecc6299db9ec823\libc-0.2.116\src\windows\msvc\mod.rs]', D:\.cargo\registry\src\github.com-1ecc6299db9ec823\flowistry_ide-0.5.18\src\spans.rs:35:8
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    error: could not compile `rs_playground`
    
    Backtrace:
    Stack backtrace:
       0: std::backtrace::Backtrace::disabled
       1: std::backtrace::Backtrace::capture
       2: <unknown>
       3: <unknown>
       4: <unknown>
       5: <unknown>
       6: <rustc_lint::BuiltinCombinedPreExpansionLintPass as rustc_lint::passes::EarlyLintPass>::check_foreign_item_post
       7: <rustc_driver::args::Error as core::fmt::Debug>::fmt
       8: <rustc_lint::BuiltinCombinedPreExpansionLintPass as rustc_lint::passes::EarlyLintPass>::check_foreign_item_post
       9: <rustc_lint::BuiltinCombinedPreExpansionLintPass as rustc_lint::passes::EarlyLintPass>::check_foreign_item_post
      10: rustc_driver::pretty::print_after_hir_lowering
      11: std::sys::windows::thread::Thread::new
      12: BaseThreadInitThunk
      13: RtlUserThreadStart', D:\.cargo\registry\src\github.com-1ecc6299db9ec823\flowistry_ide-0.5.18\src\spans.rs:35:8
    

    It should be reproducible with any project, just create an new empty .rs file in vscode, open it, and turn flowistry focus mode on and off. Note that if the file actually contains rust code, flowistry will also panic if you open that file while in focus mode and place the cursor somewhere such that it tries to analyze it.

    This can be annoying in a codebase using conditional compilation for different modules/files, for example:

    #[cfg(target_arch = "x86_64")]
    mod x86_64;
    #[cfg(target_arch = "x86_64")]
    use x86_64 as arch;
    
    #[cfg(target_arch = "aarch64")]
    mod aarch64;
    #[cfg(target_arch = "aarch64")]
    use aarch64 as arch;
    
    fn main() {}
    

    Where both x86_64.rs and aarch64.rs contain some valid rust code:

    fn f() -> () {
        ()
    }
    

    Opening aarch64.rs and placing the cursor on the return type panics with the same general error, on my x86_64 machine.

    Tested only with the vscode marketplace extension on windows 10 21H2

    bug 
    opened by nico-abram 5
Releases(v0.5.34)
Owner
Will Crichton
Let's bring cognitive science to programming.
Will Crichton
Rust IDE support for Atom, powered by the Rust Language Server (RLS)

IDE-Rust Rust language support for Atom-IDE, powered by rust-analyzer. Features Auto-completion Diagnostics (errors and warnings from rustc) Document

The Rust Programming Language 239 Dec 14, 2022
Eclipse Corrosion - Rust edition in Eclipse IDE

Eclipse Corrosion Rust edition and debug in Eclipse IDE Corrosion is a Rust development plugin for the Eclipse IDE, providing a rich edition experienc

Eclipse Foundation 194 Dec 23, 2022
RustDT is an Eclipse based IDE for the Rust programming language:

Project website: http://rustdt.github.io/ As of 2017, RustDT is no longer actively maintained, see this blog post for more information. If you are int

null 351 Aug 20, 2022
Rust IDE

This branch contains the development of a "new ride" that maintain a small impact on the ui library. This is for a few reasons. Can customize the colo

Gustav Jansson 171 Dec 24, 2022
An IDE for Rust

Introduction SolidOak is a simple IDE for Rust. See the website for binary releases. It has the following features: An embedded copy of Neovim as its

Zach Oakes 907 Dec 29, 2022
Diagnostic tools for timely dataflow computations

Timely Diagnostics Diagnostic tools for timely dataflow computations. Timely dataflows are data-parallel and scale from single threaded execution on y

Timely Dataflow 40 Aug 24, 2022
rust-analyzer is a modular compiler frontend for the Rust language

rust-analyzer is a modular compiler frontend for the Rust language. It is a part of a larger rls-2.0 effort to create excellent IDE support for Rust.

null 11.2k Jan 8, 2023
Rust language support in Atom - LOOKING FOR MAINTAINER, see #144

Rust language support in Atom Adds syntax highlighting and snippets to Rust files in Atom. Install Install the package language-rust in Atom (Preferen

Andreas Neuhaus 118 Oct 11, 2022
Emacs configuration for Rust

Table of Contents Introduction Installation Melpa Manual installation Feature guide Indentation Code formatting Running / testing / compiling code Cli

The Rust Programming Language 919 Jan 4, 2023
Rust development environment for Emacs

Rustic Table of Contents Rustic Intro Installation straight Compilation Faces rustc errors Rustfmt edition 2018 LSP Server Client eglot lsp-mode lsp-e

null 612 Dec 30, 2022