Giter Club home page Giter Club logo

aquascope's Introduction

Aquascope: Look Beneath the Surface of Rust

tests crates.io docs

Aquascope is a tool that generates interactive visualizations of Rust programs. These visualizations show how Rust's borrow checker "thinks" about a program, and how a Rust program actually executes. Here is a sample output of Aquascope:

Example Aquascope output

Click here for a live demo. Want to learn more about what the diagram means? Read the new ownership chapter in our Rust Book Experiment.

⚠️🔬 Aquascope is research software! If you encounter a bug, we welcome contributions! 🧪⚠️

Installation

We provide an mdBook preprocessor that embeds Aquascope diagrams into an mdBook. To use it, you need to install the mdbook-aquascope and cargo-aquascope binaries as follows.

cargo install mdbook-aquascope --locked --version 0.3.0
rustup toolchain install nightly-2023-08-25 -c rust-src rustc-dev llvm-tools-preview miri
cargo +nightly-2023-08-25 install aquascope_front --git https://github.com/cognitive-engineering-lab/aquascope --tag v0.3.0 --locked
cargo +nightly-2023-08-25 miri setup

Note that cargo-aquascope is installed via aquascope_front and must be installed via git and with a specific nightly toolchain. The miri setup command is a necessary prerequisite to running the Aquascope interpreter.

From Source

If you want to install from source, you first need to install cargo-make, a Rust build tool, like this:

cargo install cargo-make --locked

Then you need to install Depot, a Javascript build tool, like this:

curl https://raw.githubusercontent.com/cognitive-engineering-lab/depot/main/scripts/install.sh | sh

Then you can install Aquascope from source like this:

git clone https://github.com/cognitive-engineering-lab/aquascope.git
cd aquascope
cargo make install-mdbook

Usage

First, enable mdbook-aquascope in your mdBook's book.toml like so:

# book.toml
[preprocessor.aquascope]

Then add an Aquascope code block to one of your Markdown source files like this:

```aquascope,interpreter
#fn main() {
let mut s = String::from("hello ");`[]`
s.push_str("world");`[]`
#}
```

Further documentation on the syntax and configuration of Aquascope blocks will be provided once the interface is more stable.

Local Playground

Running the provided playground locally is also easy. First, you'll need to follow the above from source installation instructions. Then, you can launch the server by running cargo make playground and navigate to localhost:5173 to explore.

Note, the local playground does not run the tool within a sandbox. This makes the local version quicker, but don't run any malicious programs.

Having trouble?

If you want to use Aquascope but are having trouble finding the relevant information, please leave an issue or email us at [email protected] and [email protected].

Citation

Aquascope was developed as a part of our academic research on how people learn Rust. If you use Aquascope as a part of your research, please cite this paper:

@article{cgk:aquascope,
  author = {Crichton, Will and Gray, Gavin and Krishnamurthi, Shriram},
  title = {A Grounded Conceptual Model for Ownership Types in Rust},
  year = {2023},
  issue_date = {October 2023},
  publisher = {Association for Computing Machinery},
  address = {New York, NY, USA},
  volume = {7},
  number = {OOPSLA2},
  url = {https://doi.org/10.1145/3622841},
  doi = {10.1145/3622841},
  journal = {Proc. ACM Program. Lang.},
  month = {oct},
  articleno = {265},
  numpages = {29},
  keywords = {Rust, concept inventory, ownership types, program state visualization}
}

aquascope's People

Contributors

gavinleroy avatar kianmeng avatar willcrichton avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aquascope's Issues

Visualizing outlives-constraints and lifetime parameters

To talk about borrow checker errors involving lifetime parameters, we designed a "flow permission" that is distinct from read/write/own (RWO). See this section of the Rust Book Experiment for explanation: https://rust-book.cs.brown.edu/ch04-02-references-and-borrowing.html#data-must-outlive-all-of-its-references

This flow permission is unsatisfactory because, unlike RWO, it doesn't have a "state" that can be visualized. The issue is that we don't have any way to talk about the outlives-constraints in the program, namely the outlives-constraints between function parameters, and their relation to outlives-constraints induced in the function body.

We are interested in either refining or replacing the flow permission. The ultimate goal of the refinement/replacement is to help Rust users understand how lifetime parameters work.

Meaning of the icons?

Hi 👋

I am new to rust, I was wondering if there is a link/legend that explains the meaning of the icons

Screenshot 2023-02-26 at 18 05 33

Thanks

Cheers,

Fra

cannot compile code with function pointer

It looks like function pointers are not support at this moment.

fn add_one(x: i32) -> i32 {
    x + 1
}

fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
    f(arg) + f(arg)
}

