From b963c537802d89a07131f0d1a9c5d90bda15656a Mon Sep 17 00:00:00 2001 From: David Barsky Date: Mon, 14 Oct 2024 10:57:26 -0400 Subject: [PATCH] internal: port base-db to new Salsa --- Cargo.lock | 183 +++++++++++++++++++++++++++++------ Cargo.toml | 1 + crates/base-db/Cargo.toml | 2 + crates/base-db/src/lib.rs | 1 + crates/base-db/src/new_db.rs | 132 +++++++++++++++++++++++++ 5 files changed, 289 insertions(+), 30 deletions(-) create mode 100644 crates/base-db/src/new_db.rs diff --git a/Cargo.lock b/Cargo.lock index 4a6da47a47df..83061f3e451a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,18 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "always-assert" version = "0.2.0" @@ -32,12 +44,24 @@ version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +[[package]] +name = "append-only-vec" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7992085ec035cfe96992dd31bfd495a2ebd31969bb95f624471cb6c0b349e571" + [[package]] name = "arbitrary" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + [[package]] name = "arrayvec" version = "0.7.4" @@ -70,11 +94,13 @@ name = "base-db" version = "0.0.0" dependencies = [ "cfg", + "dashmap 5.5.3", "intern", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "lz4_flex", - "rustc-hash", - "salsa", + "rustc-hash 1.1.0", + "salsa 0.0.0", + "salsa 0.18.0", "semver", "span", "stdx", @@ -161,7 +187,7 @@ dependencies = [ "expect-test", "intern", "oorandom", - "rustc-hash", + "rustc-hash 1.1.0", "syntax", "syntax-bridge", "tt", @@ -216,7 +242,7 @@ dependencies = [ "chalk-derive", "chalk-ir", "chalk-solve", - "rustc-hash", + "rustc-hash 1.1.0", "tracing", ] @@ -232,7 +258,7 @@ dependencies = [ "indexmap", "itertools", "petgraph", - "rustc-hash", + "rustc-hash 1.1.0", "tracing", ] @@ -257,6 +283,19 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + [[package]] name = "crossbeam-channel" version = "0.5.13" @@ -285,6 +324,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.20" @@ -314,6 +362,20 @@ dependencies = [ "parking_lot_core", ] +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "deranged" version = "0.3.11" @@ -487,6 +549,18 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashlink" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" +dependencies = [ + "hashbrown", +] [[package]] name = "heck" @@ -494,6 +568,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -513,7 +593,7 @@ dependencies = [ "hir-ty", "intern", "itertools", - "rustc-hash", + "rustc-hash 1.1.0", "smallvec", "span", "stdx", @@ -532,7 +612,7 @@ dependencies = [ "bitflags 2.6.0", "cfg", "cov-mark", - "dashmap", + "dashmap 5.5.3", "drop_bomb", "either", "expect-test", @@ -547,7 +627,7 @@ dependencies = [ "mbe", "ra-ap-rustc_abi", "ra-ap-rustc_parse_format", - "rustc-hash", + "rustc-hash 1.1.0", "rustc_apfloat", "smallvec", "span", @@ -577,7 +657,7 @@ dependencies = [ "limit", "mbe", "parser", - "rustc-hash", + "rustc-hash 1.1.0", "smallvec", "span", "stdx", @@ -616,7 +696,7 @@ dependencies = [ "ra-ap-rustc_abi", "ra-ap-rustc_index", "ra-ap-rustc_pattern_analysis", - "rustc-hash", + "rustc-hash 1.1.0", "rustc_apfloat", "scoped-tls", "smallvec", @@ -737,7 +817,7 @@ dependencies = [ "parser", "profile", "rayon", - "rustc-hash", + "rustc-hash 1.1.0", "span", "stdx", "syntax", @@ -832,9 +912,9 @@ dependencies = [ name = "intern" version = "0.0.0" dependencies = [ - "dashmap", + "dashmap 5.5.3", "hashbrown", - "rustc-hash", + "rustc-hash 1.1.0", "sptr", "triomphe", ] @@ -1051,7 +1131,7 @@ dependencies = [ "intern", "parser", "ra-ap-rustc_lexer", - "rustc-hash", + "rustc-hash 1.1.0", "smallvec", "span", "stdx", @@ -1345,7 +1425,7 @@ dependencies = [ "indexmap", "intern", "paths", - "rustc-hash", + "rustc-hash 1.1.0", "serde", "serde_json", "span", @@ -1435,7 +1515,7 @@ dependencies = [ "itertools", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "paths", - "rustc-hash", + "rustc-hash 1.1.0", "semver", "serde", "serde_json", @@ -1555,7 +1635,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "273d5f72926a58c7eea27aebc898d1d5b32d23d2342f692a94a2cf8746aa4a2f" dependencies = [ "ra-ap-rustc_index", - "rustc-hash", + "rustc-hash 1.1.0", "rustc_apfloat", "smallvec", "tracing", @@ -1640,7 +1720,7 @@ dependencies = [ "countme", "hashbrown", "memoffset", - "rustc-hash", + "rustc-hash 1.1.0", "text-size", ] @@ -1680,7 +1760,7 @@ dependencies = [ "profile", "project-model", "rayon", - "rustc-hash", + "rustc-hash 1.1.0", "scip", "semver", "serde", @@ -1717,6 +1797,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hash" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" + [[package]] name = "rustc_apfloat" version = "0.2.1+llvm-462a31f5a5ab" @@ -1746,21 +1832,58 @@ dependencies = [ "oorandom", "parking_lot", "rand", - "rustc-hash", - "salsa-macros", + "rustc-hash 1.1.0", + "salsa-macros 0.0.0", "smallvec", "tracing", "triomphe", ] +[[package]] +name = "salsa" +version = "0.18.0" +source = "git+https://github.com/salsa-rs/salsa.git?rev=c3de24ce12b28ad5f125cf1e30e5d2c26124d812#c3de24ce12b28ad5f125cf1e30e5d2c26124d812" +dependencies = [ + "append-only-vec", + "arc-swap", + "crossbeam", + "dashmap 6.1.0", + "hashlink", + "indexmap", + "lazy_static", + "parking_lot", + "rustc-hash 2.0.0", + "salsa-macro-rules", + "salsa-macros 0.18.0", + "smallvec", + "tracing", +] + +[[package]] +name = "salsa-macro-rules" +version = "0.1.0" +source = "git+https://github.com/salsa-rs/salsa.git?rev=c3de24ce12b28ad5f125cf1e30e5d2c26124d812#c3de24ce12b28ad5f125cf1e30e5d2c26124d812" + [[package]] name = "salsa-macros" version = "0.0.0" dependencies = [ - "heck", + "heck 0.4.1", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "salsa-macros" +version = "0.18.0" +source = "git+https://github.com/salsa-rs/salsa.git?rev=c3de24ce12b28ad5f125cf1e30e5d2c26124d812#c3de24ce12b28ad5f125cf1e30e5d2c26124d812" +dependencies = [ + "heck 0.5.0", "proc-macro2", "quote", "syn", + "synstructure", ] [[package]] @@ -1898,8 +2021,8 @@ version = "0.0.0" dependencies = [ "hashbrown", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hash", - "salsa", + "rustc-hash 1.1.0", + "salsa 0.0.0", "stdx", "syntax", "text-size", @@ -1967,7 +2090,7 @@ dependencies = [ "ra-ap-rustc_lexer", "rayon", "rowan", - "rustc-hash", + "rustc-hash 1.1.0", "rustc_apfloat", "smol_str", "stdx", @@ -1983,7 +2106,7 @@ version = "0.0.0" dependencies = [ "intern", "parser", - "rustc-hash", + "rustc-hash 1.1.0", "span", "stdx", "syntax", @@ -2000,7 +2123,7 @@ dependencies = [ "cfg", "hir-expand", "intern", - "rustc-hash", + "rustc-hash 1.1.0", "span", "stdx", "test-utils", @@ -2014,7 +2137,7 @@ dependencies = [ "dissimilar", "paths", "profile", - "rustc-hash", + "rustc-hash 1.1.0", "stdx", "text-size", "tracing", @@ -2361,7 +2484,7 @@ dependencies = [ "indexmap", "nohash-hasher", "paths", - "rustc-hash", + "rustc-hash 1.1.0", "stdx", "tracing", ] @@ -2374,7 +2497,7 @@ dependencies = [ "notify", "paths", "rayon", - "rustc-hash", + "rustc-hash 1.1.0", "stdx", "tracing", "vfs", diff --git a/Cargo.toml b/Cargo.toml index 8c099f324b46..45f4bf464d2b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -137,6 +137,7 @@ pulldown-cmark-to-cmark = "10.0.4" pulldown-cmark = { version = "0.9.0", default-features = false } rayon = "1.8.0" rustc-hash = "1.1.0" +salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "c3de24ce12b28ad5f125cf1e30e5d2c26124d812" } semver = "1.0.14" serde = { version = "1.0.192", features = ["derive"] } serde_json = "1.0.108" diff --git a/crates/base-db/Cargo.toml b/crates/base-db/Cargo.toml index 788ceb8857e9..f23ec96663af 100644 --- a/crates/base-db/Cargo.toml +++ b/crates/base-db/Cargo.toml @@ -17,6 +17,8 @@ lz4_flex = { version = "0.11", default-features = false } la-arena.workspace = true ra-salsa.workspace = true +salsa.workspace = true +dashmap.workspace = true rustc-hash.workspace = true triomphe.workspace = true semver.workspace = true diff --git a/crates/base-db/src/lib.rs b/crates/base-db/src/lib.rs index 0a9e83bc3bad..0e54c5e1c588 100644 --- a/crates/base-db/src/lib.rs +++ b/crates/base-db/src/lib.rs @@ -2,6 +2,7 @@ // FIXME: Rename this crate, base db is non descriptive mod change; mod input; +pub mod new_db; use std::panic; diff --git a/crates/base-db/src/new_db.rs b/crates/base-db/src/new_db.rs new file mode 100644 index 000000000000..a6f9c8b19a9b --- /dev/null +++ b/crates/base-db/src/new_db.rs @@ -0,0 +1,132 @@ +//! //! `base_db`` defines basic database traits. +//! +//! This module has a similar purpose as [`crate::SourceDatabase`], in that +//! it bridges to non-Salsa managed data. This module should not be used until +//! all of rust-analyzer has moved to the new Salsa. + +use std::hash::BuildHasherDefault; + +use dashmap::DashMap; +use rustc_hash::FxHasher; +use salsa::{Accumulator, Durability, Event}; +use span::Edition; +use syntax::{ast, Parse, SyntaxError}; +use triomphe::Arc; + +use crate::{CrateId, ReleaseChannel}; + +#[salsa::tracked] +pub struct ParsedFile<'db> { + pub file: Parse, +} + +#[salsa::input] +pub struct SourceFile { + #[return_ref] + text: String, +} + +/// Returns the set of errors obtained from parsing the file. +#[salsa::accumulator] +pub struct ParseError { + pub error: SyntaxError, +} + +#[salsa::input] +pub struct CrateGraph { + pub crate_graph: Arc, +} + +#[salsa::input] +pub struct CrateWorkspaceData { + #[return_ref] + data: Arc>>, +} + +/// Database which stores all significant input facts: source code and project +/// model. Everything else in rust-analyzer is derived from these queries. +#[salsa::db] +pub trait Db: salsa::Database { + /// Text of the file. + fn file_text(&self, file_id: vfs::FileId) -> SourceFile; + + fn parse_errors(&self, file: SourceFile) -> Option>; + + /// The crate graph. + fn crate_graph(&self) -> CrateGraph; + + fn crate_workspace_data(&self) -> CrateWorkspaceData; + + fn toolchain_channel(&self, krate: CrateId) -> Option; +} + +#[salsa::tracked] +pub fn parse<'db>(db: &'db dyn Db, file: SourceFile) -> ParsedFile<'db> { + let _p = tracing::info_span!("parse", ?file).entered(); + let edition = Edition::CURRENT; // TODO: use the actual edition. + let text = file.text(db); + + let parsed = ast::SourceFile::parse(text, edition); + for error in parsed.errors() { + ParseError { error }.accumulate(db); + } + + ParsedFile::new(db, parsed) +} + +#[salsa::db] +pub struct SourceDatabase { + storage: salsa::Storage, + files: DashMap>, + crate_graph: CrateGraph, + workspace_data: CrateWorkspaceData, +} + +impl SourceDatabase { + pub fn set_file_text(&self, file_id: vfs::FileId, text: &str, durability: Durability) { + let file = SourceFile::builder(text.to_owned()).durability(durability).new(self); + self.files.insert(file_id, file); + } +} + +#[salsa::db] +impl salsa::Database for SourceDatabase { + fn salsa_event(&self, _event: &dyn Fn() -> Event) {} +} + +#[salsa::db] +impl Db for SourceDatabase { + fn file_text(&self, file_id: vfs::FileId) -> SourceFile { + *self.files.get(&file_id).expect("Unable to get non-existent file") + } + + fn parse_errors(&self, file: SourceFile) -> Option> { + let _parsed = parse(self, file); + let errors = parse::accumulated::(self, file); + + if errors.is_empty() { + None + } else { + Some(errors) + } + } + + fn crate_graph(&self) -> CrateGraph { + self.crate_graph + } + + fn crate_workspace_data(&self) -> CrateWorkspaceData { + self.workspace_data + } + + fn toolchain_channel(&self, krate: CrateId) -> Option { + let db = self; + + db.crate_workspace_data() + .data(db) + .get(&krate)? + .toolchain + .as_ref() + .and_then(|v| ReleaseChannel::from_str(&v.pre)) + } +}