Skip to content

Commit 1c69d3b

Browse files
authored
Merge pull request #518 from nikomatsakis/lazy-ingredients
salsa the beautiful
2 parents 57eb0c4 + b59427c commit 1c69d3b

File tree

166 files changed

+3908
-6207
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

166 files changed

+3908
-6207
lines changed

.github/workflows/test.yml

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ jobs:
6161

6262
miri:
6363
name: Miri
64+
continue-on-error: true # FIXME: https://github.com/salsa-rs/salsa/issues/520
6465
runs-on: ubuntu-latest
6566
steps:
6667
- name: Checkout

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ salsa-macros = { path = "components/salsa-macros" }
2323
smallvec = "1.0.0"
2424

2525
[dev-dependencies]
26+
annotate-snippets = "0.11.4"
2627
derive-new = "0.5.9"
2728
expect-test = "1.4.0"
2829
eyre = "0.6.8"

components/salsa-macro-rules/src/lib.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,13 @@
1212
//! from a submodule is to use multiple crates, hence the existence
1313
//! of this crate.
1414
15+
mod macro_if;
1516
mod maybe_backdate;
1617
mod maybe_clone;
17-
mod setup_input;
18-
mod setup_interned_fn;
19-
mod setup_struct_fn;
18+
mod setup_accumulator_impl;
19+
mod setup_input_struct;
20+
mod setup_interned_struct;
21+
mod setup_method_body;
22+
mod setup_tracked_fn;
2023
mod setup_tracked_struct;
2124
mod unexpected_cycle_recovery;
22-
23-
#[macro_export]
24-
macro_rules! setup_fn {
25-
() => {};
26-
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#[macro_export]
2+
macro_rules! macro_if {
3+
(true => $($t:tt)*) => {
4+
$($t)*
5+
};
6+
7+
(false => $($t:tt)*) => {
8+
};
9+
10+
(if true { $($t:tt)* } else { $($f:tt)*}) => {
11+
$($t)*
12+
};
13+
14+
(if false { $($t:tt)* } else { $($f:tt)*}) => {
15+
$($f)*
16+
};
17+
18+
(if0 0 { $($t:tt)* } else { $($f:tt)*}) => {
19+
$($t)*
20+
};
21+
22+
(if0 $n:literal { $($t:tt)* } else { $($f:tt)*}) => {
23+
$($f)*
24+
};
25+
}

components/salsa-macro-rules/src/maybe_backdate.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#[macro_export]
33
macro_rules! maybe_backdate {
44
(
5-
($maybe_clone:ident, no_backdate)
5+
($maybe_clone:ident, no_backdate),
66
$field_ty:ty,
77
$old_field_place:expr,
88
$new_field_place:expr,
@@ -11,7 +11,7 @@ macro_rules! maybe_backdate {
1111
$zalsa:ident,
1212

1313
) => {
14-
$zalsa::update::always_update(
14+
$zalsa::always_update(
1515
&mut $revision_place,
1616
$current_revision,
1717
&mut $old_field_place,
@@ -28,12 +28,11 @@ macro_rules! maybe_backdate {
2828
$current_revision:expr,
2929
$zalsa:ident,
3030
) => {
31-
if $zalsa::update::helper::Dispatch::<$field_ty>::maybe_update(
32-
$old_field_ptr_expr,
31+
if $zalsa::UpdateDispatch::<$field_ty>::maybe_update(
3332
std::ptr::addr_of_mut!($old_field_place),
3433
$new_field_place,
3534
) {
36-
$revision_place = #current_revision;
35+
$revision_place = $current_revision;
3736
}
38-
};
37+
};
3938
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/// Macro for setting up a function that must intern its arguments.
2+
#[macro_export]
3+
macro_rules! setup_accumulator_impl {
4+
(
5+
// Name of the struct
6+
Struct: $Struct:ident,
7+
8+
// Annoyingly macro-rules hygiene does not extend to items defined in the macro.
9+
// We have the procedural macro generate names for those items that are
10+
// not used elsewhere in the user's code.
11+
unused_names: [
12+
$zalsa:ident,
13+
$zalsa_struct:ident,
14+
$CACHE:ident,
15+
$ingredient:ident,
16+
]
17+
) => {
18+
const _: () = {
19+
use salsa::plumbing as $zalsa;
20+
use salsa::plumbing::accumulator as $zalsa_struct;
21+
22+
static $CACHE: $zalsa::IngredientCache<$zalsa_struct::IngredientImpl<$Struct>> =
23+
$zalsa::IngredientCache::new();
24+
25+
fn $ingredient(db: &dyn $zalsa::Database) -> &$zalsa_struct::IngredientImpl<$Struct> {
26+
$CACHE.get_or_create(db, || {
27+
db.add_or_lookup_jar_by_type(&<$zalsa_struct::JarImpl<$Struct>>::default())
28+
})
29+
}
30+
31+
impl $zalsa::Accumulator for $Struct {
32+
const DEBUG_NAME: &'static str = stringify!($Struct);
33+
34+
fn accumulate<Db>(self, db: &Db)
35+
where
36+
Db: ?Sized + $zalsa::Database,
37+
{
38+
$ingredient(db.as_salsa_database()).push(db.runtime(), self);
39+
}
40+
}
41+
};
42+
};
43+
}

components/salsa-macro-rules/src/setup_input.rs renamed to components/salsa-macro-rules/src/setup_input_struct.rs

+68-36
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/// Macro for setting up a function that must intern its arguments.
22
#[macro_export]
3-
macro_rules! setup_input {
3+
macro_rules! setup_input_struct {
44
(
55
// Attributes on the struct
66
attrs: [$(#[$attr:meta]),*],
@@ -20,8 +20,11 @@ macro_rules! setup_input {
2020
// Field names
2121
field_ids: [$($field_id:ident),*],
2222

23+
// Names for field getter methods (typically `foo`)
24+
field_getters: [$($field_getter_vis:vis $field_getter_id:ident),*],
25+
2326
// Names for field setter methods (typically `set_foo`)
24-
field_setter_ids: [$($field_setter_id:ident),*],
27+
field_setters: [$($field_setter_vis:vis $field_setter_id:ident),*],
2528

2629
// Field types
2730
field_tys: [$($field_ty:ty),*],
@@ -32,6 +35,12 @@ macro_rules! setup_input {
3235
// Number of fields
3336
num_fields: $N:literal,
3437

38+
// If true, this is a singleton input.
39+
is_singleton: $is_singleton:tt,
40+
41+
// If true, generate a debug impl.
42+
generate_debug_impl: $generate_debug_impl:tt,
43+
3544
// Annoyingly macro-rules hygiene does not extend to items defined in the macro.
3645
// We have the procedural macro generate names for those items that are
3746
// not used elsewhere in the user's code.
@@ -41,9 +50,6 @@ macro_rules! setup_input {
4150
$Configuration:ident,
4251
$CACHE:ident,
4352
$Db:ident,
44-
$NonNull:ident,
45-
$Revision:ident,
46-
$ValueStruct:ident,
4753
]
4854
) => {
4955
$(#[$attr])*
@@ -53,14 +59,13 @@ macro_rules! setup_input {
5359
const _: () = {
5460
use salsa::plumbing as $zalsa;
5561
use $zalsa::input as $zalsa_struct;
56-
use $zalsa::Revision as $Revision;
57-
use std::ptr::NonNull as $NonNull;
5862

5963
struct $Configuration;
6064

6165
impl $zalsa_struct::Configuration for $Configuration {
6266
const DEBUG_NAME: &'static str = stringify!($Struct);
6367
const FIELD_DEBUG_NAMES: &'static [&'static str] = &[$(stringify!($field_id)),*];
68+
const IS_SINGLETON: bool = $is_singleton;
6469

6570
/// The input struct (which wraps an `Id`)
6671
type Struct = $Struct;
@@ -73,21 +78,15 @@ macro_rules! setup_input {
7378
}
7479

7580
impl $Configuration {
76-
pub fn ingredient<Db>(db: &Db) -> &$zalsa_struct::IngredientImpl<Self>
77-
where
78-
Db: ?Sized + $zalsa::Database,
79-
{
81+
pub fn ingredient(db: &dyn $zalsa::Database) -> &$zalsa_struct::IngredientImpl<Self> {
8082
static CACHE: $zalsa::IngredientCache<$zalsa_struct::IngredientImpl<$Configuration>> =
8183
$zalsa::IngredientCache::new();
8284
CACHE.get_or_create(db, || {
8385
db.add_or_lookup_jar_by_type(&<$zalsa_struct::JarImpl<$Configuration>>::default())
8486
})
8587
}
8688

87-
pub fn ingredient_mut<Db>(db: &Db) -> (&mut $zalsa_struct::IngredientImpl<Self>, &mut $zalsa::Runtime)
88-
where
89-
Db: ?Sized + $zalsa::Database,
90-
{
89+
pub fn ingredient_mut(db: &mut dyn $zalsa::Database) -> (&mut $zalsa_struct::IngredientImpl<Self>, &mut $zalsa::Runtime) {
9190
let index = db.add_or_lookup_jar_by_type(&<$zalsa_struct::JarImpl<$Configuration>>::default());
9291
let (ingredient, runtime) = db.lookup_ingredient_mut(index);
9392
let ingredient = ingredient.assert_type_mut::<$zalsa_struct::IngredientImpl<Self>>();
@@ -107,42 +106,39 @@ macro_rules! setup_input {
107106
}
108107
}
109108

110-
impl std::fmt::Debug for $Struct {
111-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
112-
$zalsa::with_attached_database(|db| {
113-
let fields = $Configuration::ingredient(db).fields(self.0);
114-
let f = f.debug_struct(stringify!($Struct));
115-
$(
116-
let f = f.field(stringify!($field_id), &fields.$field_index);
117-
)*
118-
f.finish()
119-
}).unwrap_or_else(|| {
120-
f.debug_tuple(stringify!($Struct))
121-
.field(&self.0)
122-
.finish()
123-
})
109+
$zalsa::macro_if! { $generate_debug_impl =>
110+
impl std::fmt::Debug for $Struct {
111+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
112+
Self::default_debug_fmt(*self, f)
113+
}
114+
}
115+
}
116+
117+
impl $zalsa::SalsaStructInDb for $Struct {
118+
fn register_dependent_fn(_db: &dyn $zalsa::Database, _index: $zalsa::IngredientIndex) {
119+
// Inputs don't bother with dependent functions
124120
}
125121
}
126122

127123
impl $Struct {
128-
pub fn new<Db>(db: &Db, $($field_id: $field_ty),*) -> Self
124+
pub fn $new_fn<$Db>(db: &$Db, $($field_id: $field_ty),*) -> Self
129125
where
130126
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
131-
Db: ?Sized + salsa::Database,
127+
$Db: ?Sized + salsa::Database,
132128
{
133129
let current_revision = $zalsa::current_revision(db);
134130
let stamps = $zalsa::Array::new([$zalsa::stamp(current_revision, Default::default()); $N]);
135-
$Configuration::ingredient(db).new_input(($($field_id,)*), stamps)
131+
$Configuration::ingredient(db.as_salsa_database()).new_input(($($field_id,)*), stamps)
136132
}
137133

138134
$(
139-
pub fn $field_id<'db, $Db>(self, db: &'db $Db) -> $zalsa::maybe_cloned_ty!($field_option, 'db, $field_ty)
135+
$field_getter_vis fn $field_getter_id<'db, $Db>(self, db: &'db $Db) -> $zalsa::maybe_cloned_ty!($field_option, 'db, $field_ty)
140136
where
141137
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
142138
$Db: ?Sized + $zalsa::Database,
143139
{
144140
let runtime = db.runtime();
145-
let fields = $Configuration::ingredient(db).field(runtime, self, $field_index);
141+
let fields = $Configuration::ingredient(db.as_salsa_database()).field(runtime, self, $field_index);
146142
$zalsa::maybe_clone!(
147143
$field_option,
148144
$field_ty,
@@ -153,12 +149,12 @@ macro_rules! setup_input {
153149

154150
$(
155151
#[must_use]
156-
pub fn $field_setter_id<'db, $Db>(self, db: &'db mut $Db) -> impl salsa::Setter<FieldTy = $field_ty> + 'db
152+
$field_setter_vis fn $field_setter_id<'db, $Db>(self, db: &'db mut $Db) -> impl salsa::Setter<FieldTy = $field_ty> + 'db
157153
where
158154
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
159155
$Db: ?Sized + $zalsa::Database,
160156
{
161-
let (ingredient, runtime) = $Configuration::ingredient_mut(db);
157+
let (ingredient, runtime) = $Configuration::ingredient_mut(db.as_salsa_database_mut());
162158
$zalsa::input::SetterImpl::new(
163159
runtime,
164160
self,
@@ -168,6 +164,42 @@ macro_rules! setup_input {
168164
)
169165
}
170166
)*
167+
168+
$zalsa::macro_if! { $is_singleton =>
169+
pub fn try_get<$Db>(db: &$Db) -> Option<Self>
170+
where
171+
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
172+
$Db: ?Sized + salsa::Database,
173+
{
174+
$Configuration::ingredient(db.as_salsa_database()).get_singleton_input()
175+
}
176+
177+
#[track_caller]
178+
pub fn get<$Db>(db: &$Db) -> Self
179+
where
180+
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
181+
$Db: ?Sized + salsa::Database,
182+
{
183+
Self::try_get(db).unwrap()
184+
}
185+
}
186+
187+
/// Default debug formatting for this struct (may be useful if you define your own `Debug` impl)
188+
pub fn default_debug_fmt(this: Self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
189+
$zalsa::with_attached_database(|db| {
190+
let fields = $Configuration::ingredient(db).leak_fields(this);
191+
let mut f = f.debug_struct(stringify!($Struct));
192+
let f = f.field("[salsa id]", &$zalsa::AsId::as_id(&this).as_u32());
193+
$(
194+
let f = f.field(stringify!($field_id), &fields.$field_index);
195+
)*
196+
f.finish()
197+
}).unwrap_or_else(|| {
198+
f.debug_struct(stringify!($Struct))
199+
.field("[salsa id]", &this.0.as_u32())
200+
.finish()
201+
})
202+
}
171203
}
172204
};
173205
};

0 commit comments

Comments
 (0)