fn main() {
    let answer = do_twice(add_one, 5);

    println!("The answer is: {}", answer);
}
Checking aquascope_tmp_proj v0.1.0 (/app/aquascope_tmp_proj)

Running
 
`CARGO=/usr/local/rustup/toolchains/nightly-2023-04-12-x86_64-unknown-linux-musl/bin/cargo CARGO_BIN_NAME=aquascope_tmp_proj CARGO_CRATE_NAME=aquascope_tmp_proj CARGO_MANIFEST_DIR=/app/aquascope_tmp_proj CARGO_PKG_AUTHORS='' CARGO_PKG_DESCRIPTION='' CARGO_PKG_HOMEPAGE='' CARGO_PKG_LICENSE='' CARGO_PKG_LICENSE_FILE='' CARGO_PKG_NAME=aquascope_tmp_proj CARGO_PKG_README='' CARGO_PKG_REPOSITORY='' CARGO_PKG_RUST_VERSION='' CARGO_PKG_VERSION=0.1.0 CARGO_PKG_VERSION_MAJOR=0 CARGO_PKG_VERSION_MINOR=1 CARGO_PKG_VERSION_PATCH=0 CARGO_PKG_VERSION_PRE='' CARGO_PRIMARY_PACKAGE=1 LD_LIBRARY_PATH='/app/aquascope_tmp_proj/target/plugin-nightly-2023-04-12/debug/deps:/root/.cache/miri/lib:/usr/local/rustup/toolchains/nightly-2023-04-12-x86_64-unknown-linux-musl/lib' /usr/local/cargo/bin/aquascope-driver rustc --crate-name aquascope_tmp_proj --edition=2021 src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type bin --emit=dep-info,metadata -C embed-bitcode=no -C debuginfo=2 -C metadata=3455252d1c09473c -C extra-filename=-3455252d1c09473c --out-dir /app/aquascope_tmp_proj/target/plugin-nightly-2023-04-12/debug/deps -C incremental=/app/aquascope_tmp_proj/target/plugin-nightly-2023-04-12/debug/incremental -L dependency=/app/aquascope_tmp_proj/target/plugin-nightly-2023-04-12/debug/deps -C target-feature=-crt-static`


thread 'rustc' panicked at '`ref_to_mplace` called on non-ptr type', /rustc/9df3a39fb30575d808e70800f9fad5362aac57a2/compiler/rustc_const_eval/src/interpret/place.rs:321:47
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

error: could not compile `aquascope_tmp_proj` (bin "aquascope_tmp_proj")

Caused by:
  process didn't exit successfully: `CARGO=/usr/local/rustup/toolchains/nightly-2023-04-12-x86_64-unknown-linux-musl/bin/cargo CARGO_BIN_NAME=aquascope_tmp_proj CARGO_CRATE_NAME=aquascope_tmp_proj CARGO_MANIFEST_DIR=/app/aquascope_tmp_proj CARGO_PKG_AUTHORS='' CARGO_PKG_DESCRIPTION='' CARGO_PKG_HOMEPAGE='' CARGO_PKG_LICENSE='' CARGO_PKG_LICENSE_FILE='' CARGO_PKG_NAME=aquascope_tmp_proj CARGO_PKG_README='' CARGO_PKG_REPOSITORY='' CARGO_PKG_RUST_VERSION='' CARGO_PKG_VERSION=0.1.0 CARGO_PKG_VERSION_MAJOR=0 CARGO_PKG_VERSION_MINOR=1 CARGO_PKG_VERSION_PATCH=0 CARGO_PKG_VERSION_PRE='' CARGO_PRIMARY_PACKAGE=1 LD_LIBRARY_PATH='/app/aquascope_tmp_proj/target/plugin-nightly-2023-04-12/debug/deps:/root/.cache/miri/lib:/usr/local/rustup/toolchains/nightly-2023-04-12-x86_64-unknown-linux-musl/lib' /usr/local/cargo/bin/aquascope-driver rustc --crate-name aquascope_tmp_proj --edition=2021 src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type bin --emit=dep-info,metadata -C embed-bitcode=no -C debuginfo=2 -C metadata=3455252d1c09473c -C extra-filename=-3455252d1c09473c --out-dir /app/aquascope_tmp_proj/target/plugin-nightly-2023-04-12/debug/deps -C incremental=/app/aquascope_tmp_proj/target/plugin-nightly-2023-04-12/debug/incremental -L dependency=/app/aquascope_tmp_proj/target/plugin-nightly-2023-04-12/debug/deps -C target-feature=-crt-static` (exit status: 101)

