Skip to content

Commit 13a2bd7

Browse files
Changed return_ref syntax to returns(as_ref) and returns(cloned) (#772)
* Changed `return_ref` syntax to `returns(as_ref)` and `returns(cloned)` * Implement * renamed module for return_mode * Rename macro, fix docs, add tests, validate return modes * Cargo fmt --------- Co-authored-by: Micha Reiser <[email protected]>
1 parent d1da991 commit 13a2bd7

Some content is hidden

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

54 files changed

+538
-172
lines changed

benches/compare.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ include!("shims/global_alloc_overwrite.rs");
1010

1111
#[salsa::input]
1212
pub struct Input {
13-
#[return_ref]
13+
#[returns(ref)]
1414
pub text: String,
1515
}
1616

@@ -22,7 +22,7 @@ pub fn length(db: &dyn salsa::Database, input: Input) -> usize {
2222

2323
#[salsa::interned]
2424
pub struct InternedInput<'db> {
25-
#[return_ref]
25+
#[returns(ref)]
2626
pub text: String,
2727
}
2828

benches/incremental.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ struct Tracked<'db> {
1515
number: usize,
1616
}
1717

18-
#[salsa::tracked(return_ref)]
18+
#[salsa::tracked(returns(ref))]
1919
#[inline(never)]
2020
fn index<'db>(db: &'db dyn salsa::Database, input: Input) -> Vec<Tracked<'db>> {
2121
(0..input.field(db)).map(|i| Tracked::new(db, i)).collect()

book/src/overview.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ pub struct ProgramFile(salsa::Id);
7979
This means that, when you have a `ProgramFile`, you can easily copy it around and put it wherever you like.
8080
To actually read any of its fields, however, you will need to use the database and a getter method.
8181

82-
### Reading fields and `return_ref`
82+
### Reading fields and `returns(ref)`
8383

8484
You can access the value of an input's fields by using the getter method.
8585
As this is only reading the field, it just needs a `&`-reference to the database:
@@ -89,13 +89,13 @@ let contents: String = file.contents(&db);
8989
```
9090

9191
Invoking the accessor clones the value from the database.
92-
Sometimes this is not what you want, so you can annotate fields with `#[return_ref]` to indicate that they should return a reference into the database instead:
92+
Sometimes this is not what you want, so you can annotate fields with `#[returns(ref)]` to indicate that they should return a reference into the database instead:
9393

9494
```rust
9595
#[salsa::input]
9696
pub struct ProgramFile {
9797
pub path: PathBuf,
98-
#[return_ref]
98+
#[returns(ref)]
9999
pub contents: String,
100100
}
101101
```
@@ -145,7 +145,7 @@ Tracked functions have to follow a particular structure:
145145
- They must take a "Salsa struct" as the second argument -- in our example, this is an input struct, but there are other kinds of Salsa structs we'll describe shortly.
146146
- They _can_ take additional arguments, but it's faster and better if they don't.
147147

148-
Tracked functions can return any clone-able type. A clone is required since, when the value is cached, the result will be cloned out of the database. Tracked functions can also be annotated with `#[return_ref]` if you would prefer to return a reference into the database instead (if `parse_file` were so annotated, then callers would actually get back an `&Ast`, for example).
148+
Tracked functions can return any clone-able type. A clone is required since, when the value is cached, the result will be cloned out of the database. Tracked functions can also be annotated with `#[returns(ref)]` if you would prefer to return a reference into the database instead (if `parse_file` were so annotated, then callers would actually get back an `&Ast`, for example).
149149

150150
## Tracked structs
151151

@@ -158,7 +158,7 @@ Example:
158158
```rust
159159
#[salsa::tracked]
160160
struct Ast<'db> {
161-
#[return_ref]
161+
#[returns(ref)]
162162
top_level_items: Vec<Item>,
163163
}
164164
```
@@ -252,7 +252,7 @@ Most compilers, for example, will define a type to represent a user identifier:
252252
```rust
253253
#[salsa::interned]
254254
struct Word {
255-
#[return_ref]
255+
#[returns(ref)]
256256
pub text: String,
257257
}
258258
```
@@ -269,7 +269,7 @@ let w3 = Word::new(db, "foo".to_string());
269269

270270
When you create two interned structs with the same field values, you are guaranteed to get back the same integer id. So here, we know that `assert_eq!(w1, w3)` is true and `assert_ne!(w1, w2)`.
271271

272-
You can access the fields of an interned struct using a getter, like `word.text(db)`. These getters respect the `#[return_ref]` annotation. Like tracked structs, the fields of interned structs are immutable.
272+
You can access the fields of an interned struct using a getter, like `word.text(db)`. These getters respect the `#[returns(ref)]` annotation. Like tracked structs, the fields of interned structs are immutable.
273273

