RepoPilotOpen in app →

rust-lang/rls

Repository for the Rust Language Server (aka RLS)

Mixed

Stale — last commit 4y ago

weakest axis
Use as dependencyConcerns

non-standard license (Other); last commit was 4y ago

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • 28+ active contributors
  • Distributed ownership (top contributor 40% of recent commits)
  • Other licensed
Show all 7 evidence items →
  • CI configured
  • Tests present
  • Stale — last commit 4y ago
  • Non-standard license (Other) — review terms
What would change the summary?
  • Use as dependency ConcernsMixed if: clarify license terms

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/rust-lang/rls?axis=fork)](https://repopilot.app/r/rust-lang/rls)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/rust-lang/rls on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: rust-lang/rls

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/rust-lang/rls shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Stale — last commit 4y ago

  • 28+ active contributors
  • Distributed ownership (top contributor 40% of recent commits)
  • Other licensed
  • CI configured
  • Tests present
  • ⚠ Stale — last commit 4y ago
  • ⚠ Non-standard license (Other) — review terms

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live rust-lang/rls repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/rust-lang/rls.

What it runs against: a local clone of rust-lang/rls — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in rust-lang/rls | Confirms the artifact applies here, not a fork | | 2 | License is still Other | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | Last commit ≤ 1377 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>rust-lang/rls</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of rust-lang/rls. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/rust-lang/rls.git
#   cd rls
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of rust-lang/rls and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "rust-lang/rls(\\.git)?\\b" \\
  && ok "origin remote is rust-lang/rls" \\
  || miss "origin remote is not rust-lang/rls (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Other)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Other\"" package.json 2>/dev/null) \\
  && ok "license is Other" \\
  || miss "license drift — was Other at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 1377 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~1347d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/rust-lang/rls"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