Clone succeeded, but checkout failed.

I am trying to clone the repository but encounter the following error:

C:\Users\krites\source\repos>git clone https://github.com/cognitive-engineering-lab/aquascope.git
Cloning into 'aquascope'...
remote: Enumerating objects: 88576, done.
remote: Counting objects: 100% (88576/88576), done.
remote: Compressing objects: 100% (5973/5973), done.
remote: Total 88576 (delta 81746), reused 88457 (delta 81689), pack-reused 0
Receiving objects: 100% (88576/88576), 65.61 MiB | 12.55 MiB/s, done.
Resolving deltas: 100% (81746/81746), done.
error: invalid path 'crates/aquascope/tests/snapshots/boundaries__<anon body>@captured_0.test.snap'
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry with 'git restore --source=HEAD :/'

I also installed git LFS and tried these commands, but still getting checkout issue.

git config --system core.longpaths true
git config --global core.protectNTFS false

This problem appears under Windows 10/11. Under Linux it works without problems.

Are there any special configurations or alternative commands to avoid this error?

Pre-release TODOs

  • mdbook-quiz integration
  • Add Aquascope quizzes to ownership chapter

Misc

  • Remove code buttons when hideCode is true
  • Box to provide feedback about diagrams
  • Box to point confused readers back to Chapter 4
  • Show code button seems to take multiple clicks
  • Dark mode text color for ExtraInfo
  • mdbook header isn't sticky anymore?

Permissions

  • Make visual alignment of permission boundaries more visually appealing
  • Make letters in permission steps less aggressively bold
  • Deal with overlap of Ferris icon and permission steps
  • Add compacted vis for permission boundaries
  • Come up with better path string for enum variants (see ch06-02-match)
  • Only apply matrix filter when in a transitioning state
  • Rust theme -- step table colors
  • transition 1s all bug on code text
  • Make the arrows a little more visually apparent in light mode

Interpreter

  • Pointer arrows aren't re-rendering on container scroll
  • Reflow arrows when concreteTypes are toggled
  • Make the arrows in ch04-02-references-sec1-basics.toml Q1 look reasonable

Final checks:

  • Double-check mobile formatting
  • Double-check dark mode

Aquascope Preprocessor Failure on mdbook Build

Hello 😄 I tried going through the steps to use aquascope, but I was getting an error.

❯ mdbook build
2023-07-27 06:12:15 [INFO] (mdbook::book): Book building has started
Aquascope failed for program:
fn main() {
let mut s = String::from("hello ");
s.push_str("world");
}
with error:

2023-07-27 06:12:15 [ERROR] (mdbook::utils): Error: The "aquascope" preprocessor exited unsuccessfully with exit code: 1 status

This is how I have my files set up:

image

Here are the initial steps I took to install Aquascope, in order as shown on README:

I attempted cargo install mdbook-aquascope, but it failed due to the Rust nightly requirement.

Following that, I executed the remaining steps, including rustup toolchain install nightly ..., cargo +nightly-2023-04-12 install --git ..., and cargo +nightly-2023-04-12 miri setup. I was then able to install mdbook-aquascope.

Next, I ran mdbook init, added rust-toolchain.toml to override the toolchain for the project, and appended [preprocessor.aquascope] to book.toml. I also added a sample Rust code snippet in chapter_1.md.

After these steps, mdbook build began to fail, displaying the error message I described earlier.

Worklist Dec 2022

The following tasks were gathered from various TODO lists lying around that need to get merged. These should all be done within the first week of January (if not sooner).

