Skip to content

Commit 008e7f5

Browse files
authored
Add missing lifetime replacement for generic param decls on derive(IntoFuture) impl block (#337)
1 parent 388f695 commit 008e7f5

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

bon-macros/src/builder/builder_gen/builder_derives/into_future.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ impl BuilderGenCtx {
163163
original_lifetimes: &original_lifetimes,
164164
};
165165

166+
for decl in &mut new_generics_decl {
167+
replace_lifetimes.visit_generic_param_mut(decl);
168+
}
169+
166170
let mut new_where_clause = where_clause.clone();
167171

168172
if let Some(where_clause) = &mut new_where_clause {

bon/tests/integration/builder/attr_into_future.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,30 @@ mod tests {
151151

152152
let &Dummy = assert_send(builder).await;
153153
}
154+
155+
#[tokio::test]
156+
async fn complex_generics() {
157+
struct Dummy;
158+
159+
#[builder(derive(IntoFuture(Box)))]
160+
async fn sut<'a: 'b, 'b, T: Sync + 'a + 'b, U: Sync + 'a, const N: usize>(
161+
x1: &'a T,
162+
x2: &'b U,
163+
) -> (&'a T, &'b U, usize) {
164+
async {}.await;
165+
(x1, x2, N)
166+
}
167+
168+
// Store the dummy struct in local variables to make sure no `'static`
169+
// lifetime promotion happens
170+
let local_x1 = Dummy;
171+
let local_x2 = Dummy;
172+
173+
let builder = sut::<_, _, 42>().x1(&local_x1).x2(&local_x2);
174+
175+
let (&Dummy, &Dummy, usize) = assert_send(builder).await;
176+
assert_eq!(usize, 42);
177+
}
154178
}
155179

156180
mod test_method {
@@ -253,5 +277,32 @@ mod tests {
253277

254278
let _: &Dummy = assert_send(builder).await;
255279
}
280+
281+
#[tokio::test]
282+
async fn complex_generics() {
283+
struct Dummy;
284+
285+
#[bon]
286+
impl Dummy {
287+
#[builder(derive(IntoFuture(Box)))]
288+
async fn sut<'a: 'b, 'b, T: Sync + 'a + 'b, U: Sync + 'a, const N: usize>(
289+
x1: &'a T,
290+
x2: &'b U,
291+
) -> (&'a T, &'b U, usize) {
292+
async {}.await;
293+
(x1, x2, N)
294+
}
295+
}
296+
297+
// Store the dummy struct in local variables to make sure no `'static`
298+
// lifetime promotion happens
299+
let local_x1 = Dummy;
300+
let local_x2 = Dummy;
301+
302+
let builder = Dummy::sut::<_, _, 42>().x1(&local_x1).x2(&local_x2);
303+
304+
let (&Dummy, &Dummy, usize) = assert_send(builder).await;
305+
assert_eq!(usize, 42);
306+
}
256307
}
257308
}

0 commit comments

Comments
 (0)