Here is the full code for that method, with the extra lifetimes removed. The error message it gets without the lifetimes, follows. As you see, I am still learning. All corrections welcome. I omitted but can provide the doc comments.
fn create_quantity_attribute(
//&'a self,
&self,
//transaction_in: Option<Rc<RefCell<Transaction<'b, Postgres>>>>,
transaction_in: Option<Rc<RefCell<Transaction<Postgres>>>>,
parent_id_in: i64,
attr_type_id_in: i64,
unit_id_in: i64,
number_in: f64,
valid_on_date_in: Option<i64>,
observation_date_in: i64,
sorting_index_in: Option<i64>, /*= None*/
) -> Result</*id*/ i64, anyhow::Error>
//where
// 'a: 'b,
{
//BEGIN COPY/PASTED/DUPLICATED BLOCK-----------------------------------
// Try creating a local transaction whether we use it or not, to handle compiler errors
// about variable moves. I'm not seeing a better way to get around them by just using
// conditions and an Option (many errors):
// (I tried putting this in a function, then a macro, but it gets compile errors.
// So, copy/pasting this, unfortunately, until someone thinks of a better way. (You
// can see the macro, and one of the compile errors, in the commit of 2023-05-18.
// I didn't try a proc macro but based on some reading I think it would have the same
// problem.)
let local_tx: Transaction<Postgres> = self.begin_trans()?;
let local_tx_option = Some(Rc::new(RefCell::new(local_tx)));
let transaction = if transaction_in.clone().is_some() {
transaction_in.clone()
} else {
local_tx_option
};
//END OF COPY/PASTED/DUPLICATED BLOCK----------------------------------
let id: i64 = self.get_new_key(transaction.clone(), "QuantityAttributeKeySequence")?;
let form_id = self.get_attribute_form_id(Util::QUANTITY_TYPE)?;
self.add_attribute_sorting_row(
transaction.clone(),
parent_id_in,
form_id,
id,
sorting_index_in,
)?;
let valid_on = match valid_on_date_in {
None => "NULL".to_string(),
Some(d) => format!("{}", d),
};
self.db_action(transaction.clone(),
format!("insert into QuantityAttribute (id, entity_id, unit_id, \
quantity_number, attr_type_id, valid_on_date, observation_date) values ({},{},{},{},\
{},{},{})", id, parent_id_in, unit_id_in, number_in, attr_type_id_in, valid_on, observation_date_in).as_str(),
false, false)?;
if transaction_in.is_none() && transaction.is_some() {
// see comments at similar location in delete_objects about local_tx
// see comments in delete_objects about rollback
let local_tx_cell: Option<RefCell<Transaction<Postgres>>> =
Rc::into_inner(transaction.unwrap());
match local_tx_cell {
Some(t) => {
let unwrapped_local_tx = t.into_inner();
if let Err(e) = self.commit_trans(unwrapped_local_tx) {
return Err(anyhow!(e.to_string()));
}
}
None => {
return Err(anyhow!("Unexpectedly found None instead of Some<RefCell<Transaction<Postgres>>>. How?"));
}
}
}
Ok(id)
}
Here is the interesting part again, but with the errors shown in neovim with rust-analyzer (there are 4 messages; I show it from cargo compilation farther below)
H 705 fn create_quantity_attribute( _ consider introducing a named lifetime parameter and update trait if needed: `<'a>`, `'
706 //&'a self,
H 707 &self, _ let's call the lifetime of this reference `'1`
708 //transaction_in: Option<Rc<RefCell<Transaction<'b, Postgres>>>>,
H 709 transaction_in: Option<Rc<RefCell<Transaction<Postgres>>>>, __ has type `Option<std::rc::Rc<std::cell::RefCell<sql
710 parent_id_in: i64,
711 attr_type_id_in: i64,
712 unit_id_in: i64,
713 number_in: f64,
714 valid_on_date_in: Option<i64>,
715 observation_date_in: i64,
716 sorting_index_in: Option<i64>, /*= None*/
717 ) -> Result</*id*/ i64, anyhow::Error>
718 //where
719 // 'a: 'b,
720 {
721 //BEGIN COPY/PASTED/DUPLICATED BLOCK-----------------------------------
722 // Try creating a local transaction whether we use it or not, to handle compiler errors
723 // about variable moves. I'm not seeing a better way to get around them by just using
724 // conditions and an Option (many errors): 725 // (I tried putting this in a function, then a macro, but it gets compile errors.
726 // So, copy/pasting this, unfortunately, until someone thinks of a better way. (You
727 // can see the macro, and one of the compile errors, in the commit of 2023-05-18. 728 // I didn't try a proc macro but based on some reading I think it would have the same
729 // problem.)
730 let local_tx: Transaction<Postgres> = self.begin_trans()?;
E 731 let local_tx_option = Some(Rc::new(RefCell::new(local_tx))); _ lifetime may not live long enough argument require
732 let transaction = if transaction_in.clone().is_some() {
733 transaction_in.clone()
734 } else {
735 local_tx_option
736 };
737 //END OF COPY/PASTED/DUPLICATED BLOCK----------------------------------
Here is that part from cargo compilation:
2358 error: lifetime may not live long enough
2359 --> src/model/postgres/postgresql_database3.rs:731:44
2360 |
2361 707 | &self,
2362 | - let's call the lifetime of this reference `'1`
2363 708 | //transaction_in: Option<Rc<RefCell<Transaction<'b, Postgres>>>>,
2364 709 | transaction_in: Option<Rc<RefCell<Transaction<Postgres>>>>,
2365 | -------------- has type `Option<Rc<RefCell<Transaction<'2, Postgres>>>>`
2366 ...
2367 731 | let local_tx_option = Some(Rc::new(RefCell::new(local_tx)));
2368 | ^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
2369 |
2370 help: consider introducing a named lifetime parameter and update trait if needed
2371 |
2372 705 ~ fn create_quantity_attribute<'a>(
2373 706 | //&'a self,
2374 707 ~ &'a self,
2375 708 | //transaction_in: Option<Rc<RefCell<Transaction<'b, Postgres>>>>,
2376 709 ~ transaction_in: Option<Rc<RefCell<Transaction<'a, Postgres>>>>,
2377 |