The Rust Language Server (RLS) is a background daemon that provides IDEs and editors with semantic information about Rust code, enabling features like goto-definition, symbol search, code completion, and refactoring. It works by combining precise data from the Rust compiler with fallback symbol resolution from Racer (bundled in racer/ subdirectory) to handle cases where incremental compilation is too slow. Workspace of 4 Cargo crates: rls/ is the main LSP server implementation (rls/src/main.rs entry, rls/src/lib.rs core logic), racer/ is the bundled symbol-completion fallback engine (racer/src/racer/*.rs contains AST parsing and core matching), rls-analysis/ and rls-rustc/ are local path dependencies providing compiler integration and data structures. Configuration driven by Cargo.toml with carefully versioned compiler toolchain via racer/rust-toolchain.toml.

👥Who it's for

Rust developers using editors and IDEs (VSCode, vim, Emacs, etc.) who want IDE-like features without recompiling their entire project on every keystroke. Extension authors building RLS frontends for specific editors. Note: RLS is now deprecated in favor of rust-analyzer.

🌱Maturity & risk

RLS reached 1.41.0 and was production-ready, but is now deprecated as of the README warning — replaced by rust-analyzer. The codebase shows mature patterns (CI via .github/workflows/ci.yml, extensive dependencies, organized layout) but development has halted. This is a legacy project maintained for compatibility only, not for new feature work.

Critical risk: RLS is officially deprecated and unsupported. Technical risks include heavy reliance on nightly Rust internals (dependencies on cargo, rustc_tools_util, clippy_lints via git refs with pinned revisions), brittle pinned compiler commits (e.g., cargo rev 5514f1e0), and the project's architecture was built around incremental compilation that never fully materialized in rustc. New code should use rust-analyzer instead.

Active areas of work

No active development. The README explicitly states RLS is deprecated. Users are directed to uninstall RLS and migrate to rust-analyzer. The CI workflow (.github/workflows/ci.yml) likely runs on pushes to maintain compatibility with the stable Rust release, but no new features are being added.

🚀Get running

git clone https://github.com/rust-lang/rls.git
cd rls
rustup update
rustup component add rls rust-analysis rust-src
cargo build --release

Note: Ensure you have a working Rust toolchain; racer/rust-toolchain.toml pins a specific nightly. For development, follow debugging.md.

Daily commands: For end-users: install via rustup (already covered in README). For development: cargo build compiles the server, cargo test runs tests. The binary ./target/debug/rls or ./target/release/rls is spawned by editor extensions via LSP protocol (stdio or TCP), not run directly. See debugging.md for editor-specific setup.

🗺️Map of the codebase

  • README.md: Explicitly warns RLS is deprecated and directs users to rust-analyzer; essential context for any contributor
  • rls/src/main.rs: Entry point and main LSP server event loop; where requests are dispatched
  • rls/src/lib.rs: Core library containing server state, LSP handler implementations, and feature logic (goto def, completion, etc.)
  • racer/src/racer/core.rs: Symbol resolution engine; invoked when compiler data is insufficient
  • racer/src/racer/matchers.rs: Pattern matching and code searching for symbol completion; critical for code completion performance
  • Cargo.toml: Workspace definition and all dependency versions; pinned cargo/rustfmt revisions are critical for compatibility
  • racer/rust-toolchain.toml: Pins nightly Rust version for racer; mismatch here breaks entire project
  • architecture.md: High-level design overview explaining how compiler data and Racer are merged
  • .github/workflows/ci.yml: CI/CD pipeline showing test coverage, build matrix, and validation strategy

🛠️How to make changes

For LSP protocol changes: edit rls/src/lib.rs (main server loop and handler functions). For symbol resolution: modify racer/src/racer/core.rs (symbol lookup) or racer/src/racer/matchers.rs (pattern matching). For compiler integration: check rls-analysis/ and rls-rustc/ (local path deps). For diagnostics and completion: rls/src/lib.rs contains feature handlers. Add tests via rls/tests/ (if present) or inline #[test] modules. Keep racer/fixtures/ updated with test crates.

🪤Traps & gotchas

  1. Nightly compiler fragility: racer/rust-toolchain.toml pins a specific nightly; if your system has a newer/older nightly, builds fail silently. Run rustup update and check racer/rust-toolchain.toml carefully. 2. Git-pinned dependencies: cargo and rustfmt are fetched from git with specific revisions (Cargo.toml lines 19, 34). These can break if those branches are rebased or deleted; regenerating Cargo.lock may fail. 3. Compiler internals dependency: rls-rustc and rls-analysis depend on unstable compiler APIs; even a minor rustc update can break symbol resolution. 4. FIXME comments: Cargo.toml lines 17 and 21 note 'FIXME: Release to crates.io' — these crates are vendored as path dependencies and have never been published. 5. No incremental compilation in target: RLS was designed for incremental rustc compilation that never shipped; today all rebuilds are full. 6. Racer is unmaintained: The bundled racer/ is a secondary static copy; upstream racer-rust/racer may have diverged.

💡Concepts to learn

  • Language Server Protocol (LSP) — RLS implements LSP as its communication protocol with editors; understanding LSP is essential to modify request/response handling (rls/src/lib.rs) and add new features
  • Incremental Compilation — RLS's core design assumes the Rust compiler would support incremental builds; that never fully shipped, so RLS falls back to Racer. Understanding this limitation explains architectural decisions.
  • AST-based Symbol Resolution (Racer approach) — racer/src/racer/ast.rs and matchers.rs implement syntactic pattern matching instead of semantic analysis; this is why Racer is faster but less precise than compiler analysis
  • Compiler Internals (rustc_tools_util, rls-analysis) — RLS queries the Rust compiler via unstable internal APIs; these break frequently on nightly updates, requiring careful pinning in Cargo.toml
  • Rayon Parallelism — RLS uses rayon (dependency in Cargo.toml) for parallel compilation and analysis; understanding work-stealing thread pools is important for performance tuning
  • VFS (Virtual File System) — rls-vfs dependency abstracts file I/O; RLS doesn't directly read disk but through a VFS layer managed by the editor, enabling unsaved buffer analysis
  • Span-based Error Reporting (rls-span) — rls-span (dependency) handles source code location metadata; essential for mapping compiler diagnostics back to editor positions and ranges
  • rust-analyzer/rust-analyzer — The official successor to RLS; uses a different architecture (incremental query-based) and is actively maintained
  • racer-rust/racer — Upstream symbol completion engine that RLS uses as fallback; RLS bundles a vendored copy in racer/
  • rust-lang/rls-vscode — Official VSCode extension for RLS; demonstrates how to implement an LSP frontend communicating with this server
  • rust-lang/rust-clippy — Provides clippy_lints (optional dependency in Cargo.toml) for linting; shares compiler internals with RLS
  • rust-lang/rustfmt — Formatting engine integrated into RLS; git-pinned dependency for the formatting feature

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add deprecation migration guide for users transitioning from RLS to rust-analyzer

The README clearly states RLS is deprecated and replaced by rust-analyzer, but there's no dedicated migration guide document. Users and IDE maintainers need a concrete guide showing: how to uninstall RLS, how to install rust-analyzer for their specific editors, common configuration mappings between RLS and rust-analyzer settings, and troubleshooting for common migration issues. This would reduce support burden and improve user experience during transition.

  • [ ] Create new file MIGRATION_GUIDE.md at repo root
  • [ ] Document step-by-step uninstallation instructions for major editors (VSCode, Vim, Emacs, etc.)
  • [ ] Create RLS config → rust-analyzer config mapping table for common settings
  • [ ] Add links to rust-analyzer documentation for each editor integration
  • [ ] Link MIGRATION_GUIDE.md prominently from README.md
  • [ ] Test that all external links in guide are valid

Upgrade GitHub Actions CI workflow to catch deprecation status in automated checks

The .github/workflows/ci.yml exists but likely doesn't have a check to prevent accidental feature additions or breaking changes to deprecated code. Add a workflow job that: runs on PRs, checks for modifications to core RLS logic files (not tests/docs), and requires explicit approval with a label like 'maintenance-allowed' for non-documentation changes. This prevents the codebase from accumulating new features that could confuse users about the deprecation status.

  • [ ] Review current .github/workflows/ci.yml to understand existing checks
  • [ ] Add new workflow job that uses 'git diff' to detect changes in racer/src/racer/*.rs and rls-analysis/src/ excluding test files
  • [ ] Implement logic to fail the check unless commit message contains explicit deprecation acknowledgment OR 'maintenance-allowed' label is present
  • [ ] Document the maintenance policy in contributing.md explaining the label requirement
  • [ ] Test workflow with a sample PR that modifies core files

Create integration test suite for racer language completion against Rust stdlib

The racer/ subdirectory has fixtures in racer/fixtures/arst but lacks comprehensive integration tests validating that code completion works correctly against real Rust stdlib types. Add tests that: verify completion suggestions for common stdlib types (Vec, String, Option, etc.), test trait method completion, validate completion in different scoping contexts. This helps ensure racer continues to function correctly and provides a regression test suite for any maintenance work.

  • [ ] Create new file racer/tests/completion_stdlib.rs (or similar) for integration tests
  • [ ] Write test cases covering Vec<T> method completion, String methods, Option<T> enum variants, and Iterator trait methods
  • [ ] Add test fixtures in racer/fixtures/ with example Rust code using stdlib types
  • [ ] Ensure tests can run with 'cargo test --test completion_stdlib' from racer/ directory
  • [ ] Document test patterns in racer/README.md so future maintainers understand the test structure

🌿Good first issues

  • Add integration test for LSP hover request: rls/src/lib.rs contains hover_impl() but racer/fixtures/ test cases are minimal. Add a fixture crate with trait definitions, then write a test asserting hover returns correct type info.
  • Document the Racer symbol resolution path in architecture.md: architecture.md exists but is sparse; add a section explaining when RLS falls back to racer/src/racer/core.rs (beyond compiler analysis) and walk through a concrete example (e.g., cross-crate completion).
  • Lint and warn on deprecated RLS usage in frontends: README warns users to switch to rust-analyzer, but there's no automated detection. Add a startup log message or capability flag (lsp-types) indicating RLS is deprecated, so newer editors can refuse to start it.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 04afefa — Merge pull request #1784 from ehuss/deprecate-readme (Xanewok)
  • 1b853dc — Add notice that RLS is no longer supported (ehuss)
  • 4d8b0a1 — Merge pull request #1782 from ehuss/update-cargo (Mark-Simulacrum)
  • 3b16064 — Update cargo (ehuss)
  • fcf1f94 — Adapt to the rust-lang/rust changes (Xanewok)
  • ac4648b — Adapt to rust-lang/rust#0ed9c64c3e (Xanewok)
  • ece09b8 — Merge commit '27f4044df03d15c7c38a483c3e4635cf4f51807d' (Mark-Simulacrum)
  • a00923a — Fix a broken test introduced with the deprecation warning (Xanewok)
  • 6ae8421 — Merge pull request #1600 from bennetthardwick/fix/load-lines (Xanewok)
  • df11a04 — Merge pull request #1776 from Veykril/deprecation (Xanewok)

🔒Security observations

The RLS codebase presents significant security concerns primarily due to its deprecated and unsupported status. The project is explicitly flagged as no

  • Critical · Deprecated and Unsupported Project — README.md. The RLS project is explicitly marked as deprecated and no longer supported as indicated in the README. The project has been replaced with rust-analyzer. Using deprecated software in production exposes the system to unpatched security vulnerabilities and lack of security updates. Fix: Migrate to rust-analyzer (https://rust-analyzer.github.io/) which is the actively maintained successor. Do not use RLS in new projects or continue relying on it for production systems.
  • High · Pinned Git Dependency with Specific Revision — Cargo.toml - dependencies section (cargo, cargo-util, rustfmt-nightly). The project uses hardcoded git revisions for critical dependencies: cargo and rustfmt-nightly (rev: '5514f1e0e1b3650ed8a78306198e90b66b292693' and '5fa2727ddeef534a7cd437f9e288c221a2cf0b6a'). If these commits contain security vulnerabilities, there is no automatic mechanism to pull security updates. The approach is brittle and prevents security patch application. Fix: Use version ranges with '~' or '^' for dependencies to allow patch updates. Implement a security update process that regularly reviews and updates pinned revisions. Consider using tools like 'cargo-audit' to check for known vulnerabilities in dependencies.
  • High · Incomplete Dependency Information — Cargo.toml - end of dependencies section. The Cargo.toml appears incomplete - the last dependency 'rustc-workspace-ha' is cut off without version specification. This suggests the file content was truncated or corrupted, creating uncertainty about actual dependency versions and making security audit difficult. Fix: Ensure the complete and valid Cargo.toml file is used. Verify all dependencies have proper version specifications. Implement version control and validation for critical configuration files.
  • Medium · Multiple Unvetted Local Path Dependencies — Cargo.toml - dependencies: rls-analysis, rls-rustc, rls-ipc. The project includes several local path dependencies without published versions (rls-analysis, rls-rustc, rls-ipc) that are marked with 'FIXME' comments indicating they haven't been released to crates.io. Using unpublished, path-based dependencies makes it difficult to version control, track security updates, and establish clear dependency boundaries. Fix: Publish these crates to crates.io with proper semantic versioning. Remove the path overrides once published. Implement security review process before publishing. Add version constraints to prevent accidental breaking changes.
  • Medium · Build Script Present — build.rs. The project includes a build.rs file which runs arbitrary code during compilation. This could be a vector for supply chain attacks or unintended side effects if the build script is compromised or contains unsafe operations. Fix: Review build.rs for any security-sensitive operations, file I/O, or network access. Minimize the scope of build script functionality. Document all build-time side effects. Consider whether the functionality could be moved to runtime instead.
  • Low · Missing Security Policy — Repository root. No SECURITY.md or security policy file is visible in the repository structure, and the project is deprecated. This makes it unclear how security vulnerabilities should be reported and handled. Fix: Although the project is deprecated, add a SECURITY.md file directing users to report issues to the rust-analyzer team and explaining the deprecation status clearly. For deprecated projects, establish a vulnerability disclosure policy.
  • Low · Potential Unsafe Code in Multiple Crates — racer/src/racer/*, rls-analysis/src/*. The project contains multiple crates (racer, rls-analysis) with complex functionality. While not visible from file names alone, Rust projects dealing with code parsing and analysis often contain unsafe blocks. Without full code review, potential unsafe behavior cannot be ruled out. Fix: Conduct a thorough code review focusing on all unsafe blocks. Use tools like 'cargo-safety' and 'cargo-deny' to identify and audit unsafe code. Document justification for each unsafe block. Minimize unsafe code usage where possible.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · rust-lang/rls — RepoPilot