Meta

  • mdbook preprocessor that pre-renders Aquascope instances **
  • CI test which pushes aquascope-standalone to GitHub pages and connects to the server.
  • Add all of the current Rust Book examples to the snapshot suite.

Backend

  • Add permission boundaries (expectations v. reality) for all syntax nodes that use a path. **
  • Add modes for showing all places / all permissions vs having all permissions only for the places that changed **
  • Remove all permission step visualization tables after the first error occurs. Snatch diagnostic reports vis TRACK_DIAGNOSTICS closed by: this commit
  • Suppress rustc errors when running the testing suite (they clutter stderr which should be reserved for failed tests).
  • Exclude FadeEdges when computing post-dominators for branching terminators in the steps analysis.
  • Find trait implementations for paths. We first care about implementors of Copy. (implemented for Copy)
  • Compute Move refinements similar to how Loan refinement works. This involves using parts of the MoveData as objects in the engine.

Frontend

  • Get all permission step tables to be at the end of the line. None of this semicolon after the table business. This is usually an issue with macros but the handling of loops and conditionals can also get awkward. **
  • Support emphasis for given rows/paths in permission steps. (emphasis was roughly decided as being opacity) **
  • Make custom tooltips that are more flexible (easier to interface with) than those provided by CodeMirror.
  • Support hiding lines of code prefixed with # (similar to mdbook)

Match operand expected permissions doesn't match branches

This program:

fn main() {
let opt: Option<String> = 
    Some(String::from("Hello world"));

match opt {
    Some(_) => println!("Some!"),
    None => println!("None!")
};

println!("{:?}", opt);
}

Is visualized with these permission:

Screen Shot 2023-08-08 at 3 48 30 PM

The match on opt should not require the own permission. Case in point, if you do let x = &opt and x is live across the match, the program still compiles.

Add support for Unicode strings to the interpreter

Right now, the interpreter shows Unicode strings as random characters. For example, given this snippet from the Rust Book:

fn main() {
    let hello = String::from("السلام عليكم");
}

Then Aquascope generates the following heap:

Screen Shot 2023-05-09 at 5 20 58 PM

The issue is that Strings are serialized as a vector of chars here:

