From 2778750fdfc8c2c6397184a23aa2124190c5e883 Mon Sep 17 00:00:00 2001 From: XFFXFF <1247714429@qq.com> Date: Tue, 16 Aug 2022 07:29:43 +0800 Subject: [PATCH 1/6] add a broken test for lru --- salsa-2022-tests/tests/lru.rs | 84 +++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 salsa-2022-tests/tests/lru.rs diff --git a/salsa-2022-tests/tests/lru.rs b/salsa-2022-tests/tests/lru.rs new file mode 100644 index 00000000..324d1372 --- /dev/null +++ b/salsa-2022-tests/tests/lru.rs @@ -0,0 +1,84 @@ +//! Test that a `tracked` fn on a `salsa::input` +//! compiles and executes successfully. + +use std::sync::{atomic::{AtomicUsize, Ordering}, Arc}; + +use salsa_2022_tests::{HasLogger, Logger}; + +use expect_test::expect; +use test_log::test; + +#[salsa::jar(db = Db)] +struct Jar(MyInput, get_hot_potato); + +trait Db: salsa::DbWithJar + HasLogger {} + +#[derive(Debug, PartialEq, Eq)] +struct HotPotato(u32); + +thread_local! { + static N_POTATOES: AtomicUsize = AtomicUsize::new(0) +} + +impl HotPotato { + fn new(id: u32) -> HotPotato { + N_POTATOES.with(|n| n.fetch_add(1, Ordering::SeqCst)); + HotPotato(id) + } +} + +impl Drop for HotPotato { + fn drop(&mut self) { + N_POTATOES.with(|n| n.fetch_sub(1, Ordering::SeqCst)); + } +} + +#[salsa::input(jar = Jar)] +struct MyInput { + field: u32, +} + +#[salsa::tracked(jar = Jar, lru = 32)] +fn get_hot_potato(db: &dyn Db, input: MyInput) -> Arc { + Arc::new(HotPotato::new(input.field(db))) +} + +#[salsa::db(Jar)] +#[derive(Default)] +struct Database { + storage: salsa::Storage, + logger: Logger, +} + +impl salsa::Database for Database { + fn salsa_runtime(&self) -> &salsa::Runtime { + self.storage.runtime() + } +} + +impl Db for Database {} + +impl HasLogger for Database { + fn logger(&self) -> &Logger { + &self.logger + } +} + +fn load_n_potatoes() -> usize { + N_POTATOES.with(|n| n.load(Ordering::SeqCst)) +} + +#[test] +fn execute() { + let mut db = Database::default(); + assert_eq!(load_n_potatoes(), 0); + + for i in 0..128u32 { + let input = MyInput::new(&mut db, i); + let p = get_hot_potato(&db, input); + assert_eq!(p.0, i) + } + assert_eq!(load_n_potatoes(), 32); + + +} \ No newline at end of file From 2d59df39af96e3bc0a641af22673a8dd2e6b3c8d Mon Sep 17 00:00:00 2001 From: XFFXFF <1247714429@qq.com> Date: Tue, 16 Aug 2022 07:39:08 +0800 Subject: [PATCH 2/6] parse the lru option --- .../salsa-2022-macros/src/accumulator.rs | 2 ++ components/salsa-2022-macros/src/jar.rs | 2 ++ components/salsa-2022-macros/src/options.rs | 19 ++++++++++++++++++- .../salsa-2022-macros/src/salsa_struct.rs | 2 ++ .../salsa-2022-macros/src/tracked_fn.rs | 2 ++ 5 files changed, 26 insertions(+), 1 deletion(-) diff --git a/components/salsa-2022-macros/src/accumulator.rs b/components/salsa-2022-macros/src/accumulator.rs index cfc32c9e..26276398 100644 --- a/components/salsa-2022-macros/src/accumulator.rs +++ b/components/salsa-2022-macros/src/accumulator.rs @@ -32,6 +32,8 @@ impl crate::options::AllowedOptions for Accumulator { const DB: bool = false; const RECOVERY_FN: bool = false; + + const LRU: bool = false; } fn accumulator_contents( diff --git a/components/salsa-2022-macros/src/jar.rs b/components/salsa-2022-macros/src/jar.rs index 7a6498d4..5c582abd 100644 --- a/components/salsa-2022-macros/src/jar.rs +++ b/components/salsa-2022-macros/src/jar.rs @@ -41,6 +41,8 @@ impl crate::options::AllowedOptions for Jar { const DB: bool = true; const RECOVERY_FN: bool = false; + + const LRU: bool = false; } pub(crate) fn jar_struct_and_friends( diff --git a/components/salsa-2022-macros/src/options.rs b/components/salsa-2022-macros/src/options.rs index eb8bd937..bfbd4c26 100644 --- a/components/salsa-2022-macros/src/options.rs +++ b/components/salsa-2022-macros/src/options.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; -use syn::{ext::IdentExt, spanned::Spanned}; +use syn::{ext::IdentExt, spanned::Spanned, LitInt}; /// "Options" are flags that can be supplied to the various salsa related /// macros. They are listed like `(ref, no_eq, foo=bar)` etc. The commas @@ -46,6 +46,8 @@ pub(crate) struct Options { /// If this is `Some`, the value is the ``. pub data: Option, + pub lru: Option, + /// Remember the `A` parameter, which plays no role after parsing. phantom: PhantomData, } @@ -61,6 +63,7 @@ impl Default for Options { recovery_fn: Default::default(), data: Default::default(), phantom: Default::default(), + lru: Default::default(), } } } @@ -74,6 +77,7 @@ pub(crate) trait AllowedOptions { const DATA: bool; const DB: bool; const RECOVERY_FN: bool; + const LRU: bool; } type Equals = syn::Token![=]; @@ -195,6 +199,19 @@ impl syn::parse::Parse for Options { "`data` option not allowed here", )); } + } else if ident == "lru" { + if A::LRU { + let _eq = Equals::parse(input)?; + let lit: LitInt = input.parse()?; + if let Some(old) = std::mem::replace(&mut options.lru, Some(lit)) { + return Err(syn::Error::new(old.span(), "option `lru` provided twice")); + } + } else { + return Err(syn::Error::new( + ident.span(), + "`lru` option not allowed here", + )); + } } else { return Err(syn::Error::new( ident.span(), diff --git a/components/salsa-2022-macros/src/salsa_struct.rs b/components/salsa-2022-macros/src/salsa_struct.rs index beb7f0d2..48e4298f 100644 --- a/components/salsa-2022-macros/src/salsa_struct.rs +++ b/components/salsa-2022-macros/src/salsa_struct.rs @@ -50,6 +50,8 @@ impl crate::options::AllowedOptions for SalsaStruct { const DB: bool = false; const RECOVERY_FN: bool = false; + + const LRU: bool = false; } const BANNED_FIELD_NAMES: &[&str] = &["from", "new"]; diff --git a/components/salsa-2022-macros/src/tracked_fn.rs b/components/salsa-2022-macros/src/tracked_fn.rs index 8c0884e1..d5bcb940 100644 --- a/components/salsa-2022-macros/src/tracked_fn.rs +++ b/components/salsa-2022-macros/src/tracked_fn.rs @@ -72,6 +72,8 @@ impl crate::options::AllowedOptions for TrackedFn { const DB: bool = false; const RECOVERY_FN: bool = true; + + const LRU: bool = true; } /// Returns the key type for this tracked function. From d080e349efe3c93c48d8f599d4dceff49476cfc4 Mon Sep 17 00:00:00 2001 From: XFFXFF <1247714429@qq.com> Date: Tue, 16 Aug 2022 08:46:59 +0800 Subject: [PATCH 3/6] make lru option work --- .../salsa-2022-macros/src/tracked_fn.rs | 59 ++++++++++++++----- components/salsa-2022/src/function/lru.rs | 1 + salsa-2022-tests/tests/lru.rs | 8 ++- 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/components/salsa-2022-macros/src/tracked_fn.rs b/components/salsa-2022-macros/src/tracked_fn.rs index d5bcb940..01f6ebe4 100644 --- a/components/salsa-2022-macros/src/tracked_fn.rs +++ b/components/salsa-2022-macros/src/tracked_fn.rs @@ -230,6 +230,48 @@ fn ingredients_for_impl( } }; + let function: syn::Expr = if let Some(lru) = args.lru.clone() { + parse_quote! { + { + let index = routes.push( + |jars| { + let jar = >::jar_from_jars(jars); + let ingredients = + <_ as salsa::storage::HasIngredientsFor>::ingredient(jar); + &ingredients.function + }, + |jars| { + let jar = >::jar_from_jars_mut(jars); + let ingredients = + <_ as salsa::storage::HasIngredientsFor>::ingredient_mut(jar); + &mut ingredients.function + }); + let ingredient = salsa::function::FunctionIngredient::new(index); + ingredient.set_capacity(#lru); + ingredient + } + } + } else { + parse_quote! { + { + let index = routes.push( + |jars| { + let jar = >::jar_from_jars(jars); + let ingredients = + <_ as salsa::storage::HasIngredientsFor>::ingredient(jar); + &ingredients.function + }, + |jars| { + let jar = >::jar_from_jars_mut(jars); + let ingredients = + <_ as salsa::storage::HasIngredientsFor>::ingredient_mut(jar); + &mut ingredients.function + }); + salsa::function::FunctionIngredient::new(index) + } + } + }; + parse_quote! { impl salsa::storage::IngredientsFor for #config_ty { type Ingredients = Self; @@ -242,22 +284,7 @@ fn ingredients_for_impl( Self { intern_map: #intern_map, - function: { - let index = routes.push( - |jars| { - let jar = >::jar_from_jars(jars); - let ingredients = - <_ as salsa::storage::HasIngredientsFor>::ingredient(jar); - &ingredients.function - }, - |jars| { - let jar = >::jar_from_jars_mut(jars); - let ingredients = - <_ as salsa::storage::HasIngredientsFor>::ingredient_mut(jar); - &mut ingredients.function - }); - salsa::function::FunctionIngredient::new(index) - }, + function: #function } } } diff --git a/components/salsa-2022/src/function/lru.rs b/components/salsa-2022/src/function/lru.rs index fdc80073..9d95f8b2 100644 --- a/components/salsa-2022/src/function/lru.rs +++ b/components/salsa-2022/src/function/lru.rs @@ -18,6 +18,7 @@ impl Lru { return None; } + let mut set = self.set.lock(); set.insert(index); if set.len() > capacity { diff --git a/salsa-2022-tests/tests/lru.rs b/salsa-2022-tests/tests/lru.rs index 324d1372..d6e3031d 100644 --- a/salsa-2022-tests/tests/lru.rs +++ b/salsa-2022-tests/tests/lru.rs @@ -9,7 +9,7 @@ use expect_test::expect; use test_log::test; #[salsa::jar(db = Db)] -struct Jar(MyInput, get_hot_potato); +struct Jar(MyInput, get_hot_potato, EmptyInput); trait Db: salsa::DbWithJar + HasLogger {} @@ -43,6 +43,9 @@ fn get_hot_potato(db: &dyn Db, input: MyInput) -> Arc { Arc::new(HotPotato::new(input.field(db))) } +#[salsa::input(jar = Jar)] +struct EmptyInput {} + #[salsa::db(Jar)] #[derive(Default)] struct Database { @@ -78,7 +81,6 @@ fn execute() { let p = get_hot_potato(&db, input); assert_eq!(p.0, i) } + EmptyInput::new(&mut db); assert_eq!(load_n_potatoes(), 32); - - } \ No newline at end of file From 341fc807266aeecba4fcbce35a86a83b982e86e7 Mon Sep 17 00:00:00 2001 From: XFFXFF <1247714429@qq.com> Date: Wed, 17 Aug 2022 17:22:12 +0800 Subject: [PATCH 4/6] port more tests about lru --- components/salsa-2022-macros/src/options.rs | 3 ++ salsa-2022-tests/tests/lru.rs | 36 ++++++++++++++++++--- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/components/salsa-2022-macros/src/options.rs b/components/salsa-2022-macros/src/options.rs index bfbd4c26..a84d63b3 100644 --- a/components/salsa-2022-macros/src/options.rs +++ b/components/salsa-2022-macros/src/options.rs @@ -46,6 +46,9 @@ pub(crate) struct Options { /// If this is `Some`, the value is the ``. pub data: Option, + /// The `lru = ` option is used to set the lru capacity for a tracked function. + /// + /// If this is `Some`, the value is the ``. pub lru: Option, /// Remember the `A` parameter, which plays no role after parsing. diff --git a/salsa-2022-tests/tests/lru.rs b/salsa-2022-tests/tests/lru.rs index d6e3031d..55f70f1e 100644 --- a/salsa-2022-tests/tests/lru.rs +++ b/salsa-2022-tests/tests/lru.rs @@ -1,15 +1,14 @@ -//! Test that a `tracked` fn on a `salsa::input` +//! Test that a `tracked` fn with lru options //! compiles and executes successfully. use std::sync::{atomic::{AtomicUsize, Ordering}, Arc}; use salsa_2022_tests::{HasLogger, Logger}; -use expect_test::expect; use test_log::test; #[salsa::jar(db = Db)] -struct Jar(MyInput, get_hot_potato, EmptyInput); +struct Jar(MyInput, get_hot_potato, EmptyInput, get_volatile); trait Db: salsa::DbWithJar + HasLogger {} @@ -43,6 +42,13 @@ fn get_hot_potato(db: &dyn Db, input: MyInput) -> Arc { Arc::new(HotPotato::new(input.field(db))) } +#[salsa::tracked(jar = Jar, lru = 32)] +fn get_volatile(db: &dyn Db, _input: MyInput) -> usize { + static COUNTER: AtomicUsize = AtomicUsize::new(0); + db.salsa_runtime().report_untracked_read(); + COUNTER.fetch_add(1, Ordering::SeqCst) +} + #[salsa::input(jar = Jar)] struct EmptyInput {} @@ -72,7 +78,7 @@ fn load_n_potatoes() -> usize { } #[test] -fn execute() { +fn lru_works() { let mut db = Database::default(); assert_eq!(load_n_potatoes(), 0); @@ -81,6 +87,26 @@ fn execute() { let p = get_hot_potato(&db, input); assert_eq!(p.0, i) } - EmptyInput::new(&mut db); + + // Create a new input to change the revision, and trigger the GC + MyInput::new(&mut db, 0); assert_eq!(load_n_potatoes(), 32); +} + +#[test] +fn lru_doesnt_break_volatile_queries() { + let mut db = Database::default(); + + // Create all inputs first, so that there are no revision changes among calls to `get_volatile` + let inputs: Vec = (0..128usize).map(|i| MyInput::new(&mut db, i as u32)).collect(); + + // Here, we check that we execute each volatile query at most once, despite + // LRU. That does mean that we have more values in DB than the LRU capacity, + // but it's much better than inconsistent results from volatile queries! + for _ in 0..3 { + for (i, input) in inputs.iter().enumerate() { + let x = get_volatile(&db, *input); + assert_eq!(x, i); + } + } } \ No newline at end of file From 53785f1355169f71a893eac6b243c9aaec5b214d Mon Sep 17 00:00:00 2001 From: XFFXFF <1247714429@qq.com> Date: Wed, 17 Aug 2022 18:43:56 +0800 Subject: [PATCH 5/6] lru and specify can not be used together --- components/salsa-2022-macros/src/tracked_fn.rs | 7 +++++++ salsa-2022-tests/tests/lru.rs | 5 +---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/components/salsa-2022-macros/src/tracked_fn.rs b/components/salsa-2022-macros/src/tracked_fn.rs index 01f6ebe4..5581cb13 100644 --- a/components/salsa-2022-macros/src/tracked_fn.rs +++ b/components/salsa-2022-macros/src/tracked_fn.rs @@ -31,6 +31,13 @@ fn tracked_fn(args: Args, item_fn: syn::ItemFn) -> syn::Result { "tracked functon takes too many argments to have its value set with `specify`", )); } + + if args.lru.is_some() { + return Err(syn::Error::new( + s.span(), + "`specify` and `lru` cannot be used together", + )); + } } let struct_item = configuration_struct(&item_fn); diff --git a/salsa-2022-tests/tests/lru.rs b/salsa-2022-tests/tests/lru.rs index 55f70f1e..fc2de93d 100644 --- a/salsa-2022-tests/tests/lru.rs +++ b/salsa-2022-tests/tests/lru.rs @@ -8,7 +8,7 @@ use salsa_2022_tests::{HasLogger, Logger}; use test_log::test; #[salsa::jar(db = Db)] -struct Jar(MyInput, get_hot_potato, EmptyInput, get_volatile); +struct Jar(MyInput, get_hot_potato, get_volatile); trait Db: salsa::DbWithJar + HasLogger {} @@ -49,9 +49,6 @@ fn get_volatile(db: &dyn Db, _input: MyInput) -> usize { COUNTER.fetch_add(1, Ordering::SeqCst) } -#[salsa::input(jar = Jar)] -struct EmptyInput {} - #[salsa::db(Jar)] #[derive(Default)] struct Database { From fc4d531d76851789b2a1120d03ef0eb1298e935c Mon Sep 17 00:00:00 2001 From: XFFXFF <1247714429@qq.com> Date: Wed, 17 Aug 2022 18:44:43 +0800 Subject: [PATCH 6/6] refactor and cargo fmt --- components/salsa-2022-macros/src/options.rs | 11 ++-- .../salsa-2022-macros/src/salsa_struct.rs | 2 +- .../salsa-2022-macros/src/tracked_fn.rs | 62 ++++++------------- components/salsa-2022/src/function/lru.rs | 1 - salsa-2022-tests/tests/lru.rs | 22 +++---- salsa-2022-tests/tests/mutate_in_place.rs | 1 - 6 files changed, 36 insertions(+), 63 deletions(-) diff --git a/components/salsa-2022-macros/src/options.rs b/components/salsa-2022-macros/src/options.rs index a84d63b3..185bde14 100644 --- a/components/salsa-2022-macros/src/options.rs +++ b/components/salsa-2022-macros/src/options.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; -use syn::{ext::IdentExt, spanned::Spanned, LitInt}; +use syn::{ext::IdentExt, spanned::Spanned}; /// "Options" are flags that can be supplied to the various salsa related /// macros. They are listed like `(ref, no_eq, foo=bar)` etc. The commas @@ -47,9 +47,9 @@ pub(crate) struct Options { pub data: Option, /// The `lru = ` option is used to set the lru capacity for a tracked function. - /// + /// /// If this is `Some`, the value is the ``. - pub lru: Option, + pub lru: Option, /// Remember the `A` parameter, which plays no role after parsing. phantom: PhantomData, @@ -205,8 +205,9 @@ impl syn::parse::Parse for Options { } else if ident == "lru" { if A::LRU { let _eq = Equals::parse(input)?; - let lit: LitInt = input.parse()?; - if let Some(old) = std::mem::replace(&mut options.lru, Some(lit)) { + let lit = syn::LitInt::parse(input)?; + let value = lit.base10_parse::()?; + if let Some(old) = std::mem::replace(&mut options.lru, Some(value)) { return Err(syn::Error::new(old.span(), "option `lru` provided twice")); } } else { diff --git a/components/salsa-2022-macros/src/salsa_struct.rs b/components/salsa-2022-macros/src/salsa_struct.rs index 48e4298f..36b01df9 100644 --- a/components/salsa-2022-macros/src/salsa_struct.rs +++ b/components/salsa-2022-macros/src/salsa_struct.rs @@ -50,7 +50,7 @@ impl crate::options::AllowedOptions for SalsaStruct { const DB: bool = false; const RECOVERY_FN: bool = false; - + const LRU: bool = false; } diff --git a/components/salsa-2022-macros/src/tracked_fn.rs b/components/salsa-2022-macros/src/tracked_fn.rs index 5581cb13..4ce59b3d 100644 --- a/components/salsa-2022-macros/src/tracked_fn.rs +++ b/components/salsa-2022-macros/src/tracked_fn.rs @@ -237,47 +237,8 @@ fn ingredients_for_impl( } }; - let function: syn::Expr = if let Some(lru) = args.lru.clone() { - parse_quote! { - { - let index = routes.push( - |jars| { - let jar = >::jar_from_jars(jars); - let ingredients = - <_ as salsa::storage::HasIngredientsFor>::ingredient(jar); - &ingredients.function - }, - |jars| { - let jar = >::jar_from_jars_mut(jars); - let ingredients = - <_ as salsa::storage::HasIngredientsFor>::ingredient_mut(jar); - &mut ingredients.function - }); - let ingredient = salsa::function::FunctionIngredient::new(index); - ingredient.set_capacity(#lru); - ingredient - } - } - } else { - parse_quote! { - { - let index = routes.push( - |jars| { - let jar = >::jar_from_jars(jars); - let ingredients = - <_ as salsa::storage::HasIngredientsFor>::ingredient(jar); - &ingredients.function - }, - |jars| { - let jar = >::jar_from_jars_mut(jars); - let ingredients = - <_ as salsa::storage::HasIngredientsFor>::ingredient_mut(jar); - &mut ingredients.function - }); - salsa::function::FunctionIngredient::new(index) - } - } - }; + // set 0 as default to disable LRU + let lru = args.lru.unwrap_or(0); parse_quote! { impl salsa::storage::IngredientsFor for #config_ty { @@ -291,7 +252,24 @@ fn ingredients_for_impl( Self { intern_map: #intern_map, - function: #function + function: { + let index = routes.push( + |jars| { + let jar = >::jar_from_jars(jars); + let ingredients = + <_ as salsa::storage::HasIngredientsFor>::ingredient(jar); + &ingredients.function + }, + |jars| { + let jar = >::jar_from_jars_mut(jars); + let ingredients = + <_ as salsa::storage::HasIngredientsFor>::ingredient_mut(jar); + &mut ingredients.function + }); + let ingredient = salsa::function::FunctionIngredient::new(index); + ingredient.set_capacity(#lru); + ingredient + } } } } diff --git a/components/salsa-2022/src/function/lru.rs b/components/salsa-2022/src/function/lru.rs index 9d95f8b2..fdc80073 100644 --- a/components/salsa-2022/src/function/lru.rs +++ b/components/salsa-2022/src/function/lru.rs @@ -18,7 +18,6 @@ impl Lru { return None; } - let mut set = self.set.lock(); set.insert(index); if set.len() > capacity { diff --git a/salsa-2022-tests/tests/lru.rs b/salsa-2022-tests/tests/lru.rs index fc2de93d..21d2ecb4 100644 --- a/salsa-2022-tests/tests/lru.rs +++ b/salsa-2022-tests/tests/lru.rs @@ -1,16 +1,17 @@ //! Test that a `tracked` fn with lru options //! compiles and executes successfully. -use std::sync::{atomic::{AtomicUsize, Ordering}, Arc}; - -use salsa_2022_tests::{HasLogger, Logger}; +use std::sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, +}; use test_log::test; #[salsa::jar(db = Db)] struct Jar(MyInput, get_hot_potato, get_volatile); -trait Db: salsa::DbWithJar + HasLogger {} +trait Db: salsa::DbWithJar {} #[derive(Debug, PartialEq, Eq)] struct HotPotato(u32); @@ -53,7 +54,6 @@ fn get_volatile(db: &dyn Db, _input: MyInput) -> usize { #[derive(Default)] struct Database { storage: salsa::Storage, - logger: Logger, } impl salsa::Database for Database { @@ -64,12 +64,6 @@ impl salsa::Database for Database { impl Db for Database {} -impl HasLogger for Database { - fn logger(&self) -> &Logger { - &self.logger - } -} - fn load_n_potatoes() -> usize { N_POTATOES.with(|n| n.load(Ordering::SeqCst)) } @@ -95,7 +89,9 @@ fn lru_doesnt_break_volatile_queries() { let mut db = Database::default(); // Create all inputs first, so that there are no revision changes among calls to `get_volatile` - let inputs: Vec = (0..128usize).map(|i| MyInput::new(&mut db, i as u32)).collect(); + let inputs: Vec = (0..128usize) + .map(|i| MyInput::new(&mut db, i as u32)) + .collect(); // Here, we check that we execute each volatile query at most once, despite // LRU. That does mean that we have more values in DB than the LRU capacity, @@ -106,4 +102,4 @@ fn lru_doesnt_break_volatile_queries() { assert_eq!(x, i); } } -} \ No newline at end of file +} diff --git a/salsa-2022-tests/tests/mutate_in_place.rs b/salsa-2022-tests/tests/mutate_in_place.rs index 4d6c1a5c..83166c96 100644 --- a/salsa-2022-tests/tests/mutate_in_place.rs +++ b/salsa-2022-tests/tests/mutate_in_place.rs @@ -3,7 +3,6 @@ use salsa_2022_tests::{HasLogger, Logger}; -use expect_test::expect; use test_log::test; #[salsa::jar(db = Db)]