Return type with lifetime cannot return value referencing temporary value

I can not return OptionTransaction<'a> , would it be possible anyone help me?

//#[derive(Debug,Serialize, Deserialize)]
pub struct OptionTransaction<'a>{
    pub puts: &'a  Option<Transaction>
}
  pub fn new(inputs: Vec<Value>, outputs: Vec<Value>) ->  OptionTransaction<'a> {       

       OptionTransaction{ puts:
                            &Option::from(Self {            //Error---------------------
                                inputs,
                                outputs,
                            })
                        }
    }
cannot return value referencing temporary value
returns a value referencing data owned by the current functionrustcE0515
transaction.rs(169, 30): temporary value created here

Make it owning instead of borrowing:

pub struct OptionTransaction {
    pub puts: Option<Transaction>,
}

References are for short-term borrows, not for holding onto owned data. Borrowing structures can only borrow things (hold references to things) for as long as the borrowed thing lasts. In the case of your error, the borrowed thing only lasts until the end of the function.

1 Like

Good but I need lifetime 'a for the struct. Even I need attr buf for now I disabled

If it must be a borrowed struct, the thing you borrow will need to outlive it. The simplest adjustment to your code is perhaps:

pub struct OptionTransaction<'a>{
    pub puts: &'a Option<Transaction>,
}

impl Transaction {
    pub fn new(puts: &Option<Self>) -> OptionTransaction<'_> {
        OptionTransaction { puts, }
    }
}

Or maybe:

pub struct OptionTransaction<'a>{
    pub puts: Option<&'a Transaction>,
    // reference is  ^^^ here now
}

impl Transaction {
    pub fn new(&self) -> OptionTransaction<'_> {
        let puts = Some(self);
        OptionTransaction { puts, }
    }
}

But without more details as to your actual use case, the chances of these being what you need are slim.

1 Like

It have consequences like this:

 let mut c=Cell::new(maked_transactions_of_a_block.as_slice());
....

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements

because I need 'a life time...?!

Repo OpenSource

Yes. There is no getting around the fundamental issue here: a reference needs to refer to something, and the thing it refers to needs to live at least as long as the reference does.

A temporary value ceases to exist after the expression or function that owns it is fully evaluated, so anything that borrows from a temporary value must also be constrained to that lifetime. In your code, OptionTransaction borrows a reference, and in your examples, you're trying to use a reference to a temporary value in your OptionTransaction values:

OptionTransaction{ puts:
  &Option::from(Self {
    inputs,
    outputs,
  })
}

The Option returned by Option::from(…) is temporary and is destroyed at the end of the expression.

let puts = Some(self);
OptionTransaction { puts, }

The Some(self) value you create is bound to a local variable and never moved out of it, so it ceases to exist when puts goes out of scope.

In both cases, the compiler is telling you that your code contains a mistake that you might not have noticed - that you are trying to use a temporary value after it no longer exists. Given your requirements, that you are able to return the OptionTransaction, and your apparent intent to build the transaction out of Self, I suspect that what you're looking for is something akin to

pub struct OptionTransaction<'a>{
    pub puts: Option<&'a Transaction>
}

// ...

pub fn new<'a>(&'a self) -> OptionTransaction<'a> {
  OptionTransaction { Some(&self) }
}

Using the same lifetime for self and the return value tells the compiler that the return value must not live longer than self does, no matter where this is called from, but allows the return value to borrow from self.

1 Like

I think you're trying to store things "by reference", but Rust's references aren't for this purpose. Storing things in structs by reference is done with Box or Arc.

The & feature is for temporary scope-bound loans. It means the struct does not store this data.

OptionTransaction<'a> means "OptionTransaction is not the place where Transaction is stored, please look elsewhere marked by 'a".

So it's impossible to make a new Transaction and store it in OptionTransaction<'_>. It's only for viewing/referencing a pre-existing Transaction that has been already created before, in a larger scope, and has a permanent storage in some other struct or variable in another function.

In short: don't use temporary references in structs. They by definition can't return any new data from functions.

You most likely need puts: Option<Arc<Transaction>> or just puts: Option<Transaction>. If it's really sometimes newly created object owned by this struct, and sometimes a view into an object that belongs to some other struct, then Option<Cow<'a, Transaction>>.