274274
## Accumulators
275275

book/src/reference/algorithm.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fn parse_module(db: &dyn Db, module: Module) -> Ast {
2020
Ast::parse_text(module_text)
2121
}
2222

23-
#[salsa::tracked(return_ref)]
23+
#[salsa::tracked(returns(ref))]
2424
fn module_text(db: &dyn Db, module: Module) -> String {
2525
panic!("text for module `{module:?}` not set")
2626
}

book/src/tutorial/ir.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ Apart from the fields being immutable, the API for working with a tracked struct
9292

9393
- You can create a new value by using `new`: e.g., `Program::new(&db, some_statements)`
9494
- You use a getter to read the value of a field, just like with an input (e.g., `my_func.statements(db)` to read the `statements` field).
95-
- In this case, the field is tagged as `#[return_ref]`, which means that the getter will return a `&Vec<Statement>`, instead of cloning the vector.
95+
- In this case, the field is tagged as `#[returns(ref)]`, which means that the getter will return a `&Vec<Statement>`, instead of cloning the vector.
9696

9797
### The `'db` lifetime
9898

book/src/tutorial/parser.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,12 @@ Tracked functions may take other arguments as well, though our examples here do
6161
Functions that take additional arguments are less efficient and flexible.
6262
It's generally better to structure tracked functions as functions of a single Salsa struct if possible.
6363

64-
### The `return_ref` annotation
64+
### The `returns(ref)` annotation
6565

66-
You may have noticed that `parse_statements` is tagged with `#[salsa::tracked(return_ref)]`.
66+
You may have noticed that `parse_statements` is tagged with `#[salsa::tracked(returns(ref))]`.
6767
Ordinarily, when you call a tracked function, the result you get back is cloned out of the database.
68-
The `return_ref` attribute means that a reference into the database is returned instead.
68+
The `returns(ref)` attribute means that a reference into the database is returned instead.
6969
So, when called, `parse_statements` will return an `&Vec<Statement>` rather than cloning the `Vec`.
7070
This is useful as a performance optimization.
71-
(You may recall the `return_ref` annotation from the [ir](./ir.md) section of the tutorial,
71+
(You may recall the `returns(ref)` annotation from the [ir](./ir.md) section of the tutorial,
7272
where it was placed on struct fields, with roughly the same meaning.)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
1515
mod macro_if;
1616
mod maybe_backdate;
17-
mod maybe_clone;
1817
mod maybe_default;
18+
mod return_mode;
1919
mod setup_accumulator_impl;
2020
mod setup_input_struct;
2121
mod setup_interned_struct;

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

Lines changed: 2 additions & 2 deletions
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, $maybe_default:ident),
5+
($return_mode:ident, no_backdate, $maybe_default:ident),
66
$field_ty:ty,
77
$old_field_place:expr,
88
$new_field_place:expr,
@@ -20,7 +20,7 @@ macro_rules! maybe_backdate {
2020
};
2121

