# Technical Documentation: cordx56/rustowl

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/cordx56/rustowl)

### Overview (`README.md`)

<div align="center">
    <h1>
      <picture>
        <source media="(prefers-color-scheme: dark)" srcset="docs/assets/rustowl-logo-dark.svg">
        <img alt="RustOwl" src="docs/assets/rustowl-logo.svg" width="400">
      </picture>
    </h1>
    <p>
      Visualize ownership and lifetimes in Rust for debugging and optimization
    </p>
    <p>
      You can try out RustOwl on <a href="https://play.rustowl.rs/">play.rustowl.rs</a>
    </p>
    <p>
      <font size="4">
          <a href="https://crates.io/crates/rustowl">
              <img alt="Crates.io Version" src="https://img.shields.io/crates/v/rustowl?style=for-the-badge">
          </a>
          <a href="https://aur.archlinux.org/packages/rustowl-bin">
              <img alt="AUR Version" src="https://img.shields.io/aur/version/rustowl-bin?style=for-the-badge">
          </a>
          <img alt="WinGet Package Version" src="https://img.shields.io/winget/v/Cordx56.Rustowl?style=for-the-badge">
      </font>
    </p>
    <p>
      <font size="4">
          <a href="https://marketplace.visualstudio.com/items?itemName=cordx56.rustowl-vscode">
              <img alt="VS Code Static Badge" src="https://img.shields.io/badge/VS_Code-Marketplace-%234daafc?style=for-the-badge">
          </a>
          <a href="https://open-vsx.org/extension/cordx56/rustowl-vscode">
              <img alt="Open VSX Version" src="https://img.shields.io/open-vsx/v/cordx56/rustowl-vscode?style=for-the-badge">
          </a>
          <a href="https://github.com/siketyan/intellij-rustowl">
              <img alt="JetBrains Plugin Version" src="https://img.shields.io/jetbrains/plugin/v/26504-rustowl?style=for-the-badge">
          </a>
      </font>
    </p>
    <p>
      <font size="4">
          <a href="https://discord.gg/XbxN949dpG">
              <img alt="Discord" src="https://img.shields.io/discord/1379759912942436372?style=for-the-badge&logo=discord">
          </a>
      </font>
    </p>
    <p>
        <img src="docs/assets/readme-screenshot-4.png" />
    </p>
</div>

RustOwl visualizes ownership movement and lifetimes of variables.
When you save Rust source code, it is analyzed, and the ownership and lifetimes of variables are visualized when you hover over a variable or function call.

RustOwl visualizes those by using underlines:

- 🟩 green: variable's lifetime
  - **definitely live**: the variable is provably initialized on every path reaching this point
  - **maybe live** (wavy): the variable is initialized on some paths but may have been moved, dropped, or be uninitialized on others
- 🟦 blue: immutable borrowing
- 🟪 purple: mutable borrowing
- 🟧 orange: value moved / function call
- 🟥 red: lifetime error
  - Diff of lifetime between actual and expected, or
  - Invalid overlapped lifetime of mutable and shared (immutable) references

Detailed usage is described [here](docs/usage.md).

Currently, we offer VSCode extension, Neovim plugin and Emacs package.
For these editors, move the text cursor over the variable or function call you want to inspect and wait for 2 seconds to visualize the information.
We implemented LSP server with an extended protocol.
So, RustOwl can be used easily from other editor.

## Table Of Contents



