diff options
| author | bors <bors@rust-lang.org> | 2025-04-30 20:42:22 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-04-30 20:42:22 +0000 |
| commit | b45dd71d1824f176fba88f6c40467030a16afa2c (patch) | |
| tree | e411711ed4353d3828f34aebca7bdeda8f357d28 /src/tools/rust-analyzer/crates/query-group-macro/tests | |
| parent | 251cda5e1f0057eb04fd9fc1653f2f1e010e8f97 (diff) | |
| parent | a477172cedb83e1b8295bb20f4bff6e79f9e7bb1 (diff) | |
| download | rust-b45dd71d1824f176fba88f6c40467030a16afa2c.tar.gz rust-b45dd71d1824f176fba88f6c40467030a16afa2c.zip | |
Auto merge of #140529 - matthiaskrgr:rollup-jpaa2ky, r=matthiaskrgr
Rollup of 10 pull requests Successful merges: - #140385 (Subtree update of `rust-analyzer`) - #140458 (Fix for async drop ice with partly dropped tuple) - #140465 (chore: edit and move tests) - #140467 (Don't FCW assoc consts in patterns) - #140468 (Minor tweaks to make some normalization (adjacent) code less confusing) - #140470 (CI: rfl: move job forward to Linux v6.15-rc4) - #140476 (chore: delete unused ui/auxiliary crates) - #140481 (Require sanitizers be enabled for asan_odr_windows.rs) - #140486 (rustfmt: Also allow bool literals as first item of let chain) - #140494 (Parser: Document restrictions) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'src/tools/rust-analyzer/crates/query-group-macro/tests')
10 files changed, 584 insertions, 0 deletions
diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/arity.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/arity.rs new file mode 100644 index 00000000000..f1b29612a17 --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/arity.rs @@ -0,0 +1,32 @@ +use query_group_macro::query_group; + +#[query_group] +pub trait ArityDb: salsa::Database { + #[salsa::invoke_interned(one)] + fn one(&self, a: ()) -> String; + + #[salsa::invoke_interned(two)] + fn two(&self, a: (), b: ()) -> String; + + #[salsa::invoke_interned(three)] + fn three(&self, a: (), b: (), c: ()) -> String; + + #[salsa::invoke_interned(none)] + fn none(&self) -> String; +} + +fn one(_db: &dyn ArityDb, _a: ()) -> String { + String::new() +} + +fn two(_db: &dyn ArityDb, _a: (), _b: ()) -> String { + String::new() +} + +fn three(_db: &dyn ArityDb, _a: (), _b: (), _c: ()) -> String { + String::new() +} + +fn none(_db: &dyn ArityDb) -> String { + String::new() +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/hello_world.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/hello_world.rs new file mode 100644 index 00000000000..b0aec8dc53b --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/hello_world.rs @@ -0,0 +1,129 @@ +use expect_test::expect; +use query_group_macro::query_group; + +mod logger_db; +use logger_db::LoggerDb; + +#[query_group] +pub trait HelloWorldDatabase: salsa::Database { + // input + // // input with no params + #[salsa::input] + fn input_string(&self) -> String; + + // unadorned query + #[salsa::invoke_interned(length_query)] + fn length_query(&self, key: ()) -> usize; + + // unadorned query + fn length_query_with_no_params(&self) -> usize; + + // renamed/invoke query + #[salsa::invoke_interned(invoke_length_query_actual)] + fn invoke_length_query(&self, key: ()) -> usize; + + // not a query. should not invoked + #[salsa::transparent] + fn transparent_length(&self, key: ()) -> usize; + + #[salsa::transparent] + #[salsa::invoke_interned(transparent_and_invoke_length_actual)] + fn transparent_and_invoke_length(&self, key: ()) -> usize; +} + +fn length_query(db: &dyn HelloWorldDatabase, _key: ()) -> usize { + db.input_string().len() +} + +fn length_query_with_no_params(db: &dyn HelloWorldDatabase) -> usize { + db.input_string().len() +} + +fn invoke_length_query_actual(db: &dyn HelloWorldDatabase, _key: ()) -> usize { + db.input_string().len() +} + +fn transparent_length(db: &dyn HelloWorldDatabase, _key: ()) -> usize { + db.input_string().len() +} + +fn transparent_and_invoke_length_actual(db: &dyn HelloWorldDatabase, _key: ()) -> usize { + db.input_string().len() +} + +#[test] +fn unadorned_query() { + let mut db = LoggerDb::default(); + + db.set_input_string(String::from("Hello, world!")); + let len = db.length_query(()); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_HelloWorldDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(DidValidateMemoizedValue { database_key: create_data_HelloWorldDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: length_query_shim(Id(800)) })", + "salsa_event(WillCheckCancellation)", + ]"#]]); +} + +#[test] +fn invoke_query() { + let mut db = LoggerDb::default(); + + db.set_input_string(String::from("Hello, world!")); + let len = db.invoke_length_query(()); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_HelloWorldDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(DidValidateMemoizedValue { database_key: create_data_HelloWorldDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: invoke_length_query_shim(Id(800)) })", + "salsa_event(WillCheckCancellation)", + ]"#]]); +} + +#[test] +fn transparent() { + let mut db = LoggerDb::default(); + + db.set_input_string(String::from("Hello, world!")); + let len = db.transparent_length(()); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_HelloWorldDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(DidValidateMemoizedValue { database_key: create_data_HelloWorldDatabase(Id(0)) })", + ]"#]]); +} + +#[test] +fn transparent_invoke() { + let mut db = LoggerDb::default(); + + db.set_input_string(String::from("Hello, world!")); + let len = db.transparent_and_invoke_length(()); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_HelloWorldDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(DidValidateMemoizedValue { database_key: create_data_HelloWorldDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: transparent_and_invoke_length_shim(Id(800)) })", + "salsa_event(WillCheckCancellation)", + ]"#]]); +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/interned.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/interned.rs new file mode 100644 index 00000000000..26ed316122a --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/interned.rs @@ -0,0 +1,50 @@ +use query_group_macro::query_group; + +use expect_test::expect; +use salsa::plumbing::AsId; + +mod logger_db; +use logger_db::LoggerDb; + +#[salsa::interned(no_lifetime)] +pub struct InternedString { + data: String, +} + +#[query_group] +pub trait InternedDB: salsa::Database { + #[salsa::interned] + fn intern_string(&self, data: String) -> InternedString; + + fn interned_len(&self, id: InternedString) -> usize; +} + +fn interned_len(db: &dyn InternedDB, id: InternedString) -> usize { + db.lookup_intern_string(id).len() +} + +#[test] +fn intern_round_trip() { + let db = LoggerDb::default(); + + let id = db.intern_string(String::from("Hello, world!")); + let s = db.lookup_intern_string(id); + + assert_eq!(s.len(), 13); + db.assert_logs(expect![[r#"[]"#]]); +} + +#[test] +fn intern_with_query() { + let db = LoggerDb::default(); + + let id = db.intern_string(String::from("Hello, world!")); + let len = db.interned_len(id); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: interned_len_shim(Id(0)) })", + ]"#]]); +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs new file mode 100644 index 00000000000..5cf9be36f70 --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/logger_db.rs @@ -0,0 +1,60 @@ +use std::sync::{Arc, Mutex}; + +#[salsa::db] +#[derive(Default, Clone)] +pub(crate) struct LoggerDb { + storage: salsa::Storage<Self>, + logger: Logger, +} + +#[derive(Default, Clone)] +struct Logger { + logs: Arc<Mutex<Vec<String>>>, +} + +#[salsa::db] +impl salsa::Database for LoggerDb { + fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) { + let event = event(); + match event.kind { + salsa::EventKind::WillExecute { .. } + | salsa::EventKind::WillCheckCancellation + | salsa::EventKind::DidValidateMemoizedValue { .. } + | salsa::EventKind::WillDiscardStaleOutput { .. } + | salsa::EventKind::DidDiscard { .. } => { + self.push_log(format!("salsa_event({:?})", event.kind)); + } + _ => {} + } + } +} + +impl LoggerDb { + /// Log an event from inside a tracked function. + pub(crate) fn push_log(&self, string: String) { + self.logger.logs.lock().unwrap().push(string); + } + + /// Asserts what the (formatted) logs should look like, + /// clearing the logged events. This takes `&mut self` because + /// it is meant to be run from outside any tracked functions. + pub(crate) fn assert_logs(&self, expected: expect_test::Expect) { + let logs = std::mem::take(&mut *self.logger.logs.lock().unwrap()); + expected.assert_eq(&format!("{:#?}", logs)); + } +} + +/// Test the logger database. +/// +/// This test isn't very interesting, but it *does* remove a dead code warning. +#[test] +fn test_logger_db() { + let db = LoggerDb::default(); + db.push_log("test".to_string()); + db.assert_logs(expect_test::expect![ + r#" + [ + "test", + ]"# + ]); +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/lru.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/lru.rs new file mode 100644 index 00000000000..f56dd5c2f9b --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/lru.rs @@ -0,0 +1,68 @@ +use expect_test::expect; + +mod logger_db; +use logger_db::LoggerDb; +use query_group_macro::query_group; + +#[query_group] +pub trait LruDB: salsa::Database { + // // input with no params + #[salsa::input] + fn input_string(&self) -> String; + + #[salsa::lru(16)] + #[salsa::invoke_interned(length_query)] + fn length_query(&self, key: ()) -> usize; + + #[salsa::lru(16)] + #[salsa::invoke_interned(invoked_query)] + fn length_query_invoke(&self, key: ()) -> usize; +} + +fn length_query(db: &dyn LruDB, _key: ()) -> usize { + db.input_string().len() +} + +fn invoked_query(db: &dyn LruDB, _key: ()) -> usize { + db.input_string().len() +} + +#[test] +fn plain_lru() { + let mut db = LoggerDb::default(); + + db.set_input_string(String::from("Hello, world!")); + let len = db.length_query(()); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_LruDB(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(DidValidateMemoizedValue { database_key: create_data_LruDB(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: length_query_shim(Id(800)) })", + "salsa_event(WillCheckCancellation)", + ]"#]]); +} + +#[test] +fn invoke_lru() { + let mut db = LoggerDb::default(); + + db.set_input_string(String::from("Hello, world!")); + let len = db.length_query_invoke(()); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_LruDB(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(DidValidateMemoizedValue { database_key: create_data_LruDB(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: length_query_invoke_shim(Id(800)) })", + "salsa_event(WillCheckCancellation)", + ]"#]]); +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/multiple_dbs.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/multiple_dbs.rs new file mode 100644 index 00000000000..f36e7fdbebf --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/multiple_dbs.rs @@ -0,0 +1,25 @@ +use query_group_macro::query_group; + +#[query_group] +pub trait DatabaseOne: salsa::Database { + #[salsa::input] + fn input_string(&self) -> String; + + // unadorned query + #[salsa::invoke_interned(length)] + fn length(&self, key: ()) -> usize; +} + +#[query_group] +pub trait DatabaseTwo: DatabaseOne { + #[salsa::invoke_interned(second_length)] + fn second_length(&self, key: ()) -> usize; +} + +fn length(db: &dyn DatabaseOne, _key: ()) -> usize { + db.input_string().len() +} + +fn second_length(db: &dyn DatabaseTwo, _key: ()) -> usize { + db.input_string().len() +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/old_and_new.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/old_and_new.rs new file mode 100644 index 00000000000..a18b23a7d8a --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/old_and_new.rs @@ -0,0 +1,109 @@ +use expect_test::expect; + +mod logger_db; +use logger_db::LoggerDb; +use query_group_macro::query_group; + +#[salsa::input] +struct Input { + str: String, +} + +#[query_group] +trait PartialMigrationDatabase: salsa::Database { + fn length_query(&self, input: Input) -> usize; + + // renamed/invoke query + #[salsa::invoke(invoke_length_query_actual)] + fn invoke_length_query(&self, input: Input) -> usize; + + // invoke tracked function + #[salsa::invoke(invoke_length_tracked_actual)] + fn invoke_length_tracked(&self, input: Input) -> usize; +} + +fn length_query(db: &dyn PartialMigrationDatabase, input: Input) -> usize { + input.str(db).len() +} + +fn invoke_length_query_actual(db: &dyn PartialMigrationDatabase, input: Input) -> usize { + input.str(db).len() +} + +#[salsa::tracked] +fn invoke_length_tracked_actual(db: &dyn PartialMigrationDatabase, input: Input) -> usize { + input.str(db).len() +} + +#[test] +fn unadorned_query() { + let db = LoggerDb::default(); + + let input = Input::new(&db, String::from("Hello, world!")); + let len = db.length_query(input); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: length_query_shim(Id(0)) })", + ]"#]]); +} + +#[test] +fn invoke_query() { + let db = LoggerDb::default(); + + let input = Input::new(&db, String::from("Hello, world!")); + let len = db.invoke_length_query(input); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: invoke_length_query_shim(Id(0)) })", + ]"#]]); +} + +// todo: does this even make sense? +#[test] +fn invoke_tracked_query() { + let db = LoggerDb::default(); + + let input = Input::new(&db, String::from("Hello, world!")); + let len = db.invoke_length_tracked(input); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: invoke_length_tracked_shim(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: invoke_length_tracked_actual(Id(0)) })", + ]"#]]); +} + +#[test] +fn new_salsa_baseline() { + let db = LoggerDb::default(); + + #[salsa::input] + struct Input { + str: String, + } + + #[salsa::tracked] + fn new_salsa_length_query(db: &dyn PartialMigrationDatabase, input: Input) -> usize { + input.str(db).len() + } + + let input = Input::new(&db, String::from("Hello, world!")); + let len = new_salsa_length_query(&db, input); + + assert_eq!(len, 13); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: new_salsa_length_query(Id(0)) })", + ]"#]]); +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/result.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/result.rs new file mode 100644 index 00000000000..06f7f403c7e --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/result.rs @@ -0,0 +1,52 @@ +mod logger_db; +use expect_test::expect; +use logger_db::LoggerDb; + +use query_group_macro::query_group; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Error; + +#[query_group] +pub trait ResultDatabase: salsa::Database { + #[salsa::input] + fn input_string(&self) -> String; + + #[salsa::invoke_interned(length)] + fn length(&self, key: ()) -> Result<usize, Error>; + + #[salsa::invoke_interned(length2)] + fn length2(&self, key: ()) -> Result<usize, Error>; +} + +fn length(db: &dyn ResultDatabase, _key: ()) -> Result<usize, Error> { + Ok(db.input_string().len()) +} + +fn length2(db: &dyn ResultDatabase, _key: ()) -> Result<usize, Error> { + Ok(db.input_string().len()) +} + +#[test] +fn test_queries_with_results() { + let mut db = LoggerDb::default(); + let input = "hello"; + db.set_input_string(input.to_owned()); + assert_eq!(db.length(()), Ok(input.len())); + assert_eq!(db.length2(()), Ok(input.len())); + + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_ResultDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(DidValidateMemoizedValue { database_key: create_data_ResultDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: length_shim(Id(800)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: length2_shim(Id(c00)) })", + "salsa_event(WillCheckCancellation)", + ]"#]]); +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/supertrait.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/supertrait.rs new file mode 100644 index 00000000000..70073ac1de3 --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/supertrait.rs @@ -0,0 +1,20 @@ +use query_group_macro::query_group; + +#[salsa::db] +pub trait SourceDb: salsa::Database { + /// Text of the file. + fn file_text(&self, id: usize) -> String; +} + +#[query_group] +pub trait RootDb: SourceDb { + #[salsa::invoke_interned(parse)] + fn parse(&self, id: usize) -> String; +} + +fn parse(db: &dyn RootDb, id: usize) -> String { + // this is the test: does the following compile? + db.file_text(id); + + String::new() +} diff --git a/src/tools/rust-analyzer/crates/query-group-macro/tests/tuples.rs b/src/tools/rust-analyzer/crates/query-group-macro/tests/tuples.rs new file mode 100644 index 00000000000..af0e852695e --- /dev/null +++ b/src/tools/rust-analyzer/crates/query-group-macro/tests/tuples.rs @@ -0,0 +1,39 @@ +use query_group_macro::query_group; + +mod logger_db; +use expect_test::expect; +use logger_db::LoggerDb; + +#[query_group] +pub trait HelloWorldDatabase: salsa::Database { + #[salsa::input] + fn input_string(&self) -> String; + + #[salsa::invoke_interned(length_query)] + fn length_query(&self, key: ()) -> (usize, usize); +} + +fn length_query(db: &dyn HelloWorldDatabase, _key: ()) -> (usize, usize) { + let len = db.input_string().len(); + (len, len) +} + +#[test] +fn query() { + let mut db = LoggerDb::default(); + + db.set_input_string(String::from("Hello, world!")); + let len = db.length_query(()); + + assert_eq!(len, (13, 13)); + db.assert_logs(expect![[r#" + [ + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: create_data_HelloWorldDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(DidValidateMemoizedValue { database_key: create_data_HelloWorldDatabase(Id(0)) })", + "salsa_event(WillCheckCancellation)", + "salsa_event(WillExecute { database_key: length_query_shim(Id(800)) })", + "salsa_event(WillCheckCancellation)", + ]"#]]); +} |
