|
4 | 4 | mod common;
|
5 | 5 | use common::LogDatabase;
|
6 | 6 | use expect_test::expect;
|
7 |
| -use salsa::{Database, Setter}; |
| 7 | +use salsa::{Database, Durability, Setter}; |
8 | 8 | use test_log::test;
|
9 | 9 |
|
10 | 10 | #[salsa::input]
|
@@ -342,3 +342,47 @@ fn test_reuse_multiple_interned_input() {
|
342 | 342 | let result = use_nested_interned(&db, nested_interned);
|
343 | 343 | assert_eq!(result, 2);
|
344 | 344 | }
|
| 345 | + |
| 346 | +#[test] |
| 347 | +fn test_durability_increase() { |
| 348 | + #[salsa::tracked] |
| 349 | + fn intern<'db>(db: &'db dyn Database, input: Input, value: usize) -> Interned<'db> { |
| 350 | + let _f = input.field1(db); |
| 351 | + Interned::new(db, BadHash(value)) |
| 352 | + } |
| 353 | + |
| 354 | + let mut db = common::EventLoggerDatabase::default(); |
| 355 | + |
| 356 | + let high_durability = Input::builder(0).durability(Durability::HIGH).new(&db); |
| 357 | + let low_durability = Input::builder(1).durability(Durability::LOW).new(&db); |
| 358 | + |
| 359 | + // Intern `i0`. |
| 360 | + let _i0 = intern(&db, low_durability, 0); |
| 361 | + // Re-intern `i0`, this time using a high-durability. |
| 362 | + let _i0 = intern(&db, high_durability, 0); |
| 363 | + |
| 364 | + // Get the garbage collector to consider `i0` stale. |
| 365 | + for _ in 0..100 { |
| 366 | + let _dummy = intern(&db, low_durability, 1000).field1(&db); |
| 367 | + db.synthetic_write(Durability::LOW); |
| 368 | + } |
| 369 | + |
| 370 | + // Intern `i1`. |
| 371 | + // |
| 372 | + // The slot of `i0` should not be reused as it is high-durability, and there |
| 373 | + // were no high-durability writes. |
| 374 | + let _i1 = intern(&db, low_durability, 1); |
| 375 | + |
| 376 | + // Re-intern and read `i0`. |
| 377 | + // |
| 378 | + // If the slot was reused, the memo would be shallow-verified and we would |
| 379 | + // read `i1` incorrectly. |
| 380 | + let value = intern(&db, high_durability, 0); |
| 381 | + assert_eq!(value.field1(&db).0, 0); |
| 382 | + |
| 383 | + db.synthetic_write(Durability::LOW); |
| 384 | + |
| 385 | + // We should have the same issue even after a low-durability write. |
| 386 | + let value = intern(&db, high_durability, 0); |
| 387 | + assert_eq!(value.field1(&db).0, 0); |
| 388 | +} |
0 commit comments