- [Table Of Contents](#table-of-contents)
- [Support](#support)
- [Quick Start](#quick-start)
  - [Prerequisite](#prerequisite)
  - [VS Code](#vs-code)
  - [Vscodium](#vscodium)
- [Other editor support](#other-editor-support)
  - [Neovim](#neovim)
  - [Emacs](#emacs)
  - [RustRover / IntelliJ IDEs](#rustrover--intellij-ides)
  - [Sublime Text](#sublime-text)
- [Installation](#installation)
- [Usage](#usage)
- [Note](#note)


## Support

If you're looking for support, please consider checking all issues, existing discussions, and [starting a discussion](https://github.com/cordx56/rustowl/discussions/new?category=q-a) first!

Also, you can reach out to us on the Discord server provided above.

## Quick Start

Here we describe how to start using RustOwl.

### Prerequisite

- `cargo` installed
  - You can install `cargo` using `rustup` from [this link](https://rustup.rs/).
- Visual Studio Code (VS Code) installed

We tested this guide on macOS Sequoia 15.3.2 on arm64 architecture with VS Code 1.99.3 and `cargo` 1.90.0.

### VS Code

You can install VS Code extension from [this link](https://marketplace.visualstudio.com/items?itemName=cordx56.rustowl-vscode).
RustOwl will be installed automatically when the extension is activated.

For more detailed configuration options, see the [VS Code Configuration Guide](docs/vscode-configuration.md).

### Vscodium

You can install Vscodium extension from [this link](https://open-vsx.org/extension/cordx56/rustowl-vscode).
RustOwl will be installed automatically when the extension is activated.

After installation, the extension will automatically run RustOwl when you save any Rust program in cargo workspace.
The initial analysis may take some time, but from the second run onward, compile caching is used to reduce the analysis time.

Same as [VS Code](#vs-code), see the [VS Code Configuration Guide](docs/vscode-configuration.md) for more detailed configuration options.

## Other editor support

We support Neovim and Emacs.
You have to [install RustOwl](./docs/installation.md) before using RustOwl with other editors.

You can also create your own LSP client.
If you would like to implement a client, please refer to the [The RustOwl LSP specification](docs/lsp-spec.md).

### Neovim

Minimal setup with [lazy.nvim](https://github.com/folke/lazy.nvim):

```lua
{
  'cordx56/rustowl',
  version = '*', -- Latest stable version
  build = 'cargo install rustowl',
  lazy = false, -- This plugin is already lazy
  opts = {},
}
```

For comprehensive configuration options including custom highlight colors, see the [Neovim Configuration Guide](docs/neovim-configuration.md).

### Emacs

Elpaca example:

```elisp
(elpaca
  (rustowl
    :host github
    :repo "cordx56/rustowl"))
```

Then use-package:

```elisp
(use-package rustowl
  :after lsp-mode)
```

You have to install RustOwl LSP server manually.

For more detailed configuration options, see the [Emacs Configuration Guide](./docs/emacs-configuration.md).

### RustRover / IntelliJ IDEs

There is a [third-party repository](https://github.com/siketyan/intellij-rustowl) that supports IntelliJ IDEs.
You have to install RustOwl LSP server manually.

### Sublime Text

There is a [third-party repository](https://github.com/CREAsTIVE/LSP-rustowl) that supports Sublime Text.

## Installation

Please see [Installation](docs/installation.md) for detailed installation instructions.

## Usage

Please see [Usage](docs/usage.md) for detailed usage instructions.

## Note

We support the 5 latest versions of Rust (best effort).

In this tool, due to the limitations of VS Code's decoration specifications, characters with descenders, such as g or parentheses, may occasionally not display underlines properly.
Additionally, we observed that the `println!` macro sometimes produces extra output, though this does not affect usability in any significant way.

---

### Overview (`scripts/README.md`)

# RustOwl Scripts

This directory contains utility scripts for local development and testing that complement the CI workflows.

## Quick Start

```bash
# Run development checks
./scripts/dev-checks.sh

# Check binary size changes
./scripts/size-check.sh

# Run security and memory safety tests
./scripts/security.sh

# Run performance benchmarks
./scripts/bench.sh

# Run Neovim Tests
./scripts/run_nvim_tests.sh
```

## Script Overview

### `dev-checks.sh`

Runs comprehensive development checks including formatting, linting, and tests.

**Features:**

- Code formatting checks (`cargo fmt`)
- Linting with Clippy
- Unit tests
- Integration tests
- Documentation tests

### `size-check.sh`

Analyzes binary size changes to detect bloat and track optimization efforts.

**Features:**

- Binary size comparison
- Dependency analysis
- Size regression detection

### 🛡️ `security.sh`

Comprehensive security and memory safety testing framework.

**Features:**

- Multi-tool testing (Miri, Valgrind, ThreadSanitizer, cargo-deny, cargo-shear, Instruments)
- Cross-platform support (Linux, macOS, ARM64)
- Graceful degradation when tools unavailable
- Configurable test categories
- Color-coded output with progress indicators

**Usage:**

```bash
# Run all applicable tests for the current platform
./scripts/security.sh

# Run specific test categories
./scripts/security.sh --no-miri
./scripts/security.sh --no-valgrind
./scripts/security.sh --no-audit

# ThreadSanitizer is opt-in: it instruments every build, so it is slow
./scripts/security.sh --thread-sanitizer

# Check available tools and configuration
./scripts/security.sh --check
```

**Platform notes:**

- On Linux, Instruments is disabled and Valgrind covers memory errors.
- On macOS, Valgrind is disabled and a Time Profiler trace is captured with
  `xcrun xctrace` instead. The trace is written as
  `instruments_output_<timestamp>.trace`, which CI uploads as an artifact when
  the run fails.
- ThreadSanitizer requires a nightly toolchain and is opt-in on any platform
  via `--thread-sanitizer`. CI exercises it in a dedicated Linux job. It needs
  `rust-src`, because `-Zsanitizer` changes the
  crate ABI and therefore requires `-Zbuild-std` to rebuild `core` and
  `compiler_builtins` with the same flag — without it rustc fails with
  "mixing `-Zsanitizer` will cause an ABI mismatch".
- Findings matching [`.tsan-suppressions`](../.tsan-suppressions) are
  suppressed. They are not real races: any program building a multi-threaded
  tokio runtime reproduces them when the synchronisation sits inside
  `OnceLock`/`Mutex` or is driven through epoll, and tokio's own suite is clean
  under `-Zbuild-std`. The file records the evidence and what would make each
  entry safe to remove.
- The instrumented build and the instrumented run are two separate steps. An
  aborted run produces zero ThreadSanitizer warnings and would otherwise be
  indistinguishable from a clean one, so a failed build fails the suite rather
  than reporting "no races detected".
- The run is bounded at 300s, because a TSan run does not always converge —
  tokio's `test_tuning` in `rt_threaded.rs` has to be killed after ~27 minutes
  under the sanitizer.
- `cargo-shear` runs on both Linux and macOS.
- In CI, missing tools are installed automatically unless you pass
  `--no-auto-install`, which is honoured even though CI detection would
  otherwise enable installation.

### Dependency policy: `cargo-deny`

[`cargo-deny`](https://embarkstudios.github.io/cargo-deny/) checks the
dependency graph for known advisories, disallowed licences, banned crates and
unexpected sources. Its rules live in [`deny.toml`](../deny.toml) at the repo
root; `cargo deny check` must pass locally before pushing.

```bash
cargo deny check                     # all four checks
cargo deny check advisories          # just the vulnerability check
```

CI runs this in a separate job via
[`EmbarkStudios/cargo-deny-action`](https://github.com/EmbarkStudios/cargo-deny-action),
so `security.sh` is invoked there with `--no-audit` to avoid resolving the full
graph three times across the OS matrix.

Notes on the current configuration:

- `multiple-versions` is a **warning**: duplicate versions are normal in a real
  graph and unifying them is rarely worth the churn.
- MPL-2.0 is **not** in the blanket allow list. `rustowl` is MPL-2.0, and it is
  permitted by name, so adding another MPL-2.0 dependency has to be a deliberate
  edit rather than an accident.
- Other per-crate exceptions exist for `r-efi` (LGPL-2.1-or-later),
  `webpki-root-certs` (CDLA-Permissive-2.0) and `libbz2-rs-sys`
  (`bzip2-1.0.6`), each with a comment explaining why.

### Unused dependencies: `cargo-shear`

[`cargo-shear`](https://crates.io/crates/cargo-shear) replaces `cargo-machete`.
`security.sh` runs it with `--check-test-targets`, so a dependency used only
from a test target is not reported as unused.

```bash
cargo shear --check-test-targets
```

### 📊 `bench.sh`

Local performance benchmarking with regression detection.

**Features:**

- Criterion benchmark integration
- Baseline creation and comparison
- Automatic test package detection
- Configurable regression thresholds
- HTML report generation
- Local development focus

**Usage:**

```bash
# Standard benchmark run
./scripts/bench.sh

# Create and compare baselines
./scripts/bench.sh --save my-baseline
./scripts/bench.sh --load my-baseline --threshold 3%

# Development workflow
./scripts/bench.sh --clean --open --test-package ./examples
```

**Note:** Benchmarks are designed for local development only. CI environments introduce too much variability for reliable performance measurement.

### `run_nvim_tests.sh`

Run tests defined in [`nvim-tests`](../nvim-tests) directory.

**Usage**

```bash
./scripts/run_nvim_tests.sh
```

In uses `[mini.test](https://github.com/echasnovski/mini.test)` plugin to test.

## Prerequisites

### Common Requirements

- Rust toolchain (automatically managed via `rust-toolchain.toml`)
- Basic build tools
- Neovim (Only For The Tests And If You Are Changing Neovim Specific Things)

### Platform-Specific Tools

#### Linux

```bash
sudo apt-get update
sudo apt-get install -y valgrind gnuplot build-essential
```

#### macOS

```bash
brew install gnuplot
# Optional: brew install valgrind (limited support)
```

## Integration with CI

These scripts are designed to complement CI workflows where applicable:

- **`security.sh`** ↔ **`.github/workflows/security.yml`**: Same security analysis tools

Note: Benchmarking (`bench.sh`) is intentionally local-only due to CI environment variability.

### GitHub Actions Integration

The scripts integrate with workflows where appropriate:

#### Security Workflows

- **`security.yml`**: Runs comprehensive security testing across platforms

#### Development Scripts

- **`bench.sh`**: Local-only performance testing (not suitable for CI)
- **`dev-checks.sh`**: Can be used in CI for code quality checks

## Development Workflow

### Before Committing

```bash
# Run all development checks
./scripts/dev-checks.sh

# Run security tests
./scripts/security.sh

# Check performance impact (local only)
./scripts/bench.sh

# Check binary size impact
./scripts/size-check.sh

# If you changed any neovim specific things (like lua files)
./scripts/run_nvim_tests.sh
```

### Setting Up New Environment

For setting up a development environment, ensure you have the platform-specific tools listed in the Prerequisites section above.

## Troubleshooting

### Script Permissions

```bash
chmod +x scripts/*.sh
```

### Missing Tools

Run the setup script or check platform-specific installation commands above.

### CI Failures

- Check workflow logs for specific error messages
- Verify `rust-toolchain.toml` compatibility
- Ensure scripts have execution permissions
- Test locally with the same script used in CI

## Script Architecture

All scripts follow common patterns:

- **Color-coded output** with emoji indicators
- **Progressive enhancement** based on available tools
- **Comprehensive help text** with examples
- **Error handling** with remediation suggestions
- **Cross-platform compatibility** with platform-specific optimizations

### Shared code

`lib/common.sh` holds everything the in-repo scripts have in common: the colour
constants and `log_*` helpers, the NixOS `nix-ld` path setup, `have_cmd` /
`require_cmd`, `print_host_tuple`, the rustc version gate, and the integer
percentage helpers. Scripts source it as `lib/common.sh` relative to their own
directory:

```sh
SCRIPT_DIR="$(CDPATH='' cd -- "$(dirname "$0")" && pwd)"
. "$SCRIPT_DIR/lib/common.sh"
```

The library is POSIX `sh` — no `[[ ]]`, no arrays, no `echo -e` — because
`toolchain` sources it and runs under dash and busybox-ash in CI. It also has no
side effects at source time.

`installer` is the one exception. It is piped into `sh` from a URL and so has
to stay self-contained; it keeps its own copy of `print_host_tuple`.

---

### Overview (`vscode/README.md`)

# RustOwl VSCode

This is RustOwl extension for VSCode. It will download the binaries and will do toolchain setup automatically.

## Configuring RustOwl

For detail, refer to the [vscode configuration guide](https://github.com/cordx56/rustowl/blob/main/docs/vscode-configuration.md).

---

### Overview (`crates/rustowl/perf-tests/dummy-package/README.md`)

# RustOwl Performance Test Dummy Package

This is a dummy Rust package specifically designed for performance testing with RustOwl. The package contains various Rust patterns and constructs that RustOwl can analyze, including:

## Features Tested

### Ownership and Borrowing Issues

- Methods returning references to internal data
- Potential lifetime issues
- Clone operations that might be unnecessary

### Error Handling Patterns

- Use of `unwrap()` that might panic
- Proper error handling with `Result` and `Context`
- Missing error propagation

### Resource Management

- File handling and potential resource leaks
- Thread safety and potential deadlocks
- Memory allocation patterns

### Async/Concurrency Patterns

- Async operations with tokio
- Thread-based parallel processing
- Shared state with `Arc<Mutex<T>>`

### Performance Patterns

- Memory-intensive operations
- CPU-intensive computations
- I/O operations

## Usage

The dummy package can be built and run to provide realistic workload for RustOwl analysis:

```bash
cargo build --release
cargo run -- --help
```

## Operations

The dummy application supports several operations:

- `data` - Run data structure operations with potential ownership issues
- `network` - Run network operations (may fail without internet)
- `files` - Run file I/O operations
- `compute` - Run CPU-intensive computations
- `all` - Run all operations

## Performance Testing

This package is used by the RustOwl performance testing script (`perf-tests.sh`) to provide a consistent, realistic codebase for performance analysis.

The code intentionally contains patterns that RustOwl can analyze and potentially flag, making it an ideal test case for measuring RustOwl's analysis performance on real-world-like Rust code.

### Testing Modes

The performance testing script supports different analysis modes:

- **Default Mode**: Fast analysis with current target and default features
- **Comprehensive Mode**: Thorough analysis with `--all-targets --all-features`

The package includes multiple targets (main binary, examples, tests) and conditional features to enable comprehensive testing of RustOwl's analysis capabilities across different code paths and compilation scenarios.

---

### CODE OF CONDUCT (`docs/CODE_OF_CONDUCT.md`)

# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, caste, color, religion, or sexual
identity and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.

## Our Standards

Examples of behavior that contributes to a positive environment for our
community include:

- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
  and learning from the experience
- Focusing on what is best not just for us as individuals, but for the overall
  community

Examples of unacceptable behavior include:

- The use of sexualized language or imagery, and sexual attention or advances of
  any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email address,
  without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.

Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.

## Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official email address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
[cordx56@cordx.cx](mailto:cordx56@cordx.cx).
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
reporter of any incident.

## Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:

### 1. Correction

**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.

**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.

### 2. Warning

**Community Impact**: A violation through a single incident or series of
actions.

**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or permanent
ban.

### 3. Temporary Ban

**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.

**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.

### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within the
community.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].

Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][mozilla coc].

For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][faq]. Translations are available at
[https://www.contributor-covenant.org/translations][translations].

[faq]: https://www.contributor-covenant.org/faq
[homepage]: https://www.contributor-covenant.org
[mozilla coc]: https://github.com/mozilla/diversity
[translations]: https://www.contributor-covenant.org/translations
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html

---

### CONTRIBUTING (`docs/CONTRIBUTING.md`)

# Contribution guide

_This document is under construction_.

Thank you for considering to contribute RustOwl!

In this document we describe how to contribute our project, as follows:

- How to setup development environment
- Checklist before submitting PR

## Table of Contents

- [Set up your environment](#set-up-your-environment)
  - [Prerequisites](#prerequisites)
    - [Common Requirements](#common-requirements)
    - [Platform-Specific Tools](#platform-specific-tools)
  - [Rust code](#rust-code)
  - [Editor extensions](#editor-extensions)
- [Before submitting PR](#before-submitting-pr)
  - [Development Checks](#development-checks)
  - [Security and Memory Safety Testing](#security-and-memory-safety-testing)
  - [Performance Testing](#performance-testing)
  - [Binary Size Monitoring](#binary-size-monitoring)
  - [Manual Checks](#manual-checks)
- [Development Workflow](#development-workflow)
- [Troubleshooting](#troubleshooting)

## Set up your environment

### Prerequisites

#### Common Requirements

- Rust toolchain (automatically managed via `rust-toolchain.toml`)
- Basic build tools

#### Platform-Specific Tools

##### Linux

```bash
sudo apt-get update
sudo apt-get install -y valgrind bc gnuplot build-essential # For Rustowl Itself
sudo apt-get install -y neovim # Optional: Install Neovim for neovim plugin development
sudo apt-get install -y emacs # Optional: Install Emacs for emacs plugin development
# Install Visual Studio Code as in their documentation
```

##### macOS

```bash
brew install gnuplot
# Optional: brew install valgrind (limited support)
brew install neovim # Optional: Install Neovim for neovim plugin development
brew install emacs # Optional: Install Emacs for emacs plugin development
# Install Visual Studio Code as in their documentation
```

### Rust code

In the Rust code, we utilize nightly compiler features, which require some tweaks.
Before starting this section, you might be required to install `rustup` since our project requires nightly compiler.

Our project uses `rust-toolchain.toml` to automatically manage the correct Rust version.

#### Build and test using the nightly environment

For building, testing, or installing, you can do the same as any common Rust project using the `cargo` command.

#### Build with stable Rust compiler

To distribute release binary, we use stable Rust compiler to ship RustOwl with stable Rust compiler for users.

The executable binary named `rustowlc`, which is one of the components of RustOwl, behaves like a Rust compiler.
So we would like to compile `rustowlc`, which uses nightly features, with the stable Rust compiler.

> [!NOTE]
> Using this method is strongly discouraged officially. See [Unstable Book](doc.rust-lang.org/nightly/unstable-book/compiler-flags/rustc-bootstrap.html).

To compile `rustowlc` with stable compiler, you should set environment variable as `RUSTC_BOOTSTRAP=1`.

Our script automates most of the work, so to build with the toolchain specified in [channel](../scripts/build/channel) file:

```bash
./scripts/build/toolchain cargo build --release
```

To do it manually:

```bash
# 1.89.0 can be any version
RUSTC_BOOTSTRAP=1 rustup +1.89.0 run cargo build --release
```

As new Rust versions release, their APIs change. Thus, RustOwl code also changes. You might see errors if the version is newer. We strive to make the code in the main branch compatible with the latest Rust version, which is specified in the [channel](../scripts/build/channel) file.

Note that by using normal `cargo` command RustOwl will be built with nightly compiler since there is a `rust-toolchain.toml` which specifies nightly compiler for development environment.

### VS Code extension

For VS Code extension, we use `pnpm` to setup environment.
To get started, you have to install dependencies by running following command inside `vscode` directory:

```bash
pnpm install
```

### Neovim Plugin

You need to install [stylua](https://github.com/JohnnyMorganz/StyLua) and [selene](https://github.com/Kampfkarren/selene) for code formatting and linting.

Now write your code, see [lua](../lua), [ftplugin](../ftplugin), [nvim-tests](../nvim-tests).

Please write a test using [mini.test](https://github.com/echasnovski/mini.test) before submitting a pr, you can run tests using [run_nvim_tests.sh](../scripts/run_nvim_tests.sh).

### Emacs Plugin

You need to install [eask](https://github.com/emacs-eask/cli) for code formatting, linting, testing and whatnot.

Now write your code, see [rustowl.el](../rustowl.el) and [emacs-tests](../emacs-tests).

Please write a test using [ERT](https://www.gnu.org/software/emacs/manual/html_mono/ert.html) before submitting a pr, you can run tests using `eask script run test`. (needs `eask`)

## Before submitting PR

Before submitting PR, you have to check below:

### Development Checks

Use the helper scripts in `./scripts` to run development checks and fixes. Examples:

```bash
# Run all development checks
./scripts/dev-checks.sh

# Run checks and automatically fix issues where possible
./scripts/dev-checks.sh --fix
```

Refer to individual scripts for details (security, benchmarking, size checks). For CI-consistent runs, prefer the scripts above instead of invoking tools manually.

### Security and Memory Safety Testing

Use `./scripts/security.sh` to run the available security and UB detection tools. See the script for options to skip Miri/Valgrind/audit steps.

### Performance Testing

Use `./scripts/bench.sh` to run performance benchmarks. Create and compare baselines using the script's flags.

### Binary Size Monitoring

Use `./scripts/size-check.sh` to analyze and compare binary sizes. Save/Load baselines via the script flags.

### Manual Checks

If the automated scripts are not available, ensure:

#### Rust code correctness and formatting

- Correctly formatted by `cargo fmt`
- Linted using Clippy by `cargo clippy`
- All tests pass with `cargo test`

#### VS Code extension Style

- Correctly formatted by `pnpm fmt`
- Linting passes with `pnpm lint`
- Type checking passes with `pnpm check-types`

#### Neovim Plugin Checks

- Correctly formatted by `stylua`
- Linting passes with `selene`
- Tests passing with `mini.test`

## Development Workflow

### Recommended Development Process

1. **Before making changes**:

   ```bash
   # Create performance baseline
   ./scripts/bench.sh --save before-changes
   ```

2. **During development**:

   ```bash
   # Run quick checks frequently
   ./scripts/dev-checks.sh --fix
   ```

3. **Before committing**:

   ```bash
   # For Rust Code
   ./scripts/dev-checks.sh
   ./scripts/security.sh
   ./scripts/bench.sh --load before-changes
   ./scripts/size-check.sh
   # For Neovim
   ./scripts/run_nvim_tests.sh
   stylua .
   selene .
   # For Emacs
   eask script run test
   eask script run format
   eask lint <linter>
   ```

## Troubleshooting

### Script Permissions

```bash
chmod +x scripts/*.sh
```

### Missing Tools

Install the required tools manually using the platform-specific commands in the Prerequisites section above.

### CI Failures

- Check workflow logs for specific error messages
- Verify `rust-toolchain.toml` compatibility
- Ensure scripts have execution permissions
- Test locally with the same script used in CI

For more detailed information about the scripts, see [`scripts/README.md`](../scripts/README.md).

---

### SECURITY (`docs/SECURITY.md`)

# Security Reporting

If you wish to report a security vulnerability but not in a public issue -- thank you! -- we ask that you follow the following process.

Please report security vulnerabilities by filling out the following template:

- PUBLIC: Please let us know if this vulnerability has been made or discussed publicly already, and if so, please let us know where.
- DESCRIPTION: Please provide precise description of the security vulnerability you have found with as much information as you are able and willing to provide.

Please send the above info, along with any other information you feel is pertinent to: <cordx56@cordx.cx>.

In addition, you may request that the project provide you a patched release in advance of the release announcement, however, we can not guarantee that such information will be provided to you in advance of the public release and announcement.

However, I will email you at the same time the public announcement is made.
We will let you know within a few weeks whether or not your report has been accepted or rejected.
We ask that you please keep the report confidential until we have made a public announcement.

---

### Build (`docs/build.md`)

# Build guide


- [Build guide](#build-guide)
  - [RustOwl](#rustowl)
    - [Build RustOwl using stable toolchain](#build-rustowl-using-stable-toolchain)
    - [Build RustOwl using custom toolchain](#build-rustowl-using-custom-toolchain)
  - [VSCode extension](#vscode-extension)
    - [Prerequisite](#prerequisite)
    - [Build & Run](#build-run)


Here we describe how to build each of our repository.

## RustOwl

You can choose one of two ways to build RustOwl.

You can add runtime directory paths to the search paths by specifying the `RUSTOWL_RUNTIME_DIRS` or `RUSTOWL_SYSROOTS` environment variables.
The default runtime directory is `$HOME/.rustowl`.

On a freshly installed Ubuntu system, you need to run `apt install build-essential` to ensure all required build tools are available for linking.

### Build RustOwl using stable toolchain

There are scripts to build the stable version of RustOwl.
`scripts/toolchain` sets up the RustOwl toolchain and executes command using that toolchain.

```bash
./scripts/toolchain cargo install --path . --locked
```

### Build RustOwl using custom toolchain

You can build RustOwl using a custom toolchain. This method is recommended for contributors to RustOwl.

The prerequisites are as follows:

- `rustup` installed
  - You can install `rustup` from [this link](https://rustup.rs/).
  - You need to set up the `PATH` environment variable. Follow the instructions provided by the `rustup` installer to do this.
- `gcc` or `clang` installed.
  - On Windows, you can install the Visual Studio toolchain instead.

Building RustOwl requires a nightly build of `rustc`. It will be installed automatically by `rustup` if needed.

Other dependencies are specified in the configuration files and will be installed automatically.

```bash
cargo install --path . --locked
```

## VSCode extension

### Prerequisite

- VS Code installed
  - You can install VS Code from [this link](https://code.visualstudio.com/).
- Node.js installed
- `pnpm` installed
  - After installing Node.js, You can install `pnpm` by running `npm install pnpm`.

VS Code extension has been tested on macOS Sequoia 15.3.2 on arm64 architecture with Visual Studio Code 1.99.3, Node.js v20.16.0, and `pnpm` 1.22.22.
Other dependencies are locked in the configuration files and will be installed automatically.

### Build & Run

First, install the dependencies:

```bash
cd vscode
pnpm install --frozen-lockfile
```

Then, open the `vscode` directory in VS Code.

A notification to install the recommended VS Code extension will appear in the bottom right corner of VS Code.
Click the install button, wait for the installation to finish, and then restart VS Code.

Open the `vscode` directory again, and press the `F5` key in the VS Code window.
A new VS Code window with the extension enabled will appear.

Open the cargo workspace directory in the new VS Code window.

When you save Rust files, decorations indicating the movement of ownership and lifetimes will appear in the editor.

---

### Emacs Configuration (`docs/emacs-configuration.md`)

# RustOwl Configuration (Emacs)

## Table Of Contents


- [RustOwl Configuration (Emacs)](#rustowl-configuration-emacs)
  - [Table Of Contents](#table-of-contents)
  - [Quick Start](#quick-start)
  - [Basic Setup](#basic-setup)
  - [What the package does](#what-the-package-does)
  - [Defaults and variables](#defaults-and-variables)
  - [How highlighting works](#how-highlighting-works)
  - [Enabling / Disabling](#enabling-disabling)
  - [Examples](#examples)
  - [Troubleshooting](#troubleshooting)


## Quick Start

1. Install RustOwl (see docs/installation.md) and install the Emacs package via `elpaca` or `use-package`.
2. Open a Rust Cargo workspace in Emacs.
3. Place the cursor on a variable and wait ~2 seconds (default) to see overlays with lifetime and borrow info.

This document describes how to use RustOwl from Emacs. It mirrors the detail level of `docs/neovim-configuration.md` and is derived from `rustowl.el`.

## Basic Setup

Install the `rustowl` executable (see `docs/installation.md`). Install the Emacs package via `elpaca` or `use-package`.

Elpaca example:

```elisp
(elpaca
  (rustowl
    :host github
    :repo "cordx56/rustowl"))
```

Use-package example:

```elisp
(use-package rustowl
  :after lsp-mode)
```

## What the package does

- Registers an LSP client for `rust-mode`, `rust-ts-mode`, and `rustic-mode` using `rustowl` as the executable.
- Sends `rustowl/analyze` on save (see `rustowl-enable-analyze-on-save`).
- Sends `rustowl/cursor` when the cursor has been idle for `rustowl-cursor-timeout` seconds (default 2.0 seconds) and applies underlines via overlays.

## Defaults and variables

- `rustowl-cursor-timeout` (float) — default: 2.0 seconds. Idle time before the cursor request is sent.
- `rustowl-cursor-timer` — internal timer variable managed by the package.

## How highlighting works

- The package sends `rustowl/cursor` with position and document URI. The server responds with decorations (type, range, hover text, overlapped).
- For each non-overlapped decoration, the package maps types to underline colors:
  - `definitely_live` → `#00cc00` (green, straight)
  - `maybe_initialized` → `#00cc00` (green, wavy)
  - `imm_borrow` → `#0000cc` (blue)
  - `mut_borrow` → `#cc00cc` (purple)
  - `move` / `call` → `#cccc00` (yellow)
  - `outlive` / `shared_mut` → `#cc0000` (red, wavy)
- Underlines are implemented via overlays with face `(:underline (:color <color> :style wave))`.

## Enabling / Disabling

- `rustowl-enable-cursor` — enable cursor-based highlighting for current buffer (adds post-command-hook).
- `rustowl-disable-cursor` — disable cursor-based highlighting (removes hook, cancels timer and clears overlays).
- Cursor highlighting is automatically enabled for Rust buffers via `rust-mode-hook`, `rust-ts-mode-hook`, and `rustic-mode-hook`.
- Obsolete aliases `enable-rustowl-cursor` / `disable-rustowl-cursor` remain for backward compatibility.

## Examples

To disable analyze-on-save globally, remove the hooks or call:

```elisp
(remove-hook 'rust-mode-hook #'rustowl-enable-cursor)
```

To customize the timeout in your config:

```elisp
(setq rustowl-cursor-timeout 1.0) ; 1 second
```

## Troubleshooting

- If overlays don't appear, ensure `lsp-mode` is active and `rustowl` server is reachable.
- Use `M-x rustowl-clear-overlays` to clear overlays if they persist.

See `docs/lsp-spec.md` for the LSP request/response shapes.

---

### Installation (`docs/installation.md`)

# Installation

## Table Of Contents


- [Installation](#installation)
  - [Table Of Contents](#table-of-contents)
  - [Quick Start](#quick-start)
  - [cargo-binstall (recommended)](#cargo-binstall)
  - [Windows (winget)](#windows-winget)
  - [Arch Linux (AUR)](#arch-linux-aur)
  - [Nix flake](#nix-flake)
  - [GitHub Releases](#github-releases)
  - [Docker](#docker)
  - [Build manually](#build-manually)
  

## Quick Start

- Install using our script (recommended):

```
curl -L https://raw.githubusercontent.com/cordx56/rustowl/refs/heads/main/scripts/installer | sh
```

## cargo-binstall

Install the prebuilt binary using cargo-binstall:

```bash
cargo binstall rustowl
```

This automatically downloads and unpacks a Rust toolchain if required.

## Windows (winget)

Install with:

```sh
winget install rustowl
```

## Arch Linux (AUR)

We provide AUR packages that either install prebuilt binaries or build from source.
Prebuilt binaries (recommended):

```sh
yay -S rustowl-bin
```

Build from AUR (cargo build):

```sh
yay -S rustowl
```

Git (build from latest source):

```sh
yay -S rustowl-git
```

Replace `yay` with your AUR helper of choice.

## Nix flake

There is a [third-party Nix flake repository](https://github.com/nix-community/rustowl-flake) in the Nix community.

## GitHub Releases

Download the `rustowl` executable from the release page:

https://github.com/cordx56/rustowl/releases/latest

Place the executable into a directory on your PATH.

## Docker

Run the prebuilt image from GitHub Container Registry:

```sh
docker pull ghcr.io/cordx56/rustowl:latest
```

Run it against a project directory:

```sh
docker run --rm -v /path/to/project:/app ghcr.io/cordx56/rustowl:latest
```

Use an alias to act like a local CLI:

```sh
alias rustowl='docker run --rm -v $(pwd):/app ghcr.io/cordx56/rustowl:latest'
```

## Build manually

See `docs/build.md` for detailed build instructions and how to build editor extensions.

---

### Lsp Spec (`docs/lsp-spec.md`)

# The RustOwl LSP specification

## Table of Contents



- [The RustOwl LSP specification](#the-rustowl-lsp-specification)
  - [Table of Contents](#table-of-contents)
  - [Types](#types)
    - [`OprType`](#oprtype)
    - [`Decoration`](#decoration)
  - [Methods](#methods)
    - [`rustowl/cursor`](#rustowlcursor)
      - [Request payload](#request-payload)
      - [Response payload](#response-payload)


`rustowl`, is an LSP server which provides RustOwl information.
To display various types of decorations, RustOwl supports some custom methods from the client.

Here, we describe the specifications of those custom methods.

## Types

Here, we describe the types we will use in this document.

### `OprType`


```typescript
"lifetime" | "definitely_live" | "maybe_initialized"
| "imm_borrow" | "mut_borrow" | "move" | "call"
| "outlive" | "shared_mut"
```


`definitely_live` and `maybe_initialized` are derived from a CFG-based liveness analysis:

- `definitely_live` covers ranges where the local is provably initialized on every path that reaches the location (state is exactly `{Initialized}`).
- `maybe_initialized` covers ranges where the local is initialized on at least one path but may also have been moved, dropped, or be uninitialized on others (state contains `Initialized` together with other variants). Useful for spotting conditional drops and other resource-management ambiguity.

`lifetime` is retained for backward compatibility; clients should treat `definitely_live` as the replacement for the previous "actual lifetime" decoration.

### `Decoration`

<pre><code>{
    "type": <a href="#oprtype">OprType</a>,
    "range": <a href="https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#range">Range</a>,
    "hover_text": Option&lt;String&gt;,
    "overlapped": bool
}
</code></pre>

`overlapped` field indicates that the decoration is overlapped and should be hidden.

## Methods

We describe the custom methods used in RustOwl.

### `rustowl/cursor`

#### Request payload

<pre><code>{
    "position": <a href="https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#position">Position</a>,
    "document": {
        "uri": <a href="https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#documentUri">DocumentUri</a>
    }
}
</code></pre>

#### Response payload

<pre><code>{
    "is_analyzed": bool,
    "decorations": [<a href="#decoration">Decoration</a>]
}
</code></pre>

---

### Neovim Configuration (`docs/neovim-configuration.md`)

# RustOwl Configuration (Neovim)

## Quick Start

1. Install RustOwl (see docs/installation.md) and the Neovim plugin via your plugin manager.
2. Add the minimal setup to your lazy.nvim config and open a Rust Cargo workspace.
3. Hover the cursor over a variable and wait ~500ms to see visualizations.

This document describes all available configuration options for the RustOwl Neovim plugin.

## Table of Contents



- [RustOwl Configuration (Neovim)](#rustowl-configuration-neovim)
  - [Quick Start](#quick-start)
  - [Table of Contents](#table-of-contents)
  - [Basic Setup](#basic-setup)
  - [Configuration Options](#configuration-options)
    - [`auto_attach` (boolean)](#autoattach-boolean)
    - [`auto_enable` (boolean)](#autoenable-boolean)
    - [`idle_time` (number)](#idletime-number)
    - [`highlight_style` (string)](#highlightstyle-string)
    - [`colors` (table)](#colors-table)
      - [Available Color Options:](#available-color-options)
    - [`client` (table)](#client-table)
  - [Customizing Highlight Colors](#customizing-highlight-colors)
    - [Default Highlight Style](#default-highlight-style)
    - [Default Colors](#default-colors)
    - [Custom Colors](#custom-colors)
      - [Color Format](#color-format)
    - [Partial Color Customization](#partial-color-customization)
  - [Examples](#examples)
    - [Example 1: Minimal Configuration](#example-1-minimal-configuration)
    - [Example 2: Auto-enable with Custom Colors](#example-2-auto-enable-with-custom-colors)
    - [Example 3: Custom Key Binding and Styling](#example-3-custom-key-binding-and-styling)
    - [Example 4: Dark Theme Optimized Colors](#example-4-dark-theme-optimized-colors)
    - [Example 5: For init.vim Users](#example-5-for-initvim-users)
  - [Usage Commands](#usage-commands)
  

## Basic Setup

The minimal configuration for RustOwl using [lazy.nvim](https://github.com/folke/lazy.nvim):

```lua
{
  'cordx56/rustowl',
  version = '*', -- Latest stable version
  build = 'cargo install rustowl',
  lazy = false, -- This plugin is already lazy
  opts = {},
}
```

## Configuration Options

All configuration options are optional and have sensible defaults:

### `auto_attach` (boolean)

- **Default**: `true`
- **Description**: Automatically attach the RustOwl LSP client when opening a Rust file.

### `auto_enable` (boolean)

- **Default**: `false`
- **Description**: Enable RustOwl highlighting immediately when the LSP client attaches. When `false`, you need to manually enable highlighting using `:Rustowl enable` or `require('rustowl').enable()`.

### `idle_time` (number)

- **Default**: `500`
- **Description**: Time in milliseconds to hover with the cursor before triggering RustOwl analysis and highlighting.

### `highlight_style` (table)

- **Description**: The style of underline for different highlight types. `'undercurl'` or `'underline'`.

### `colors` (table)

- **Description**: Custom colors for different highlight types. Each color should be a hex color string (e.g., `'#ff0000'`).

#### Available Color Options:

- `lifetime`: Color for variable lifetime highlights (default: `'#00cc00'` - green)
- `imm_borrow`: Color for immutable borrow highlights (default: `'#0000cc'` - blue)
- `mut_borrow`: Color for mutable borrow highlights (default: `'#cc00cc'` - purple)
- `move`: Color for value move highlights (default: `'#cccc00'` - yellow)
- `call`: Color for function call highlights (default: `'#cccc00'` - yellow)
- `outlive`: Color for lifetime error highlights (default: `'#cc0000'` - red)

### `client` (table)

- **Description**: LSP client configuration that gets passed to `vim.lsp.start`. This follows the same structure as Neovim's LSP client configuration.

## Customizing Highlight Colors

### Default Highlight Style

Default highlight style is straight underline except for maybe live and errors.

### Default Colors

The default color scheme uses the following colors that correspond to the visual legend:

- 🟩 **Green** (`#00cc00`): Variable's lifetime
- 🟦 **Blue** (`#0000cc`): Immutable borrowing
- 🟪 **Purple** (`#cc00cc`): Mutable borrowing
- 🟧 **Yellow** (`#cccc00`): Value moved / function call
- 🟥 **Red** (`#cc0000`): Lifetime errors

### Custom Colors

To customize colors, specify them in the `colors` table:

```lua
opts = {
  colors = {
    lifetime = '#32cd32',   -- Lime green
    imm_borrow = '#4169e1', -- Royal blue
    mut_borrow = '#ff69b4', -- Hot pink
    move = '#ffa500',       -- Orange
    call = '#ffd700',       -- Gold
    outlive = '#dc143c',    -- Crimson
  },
}
```

#### Color Format

Colors must be specified as hex color strings:

- ✅ Valid: `'#ff0000'`, `'#00ff00'`, `'#0000ff'`
- ❌ Invalid: `'red'`, `'rgb(255,0,0)'`, `'#f00'`

### Partial Color Customization

You can customize only specific colors while keeping the defaults for others:

```lua
opts = {
  colors = {
    lifetime = '#90ee90',   -- Light green for better visibility
    outlive = '#ff4500',    -- Orange red for errors
    -- Other colors will use defaults
  },
}
```

## Examples

### Example 1: Minimal Configuration

```lua
{
  'cordx56/rustowl',
  version = '*',
  build = 'cargo install rustowl',
  lazy = false,
  opts = {},
}
```

### Example 2: Auto-enable with Custom Colors

```lua
{
  'cordx56/rustowl',
  version = '*',
  build = 'cargo install rustowl',
  lazy = false,
  opts = {
    auto_enable = true,
    colors = {
      lifetime = '#90ee90',   -- Light green
      imm_borrow = '#87ceeb', -- Sky blue
      mut_borrow = '#dda0dd', -- Plum
      move = '#f0e68c',       -- Khaki
      call = '#ffd700',       -- Gold
      outlive = '#ff6347',    -- Tomato
    },
  },
}
```

### Example 3: Custom Key Binding and Styling

```lua
{
  'cordx56/rustowl',
  version = '*',
  build = 'cargo install rustowl',
  lazy = false,
  opts = {
    auto_enable = false,
    idle_time = 300,
    highlight_style = {
      definitely_live = 'underline',
      maybe_initialized = 'undercurl',
    },
    colors = {
      outlive = '#ff0000', -- Bright red for errors
    },
    client = {
      on_attach = function(_, buffer)
        vim.keymap.set('n', '<leader>ro', function()
          require('rustowl').toggle(buffer)
        end, { buffer = buffer, desc = 'Toggle RustOwl' })

        vim.keymap.set('n', '<leader>re', function()
          require('rustowl').enable(buffer)
        end, { buffer = buffer, desc = 'Enable RustOwl' })

        vim.keymap.set('n', '<leader>rd', function()
          require('rustowl').disable(buffer)
        end, { buffer = buffer, desc = 'Disable RustOwl' })
      end
    },
  },
}
```

### Example 4: Dark Theme Optimized Colors

```lua
{
  'cordx56/rustowl',
  version = '*',
  build = 'cargo install rustowl',
  lazy = false,
  opts = {
    colors = {
      lifetime = '#50fa7b',   -- Dracula green
      imm_borrow = '#8be9fd', -- Dracula cyan
      mut_borrow = '#ff79c6', -- Dracula pink
      move = '#f1fa8c',       -- Dracula yellow
      call = '#ffb86c',       -- Dracula orange
      outlive = '#ff5555',    -- Dracula red
    },
  },
}
```

### Example 5: For init.vim Users

If you're using `init.vim` instead of `init.lua`, you can configure RustOwl using Vim script:

```vim
lua << EOF
require('lazy').setup({
  {
    'cordx56/rustowl',
    version = '*',
    build = 'cargo install rustowl',
    lazy = false,
    opts = {
      colors = {
        lifetime = '#00ff00',
        imm_borrow = '#0080ff',
        mut_borrow = '#ff00ff',
        move = '#ffff00',
        call = '#ffa500',
        outlive = '#ff0000',
      },
    },
  },
})
EOF
```

## Usage Commands

When opening a Rust file, the following commands become available:

- `:Rustowl start_client` - Start the RustOwl LSP client
- `:Rustowl stop_client` - Stop the RustOwl LSP client
- `:Rustowl restart_client` - Restart the RustOwl LSP client
- `:Rustowl enable` - Enable RustOwl highlighting
- `:Rustowl disable` - Disable RustOwl highlighting
- `:Rustowl toggle` - Toggle RustOwl highlighting

You can also use the Lua API:

```lua
require('rustowl').enable()   -- Enable highlighting
require('rustowl').disable()  -- Disable highlighting
require('rustowl').toggle()   -- Toggle highlighting
require('rustowl').is_enabled() -- Check if enabled
```

---

### Usage (`docs/usage.md`)

# RustOwl usage

## Table of Contents



- [RustOwl usage](#rustowl-usage)
  - [Table of Contents](#table-of-contents)
  - [Quick Start](#quick-start)
  - [Getting started](#getting-started)
  - [Basic usage](#basic-usage)
  - [Advanced usage](#advanced-usage)
  

## Quick Start

1. Install RustOwl (docs/installation.md) and the editor extension for your editor.
2. Open a Rust Cargo workspace and save a Rust file to trigger analysis.
3. Place the cursor on a variable or function call and wait a short idle time to see visualizations.

Here, I describe how to use RustOwl in your workflow.

## Getting started

First, please install the RustOwl LSP server and extension for your editor.
Installation guide is on [installation](/docs/installation.md) file.

Then, please open a Rust source code file (`.rs`) in the editor.
RustOwl only works with a Cargo workspace, so you need to open the source code that is part of a Cargo workspace.
I recommend you try RustOwl with a small, simple workspace first.
RustOwl's analysis may take a long time for a large workspace.

VS Code extension will automatically start analyzing the workspace.
For other editors, you may need to enable RustOwl manually, but you can enable automatic loading in your configuration file.
The progress of analysis will be shown in your editor.


After the analysis started, RustOwl waits for your request.
Please place the text cursor on a variable or function call you would like to inspect.

RustOwl works for the analyzed portion, even if the entire analysis has not finished.
If your program has some fatal errors (e.g., syntax errors or unrecoverable type errors), RustOwl cannot work for the part where the analysis failed.

Wait for a few seconds, and then the ownership-related operations and lifetimes of the variable to which the `unwrap()` method call assigns a value will appear.


## Basic usage

Basically, RustOwl can be used to resolve ownership and lifetime errors.
What RustOwl visualizes is:

- Lifetime of variables, split into two precisions:
  - **Definitely live** range: the variable is provably initialized on every path that reaches the location.
  - **Maybe live** range: the variable is initialized on at least one path but may have been moved, dropped, or be uninitialized on others.
- Shared (immutable) borrowing of variables
- Mutable borrowing of variables
- Value movement
- Function call
- Ownership and lifetime errors

You can see which color is assigned to them on the top page of this repository.
RustOwl can be used to see where a variable lives, where it dies, and where it is borrowed or moved.

For VS Code, you can see the message that explains the meaning of the underline by hovering your mouse cursor over it.


This is the basic usage of RustOwl!
Now you have a master's degree in RustOwl.

## Advanced usage

The lifetime that RustOwl visualizes is the range of these variables:

- Where the variable _lives_
  - For the meaning of _NLL_
- Until the variable is _dropped_ or _moved_
  - For the meaning of _RAII_

Based on this, we can use RustOwl as listed below:

- To resolve _dead lock_ that is caused by some data structures like `Mutex`
  - Because these _locks_ are freed where the lock object is dropped
- To manage resources
  - Like memories, files, and anything which is managed by _RAII_ respective

### Definitely live vs. maybe live

The lifetime visualization is split by a CFG-based liveness analysis into two precisions, which is useful when ownership depends on control flow.

```rust
fn f(cond: bool) {
    let v: Vec<_> = (0..100).collect();
    if cond {
        drop(v); // v is dropped only on the `cond == true` branch
    }
    // After the `if`, v is "maybe live": still owned on the `false`
    // branch, but already dropped on the `true` branch.
}
```

- A **definitely live** range marks code where the variable is owned on every path. Dropping or freeing a resource here is safe.
- A **maybe live** range marks code where the variable is owned on some paths only. Reading from or moving the variable here would not compile, and it is a hint that resource cleanup is happening conditionally.

When auditing resource management (file handles, locks, allocations), the boundary between the two ranges is typically the location to inspect.

Did you get a Ph.D. in lifetimes?
So let's try managing resources with RustOwl.
You will get a Ph.D. in RustOwl and computer resource management.

---

### Vscode Configuration (`docs/vscode-configuration.md`)

# RustOwl Configuration (VS Code)

## Table Of Contents



- [RustOwl Configuration (VS Code)](#rustowl-configuration-vs-code)
  - [Table Of Contents](#table-of-contents)
  - [Quick Start](#quick-start)
  - [Configuration](#configuration)
  - [Settings (configuration keys)](#settings-configuration-keys)
  - [Commands](#commands)
  - [Behavior](#behavior)
  - [Examples](#examples)
  - [Troubleshooting](#troubleshooting)
  

This document describes configuration options for the RustOwl VS Code extension.

## Quick Start

Install the extension from the Marketplace or Open VSX. The extension will download and run the rustowl binary automatically when activated.


1. Install the extension in VS Code.
2. Open a Rust Cargo workspace.
3. Save a Rust file and hover over a variable after a short idle time to see decorations.

## Configuration

The VS Code extension exposes configurable settings and commands. Here are the concrete settings and behavior derived from code.

## Settings (configuration keys)

- `rustowl.underlineThickness` (string) — The stroke thickness of the underline line. Allowed values: "1", "2", "3", "4".
- `rustowl.lifetimeColor` (string) — The color of the lifetime (definitely live).
- `rustowl.maybeInitColor` (string) — The color of the lifetime (maybe initialized).
- `rustowl.moveCallColor` (string) — The color of the move/call.
- `rustowl.immutableBorrowColor` (string) — The color of the immutable borrow.
- `rustowl.mutableBorrowColor` (string) — The color of the mutable borrow.
- `rustowl.outliveColor` (string) — The color of the outlive.
- `rustowl.displayDelay` (number) — Delay in displaying underlines (ms).
- `rustowl.highlightBackground` (boolean) — Highlight text background instead of underline.
- `rustowl.defaultEnabled` (boolean) — Enabled by default.

## Commands

- `rustowl.hover` — manually request hover/decorations for current selection.
- `rustowl.toggle` — toggle decorations on/off (status bar changes accordingly).

## Behavior

- The extension bootstraps the `rustowl` binary using `bootstrap.ts` and starts an LSP client pointing at the executable.
- On save of Rust files the extension sends `rustowl/analyze` to the server (if enabled).
- On cursor selection changes, after `displayDelay` ms the extension sends `rustowl/cursor` and applies decorations returned by server.
- Decorations ignore overlapped ranges and map LSP response types to decorations (lifetime, imm_borrow, mut_borrow, move/call, outlive/shared_mut).

## Examples

Add settings to `.vscode/settings.json`:

```json
{
  "rustowl.displayDelay": 2000,
  "rustowl.defaultEnabled": true,
  "rustowl.lifetimeColor": "#00cc00",
  "rustowl.maybeInitColor": "#00cc00",
  "rustowl.immutableBorrowColor": "#0000cc",
  "rustowl.mutableBorrowColor": "#cc00cc",
  "rustowl.moveCallColor": "#cccc00",
  "rustowl.outliveColor": "#cc0000",
  "rustowl.highlightBackground": false,
  "rustowl.underlineThickness": 2
}
```

## Troubleshooting

- Check Output -> RustOwl for logs. If the server failed to start, the extension shows an error message.
- Ensure the `rustowl` executable is in PATH or let the extension download it (bootstrap).

---

--- METRICS ---
- Files Extracted: 14
- Estimated Token Budget: ~15000 tokens
- Canonical Reference: https://codewiki.google/github.com/cordx56/rustowl
