Hello, I've recently implemented some redundant code as an async function that takes an async closure. In one of my attempts to call it, I have no problem, but in the other I get the following error:
async block may outlive the current function, but it borrows current_set
, which is owned by the current function
I think lifetimes can help me correctly constrain the function, but I don't understand what they should be or where they shoudl be. Here is the minimally reproduced code:
pub async fn operate_on_same_timestamp< Func, Fut>(rows : Vec<PgresRow>, mut operator : Func) -> Result<(), Status>
where
Func : FnMut(Vec<PgresRow>) -> Fut,
Fut : Future<Output = Result<(), Status>>
{
let mut next_set = rows;
while next_set.len() != 0
{
let first_date_time = next_set[0].get::<&str, DateTime<Utc>>("session_time");
let (current_set, rest_set) : (Vec<PgresRow>, Vec<PgresRow>) = next_set.into_iter().partition(|row| { row.get::<&str, DateTime<Utc>>("session_time") == first_date_time });
next_set = rest_set;
operator(current_set).await?;
}
Ok(())
}
And the function that calls it:
async fn append_similar_times(
&self,
row_set: Vec<PgresRow>,
) -> Result<Vec<ProposedSession>, Status> {
let return_set = Arc::new(Mutex::new(vec![]));
operate_on_same_timestamp(row_set, |current_set| async {
let return_set = return_set.clone();
let mut return_set = return_set.lock().await;
let date_time = grpc_auto_error!(
tonic::Code::OutOfRange,
current_set[0].try_get("session_time")
);
let date_time = grpc_auto_error!(
tonic::Code::InvalidArgument,
convert_from_sql_timestamp(&date_time)
);
let inner_date = date_time.date.as_ref().ok_or(Status::new(
tonic::Code::InvalidArgument,
"Date option was not available",
))?;
let inner_time = date_time.time.as_ref().ok_or(Status::new(
tonic::Code::InvalidArgument,
"Hour option was not available",
))?;
let month = inner_date.month;
let year = inner_date.year;
let day = inner_date.day;
let hour = inner_time.hour;
let minute = inner_time.minute;
let coach_id =
grpc_auto_error!(tonic::Code::OutOfRange, current_set[0].try_get("coach_id"));
let duration_minutes = grpc_auto_error!(
tonic::Code::OutOfRange,
current_set[0].try_get("session_duration")
);
let cost_session_cents = grpc_auto_error!(
tonic::Code::OutOfRange,
current_set[0].try_get("price_cents")
);
return_set.push(ProposedSession {
proposed_session_id: vec![],
coach_id,
location: None,
date_time: Some(DateTimeSession {
date: Some(Date { month, year, day }),
time: Some(Time { hour, minute }),
}),
duration_minutes,
session_types: vec![],
cost_session_cents,
});
//Add location data
if let Some(last_element) = return_set.last_mut() {
for row in current_set.iter() {
let prop_sess_id =
grpc_auto_error!(tonic::Code::OutOfRange, row.try_get("proposed_session_id"));
let sess_types =
grpc_auto_error!(tonic::Code::OutOfRange, row.try_get("session_string"));
last_element.proposed_session_id.push(prop_sess_id);
last_element.session_types.push(sess_types);
}
}
Ok(())
})
.await?;
let return_set = return_set.lock().await;
Ok(return_set.clone())
}
The full error message:
error[E0373]: async block may outlive the current function, but it borrows `current_set`, which is owned by the current function
--> src/query_interface.rs:71:64
|
71 | operate_on_same_timestamp(row_set, |current_set| async {
| ________________________________________________________________^
72 | |
73 | | let return_set = return_set.clone();
74 | | let mut return_set = return_set.lock().await;
75 | |
76 | | let date_time = grpc_auto_error!(tonic::Code::OutOfRange, current_set[0]....
| | ----------- `current_set` is borrowed here
... |
114 | | Ok(())
115 | | }).await?;
| |_____________________________________________________________^ may outlive borrowed value `current_set`
|
note: async block is returned here
--> src/query_interface.rs:71:58
|
71 | operate_on_same_timestamp(row_set, |current_set| async {
| __________________________________________________________^
72 | |
73 | | let return_set = return_set.clone();
74 | | let mut return_set = return_set.lock().await;
... |
114 | | Ok(())
115 | | }).await?;
| |_____________________________________________________________^