Some(MHeapAllocKind::String { len }) => {
let array =
self.read_array(base, base.layout.size, *len, base.layout.ty)?;
let MValue::Array(values) = array else { unreachable!() };
let chars = values.map(|el| {
let MValue::Uint(c) = el else { unreachable!() };
MValue::Char(c as usize)
});
MValue::Array(chars)

And then each char is individually converted back to a character here:

String.fromCharCode(value.value).replace(" ", "\u00A0")

But that strategy doesn't work for non-ASCII strings.

Questions in the demo example

address:https://cognitive-engineering-lab.github.io/aquascope/

My understanding in the notation in this diagram is that R stands for readable, W stands for writable, and O stands for having ownership. If my understanding is correct I have a question, in the third line of code shown in the diagram on the right side of the label n is owned, this is not correct it is only a reference to v and does not have ownership.

image

Add support for references to unnamed data

Example:

fn foo(s: &str) {
  println!("{s}");
}

fn main() {
  foo(&String::from("Hello world"));
}

Currently this fails because the anonymous string is never discovered as a named local.

How to use on existing program?

This is a super cool tool! It is great for understanding Rust and for debugging purposes. Is there a way to run and use this locally on an existing project?

Hide code in embedded editor

In the Rust Book it's common to have a markdown syntax

```
# fn main() {
  let x = 0;
  // ...
# }
```

this makes the code executable but presents the snippet without the first and last lines.

Loss of own permissions is confusing.

I'm working with a group of people from umich. And we all find the loss of own permissions when something is borrowed confusing.
Confusing indication in Aquascrope
It's easily misunderstood as if the subject loses its ownership or its ownership is moved. So we want to make a post to let you know about it.
Would it be better to state here that the resource owned can't be moved instead of saying it lost own permissions?

Add support for &'static data to the interpreter

Currently, the interpreter does not support visualizing data that lives in the binary, e.g. &'static str (see also #49). For example, we should be able to visualize this program in the Rust Book:

fn main() {
let s: &'static str = "I have a static lifetime.";
}

This change will require modifying VisEvaluator::build_step to extract data held in the "binary" (wherever that is in Miri, not sure) similar to how the heap is extracted. Then the StepView will need to be updated to contain a new memory region that represents the binary.

Build from source instructions help and error.

First, we have to install cargo-make. After that, the last two lines are meant to be called from the root dir, but the third last line cds into the root directory - perhaps we should change the instructions like this:

git clone https://github.com/cognitive-engineering-lab/aquascope.git
cd aquascope
npm install -g graco
cargo install cargo-make
cargo make init-bindings
cd frontend && graco prepare
cd .. && cargo install --path crates/aquascope_front
cargo install --path crates/mdbook-aquascope

Apart from that, when I try to run graco prepare, the following error comes: (... used to denote the parent folder of aquascope)

................................................................................

lint


.../aquascope/frontend/packages/aquascope-editor/src/editor-utils/interpreter.tsx
  448:7  error  'config' is assigned a value but never used. Allowed unused vars must match /^_/u  @typescript-eslint/no-unused-vars
  577:1  error  Delete `········`                                                                  prettier/prettier

.../aquascope/frontend/packages/aquascope-editor/src/editor-utils/misc.tsx
  14:3   error  Insert `CharRange,⏎··`  prettier/prettier
  15:10  error  Delete `,⏎··CharRange`  prettier/prettier
  50:4   error  Insert `⏎·`             prettier/prettier

.../aquascope/frontend/packages/aquascope-editor/src/lib.tsx
   34:3   
error  Insert `CharRange,⏎··`                                                                   prettier/prettier
   35:8   error  Delete `e,⏎··CharRang`                                                                   prettier/prettier
   67:11  error  'Button' is defined but never used. Allowed unused vars must match /^_/u                 @typescript-eslint/no-unused-vars
   73:7   error  'BUTTON_ORDER' is assigned a value but never used. Allowed unused vars must match /^_/u  @typescript-eslint/no-unused-vars
  229:9   error  Unexpected constant condition                                                            no-constant-condition
  332:8   error  Delete `······`                                                                          prettier/prettier

✖ 11 proble
ms (11 errors, 0 warnings)
  7 errors and 0 warnings potentially fixable with the `--fix` option.


................................................................................

script

................................................................................

Running task for: aquascope-embed
Running task for: aquascope-standalone
[3:47:20 PM] error: Command failed: node /Users/safwan/.local/lib/node_modules/graco/dist/main.mjs init && node .../lib/node_modules/graco/dist/main.mjs build --release

There exists no --fix option. How can I resolve this?

Add support for intra-table provenance and permissions transfer

Aquascope shows how permissions change to help users understand why a particular permission may be missing. Per path, these changes are described as a gain or loss in permissions. An icon is used to indicate what actions caused this change but it doesn't describe how permissions are transferred. Shown in the below example is a simple move:

Screenshot 2023-05-21 at 12 08 50

This properly conveys how permissions change for each path in isolation but it doesn't show how these two changes are related. In this small example, one could think of permissions as being transferred from s to m. This idea of transfer is common in previous explanations of borrow checking and is demonstrated quite well by RustViz.

Screenshot 2023-05-22 at 20 12 26

In the above example from RustViz the reader is given "Immutable borrow from x to y" for the statement let y = &x;. One could reimagine this as saying "R is transferred from x to *y". This clearly explains where *y gets its permissions from.

It's unclear how these dependencies should be shown. Aquascope currently works under the constraints of embedding all visual annotations in a CodeMirror 6 editor. These visual annotations also have a space constraint as they are shown integrated with the code and not next to it. Additionally, Aquascope works on any Rust program with non-trivial control flow and shouldn't be limited to error-free programs (if this isn't currently true it's getting there 😄).

Variable lost R permission

  • I have searched open and closed issues and pull requests for duplicates, using these search terms:
  • I have checked the latest main branch to see if this has already been fixed, in this file:
    • src/ch04-05-ownership-recap.md

URL to the section(s) of the book with this problem: Ownership at Compile-time

Description of the problem:
In next code in diagram says that s lost R permission but looks like it's not

let mut s = String::from("Hello");
let s_ref = &s;
println!("{s_ref}");

If I add println!("{s}"); then compiler will not throw any error.

let mut s = String::from("Hello");
let s_ref = &s;
println!("{s}");
println!("{s_ref}");

In this issue cognitive-engineering-lab/rust-book#98 says that to test read permission I can call s.len() and next code proves that s has R permission

let mut s = String::from("Hello");
let s_ref = &s;
let n = s.len();
println!("{n}");
println!("{s_ref}");

Suggested fix:
As I understand, those permissions diagrams auto created with some permissions plugin of syntax highlighter and as for me or I don't understand what R permission means exactly or this permission plugin works incorrectly

Binoculars show even when they have no effect on the visualization

  • [ x ] I have checked the latest main branch to see if this has already been fixed
  • [ x ] I have searched existing issues and pull requests for duplicates

URL to the section(s) of the book with this problem:
https://rust-book.cs.brown.edu/ch04-01-what-is-ownership.html

Description of the problem:

The binocular button on some examples do not work. If you click the button it will change color but nothing happens. I assumed the button was a decorative item until I reached this part:

Note: you may wonder how we are executing this Rust program that doesn't compile. We use special tools to simulate Rust...

I followed the link and found that aquascope has the same binoculars button but it works correctly displaying the types of the values.
Then I went back and checked that the button doesn't work on some examples but it works in others, including the examples in the already answered first quiz.

Examples where the binoculars button doesn't work:

I'll write the first line of the paragraph above the example with the error:

  • Here's a program like the one you saw in Section 3.3 that ...
  • When an expression reads a variable, the variable's value ...
  • However, copying data can take up a lot of ...

By looking at the ch04-01-what-is-ownership.md code, I can't really tell what is the problem.

Suggested fix:

The binoculars button should work in these examples the same as in the other examples and the aquascope site or they should be removed.

Feature Requestion: Improved visualization of missing permission errors

First, thanks for working on and releasing Aquascope, I think it's going to have a massive impact on Rust pedagogy.

I was trying it out to see if it could help my students understand one of their most common errors where they attempt to return a mutable reference from an immutable one, and while the information is technically displayed it's not necessarily easy to understand it.

Here's the test program I used:

fn omg<T>(x : & T) -> &mut T {
  &mut x
}

fn main() {
  omg(&mut 5);
}

Aquascope shows (also has a trace which is uninformative here):

image

The permissions show that *x only has +R, but there's no display showing we want a &mut T (and thus need +R +W +O).
Perhaps one of those permissions boxes could be shown for the result when there's a borrow check error?

Eager loss of read permission - wrong or just confusing?

Hi, I'm still learning Rust so this may be a misunderstanding. I was looking at this example from chapter 4.5:

fn main() {
    let mut s = String::from("Hello");
    let s_ref = &s;   // 1
    println!("{s_ref}");
}

At point 1, Aquascope shows that s loses the R permission along with W and O - despite s_ref being an immutable reference, which seems wrong. However, if s is later used, this does not happen, e.g.:

fn main() {
    let mut s = String::from("Hello");
    let s_ref = &s;   // 1
    println!("{s_ref}");
    println!("{s}");
}

Here, s only loses W and O permissions at point 1. Is this wrong or just a somewhat confusing implementation detail?

Long-term TODOs

Permissions

  • Support for outlives constraints on lifetime parameters!
  • Visualize implicit drops and surrounding permission transfers
  • Address inconsistency introduced by place reborrows (eg a missing O perm if the function returns a reference).

Interpreter

  • Add support for visualizing &'static str in the interpreter
  • Link to standard library documentation for structs in interpreter vis
  • Randomly(?) jitter endpoints of pointer arrows to reduce confusing overlaps
  • Create more visually distinct mark for unallocated pointers
  • Add hover effect to link interpreter step markers between diagram and editor
  • Support for Unicode strings

Misc

  • Refactor Rust extension utilities from Aquascope (eg ir_mapper) and Flowistry (eg rustc_plugin) into a separate repo

Installation of mdbook-aquascope on stable rust channel

I was trying to install aquascope on rust stable channel,It was raising an issue
![feature] may not be used on the stable release channel
Hence I changed the command in default installation from
cargo install mdbook-aquascope to cargo +nightly install mdbook-aquascope.
This solved the problem with the installation.
But I am unable to use aquascope even after defining

# book.toml
[preprocessor.aquascope]

Interpret does not visualize move semantics

First of all, thanks for this awesome tool!

At my university, we have started teaching Rust recently, which involves explaining move semantics to the students.
Aquascope already does a great job at visualizing heap and stack memory, but moving values seems to duplicate them.

Example code

fn main() {
    let text_1 = String::from("Text");
    let text_2 = text_1;  // L2 -> value of text_1 is moved
    println!("{text_2}"); // Output for L3 is the same as L2
}

image

The output is right regarding the heap allocation, both variables technically point to the same value.
Yet they are not alive at the same time, so I would expect the output to only show "text_2" at L2 and L3 because "text_1" can't be accessed anymore and there are no guarantees that the (stack) memory of "text_1" is still available after L2 AFAIK.

Shadowing looks pretty odd as well:

image

Rendering issue of arrows in Aquascope diagram

I have encountered an issue with the rendering of arrows in Aquascope diagram when using with svgbob ASCII diagram. The arrows are not being drawn correctly, which is affecting the overall clarity of the diagram.

Example1:

```bob
+---+     +---+
| A | --> | B |
+---+     +---+
```
```aquascope,interpreter,horizontal
fn main() {
    let a = Box::new(5);`[]`
    let b = a;`[]`
}
```

image

When the bob ASCII diagram is empty, something strange happens

Example2:

```bob
```

image

Bug: Not able to interpret any code in playground

Hey folks, thank you for building such a cool tool, this tool has greatly helped me in learning Rust, absolutely love it.

Description

I wanted to set it up locally and followed all the instructions as mentioned in "from source" section and was able to do it successfully without any errors.

  1. Getting permissions in the playground works properly
image
  1. But while trying to interpret ANY code (even the default one), gives me this error in the Stderr section
[2024-03-04T20:13:16Z DEBUG aquascope_front::plugin] Provided PluginArgs AquascopePluginArgs { should_fail: true, command: Interpreter }
[2024-03-04T20:13:16Z DEBUG rustc_plugin::cli] PLUGIN_ARGS={"should_fail":true,"command":"Interpreter"}
[DEBUG src/driver.rs:152 2024-03-04T20:13:16Z] - Running plugin...
[DEBUG src/plugin.rs:171 2024-03-04T20:13:16Z] - Running command with callbacks: ["/Users/palanikannan/.cargo/bin/aquascope-driver", "--crate-name", "aquascope_tmp_proj", "--edition=2021", "src/main.rs", "--error-format=json", "--json=diagnostic-rendered-ansi,artifacts,future-incompat", "--crate-type", "bin", "--emit=dep-info,metadata", "-C", "embed-bitcode=no", "-C", "debuginfo=2", "-C", "split-debuginfo=unpacked", "-C", "metadata=2f3c62f7dee3217d", "-C", "extra-filename=-2f3c62f7dee3217d", "--out-dir", "/private/var/folders/t3/2hkg5_r510d884kf_vpl4wbr0000gn/T/.tmpK1Vlgx/aquascope_tmp_proj/target/plugin-nightly-2023-08-25/debug/deps", "-C", "incremental=/private/var/folders/t3/2hkg5_r510d884kf_vpl4wbr0000gn/T/.tmpK1Vlgx/aquascope_tmp_proj/target/plugin-nightly-2023-08-25/debug/incremental", "-L", "dependency=/private/var/folders/t3/2hkg5_r510d884kf_vpl4wbr0000gn/T/.tmpK1Vlgx/aquascope_tmp_proj/target/plugin-nightly-2023-08-25/debug/deps", "--sysroot", "/Users/palanikannan/.rustup/toolchains/nightly-2023-08-25-x86_64-apple-darwin", "-Z", "identify-regions", "-Z", "mir-opt-level=0", "-Z", "track-diagnostics=yes", "-Z", "maximal-hir-to-mir-coverage", "-A", "warnings"]
[DEBUG src/plugin.rs:175 2024-03-04T20:13:16Z] - building compiler ...
error: the current sysroot was built without `-Zalways-encode-mir`, or libcore seems missing. Use `cargo miri setup` to prepare a sysroot that is suitable for Miri.

error: could not compile `aquascope_tmp_proj` (bin "aquascope_tmp_proj") due to previous error

I tried to run cargo miri setup and tried cargo make install-mdbook and cargo make playground post that but it doesn't seem to work even then, I'm getting the same output in the Stderr when trying to interpret any code. Could you please point me towards a potential fix? Thanks

Add clear indication for path liveness and permissions changes

Aquascope shows how permissions change to help users understand why a particular permission may be missing. Per path, these changes are described as a gain or loss in permissions. Additionally, we use a single icon to indicate why these changes occurred, I'll refer to these icons as the change reason.

Screenshot 2023-05-21 at 11 38 46

In the above example, this table row tells the reader that the path s gained RWO permissions and the up arrow indicates that this was because the variable became live. However, showing a single icon has proven to be insufficient because, with liveness, multiple change reasons can exist. Consider line 3 in the below example:

Screenshot 2023-05-21 at 11 29 35

On line 3, the path s loses RWO permissions. A common question from readers is "hey, shouldn't s keep R permissions because the path is only borrowed immutably?" The answer is YES. A path borrowed immutably can still be read. The issue is that s is no longer used after line 3, it dies; however, because our visual indication only allows for a single icon this change in liveness is not called out to the reader.

The task here is to develop a system of indication that is flexible enough to convey multiple change reasons. The result should achieve the following goals: the visualization should remain clear, and cases where only one change reason exists should not become more confusing. In the past, we've experimented with showing multiple icons, and a dropdown list of icons, but both of these were insufficient as they violated the aforementioned goals.


The previous code for easy copy/pasting.

fn foo() {
  let mut s = String::from("");
  let b = &s;

  println!("{b}");
}

Bug: String slices break the interpreter

Observed

The interpretation of the code stops when creating a str slice:
image

Expected

Interpretation should work, showing the correct memory layout

code to reproduce:

fn main() {
  let x = 1;
  let s = "Hello, world!";
  let y = 1;
}

Using struct update syntax, permission for the source struct variable seem off

Line: let b = User { age: 1, ..a };
Shows permissions for "..a" as no-read (orange circle empty) and not owner (red-circle empty). At that point, would not a still be the owner and also have read access?

Or am I interpreting the empty circles incorrectly and, if so, are they documented somewhere that I have missed?

Thanks

struct User {
    name : String,
    age : i32,
}

fn main() {
    let mut a = User { name: String::from("Jeff"), age: 2 };
    a.age += 1;
    let b = User { age: 1, ..a };
    a.age += 1;
    println!("{} {}", b.name, b.age);
}

How to disable bug reporter and question mark in Aquascope?

Is there a way to disable the Bug Reporter and Question Mark that appears on the top right corner of the diagrams?

I looked at the documentation, but I couldn’t find any option to turn it off.

A possible workaround may be to comment out the relevant code in the source and then recompile the tool.

if so, is there any plans to add such an option?

Interpreter crashes with with stack overflow in rustc

I'm trying to make an example showing the struct update format similar to https://rust-book.cs.brown.edu/ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax but rustc is overflowing its stack.

struct Course {
    department: String,
    number: i32,
    section: i32,
    instructor: String,
}

fn new_course(department: &str, number: i32) -> Course {
    Course {
        department: department.to_string(),
        number, // No need to write number: number
        section: 1,
        instructor: String::from("Staff"),
    }
}

fn main() {
    let cs241 = new_course("CSCI", 241);
    let cs241_2 = Course {
        instructor: String::from("Stephen Checkoway"),
        section: 2,
        ..cs241
    };
}

stderr:



thread 'rustc' has overflowed its stack


fatal runtime error: stack overflow


error: could not compile `aquascope_tmp_proj` (bin "aquascope_tmp_proj")

Caused by:
  process didn't exit successfully: `/usr/local/cargo/bin/aquascope-driver /usr/local/rustup/toolchains/nightly-2023-08-25-x86_64-unknown-linux-musl/bin/rustc --crate-name aquascope_tmp_proj --edition=2021 src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type bin --emit=dep-info,metadata -C embed-bitcode=no -C debuginfo=2 -C metadata=eac331abf253eb57 -C extra-filename=-eac331abf253eb57 --out-dir /app/aquascope_tmp_proj/target/plugin-nightly-2023-08-25/debug/deps -C incremental=/app/aquascope_tmp_proj/target/plugin-nightly-2023-08-25/debug/incremental -L dependency=/app/aquascope_tmp_proj/target/plugin-nightly-2023-08-25/debug/deps -C target-feature=-crt-static` (signal: 6, SIGABRT: process abort signal)


Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.