1
1
/// Macro for setting up a function that must intern its arguments.
2
2
#[ macro_export]
3
- macro_rules! setup_input {
3
+ macro_rules! setup_input_struct {
4
4
(
5
5
// Attributes on the struct
6
6
attrs: [ $( #[ $attr: meta] ) ,* ] ,
@@ -20,8 +20,11 @@ macro_rules! setup_input {
20
20
// Field names
21
21
field_ids: [ $( $field_id: ident) ,* ] ,
22
22
23
+ // Names for field getter methods (typically `foo`)
24
+ field_getters: [ $( $field_getter_vis: vis $field_getter_id: ident) ,* ] ,
25
+
23
26
// 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) ,* ] ,
25
28
26
29
// Field types
27
30
field_tys: [ $( $field_ty: ty) ,* ] ,
@@ -32,6 +35,12 @@ macro_rules! setup_input {
32
35
// Number of fields
33
36
num_fields: $N: literal,
34
37
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
+
35
44
// Annoyingly macro-rules hygiene does not extend to items defined in the macro.
36
45
// We have the procedural macro generate names for those items that are
37
46
// not used elsewhere in the user's code.
@@ -41,9 +50,6 @@ macro_rules! setup_input {
41
50
$Configuration: ident,
42
51
$CACHE: ident,
43
52
$Db: ident,
44
- $NonNull: ident,
45
- $Revision: ident,
46
- $ValueStruct: ident,
47
53
]
48
54
) => {
49
55
$( #[ $attr] ) *
@@ -53,14 +59,13 @@ macro_rules! setup_input {
53
59
const _: ( ) = {
54
60
use salsa:: plumbing as $zalsa;
55
61
use $zalsa:: input as $zalsa_struct;
56
- use $zalsa:: Revision as $Revision;
57
- use std:: ptr:: NonNull as $NonNull;
58
62
59
63
struct $Configuration;
60
64
61
65
impl $zalsa_struct:: Configuration for $Configuration {
62
66
const DEBUG_NAME : & ' static str = stringify!( $Struct) ;
63
67
const FIELD_DEBUG_NAMES : & ' static [ & ' static str ] = & [ $( stringify!( $field_id) ) ,* ] ;
68
+ const IS_SINGLETON : bool = $is_singleton;
64
69
65
70
/// The input struct (which wraps an `Id`)
66
71
type Struct = $Struct;
@@ -73,21 +78,15 @@ macro_rules! setup_input {
73
78
}
74
79
75
80
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 > {
80
82
static CACHE : $zalsa:: IngredientCache <$zalsa_struct:: IngredientImpl <$Configuration>> =
81
83
$zalsa:: IngredientCache :: new( ) ;
82
84
CACHE . get_or_create( db, || {
83
85
db. add_or_lookup_jar_by_type( & <$zalsa_struct:: JarImpl <$Configuration>>:: default ( ) )
84
86
} )
85
87
}
86
88
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 ) {
91
90
let index = db. add_or_lookup_jar_by_type( & <$zalsa_struct:: JarImpl <$Configuration>>:: default ( ) ) ;
92
91
let ( ingredient, runtime) = db. lookup_ingredient_mut( index) ;
93
92
let ingredient = ingredient. assert_type_mut:: <$zalsa_struct:: IngredientImpl <Self >>( ) ;
@@ -107,42 +106,39 @@ macro_rules! setup_input {
107
106
}
108
107
}
109
108
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
124
120
}
125
121
}
126
122
127
123
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
129
125
where
130
126
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
131
- Db : ?Sized + salsa:: Database ,
127
+ $ Db: ?Sized + salsa:: Database ,
132
128
{
133
129
let current_revision = $zalsa:: current_revision( db) ;
134
130
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)
136
132
}
137
133
138
134
$(
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)
140
136
where
141
137
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
142
138
$Db: ?Sized + $zalsa:: Database ,
143
139
{
144
140
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) ;
146
142
$zalsa:: maybe_clone!(
147
143
$field_option,
148
144
$field_ty,
@@ -153,12 +149,12 @@ macro_rules! setup_input {
153
149
154
150
$(
155
151
#[ 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
157
153
where
158
154
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
159
155
$Db: ?Sized + $zalsa:: Database ,
160
156
{
161
- let ( ingredient, runtime) = $Configuration:: ingredient_mut( db) ;
157
+ let ( ingredient, runtime) = $Configuration:: ingredient_mut( db. as_salsa_database_mut ( ) ) ;
162
158
$zalsa:: input:: SetterImpl :: new(
163
159
runtime,
164
160
self ,
@@ -168,6 +164,42 @@ macro_rules! setup_input {
168
164
)
169
165
}
170
166
) *
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
+ }
171
203
}
172
204
} ;
173
205
} ;
0 commit comments