2222
(
23-
($maybe_clone:ident, backdate, $maybe_default:ident),
23+
($return_mode:ident, backdate, $maybe_default:ident),
2424
$field_ty:ty,
2525
$old_field_place:expr,
2626
$new_field_place:expr,

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

Lines changed: 0 additions & 40 deletions
This file was deleted.

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
#[macro_export]
55
macro_rules! maybe_default {
66
(
7-
($maybe_clone:ident, $maybe_backdate:ident, default),
7+
($return_mode:ident, $maybe_backdate:ident, default),
88
$field_ty:ty,
99
$field_ref_expr:expr,
1010
) => {
1111
<$field_ty>::default()
1212
};
1313

1414
(
15-
($maybe_clone:ident, $maybe_backdate:ident, required),
15+
($return_mode:ident, $maybe_backdate:ident, required),
1616
$field_ty:ty,
1717
$field_ref_expr:expr,
1818
) => {
@@ -22,11 +22,11 @@ macro_rules! maybe_default {
2222

2323
#[macro_export]
2424
macro_rules! maybe_default_tt {
25-
(($maybe_clone:ident, $maybe_backdate:ident, default) => $($t:tt)*) => {
25+
(($return_mode:ident, $maybe_backdate:ident, default) => $($t:tt)*) => {
2626
$($t)*
2727
};
2828

29-
(($maybe_clone:ident, $maybe_backdate:ident, required) => $($t:tt)*) => {
29+
(($return_mode:ident, $maybe_backdate:ident, required) => $($t:tt)*) => {
3030

3131
};
3232
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/// Generate the expression for the return type, depending on the return mode defined in [`salsa-macros::options::Options::returns`]
2+
///
3+
/// Used when generating field getters.
4+
#[macro_export]
5+
macro_rules! return_mode_expression {
6+
(
7+
(copy, $maybe_backdate:ident, $maybe_default:ident),
8+
$field_ty:ty,
9+
$field_ref_expr:expr,
10+
) => {
11+
*$field_ref_expr
12+
};
13+
14+
(
15+
(clone, $maybe_backdate:ident, $maybe_default:ident),
16+
$field_ty:ty,
17+
$field_ref_expr:expr,
18+
) => {
19+
::core::clone::Clone::clone($field_ref_expr)
20+
};
21+
22+
(
23+
(ref, $maybe_backdate:ident, $maybe_default:ident),
24+
$field_ty:ty,
25+
$field_ref_expr:expr,
26+
) => {
27+
$field_ref_expr
28+
};
29+
30+
(
31+
(deref, $maybe_backdate:ident, $maybe_default:ident),
32+
$field_ty:ty,
33+
$field_ref_expr:expr,
34+
) => {
35+
::core::ops::Deref::deref($field_ref_expr)
36+
};
37+
38+
(
39+
(as_ref, $maybe_backdate:ident, $maybe_default:ident),
40+
$field_ty:ty,
41+
$field_ref_expr:expr,
42+
) => {
43+
::salsa::SalsaAsRef::as_ref($field_ref_expr)
44+
};
45+
46+
(
47+
(as_deref, $maybe_backdate:ident, $maybe_default:ident),
48+
$field_ty:ty,
49+
$field_ref_expr:expr,
50+
) => {
51+
::salsa::SalsaAsDeref::as_deref($field_ref_expr)
52+
};
53+
}
54+
55+
#[macro_export]
56+
macro_rules! return_mode_ty {
57+
(
58+
(copy, $maybe_backdate:ident, $maybe_default:ident),
59+
$db_lt:lifetime,
60+
$field_ty:ty
61+
) => {
62+
$field_ty
63+
};
64+
65+
(
66+
(clone, $maybe_backdate:ident, $maybe_default:ident),
67+
$db_lt:lifetime,
68+
$field_ty:ty
69+
) => {
70+
$field_ty
71+
};
72+
73+
(
74+
(ref, $maybe_backdate:ident, $maybe_default:ident),
75+
$db_lt:lifetime,
76+
$field_ty:ty
77+
) => {
78+
& $db_lt $field_ty
79+
};
80+
81+
(
82+
(deref, $maybe_backdate:ident, $maybe_default:ident),
83+
$db_lt:lifetime,
84+
$field_ty:ty
85+
) => {
86+
& $db_lt <$field_ty as ::core::ops::Deref>::Target
87+
};
88+
89+
(
90+
(as_ref, $maybe_backdate:ident, $maybe_default:ident),
91+
$db_lt:lifetime,
92+
$field_ty:ty
93+
) => {
94+
<$field_ty as ::salsa::SalsaAsRef>::AsRef<$db_lt>
95+
};
96+
97+
(
98+
(as_deref, $maybe_backdate:ident, $maybe_default:ident),
99+
$db_lt:lifetime,
100+
$field_ty:ty
101+
) => {
102+
<$field_ty as ::salsa::SalsaAsDeref>::AsDeref<$db_lt>
103+
};
104+
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ macro_rules! setup_input_struct {
182182
}
183183

184184
$(
185-
$field_getter_vis fn $field_getter_id<'db, $Db>(self, db: &'db $Db) -> $zalsa::maybe_cloned_ty!($field_option, 'db, $field_ty)
185+
$field_getter_vis fn $field_getter_id<'db, $Db>(self, db: &'db $Db) -> $zalsa::return_mode_ty!($field_option, 'db, $field_ty)
186186
where
187187
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
188188
$Db: ?Sized + $zalsa::Database,
@@ -192,7 +192,7 @@ macro_rules! setup_input_struct {
192192
self,
193193
$field_index,
194194
);
195-
$zalsa::maybe_clone!(
195+
$zalsa::return_mode_expression!(
196196
$field_option,
197197
$field_ty,
198198
&fields.$field_index,

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,13 +215,13 @@ macro_rules! setup_interned_struct {
215215
}
216216

217217
$(
218-
$field_getter_vis fn $field_getter_id<$Db>(self, db: &'db $Db) -> $zalsa::maybe_cloned_ty!($field_option, 'db, $field_ty)
218+
$field_getter_vis fn $field_getter_id<$Db>(self, db: &'db $Db) -> $zalsa::return_mode_ty!($field_option, 'db, $field_ty)
219219
where
220220
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
221221
$Db: ?Sized + $zalsa::Database,
222222
{
223223
let fields = $Configuration::ingredient(db).fields(db.as_dyn_database(), self);
224-
$zalsa::maybe_clone!(
224+
$zalsa::return_mode_expression!(
225225
$field_option,
226226
$field_ty,
227227
&fields.$field_index,

0 commit comments

Comments
 (0)