# rust-analyzer and cargo script
## Decision Making
Responsibility for and decision making for the language and cargo are owned by their respective teams.
The rust analyzer team is an important input into those decisions.
An initial decision has been made with the acceptance of RFC 3502 and 3503.
The main question for stabilization is if the implementation or user testing has uncovered anything.
The time for feedback into that decision was during one of the previous on-ramps (Pre-RFC posted, eRFC posted, eRFC proposed merge, RFCs posted, one RFC proposed merge, second RFC proposed merge).
In addition to those on-ramps, there have been direct communication and a Call for Testing.
The main question here is whether the r-a team provides enough justification for the other teams to re-evaluate their decisions.
## Design Inputs
Desired properties for a solution
- Cargo script should have a first-class experience, rather than feel tacked on ([RFC](https://rust-lang.github.io/rfcs/3502-cargo-script.html#rationale-and-alternatives))
- Friction for starting a new single-file package should be minimal ([RFC](https://rust-lang.github.io/rfcs/3502-cargo-script.html#rationale-and-alternatives))
- Cargo/rustc diagnostics and messages (including cargo metadata) should be in terms of single-file packages and not any temporary files ([RFC](https://rust-lang.github.io/rfcs/3502-cargo-script.html#rationale-and-alternatives))
Additions since the RFC
- The Rust Language, The Standard Library, and rustc should not have Cargo-exclusive functionality
- Specializing diagnostics for cargo is the extent of what is allowed
- We should follow conventions to meet user expectations / be predictable
- e.g. when writing [scripts](https://dbohdan.com/scripts-with-dependencies), users commonly expect to write them using either the same extension as the rest of the code from that project or no extension
## r-a's concerns
Desired properties for a solution
- r-a can scale to mono repos
- r-a can handle virtual file systems (network, rpc, etc) where high latencies rule which is especially a problem for sequential file operations (much better to prime a filesystem cache in bulk)
- Where possible, r-a wants to prime the index so users don't have to have a delay on each file they load
- r-a should have a seemless experience, e.g. not requiring manually mapping files to be processed by r-a
- Heuristics are frowned upon as they lead to race conditions (TODO: needs re-framing around the fundamental property)
- For a positive contributor experience, there should be low coupling in the code base. For instance, if the source is being parsed, it should be parsed in one way in one place to avoid the problem of touching parsing in one place requiring updates to parsing in another
r-a feels cargo scripts need a uniquely identifying file name (new file extension, no extension-less files)
- Extension-less files cannot be automatically used as Rust files by r-a. Editors either need to have heuristics or users need to explicitly map.
- TODO: how is this normally handled for Python or other languages?
- TODO: what do editor heuristics generally look like and what would it take to support cargo scripts?
- Pre-fetching project metadata for `.rs` cargo scripts would require enumerating all `.rs` files and reading them to check if they are cargo scripts
- Pre-fetch happens between `cargo metadata` and mod-walking so we've not determined which `.rs` files are yet owned by a `Cargo.toml` to skip reading the file
- Without pre-fetching, project metadata is lazy loaded which means users see a delay between them opening a file and getting a functioning LSP
- Checking the file content during lazy loading blocks on reading the file which can be slow either due to virtual/remote file systems or coalescing of edits
- The standard r-a way of parsing the file (all the way to AST/HIR) would either be redundant and slow or be too late to inject lazily loaded project metadata
- Extracting the shebang/frontmatter could be done in isolation instead but that breaks the centralization of all parsing logic within r-a which they prioritize to make the contributor experience better. This can be partially mitigated by having the extraction be a function next to the parsing logic.
## Resources
cargo script related design discussions:
- https://internals.rust-lang.org/t/pre-rfc-cargo-script-for-everyone/18639
- https://github.com/rust-lang/rfcs/pull/3424 (eRFC)
- https://github.com/rust-lang/rust-analyzer/issues/14318 (detatched file support where the eRFC was brought up)
- https://github.com/rust-lang/rust-analyzer/issues/15318 (cargo script support)
- https://github.com/rust-lang/rfcs/pull/3502 (cargo script)
- https://github.com/rust-lang/rfcs/pull/3503 (frontmatter)
- https://github.com/rust-lang/rust-analyzer/pull/15456 (initial PR)
- https://github.com/rust-lang/rust-analyzer/pull/17110 (merged PR)
- https://rust-lang.zulipchat.com/#narrow/channel/185405-t-compiler.2Frust-analyzer/topic/Frontmatter.20vs.20.60import_rules!.60.20for.20scripts/with/534243844
r-a related resources:
- https://hackmd.io/y2bGZMKfS8uPen8gy59KYA?both
## epage's concerns
epage's thoughts
- Using the regular source extension matches expectations from other languages
- Using the regular source extension avoids papercuts from waiting for every tool that cares about extensions to be modified, released, and updated
- Allowing no-extension maintains expectations from other languages
- Lack of no-extension can impact the perceived quality of tools (using `ls.rs` vs `ls`)
- If the extension is cargo related, like `.crs`, that opens the question of whether this is still Rust source code and whether frontmatters need to be inside of the language which can affect the "first class" nature of this feature